mirror of
https://github.com/Piwigo/Piwigo.git
synced 2026-10-30 21:52:00 +01:00
issue #2560 person page in the gallery, links from the avatars
This commit is contained in:
1 parent
8e818c9af4
commit
d4c4db36f3
8 files changed
+180
-53
No files matched your search
@@ -327,6 +327,7 @@ function make_section_in_url($params)
|
||||
$section_of = array(
|
||||
'category' => 'categories',
|
||||
'tags' => 'tags',
|
||||
'person' => 'people',
|
||||
'list' => 'list',
|
||||
'search' => 'search',
|
||||
);
|
||||
@@ -429,6 +430,16 @@ function make_section_in_url($params)
|
||||
|
||||
break;
|
||||
}
|
||||
case 'people' :
|
||||
{
|
||||
$section_string.= '/people/'.$params['person']['id'];
|
||||
if (!empty($params['person']['url_name']))
|
||||
{
|
||||
$section_string.= '-'.$params['person']['url_name'];
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
case 'search' :
|
||||
{
|
||||
$section_string.= '/search/'.$params['search'];
|
||||
@@ -623,6 +634,25 @@ function parse_section_url( $tokens, &$next_token)
|
||||
page_not_found(l10n('Requested tag does not exist'), get_root_url().'tags.php' );
|
||||
}
|
||||
}
|
||||
elseif ( 'people' == @$tokens[$next_token] )
|
||||
{
|
||||
$next_token++;
|
||||
|
||||
if (!isset($tokens[$next_token]) or !preg_match('/^(\d+)(?:-.*)?$/', $tokens[$next_token], $matches))
|
||||
{
|
||||
bad_request('a person id is required');
|
||||
}
|
||||
$next_token++;
|
||||
|
||||
$person = get_person_by_id($matches[1]);
|
||||
if (!can_see_people() or empty($person) or 'true' != $person['is_visible'])
|
||||
{
|
||||
page_not_found(l10n('Requested person does not exist'), get_root_url());
|
||||
}
|
||||
|
||||
$page['section'] = 'people';
|
||||
$page['person'] = $person;
|
||||
}
|
||||
elseif ( 'favorites' == @$tokens[$next_token] )
|
||||
{
|
||||
$page['section'] = 'favorites';
|
||||
|
||||
@@ -357,6 +357,47 @@ else
|
||||
);
|
||||
}
|
||||
// +-----------------------------------------------------------------------+
|
||||
// | people section |
|
||||
// +-----------------------------------------------------------------------+
|
||||
else if ($page['section'] == 'people')
|
||||
{
|
||||
$query = '
|
||||
SELECT id
|
||||
FROM '.IMAGES_TABLE.'
|
||||
INNER JOIN '.IMAGE_CATEGORY_TABLE.' ON id = image_id
|
||||
WHERE id IN (
|
||||
SELECT image_id
|
||||
FROM '.IMAGE_PERSON_TABLE.'
|
||||
WHERE person_id = '.$page['person']['id'].'
|
||||
)
|
||||
'.get_sql_condition_FandF(
|
||||
array(
|
||||
'forbidden_categories' => 'category_id',
|
||||
'visible_categories' => 'category_id',
|
||||
'visible_images' => 'id'
|
||||
),
|
||||
' AND'
|
||||
).'
|
||||
GROUP BY id
|
||||
'.$conf['order_by'].'
|
||||
;';
|
||||
$items = query2array($query, null, 'id');
|
||||
|
||||
if (count($items) == 0)
|
||||
{
|
||||
page_not_found(l10n('Requested person does not exist'), get_root_url());
|
||||
}
|
||||
|
||||
$page = array_merge(
|
||||
$page,
|
||||
array(
|
||||
'title' => l10n('People').$conf['level_separator']
|
||||
.'<a href="'.duplicate_index_url(array('start'=>0)).'">'.$page['person']['name'].'</a>',
|
||||
'items' => $items,
|
||||
)
|
||||
);
|
||||
}
|
||||
// +-----------------------------------------------------------------------+
|
||||
// | search section |
|
||||
// +-----------------------------------------------------------------------+
|
||||
else if ($page['section'] == 'search')
|
||||
@@ -692,6 +733,11 @@ elseif (isset($page['tags']))
|
||||
}
|
||||
|
||||
}
|
||||
elseif (isset($page['person']))
|
||||
{
|
||||
array_push($page['body_classes'], 'person-'.$page['person']['id']);
|
||||
$page['body_data']['person_id'] = $page['person']['id'];
|
||||
}
|
||||
elseif (isset($page['search']))
|
||||
{
|
||||
array_push($page['body_classes'], 'search-'.$page['search']);
|
||||
|
||||
@@ -536,3 +536,5 @@ $lang['Verification successful! You can now choose a new password.'] = 'Verifica
|
||||
$lang['If your account exists, a verification code has been sent to your email address.'] = 'If your account exists, a verification code has been sent to your email address.';
|
||||
$lang['People'] = 'People';
|
||||
$lang['Click to highlight on the photo'] = 'Click to highlight on the photo';
|
||||
$lang['Requested person does not exist'] = 'Requested person does not exist';
|
||||
$lang['See all the photos'] = 'See all the photos';
|
||||
@@ -535,3 +535,5 @@ $lang['Verification successful! You can now choose a new password.'] = 'Vérific
|
||||
$lang['If your account exists, a verification code has been sent to your email address.'] = 'Si votre compte existe, un code de vérification a été envoyé à votre adresse email.';
|
||||
$lang['People'] = 'Personnes';
|
||||
$lang['Click to highlight on the photo'] = 'Cliquer pour repérer sur la photo';
|
||||
$lang['Requested person does not exist'] = 'La personne demandée n\'existe pas';
|
||||
$lang['See all the photos'] = 'Voir toutes ses photos';
|
||||
@@ -932,6 +932,7 @@ if (!empty($display_info['people']) and can_see_people())
|
||||
{
|
||||
$people[$i]['face'] = get_person_face_background($person);
|
||||
$people[$i]['initial'] = mb_strtoupper(mb_substr($person['name'], 0, 1));
|
||||
$people[$i]['URL'] = make_index_url(array('person' => $person));
|
||||
}
|
||||
$template->assign('related_people', $people);
|
||||
}
|
||||
|
||||
@@ -5,9 +5,12 @@
|
||||
padding: 3px 0;
|
||||
}
|
||||
|
||||
.people-avatar {
|
||||
.people-person {
|
||||
position: relative;
|
||||
display: inline-block;
|
||||
}
|
||||
|
||||
.people-avatar {
|
||||
display: block;
|
||||
width: 36px;
|
||||
height: 36px;
|
||||
border: 3px solid #ffffff;
|
||||
@@ -16,29 +19,26 @@
|
||||
background-color: #cccccc;
|
||||
background-repeat: no-repeat;
|
||||
cursor: pointer;
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
.people-avatar:focus {
|
||||
outline: none;
|
||||
}
|
||||
|
||||
.people-avatar:hover,
|
||||
.people-avatar:focus,
|
||||
.people-avatar-selected {
|
||||
.people-avatar:focus-visible,
|
||||
.people-person-selected .people-avatar {
|
||||
border-color: #FFA646;
|
||||
}
|
||||
|
||||
.people-avatar-empty {
|
||||
cursor: default;
|
||||
.people-avatar-empty,
|
||||
.people-avatar-empty:hover {
|
||||
color: #555555;
|
||||
font-weight: bold;
|
||||
font-size: 16px;
|
||||
line-height: 36px;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.people-avatar-empty:hover {
|
||||
border-color: #ffffff;
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
.people-tooltip {
|
||||
@@ -57,16 +57,53 @@
|
||||
text-align: left;
|
||||
}
|
||||
|
||||
.people-tooltip::before {
|
||||
content: '';
|
||||
position: absolute;
|
||||
left: 0;
|
||||
right: 0;
|
||||
top: -8px;
|
||||
height: 8px;
|
||||
}
|
||||
|
||||
.people-tooltip b,
|
||||
.people-tooltip i {
|
||||
.people-tooltip i,
|
||||
.people-tooltip a {
|
||||
display: block;
|
||||
}
|
||||
|
||||
.people-avatar:hover .people-tooltip,
|
||||
.people-avatar:focus .people-tooltip {
|
||||
.people-tooltip a,
|
||||
.people-tooltip a:hover {
|
||||
margin-top: 4px;
|
||||
color: #a34a00;
|
||||
font-weight: bold;
|
||||
text-decoration: underline;
|
||||
}
|
||||
|
||||
.people-person:focus-within .people-tooltip {
|
||||
display: block;
|
||||
}
|
||||
|
||||
@media (hover: hover) {
|
||||
.people-person:hover .people-avatar {
|
||||
border-color: #FFA646;
|
||||
}
|
||||
|
||||
.people-person:hover .people-tooltip {
|
||||
display: block;
|
||||
}
|
||||
}
|
||||
|
||||
@media (hover: none) {
|
||||
.people-person-selected .people-tooltip {
|
||||
display: block;
|
||||
}
|
||||
|
||||
.people-tooltip i {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
|
||||
.people-frame {
|
||||
position: absolute;
|
||||
z-index: 50;
|
||||
|
||||
@@ -1,15 +1,15 @@
|
||||
jQuery(function($) {
|
||||
const $avatars = $('.people-avatar[data-box]');
|
||||
if (!$avatars.length) {
|
||||
const $people = $('.people-person');
|
||||
if (!$people.length) {
|
||||
return;
|
||||
}
|
||||
|
||||
const $frame = $('<div class="people-frame"><span class="people-frame-name"></span></div>').hide().appendTo('body');
|
||||
let $selected = null;
|
||||
|
||||
function show_frame($avatar) {
|
||||
function show_frame($person) {
|
||||
const img = document.getElementById('theMainImage');
|
||||
if (!img || img.hasAttribute('data-src')) {
|
||||
if (!$person || !$person.data('box') || !img || img.hasAttribute('data-src')) {
|
||||
$frame.hide();
|
||||
return;
|
||||
}
|
||||
@@ -20,8 +20,8 @@ jQuery(function($) {
|
||||
return;
|
||||
}
|
||||
|
||||
const box = String($avatar.data('box')).split(',').map(Number);
|
||||
const scale = rect.width / Number($avatar.data('width'));
|
||||
const box = String($person.data('box')).split(',').map(Number);
|
||||
const scale = rect.width / Number($person.data('width'));
|
||||
|
||||
$frame.css({
|
||||
left: rect.left + window.scrollX + box[0] * scale,
|
||||
@@ -29,43 +29,47 @@ jQuery(function($) {
|
||||
width: (box[2] - box[0]) * scale,
|
||||
height: (box[3] - box[1]) * scale,
|
||||
});
|
||||
$frame.find('.people-frame-name').text($avatar.data('name'));
|
||||
$frame.find('.people-frame-name').text($person.data('name'));
|
||||
$frame.show();
|
||||
}
|
||||
|
||||
function refresh_frame() {
|
||||
if ($selected) {
|
||||
show_frame($selected);
|
||||
}
|
||||
else {
|
||||
$frame.hide();
|
||||
}
|
||||
show_frame($selected);
|
||||
}
|
||||
|
||||
$avatars
|
||||
.on('mouseenter focus', function() {
|
||||
function select_person($person) {
|
||||
$people.removeClass('people-person-selected');
|
||||
$selected = $person;
|
||||
if ($selected) {
|
||||
$selected.addClass('people-person-selected');
|
||||
}
|
||||
refresh_frame();
|
||||
}
|
||||
|
||||
$people
|
||||
.on('mouseenter', function() {
|
||||
show_frame($(this));
|
||||
})
|
||||
.on('mouseleave blur', refresh_frame)
|
||||
.on('click keydown', function(e) {
|
||||
if ('keydown' == e.type && 'Enter' != e.key && ' ' != e.key) {
|
||||
return;
|
||||
}
|
||||
e.preventDefault();
|
||||
.on('mouseleave', refresh_frame);
|
||||
|
||||
const $avatar = $(this);
|
||||
$avatars.removeClass('people-avatar-selected');
|
||||
$people.find('.people-avatar').on('click', function(e) {
|
||||
if (e.ctrlKey || e.metaKey || e.shiftKey) {
|
||||
return;
|
||||
}
|
||||
e.preventDefault();
|
||||
|
||||
if ($selected && $selected.is($avatar)) {
|
||||
$selected = null;
|
||||
}
|
||||
else {
|
||||
$selected = $avatar;
|
||||
$avatar.addClass('people-avatar-selected');
|
||||
}
|
||||
const $person = $(this).closest('.people-person');
|
||||
select_person($selected && $selected.is($person) ? null : $person);
|
||||
if (e.detail) {
|
||||
$(this).trigger('blur');
|
||||
}
|
||||
});
|
||||
|
||||
show_frame($avatar);
|
||||
});
|
||||
$(document).on('click', function(e) {
|
||||
if ($selected && !$(e.target).closest('.people-person').length) {
|
||||
select_person(null);
|
||||
}
|
||||
});
|
||||
|
||||
$(window).on('resize', refresh_frame);
|
||||
$('#theMainImage').on('load', refresh_frame);
|
||||
|
||||
@@ -222,13 +222,18 @@ y.callService(
|
||||
<dt>{'People'|@translate}</dt>
|
||||
<dd><div class="people-avatars">
|
||||
{foreach from=$related_people item=person}
|
||||
{if isset($person.face)}
|
||||
<span class="people-avatar" tabindex="0" data-name="{$person.name|escape:html}" data-box="{$person.box_x1},{$person.box_y1},{$person.box_x2},{$person.box_y2}" data-width="{$person.image_width}" style="background-image:url('{$current.selected_derivative->get_url()}');background-size:{$person.face.size}% auto;background-position:{$person.face.x}% {$person.face.y}%;">
|
||||
{else}
|
||||
<span class="people-avatar people-avatar-empty">{$person.initial}
|
||||
{/if}
|
||||
<span class="people-tooltip"><b>{$person.name}</b>{if isset($person.face)}<i>{'Click to highlight on the photo'|@translate}</i>{/if}</span>
|
||||
</span>
|
||||
<div class="people-person"{if isset($person.face)} data-name="{$person.name|escape:html}" data-box="{$person.box_x1},{$person.box_y1},{$person.box_x2},{$person.box_y2}" data-width="{$person.image_width}"{/if}>
|
||||
{if isset($person.face)}
|
||||
<a class="people-avatar" href="{$person.URL}" style="background-image:url('{$current.selected_derivative->get_url()}');background-size:{$person.face.size}% auto;background-position:{$person.face.x}% {$person.face.y}%;"></a>
|
||||
{else}
|
||||
<a class="people-avatar people-avatar-empty" href="{$person.URL}">{$person.initial}</a>
|
||||
{/if}
|
||||
<div class="people-tooltip">
|
||||
<b>{$person.name}</b>
|
||||
{if isset($person.face)}<i>{'Click to highlight on the photo'|@translate}</i>{/if}
|
||||
<a href="{$person.URL}">{'See all the photos'|@translate}</a>
|
||||
</div>
|
||||
</div>
|
||||
{/foreach}
|
||||
</div></dd>
|
||||
</div>
|
||||
|
||||
Reference in new issue
Block a user