diff --git a/include/functions_url.inc.php b/include/functions_url.inc.php index 34c3232aa..4d9275e93 100644 --- a/include/functions_url.inc.php +++ b/include/functions_url.inc.php @@ -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'; diff --git a/include/section_init.inc.php b/include/section_init.inc.php index 82b0b1bfa..1da765c03 100644 --- a/include/section_init.inc.php +++ b/include/section_init.inc.php @@ -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'] + .''.$page['person']['name'].'', + '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']); diff --git a/language/en_UK/common.lang.php b/language/en_UK/common.lang.php index 2df7d787a..56f3aeb87 100644 --- a/language/en_UK/common.lang.php +++ b/language/en_UK/common.lang.php @@ -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'; diff --git a/language/fr_FR/common.lang.php b/language/fr_FR/common.lang.php index 3a3e32faa..0dfe026cc 100644 --- a/language/fr_FR/common.lang.php +++ b/language/fr_FR/common.lang.php @@ -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'; diff --git a/picture.php b/picture.php index d13a3e75f..0f3057ed2 100644 --- a/picture.php +++ b/picture.php @@ -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); } diff --git a/themes/default/css/people.css b/themes/default/css/people.css index b2ad696d9..a841bb0fe 100644 --- a/themes/default/css/people.css +++ b/themes/default/css/people.css @@ -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; diff --git a/themes/default/js/picture_people.js b/themes/default/js/picture_people.js index ebbb9e027..0619efe0b 100644 --- a/themes/default/js/picture_people.js +++ b/themes/default/js/picture_people.js @@ -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 = $('
').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); diff --git a/themes/default/template/picture.tpl b/themes/default/template/picture.tpl index 136e67726..2008b0ba7 100644 --- a/themes/default/template/picture.tpl +++ b/themes/default/template/picture.tpl @@ -222,13 +222,18 @@ y.callService(
{'People'|@translate}
{foreach from=$related_people item=person} - {if isset($person.face)} - - {else} - {$person.initial} - {/if} - {$person.name}{if isset($person.face)}{'Click to highlight on the photo'|@translate}{/if} - +
+ {if isset($person.face)} + + {else} + {$person.initial} + {/if} +
+ {$person.name} + {if isset($person.face)}{'Click to highlight on the photo'|@translate}{/if} + {'See all the photos'|@translate} +
+
{/foreach}