mirror of
https://github.com/immich-app/immich.git
synced 2026-03-22 11:00:10 +03:00
fix(web): refresh recent albums sidebar after album changes (#26757)
This commit is contained in:
@@ -1,5 +1,6 @@
|
|||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import { shortcut } from '$lib/actions/shortcut';
|
import { shortcut } from '$lib/actions/shortcut';
|
||||||
|
import { eventManager } from '$lib/managers/event-manager.svelte';
|
||||||
import { handleError } from '$lib/utils/handle-error';
|
import { handleError } from '$lib/utils/handle-error';
|
||||||
import { updateAlbumInfo } from '@immich/sdk';
|
import { updateAlbumInfo } from '@immich/sdk';
|
||||||
import { Textarea } from '@immich/ui';
|
import { Textarea } from '@immich/ui';
|
||||||
@@ -16,12 +17,13 @@
|
|||||||
|
|
||||||
const handleFocusOut = async () => {
|
const handleFocusOut = async () => {
|
||||||
try {
|
try {
|
||||||
await updateAlbumInfo({
|
const response = await updateAlbumInfo({
|
||||||
id,
|
id,
|
||||||
updateAlbumDto: {
|
updateAlbumDto: {
|
||||||
description,
|
description,
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
eventManager.emit('AlbumUpdate', response);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
handleError(error, $t('errors.unable_to_save_album'));
|
handleError(error, $t('errors.unable_to_save_album'));
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import { shortcut } from '$lib/actions/shortcut';
|
import { shortcut } from '$lib/actions/shortcut';
|
||||||
|
import { eventManager } from '$lib/managers/event-manager.svelte';
|
||||||
import { handleError } from '$lib/utils/handle-error';
|
import { handleError } from '$lib/utils/handle-error';
|
||||||
import { updateAlbumInfo } from '@immich/sdk';
|
import { updateAlbumInfo } from '@immich/sdk';
|
||||||
import { t } from 'svelte-i18n';
|
import { t } from 'svelte-i18n';
|
||||||
@@ -21,12 +22,14 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
({ albumName } = await updateAlbumInfo({
|
const response = await updateAlbumInfo({
|
||||||
id,
|
id,
|
||||||
updateAlbumDto: {
|
updateAlbumDto: {
|
||||||
albumName: newAlbumName,
|
albumName: newAlbumName,
|
||||||
},
|
},
|
||||||
}));
|
});
|
||||||
|
({ albumName } = response);
|
||||||
|
eventManager.emit('AlbumUpdate', response);
|
||||||
onUpdate(albumName);
|
onUpdate(albumName);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
handleError(error, $t('errors.unable_to_save_album'));
|
handleError(error, $t('errors.unable_to_save_album'));
|
||||||
|
|||||||
@@ -17,7 +17,6 @@
|
|||||||
type AlbumViewSettings,
|
type AlbumViewSettings,
|
||||||
} from '$lib/stores/preferences.store';
|
} from '$lib/stores/preferences.store';
|
||||||
import { user } from '$lib/stores/user.store';
|
import { user } from '$lib/stores/user.store';
|
||||||
import { userInteraction } from '$lib/stores/user.svelte';
|
|
||||||
import { getSelectedAlbumGroupOption, sortAlbums, stringToSortOrder, type AlbumGroup } from '$lib/utils/album-utils';
|
import { getSelectedAlbumGroupOption, sortAlbums, stringToSortOrder, type AlbumGroup } from '$lib/utils/album-utils';
|
||||||
import type { ContextMenuPosition } from '$lib/utils/context-menu';
|
import type { ContextMenuPosition } from '$lib/utils/context-menu';
|
||||||
import { normalizeSearchString } from '$lib/utils/string-utils';
|
import { normalizeSearchString } from '$lib/utils/string-utils';
|
||||||
@@ -233,16 +232,11 @@
|
|||||||
return albums;
|
return albums;
|
||||||
};
|
};
|
||||||
|
|
||||||
const onUpdate = (album: AlbumResponseDto) => {
|
const onAlbumUpdate = (album: AlbumResponseDto) => {
|
||||||
ownedAlbums = findAndUpdate(ownedAlbums, album);
|
ownedAlbums = findAndUpdate(ownedAlbums, album);
|
||||||
sharedAlbums = findAndUpdate(sharedAlbums, album);
|
sharedAlbums = findAndUpdate(sharedAlbums, album);
|
||||||
};
|
};
|
||||||
|
|
||||||
const onAlbumUpdate = (album: AlbumResponseDto) => {
|
|
||||||
onUpdate(album);
|
|
||||||
userInteraction.recentAlbums = findAndUpdate(userInteraction.recentAlbums || [], album);
|
|
||||||
};
|
|
||||||
|
|
||||||
const onAlbumDelete = (album: AlbumResponseDto) => {
|
const onAlbumDelete = (album: AlbumResponseDto) => {
|
||||||
ownedAlbums = ownedAlbums.filter(({ id }) => id !== album.id);
|
ownedAlbums = ownedAlbums.filter(({ id }) => id !== album.id);
|
||||||
sharedAlbums = sharedAlbums.filter(({ id }) => id !== album.id);
|
sharedAlbums = sharedAlbums.filter(({ id }) => id !== album.id);
|
||||||
@@ -250,7 +244,7 @@
|
|||||||
|
|
||||||
const onSharedLinkCreate = (sharedLink: SharedLinkResponseDto) => {
|
const onSharedLinkCreate = (sharedLink: SharedLinkResponseDto) => {
|
||||||
if (sharedLink.album) {
|
if (sharedLink.album) {
|
||||||
onUpdate(sharedLink.album);
|
onAlbumUpdate(sharedLink.album);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
</script>
|
</script>
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import MenuOption from '$lib/components/shared-components/context-menu/menu-option.svelte';
|
import MenuOption from '$lib/components/shared-components/context-menu/menu-option.svelte';
|
||||||
|
import { eventManager } from '$lib/managers/event-manager.svelte';
|
||||||
import { handleError } from '$lib/utils/handle-error';
|
import { handleError } from '$lib/utils/handle-error';
|
||||||
import { updateAlbumInfo, type AlbumResponseDto, type AssetResponseDto } from '@immich/sdk';
|
import { updateAlbumInfo, type AlbumResponseDto, type AssetResponseDto } from '@immich/sdk';
|
||||||
import { toastManager } from '@immich/ui';
|
import { toastManager } from '@immich/ui';
|
||||||
@@ -15,12 +16,13 @@
|
|||||||
|
|
||||||
const handleUpdateThumbnail = async () => {
|
const handleUpdateThumbnail = async () => {
|
||||||
try {
|
try {
|
||||||
await updateAlbumInfo({
|
const response = await updateAlbumInfo({
|
||||||
id: album.id,
|
id: album.id,
|
||||||
updateAlbumDto: {
|
updateAlbumDto: {
|
||||||
albumThumbnailAssetId: asset.id,
|
albumThumbnailAssetId: asset.id,
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
eventManager.emit('AlbumUpdate', response);
|
||||||
toastManager.success($t('album_cover_updated'));
|
toastManager.success($t('album_cover_updated'));
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
handleError(error, $t('errors.unable_to_update_album_cover'));
|
handleError(error, $t('errors.unable_to_update_album_cover'));
|
||||||
|
|||||||
@@ -3,17 +3,12 @@
|
|||||||
import { userInteraction } from '$lib/stores/user.svelte';
|
import { userInteraction } from '$lib/stores/user.svelte';
|
||||||
import { getAssetMediaUrl } from '$lib/utils';
|
import { getAssetMediaUrl } from '$lib/utils';
|
||||||
import { handleError } from '$lib/utils/handle-error';
|
import { handleError } from '$lib/utils/handle-error';
|
||||||
import { getAllAlbums, type AlbumResponseDto } from '@immich/sdk';
|
import { getAllAlbums } from '@immich/sdk';
|
||||||
import { onMount } from 'svelte';
|
|
||||||
import { t } from 'svelte-i18n';
|
import { t } from 'svelte-i18n';
|
||||||
|
|
||||||
let albums: AlbumResponseDto[] = $state([]);
|
let albums = $state(userInteraction.recentAlbums);
|
||||||
|
|
||||||
onMount(async () => {
|
const refreshAlbums = async () => {
|
||||||
if (userInteraction.recentAlbums) {
|
|
||||||
albums = userInteraction.recentAlbums;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
try {
|
try {
|
||||||
const allAlbums = await getAllAlbums({});
|
const allAlbums = await getAllAlbums({});
|
||||||
albums = allAlbums.sort((a, b) => (a.updatedAt > b.updatedAt ? -1 : 1)).slice(0, 3);
|
albums = allAlbums.sort((a, b) => (a.updatedAt > b.updatedAt ? -1 : 1)).slice(0, 3);
|
||||||
@@ -21,6 +16,12 @@
|
|||||||
} catch (error) {
|
} catch (error) {
|
||||||
handleError(error, $t('failed_to_load_assets'));
|
handleError(error, $t('failed_to_load_assets'));
|
||||||
}
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
$effect(() => {
|
||||||
|
if (!userInteraction.recentAlbums) {
|
||||||
|
void refreshAlbums();
|
||||||
|
}
|
||||||
});
|
});
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
|||||||
@@ -39,6 +39,7 @@ export type Events = {
|
|||||||
AssetsTag: [string[]];
|
AssetsTag: [string[]];
|
||||||
|
|
||||||
AlbumAddAssets: [{ assetIds: string[]; albumIds: string[] }];
|
AlbumAddAssets: [{ assetIds: string[]; albumIds: string[] }];
|
||||||
|
AlbumCreate: [AlbumResponseDto];
|
||||||
AlbumUpdate: [AlbumResponseDto];
|
AlbumUpdate: [AlbumResponseDto];
|
||||||
AlbumDelete: [AlbumResponseDto];
|
AlbumDelete: [AlbumResponseDto];
|
||||||
AlbumShare: [];
|
AlbumShare: [];
|
||||||
|
|||||||
@@ -5,6 +5,7 @@
|
|||||||
AlbumModalRowType,
|
AlbumModalRowType,
|
||||||
isSelectableRowType,
|
isSelectableRowType,
|
||||||
} from '$lib/components/shared-components/album-selection/album-selection-utils';
|
} from '$lib/components/shared-components/album-selection/album-selection-utils';
|
||||||
|
import { eventManager } from '$lib/managers/event-manager.svelte';
|
||||||
import { albumViewSettings } from '$lib/stores/preferences.store';
|
import { albumViewSettings } from '$lib/stores/preferences.store';
|
||||||
import { createAlbum, getAllAlbums, type AlbumResponseDto } from '@immich/sdk';
|
import { createAlbum, getAllAlbums, type AlbumResponseDto } from '@immich/sdk';
|
||||||
import { Button, Icon, Modal, ModalBody, ModalFooter, Text } from '@immich/ui';
|
import { Button, Icon, Modal, ModalBody, ModalFooter, Text } from '@immich/ui';
|
||||||
@@ -43,6 +44,7 @@
|
|||||||
|
|
||||||
const onNewAlbum = async (name: string) => {
|
const onNewAlbum = async (name: string) => {
|
||||||
const album = await createAlbum({ createAlbumDto: { albumName: name } });
|
const album = await createAlbum({ createAlbumDto: { albumName: name } });
|
||||||
|
eventManager.emit('AlbumCreate', album);
|
||||||
onClose([album]);
|
onClose([album]);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -22,10 +22,17 @@ const defaultUserInteraction: UserInteractions = {
|
|||||||
|
|
||||||
export const userInteraction = $state<UserInteractions>(defaultUserInteraction);
|
export const userInteraction = $state<UserInteractions>(defaultUserInteraction);
|
||||||
|
|
||||||
|
const resetRecentAlbums = () => {
|
||||||
|
userInteraction.recentAlbums = undefined;
|
||||||
|
};
|
||||||
|
|
||||||
const reset = () => {
|
const reset = () => {
|
||||||
Object.assign(userInteraction, defaultUserInteraction);
|
Object.assign(userInteraction, defaultUserInteraction);
|
||||||
};
|
};
|
||||||
|
|
||||||
eventManager.on({
|
eventManager.on({
|
||||||
|
AlbumCreate: () => resetRecentAlbums(),
|
||||||
|
AlbumUpdate: () => resetRecentAlbums(),
|
||||||
|
AlbumDelete: () => resetRecentAlbums(),
|
||||||
AuthLogout: () => reset(),
|
AuthLogout: () => reset(),
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
import { goto } from '$app/navigation';
|
import { goto } from '$app/navigation';
|
||||||
|
import { eventManager } from '$lib/managers/event-manager.svelte';
|
||||||
import { Route } from '$lib/route';
|
import { Route } from '$lib/route';
|
||||||
import {
|
import {
|
||||||
AlbumFilter,
|
AlbumFilter,
|
||||||
@@ -29,6 +30,7 @@ export const createAlbum = async (name?: string, assetIds?: string[]) => {
|
|||||||
assetIds,
|
assetIds,
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
eventManager.emit('AlbumCreate', newAlbum);
|
||||||
return newAlbum;
|
return newAlbum;
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
const $t = get(t);
|
const $t = get(t);
|
||||||
|
|||||||
@@ -30,6 +30,7 @@
|
|||||||
import { AlbumPageViewMode } from '$lib/constants';
|
import { AlbumPageViewMode } from '$lib/constants';
|
||||||
import { activityManager } from '$lib/managers/activity-manager.svelte';
|
import { activityManager } from '$lib/managers/activity-manager.svelte';
|
||||||
import { assetViewerManager } from '$lib/managers/asset-viewer-manager.svelte';
|
import { assetViewerManager } from '$lib/managers/asset-viewer-manager.svelte';
|
||||||
|
import { eventManager } from '$lib/managers/event-manager.svelte';
|
||||||
import { featureFlagsManager } from '$lib/managers/feature-flags-manager.svelte';
|
import { featureFlagsManager } from '$lib/managers/feature-flags-manager.svelte';
|
||||||
import { TimelineManager } from '$lib/managers/timeline-manager/timeline-manager.svelte';
|
import { TimelineManager } from '$lib/managers/timeline-manager/timeline-manager.svelte';
|
||||||
import type { TimelineAsset } from '$lib/managers/timeline-manager/types';
|
import type { TimelineAsset } from '$lib/managers/timeline-manager/types';
|
||||||
@@ -192,12 +193,13 @@
|
|||||||
|
|
||||||
const updateThumbnail = async (assetId: string) => {
|
const updateThumbnail = async (assetId: string) => {
|
||||||
try {
|
try {
|
||||||
await updateAlbumInfo({
|
const response = await updateAlbumInfo({
|
||||||
id: album.id,
|
id: album.id,
|
||||||
updateAlbumDto: {
|
updateAlbumDto: {
|
||||||
albumThumbnailAssetId: assetId,
|
albumThumbnailAssetId: assetId,
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
eventManager.emit('AlbumUpdate', response);
|
||||||
toastManager.success($t('album_cover_updated'));
|
toastManager.success($t('album_cover_updated'));
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
handleError(error, $t('errors.unable_to_update_album_cover'));
|
handleError(error, $t('errors.unable_to_update_album_cover'));
|
||||||
|
|||||||
Reference in New Issue
Block a user