File tree Expand file tree Collapse file tree 6 files changed +46
-1
lines changed
routes/(user)/people/[personId]/[[photos=photos]]/[[assetId=id]] Expand file tree Collapse file tree 6 files changed +46
-1
lines changed Original file line number Diff line number Diff line change 1142
1142
"set" : " Set" ,
1143
1143
"set_as_album_cover" : " Set as album cover" ,
1144
1144
"set_as_profile_picture" : " Set as profile picture" ,
1145
+ "set_as_featured_photo" : " Set as featured photo" ,
1145
1146
"set_date_of_birth" : " Set date of birth" ,
1146
1147
"set_profile_picture" : " Set profile picture" ,
1147
1148
"set_slideshow_to_fullscreen" : " Set Slideshow to fullscreen" ,
Original file line number Diff line number Diff line change
1
+ <script lang =" ts" >
2
+ import MenuOption from ' $lib/components/shared-components/context-menu/menu-option.svelte' ;
3
+ import {
4
+ notificationController ,
5
+ NotificationType ,
6
+ } from ' $lib/components/shared-components/notification/notification' ;
7
+ import { handleError } from ' $lib/utils/handle-error' ;
8
+ import { updatePerson , type AssetResponseDto , type PersonResponseDto } from ' @immich/sdk' ;
9
+ import { mdiFaceManProfile } from ' @mdi/js' ;
10
+ import { t } from ' svelte-i18n' ;
11
+
12
+ interface Props {
13
+ asset: AssetResponseDto ;
14
+ person: PersonResponseDto ;
15
+ }
16
+
17
+ let { asset, person }: Props = $props ();
18
+
19
+ const handleSelectFeaturePhoto = async () => {
20
+ try {
21
+ await updatePerson ({ id: person .id , personUpdateDto: { featureFaceAssetId: asset .id } });
22
+ notificationController .show ({ message: $t (' feature_photo_updated' ), type: NotificationType .Info });
23
+ } catch (error ) {
24
+ handleError (error , $t (' errors.unable_to_set_feature_photo' ));
25
+ }
26
+ };
27
+ </script >
28
+
29
+ <MenuOption text ={$t (' set_as_featured_photo' )} icon ={mdiFaceManProfile } onClick ={handleSelectFeaturePhoto } />
Original file line number Diff line number Diff line change 9
9
import FavoriteAction from ' $lib/components/asset-viewer/actions/favorite-action.svelte' ;
10
10
import RestoreAction from ' $lib/components/asset-viewer/actions/restore-action.svelte' ;
11
11
import SetAlbumCoverAction from ' $lib/components/asset-viewer/actions/set-album-cover-action.svelte' ;
12
+ import SetFeaturedPhotoAction from ' $lib/components/asset-viewer/actions/set-person-featured-action.svelte' ;
12
13
import SetProfilePictureAction from ' $lib/components/asset-viewer/actions/set-profile-picture-action.svelte' ;
13
14
import ShareAction from ' $lib/components/asset-viewer/actions/share-action.svelte' ;
14
15
import ShowDetailAction from ' $lib/components/asset-viewer/actions/show-detail-action.svelte' ;
27
28
AssetTypeEnum ,
28
29
type AlbumResponseDto ,
29
30
type AssetResponseDto ,
31
+ type PersonResponseDto ,
30
32
type StackResponseDto ,
31
33
} from ' @immich/sdk' ;
32
34
import {
50
52
interface Props {
51
53
asset: AssetResponseDto ;
52
54
album? : AlbumResponseDto | null ;
55
+ person? : PersonResponseDto | null ;
53
56
stack? : StackResponseDto | null ;
54
57
showDetailButton: boolean ;
55
58
showSlideshow? : boolean ;
67
70
let {
68
71
asset,
69
72
album = null ,
73
+ person = null ,
70
74
stack = null ,
71
75
showDetailButton,
72
76
showSlideshow = false ,
169
173
{#if album }
170
174
<SetAlbumCoverAction {asset } {album } />
171
175
{/if }
176
+ {#if person }
177
+ <SetFeaturedPhotoAction {asset } {person } />
178
+ {/if }
172
179
{#if asset .type === AssetTypeEnum .Image }
173
180
<SetProfilePictureAction {asset } />
174
181
{/if }
Original file line number Diff line number Diff line change 30
30
type ActivityResponseDto ,
31
31
type AlbumResponseDto ,
32
32
type AssetResponseDto ,
33
+ type PersonResponseDto ,
33
34
type StackResponseDto ,
34
35
} from ' @immich/sdk' ;
35
36
import { onDestroy , onMount , untrack } from ' svelte' ;
56
57
withStacked? : boolean ;
57
58
isShared? : boolean ;
58
59
album? : AlbumResponseDto | null ;
60
+ person? : PersonResponseDto | null ;
59
61
onAction? : OnAction | undefined ;
60
62
reactions? : ActivityResponseDto [];
61
63
onClose: (dto : { asset: AssetResponseDto }) => void ;
72
74
withStacked = false ,
73
75
isShared = false ,
74
76
album = null ,
77
+ person = null ,
75
78
onAction = undefined ,
76
79
reactions = $bindable ([]),
77
80
onClose,
429
432
<AssetViewerNavBar
430
433
{asset }
431
434
{album }
435
+ {person }
432
436
{stack }
433
437
showDetailButton ={enableDetailPanel }
434
438
showSlideshow ={!! assetStore }
Original file line number Diff line number Diff line change 19
19
type ScrollTargetListener ,
20
20
} from ' $lib/utils/timeline-util' ;
21
21
import { TUNABLES } from ' $lib/utils/tunables' ;
22
- import type { AlbumResponseDto , AssetResponseDto } from ' @immich/sdk' ;
22
+ import type { AlbumResponseDto , AssetResponseDto , PersonResponseDto } from ' @immich/sdk' ;
23
23
import { throttle } from ' lodash-es' ;
24
24
import { onDestroy , onMount , type Snippet } from ' svelte' ;
25
25
import Portal from ' ../shared-components/portal/portal.svelte' ;
52
52
showArchiveIcon? : boolean ;
53
53
isShared? : boolean ;
54
54
album? : AlbumResponseDto | null ;
55
+ person? : PersonResponseDto | null ;
55
56
isShowDeleteConfirmation? : boolean ;
56
57
onSelect? : (asset : AssetResponseDto ) => void ;
57
58
onEscape? : () => void ;
70
71
showArchiveIcon = false ,
71
72
isShared = false ,
72
73
album = null ,
74
+ person = null ,
73
75
isShowDeleteConfirmation = $bindable (false ),
74
76
onSelect = () => {},
75
77
onEscape = () => {},
914
916
preloadAssets ={$preloadAssets }
915
917
{isShared }
916
918
{album }
919
+ {person }
917
920
onAction ={handleAction }
918
921
onPrevious ={handlePrevious }
919
922
onNext ={handleNext }
Original file line number Diff line number Diff line change 454
454
{#key person .id }
455
455
<AssetGrid
456
456
enableRouting ={true }
457
+ {person }
457
458
{assetStore }
458
459
{assetInteraction }
459
460
isSelectionMode ={viewMode === PersonPageViewMode .SELECT_PERSON }
You can’t perform that action at this time.
0 commit comments