mirror of
https://github.com/immich-app/immich.git
synced 2025-03-11 02:23:09 -05:00
fix(web): person asset grid (#12370)
This commit is contained in:
parent
d6729c50c9
commit
b0af9be513
1 changed files with 38 additions and 46 deletions
|
@ -76,13 +76,20 @@
|
||||||
isArchived: false,
|
isArchived: false,
|
||||||
personId: data.person.id,
|
personId: data.person.id,
|
||||||
});
|
});
|
||||||
|
|
||||||
|
$: person = data.person;
|
||||||
|
$: thumbnailData = getPeopleThumbnailUrl(person);
|
||||||
|
$: if (person) {
|
||||||
|
handlePromiseError(updateAssetCount());
|
||||||
|
handlePromiseError(assetStore.updateOptions({ personId: person.id }));
|
||||||
|
}
|
||||||
|
|
||||||
const assetInteractionStore = createAssetInteractionStore();
|
const assetInteractionStore = createAssetInteractionStore();
|
||||||
const { selectedAssets, isMultiSelectState } = assetInteractionStore;
|
const { selectedAssets, isMultiSelectState } = assetInteractionStore;
|
||||||
|
|
||||||
let viewMode: ViewMode = ViewMode.VIEW_ASSETS;
|
let viewMode: ViewMode = ViewMode.VIEW_ASSETS;
|
||||||
let isEditingName = false;
|
let isEditingName = false;
|
||||||
let previousRoute: string = AppRoute.EXPLORE;
|
let previousRoute: string = AppRoute.EXPLORE;
|
||||||
let previousPersonId: string = data.person.id;
|
|
||||||
let people: PersonResponseDto[] = [];
|
let people: PersonResponseDto[] = [];
|
||||||
let personMerge1: PersonResponseDto;
|
let personMerge1: PersonResponseDto;
|
||||||
let personMerge2: PersonResponseDto;
|
let personMerge2: PersonResponseDto;
|
||||||
|
@ -91,9 +98,6 @@
|
||||||
let refreshAssetGrid = false;
|
let refreshAssetGrid = false;
|
||||||
|
|
||||||
let personName = '';
|
let personName = '';
|
||||||
$: thumbnailData = getPeopleThumbnailUrl(data.person);
|
|
||||||
|
|
||||||
let name: string = data.person.name;
|
|
||||||
let suggestedPeople: PersonResponseDto[] = [];
|
let suggestedPeople: PersonResponseDto[] = [];
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -120,8 +124,8 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
return websocketEvents.on('on_person_thumbnail', (personId: string) => {
|
return websocketEvents.on('on_person_thumbnail', (personId: string) => {
|
||||||
if (data.person.id === personId) {
|
if (person.id === personId) {
|
||||||
thumbnailData = getPeopleThumbnailUrl(data.person, Date.now().toString());
|
thumbnailData = getPeopleThumbnailUrl(person, Date.now().toString());
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
@ -141,7 +145,7 @@
|
||||||
|
|
||||||
const updateAssetCount = async () => {
|
const updateAssetCount = async () => {
|
||||||
try {
|
try {
|
||||||
const { assets } = await getPersonStatistics({ id: data.person.id });
|
const { assets } = await getPersonStatistics({ id: person.id });
|
||||||
numberOfAssets = assets;
|
numberOfAssets = assets;
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
handleError(error, "Can't update the asset count");
|
handleError(error, "Can't update the asset count");
|
||||||
|
@ -150,20 +154,9 @@
|
||||||
|
|
||||||
afterNavigate(({ from }) => {
|
afterNavigate(({ from }) => {
|
||||||
// Prevent setting previousRoute to the current page.
|
// Prevent setting previousRoute to the current page.
|
||||||
if (from && from.route.id !== $page.route.id) {
|
if (from?.url && from.route.id !== $page.route.id) {
|
||||||
previousRoute = from.url.href;
|
previousRoute = from.url.href;
|
||||||
}
|
}
|
||||||
if (previousPersonId !== data.person.id) {
|
|
||||||
handlePromiseError(updateAssetCount());
|
|
||||||
assetStore.destroy();
|
|
||||||
assetStore = new AssetStore({
|
|
||||||
isArchived: false,
|
|
||||||
personId: data.person.id,
|
|
||||||
});
|
|
||||||
previousPersonId = data.person.id;
|
|
||||||
name = data.person.name;
|
|
||||||
refreshAssetGrid = !refreshAssetGrid;
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
|
|
||||||
const handleUnmerge = () => {
|
const handleUnmerge = () => {
|
||||||
|
@ -179,8 +172,8 @@
|
||||||
const toggleHidePerson = async () => {
|
const toggleHidePerson = async () => {
|
||||||
try {
|
try {
|
||||||
await updatePerson({
|
await updatePerson({
|
||||||
id: data.person.id,
|
id: person.id,
|
||||||
personUpdateDto: { isHidden: !data.person.isHidden },
|
personUpdateDto: { isHidden: !person.isHidden },
|
||||||
});
|
});
|
||||||
|
|
||||||
notificationController.show({
|
notificationController.show({
|
||||||
|
@ -208,7 +201,7 @@
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
try {
|
try {
|
||||||
await updatePerson({ id: data.person.id, personUpdateDto: { featureFaceAssetId: asset.id } });
|
await updatePerson({ id: person.id, personUpdateDto: { featureFaceAssetId: asset.id } });
|
||||||
notificationController.show({ message: $t('feature_photo_updated'), type: NotificationType.Info });
|
notificationController.show({ message: $t('feature_photo_updated'), type: NotificationType.Info });
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
handleError(error, $t('errors.unable_to_set_feature_photo'));
|
handleError(error, $t('errors.unable_to_set_feature_photo'));
|
||||||
|
@ -233,7 +226,7 @@
|
||||||
type: NotificationType.Info,
|
type: NotificationType.Info,
|
||||||
});
|
});
|
||||||
people = people.filter((person: PersonResponseDto) => person.id !== personToMerge.id);
|
people = people.filter((person: PersonResponseDto) => person.id !== personToMerge.id);
|
||||||
if (personToBeMergedIn.name != personName && data.person.id === personToBeMergedIn.id) {
|
if (personToBeMergedIn.name != personName && person.id === personToBeMergedIn.id) {
|
||||||
await updateAssetCount();
|
await updateAssetCount();
|
||||||
refreshAssetGrid = !refreshAssetGrid;
|
refreshAssetGrid = !refreshAssetGrid;
|
||||||
return;
|
return;
|
||||||
|
@ -244,22 +237,22 @@
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
const handleSuggestPeople = (person: PersonResponseDto) => {
|
const handleSuggestPeople = (person2: PersonResponseDto) => {
|
||||||
isEditingName = false;
|
isEditingName = false;
|
||||||
potentialMergePeople = [];
|
potentialMergePeople = [];
|
||||||
personName = person.name;
|
personName = person.name;
|
||||||
personMerge1 = data.person;
|
personMerge1 = person;
|
||||||
personMerge2 = person;
|
personMerge2 = person2;
|
||||||
viewMode = ViewMode.SUGGEST_MERGE;
|
viewMode = ViewMode.SUGGEST_MERGE;
|
||||||
};
|
};
|
||||||
|
|
||||||
const changeName = async () => {
|
const changeName = async () => {
|
||||||
viewMode = ViewMode.VIEW_ASSETS;
|
viewMode = ViewMode.VIEW_ASSETS;
|
||||||
data.person.name = personName;
|
person.name = personName;
|
||||||
try {
|
try {
|
||||||
isEditingName = false;
|
isEditingName = false;
|
||||||
|
|
||||||
await updatePerson({ id: data.person.id, personUpdateDto: { name: personName } });
|
await updatePerson({ id: person.id, personUpdateDto: { name: personName } });
|
||||||
|
|
||||||
notificationController.show({
|
notificationController.show({
|
||||||
message: $t('change_name_successfully'),
|
message: $t('change_name_successfully'),
|
||||||
|
@ -283,7 +276,7 @@
|
||||||
potentialMergePeople = [];
|
potentialMergePeople = [];
|
||||||
personName = name;
|
personName = name;
|
||||||
|
|
||||||
if (data.person.name === personName) {
|
if (person.name === personName) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (name === '') {
|
if (name === '') {
|
||||||
|
@ -294,12 +287,11 @@
|
||||||
const result = await searchPerson({ name: personName, withHidden: true });
|
const result = await searchPerson({ name: personName, withHidden: true });
|
||||||
|
|
||||||
const existingPerson = result.find(
|
const existingPerson = result.find(
|
||||||
(person: PersonResponseDto) =>
|
({ name, id }: PersonResponseDto) => name.toLowerCase() === personName.toLowerCase() && id !== person.id && name,
|
||||||
person.name.toLowerCase() === personName.toLowerCase() && person.id !== data.person.id && person.name,
|
|
||||||
);
|
);
|
||||||
if (existingPerson) {
|
if (existingPerson) {
|
||||||
personMerge2 = existingPerson;
|
personMerge2 = existingPerson;
|
||||||
personMerge1 = data.person;
|
personMerge1 = person;
|
||||||
potentialMergePeople = result
|
potentialMergePeople = result
|
||||||
.filter(
|
.filter(
|
||||||
(person: PersonResponseDto) =>
|
(person: PersonResponseDto) =>
|
||||||
|
@ -318,10 +310,10 @@
|
||||||
const handleSetBirthDate = async (birthDate: string) => {
|
const handleSetBirthDate = async (birthDate: string) => {
|
||||||
try {
|
try {
|
||||||
viewMode = ViewMode.VIEW_ASSETS;
|
viewMode = ViewMode.VIEW_ASSETS;
|
||||||
data.person.birthDate = birthDate;
|
person.birthDate = birthDate;
|
||||||
|
|
||||||
const updatedPerson = await updatePerson({
|
const updatedPerson = await updatePerson({
|
||||||
id: data.person.id,
|
id: person.id,
|
||||||
personUpdateDto: { birthDate: birthDate.length > 0 ? birthDate : null },
|
personUpdateDto: { birthDate: birthDate.length > 0 ? birthDate : null },
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -354,7 +346,7 @@
|
||||||
{#if viewMode === ViewMode.UNASSIGN_ASSETS}
|
{#if viewMode === ViewMode.UNASSIGN_ASSETS}
|
||||||
<UnMergeFaceSelector
|
<UnMergeFaceSelector
|
||||||
assetIds={[...$selectedAssets].map((a) => a.id)}
|
assetIds={[...$selectedAssets].map((a) => a.id)}
|
||||||
personAssets={data.person}
|
personAssets={person}
|
||||||
on:close={() => (viewMode = ViewMode.VIEW_ASSETS)}
|
on:close={() => (viewMode = ViewMode.VIEW_ASSETS)}
|
||||||
on:confirm={handleUnmerge}
|
on:confirm={handleUnmerge}
|
||||||
/>
|
/>
|
||||||
|
@ -373,14 +365,14 @@
|
||||||
|
|
||||||
{#if viewMode === ViewMode.BIRTH_DATE}
|
{#if viewMode === ViewMode.BIRTH_DATE}
|
||||||
<SetBirthDateModal
|
<SetBirthDateModal
|
||||||
birthDate={data.person.birthDate ?? ''}
|
birthDate={person.birthDate ?? ''}
|
||||||
on:close={() => (viewMode = ViewMode.VIEW_ASSETS)}
|
on:close={() => (viewMode = ViewMode.VIEW_ASSETS)}
|
||||||
on:updated={(event) => handleSetBirthDate(event.detail)}
|
on:updated={(event) => handleSetBirthDate(event.detail)}
|
||||||
/>
|
/>
|
||||||
{/if}
|
{/if}
|
||||||
|
|
||||||
{#if viewMode === ViewMode.MERGE_PEOPLE}
|
{#if viewMode === ViewMode.MERGE_PEOPLE}
|
||||||
<MergeFaceSelector person={data.person} on:back={handleGoBack} on:merge={({ detail }) => handleMerge(detail)} />
|
<MergeFaceSelector {person} on:back={handleGoBack} on:merge={({ detail }) => handleMerge(detail)} />
|
||||||
{/if}
|
{/if}
|
||||||
|
|
||||||
<header>
|
<header>
|
||||||
|
@ -394,7 +386,7 @@
|
||||||
</ButtonContextMenu>
|
</ButtonContextMenu>
|
||||||
<FavoriteAction removeFavorite={isAllFavorite} onFavorite={() => assetStore.triggerUpdate()} />
|
<FavoriteAction removeFavorite={isAllFavorite} onFavorite={() => assetStore.triggerUpdate()} />
|
||||||
<ButtonContextMenu icon={mdiDotsVertical} title={$t('add')}>
|
<ButtonContextMenu icon={mdiDotsVertical} title={$t('add')}>
|
||||||
<DownloadAction menuItem filename="{data.person.name || 'immich'}.zip" />
|
<DownloadAction menuItem filename="{person.name || 'immich'}.zip" />
|
||||||
<MenuOption
|
<MenuOption
|
||||||
icon={mdiAccountMultipleCheckOutline}
|
icon={mdiAccountMultipleCheckOutline}
|
||||||
text={$t('fix_incorrect_match')}
|
text={$t('fix_incorrect_match')}
|
||||||
|
@ -417,8 +409,8 @@
|
||||||
onClick={() => (viewMode = ViewMode.SELECT_PERSON)}
|
onClick={() => (viewMode = ViewMode.SELECT_PERSON)}
|
||||||
/>
|
/>
|
||||||
<MenuOption
|
<MenuOption
|
||||||
text={data.person.isHidden ? $t('unhide_person') : $t('hide_person')}
|
text={person.isHidden ? $t('unhide_person') : $t('hide_person')}
|
||||||
icon={data.person.isHidden ? mdiEyeOutline : mdiEyeOffOutline}
|
icon={person.isHidden ? mdiEyeOutline : mdiEyeOffOutline}
|
||||||
onClick={() => toggleHidePerson()}
|
onClick={() => toggleHidePerson()}
|
||||||
/>
|
/>
|
||||||
<MenuOption
|
<MenuOption
|
||||||
|
@ -445,7 +437,7 @@
|
||||||
</header>
|
</header>
|
||||||
|
|
||||||
<main class="relative h-screen overflow-hidden bg-immich-bg tall:ml-4 pt-[var(--navbar-height)] dark:bg-immich-dark-bg">
|
<main class="relative h-screen overflow-hidden bg-immich-bg tall:ml-4 pt-[var(--navbar-height)] dark:bg-immich-dark-bg">
|
||||||
{#key refreshAssetGrid}
|
{#key person.id}
|
||||||
<AssetGrid
|
<AssetGrid
|
||||||
enableRouting={true}
|
enableRouting={true}
|
||||||
{assetStore}
|
{assetStore}
|
||||||
|
@ -468,9 +460,9 @@
|
||||||
<section class="flex w-64 sm:w-96 place-items-center border-black">
|
<section class="flex w-64 sm:w-96 place-items-center border-black">
|
||||||
{#if isEditingName}
|
{#if isEditingName}
|
||||||
<EditNameInput
|
<EditNameInput
|
||||||
person={data.person}
|
{person}
|
||||||
bind:suggestedPeople
|
bind:suggestedPeople
|
||||||
bind:name
|
name={person.name}
|
||||||
bind:isSearchingPeople
|
bind:isSearchingPeople
|
||||||
on:change={(event) => handleNameChange(event.detail)}
|
on:change={(event) => handleNameChange(event.detail)}
|
||||||
{thumbnailData}
|
{thumbnailData}
|
||||||
|
@ -487,15 +479,15 @@
|
||||||
circle
|
circle
|
||||||
shadow
|
shadow
|
||||||
url={thumbnailData}
|
url={thumbnailData}
|
||||||
altText={data.person.name}
|
altText={person.name}
|
||||||
widthStyle="3.375rem"
|
widthStyle="3.375rem"
|
||||||
heightStyle="3.375rem"
|
heightStyle="3.375rem"
|
||||||
/>
|
/>
|
||||||
<div
|
<div
|
||||||
class="flex flex-col justify-center text-left px-4 h-14 text-immich-primary dark:text-immich-dark-primary"
|
class="flex flex-col justify-center text-left px-4 h-14 text-immich-primary dark:text-immich-dark-primary"
|
||||||
>
|
>
|
||||||
{#if data.person.name}
|
{#if person.name}
|
||||||
<p class="w-40 sm:w-72 font-medium truncate">{data.person.name}</p>
|
<p class="w-40 sm:w-72 font-medium truncate">{person.name}</p>
|
||||||
<p class="absolute w-fit text-sm text-gray-500 dark:text-immich-gray bottom-0">
|
<p class="absolute w-fit text-sm text-gray-500 dark:text-immich-gray bottom-0">
|
||||||
{$t('assets_count', { values: { count: numberOfAssets } })}
|
{$t('assets_count', { values: { count: numberOfAssets } })}
|
||||||
</p>
|
</p>
|
||||||
|
|
Loading…
Add table
Reference in a new issue