refactor: shared link queries (#32666)
(cherry picked from commit 0a73481a8fdb3cfbab29f23da48e26133dc4c064)
This commit is contained in:
@@ -15,7 +15,7 @@
|
||||
} from '$lib/stores/preferences.store';
|
||||
import { getSelectedAlbumGroupOption, sortAlbums, stringToSortOrder, type AlbumGroup } from '$lib/utils/album-utils';
|
||||
import { normalizeSearchString } from '$lib/utils/string-utils';
|
||||
import { type AlbumResponseDto, type SharedLinkResponseDto } from '@immich/sdk';
|
||||
import { type AlbumResponseDto } from '@immich/sdk';
|
||||
import { groupBy } from 'lodash-es';
|
||||
import { onMount, type Snippet } from 'svelte';
|
||||
import { t } from 'svelte-i18n';
|
||||
@@ -185,15 +185,9 @@
|
||||
ownedAlbums = ownedAlbums.filter(({ id }) => id !== album.id);
|
||||
sharedAlbums = sharedAlbums.filter(({ id }) => id !== album.id);
|
||||
};
|
||||
|
||||
const onSharedLinkCreate = (sharedLink: SharedLinkResponseDto) => {
|
||||
if (sharedLink.album) {
|
||||
onAlbumUpdate(sharedLink.album);
|
||||
}
|
||||
};
|
||||
</script>
|
||||
|
||||
<OnEvents {onAlbumUpdate} {onAlbumDelete} {onSharedLinkCreate} />
|
||||
<OnEvents {onAlbumUpdate} {onAlbumDelete} />
|
||||
|
||||
{#if albums.length > 0}
|
||||
{#if userSettings.view === AlbumViewMode.Cover}
|
||||
|
||||
@@ -1,9 +1,10 @@
|
||||
<script lang="ts">
|
||||
import { shortcut } from '$lib/actions/shortcut';
|
||||
import { assetMultiSelectManager } from '$lib/managers/asset-multi-select-manager.svelte';
|
||||
import { handleRemoveSharedLinkAssets } from '$lib/services/shared-link.service';
|
||||
import { executeMutation } from '$lib/queries/client';
|
||||
import { removeSharedLinkAssetsMutation } from '$lib/queries/shared-link.query';
|
||||
import { type SharedLinkResponseDto } from '@immich/sdk';
|
||||
import { IconButton } from '@immich/ui';
|
||||
import { IconButton, modalManager, toastManager } from '@immich/ui';
|
||||
import { mdiDeleteOutline } from '@mdi/js';
|
||||
import { t } from 'svelte-i18n';
|
||||
|
||||
@@ -13,22 +14,35 @@
|
||||
|
||||
let { sharedLink = $bindable() }: Props = $props();
|
||||
|
||||
const handleSelect = async () => {
|
||||
const onAction = async () => {
|
||||
const assetIds = assetMultiSelectManager.assets.map(({ id }) => id);
|
||||
const success = await handleRemoveSharedLinkAssets(sharedLink, assetIds);
|
||||
if (success) {
|
||||
assetMultiSelectManager.clear();
|
||||
const success = await modalManager.showDialog({
|
||||
title: $t('remove_assets_title'),
|
||||
prompt: $t('remove_assets_shared_link_confirmation', { values: { count: assetIds.length } }),
|
||||
confirmText: $t('remove'),
|
||||
});
|
||||
if (!success) {
|
||||
return;
|
||||
}
|
||||
|
||||
await executeMutation(removeSharedLinkAssetsMutation, [{ id: sharedLink.id, assetIdsDto: { assetIds } }], {
|
||||
onSuccess: (results) => {
|
||||
const removed = new Set(results.filter(({ success }) => success).map(({ assetId }) => assetId));
|
||||
sharedLink.assets = sharedLink.assets.filter(({ id }) => !removed.has(id));
|
||||
toastManager.primary($t('assets_removed_count', { values: { count: removed.size } }));
|
||||
assetMultiSelectManager.clear();
|
||||
},
|
||||
});
|
||||
};
|
||||
</script>
|
||||
|
||||
<svelte:document use:shortcut={{ shortcut: { key: 'Delete' }, onShortcut: handleSelect }} />
|
||||
<svelte:document use:shortcut={{ shortcut: { key: 'Delete' }, onShortcut: onAction }} />
|
||||
|
||||
<IconButton
|
||||
shape="round"
|
||||
color="secondary"
|
||||
variant="ghost"
|
||||
aria-label={$t('remove_from_shared_link')}
|
||||
onclick={handleSelect}
|
||||
onclick={onAction}
|
||||
icon={mdiDeleteOutline}
|
||||
/>
|
||||
|
||||
@@ -10,7 +10,6 @@ import type {
|
||||
PersonResponseDto,
|
||||
QueueResponseDto,
|
||||
ReleaseEventV1,
|
||||
SharedLinkResponseDto,
|
||||
StackResponseDto,
|
||||
AdminConfigDto,
|
||||
TagResponseDto,
|
||||
@@ -67,10 +66,6 @@ export type Events = {
|
||||
|
||||
QueueUpdate: [QueueResponseDto];
|
||||
|
||||
SharedLinkCreate: [SharedLinkResponseDto];
|
||||
SharedLinkUpdate: [SharedLinkResponseDto];
|
||||
SharedLinkDelete: [SharedLinkResponseDto];
|
||||
|
||||
StackCreate: [StackResponseDto];
|
||||
/** Unstacked, with assets to handle */
|
||||
StackDelete: [{ id: string; assets: AssetResponseDto[] }];
|
||||
|
||||
@@ -9,17 +9,11 @@
|
||||
handleUpdateAlbum,
|
||||
handleUpdateUserAlbumRole,
|
||||
} from '$lib/services/album.service';
|
||||
import {
|
||||
AlbumUserRole,
|
||||
AssetOrder,
|
||||
getAlbumInfo,
|
||||
getAllSharedLinks,
|
||||
type AlbumResponseDto,
|
||||
type SharedLinkResponseDto,
|
||||
type UserResponseDto,
|
||||
} from '@immich/sdk';
|
||||
import { AlbumUserRole, AssetOrder, getAlbumInfo, type AlbumResponseDto, type UserResponseDto } from '@immich/sdk';
|
||||
import { Field, HStack, Modal, ModalBody, Select, Stack, Switch, Text, type SelectOption } from '@immich/ui';
|
||||
import { onMount } from 'svelte';
|
||||
import { createQuery } from '@tanstack/svelte-query';
|
||||
import { queryClient } from '$lib/queries/client';
|
||||
import { getAllSharedLinksQuery } from '$lib/queries/shared-link.query';
|
||||
import { t } from 'svelte-i18n';
|
||||
|
||||
type Props = {
|
||||
@@ -48,30 +42,16 @@
|
||||
await refreshAlbum();
|
||||
};
|
||||
|
||||
const onSharedLinkCreate = (sharedLink: SharedLinkResponseDto) => {
|
||||
sharedLinks.push(sharedLink);
|
||||
};
|
||||
|
||||
const onSharedLinkDelete = (sharedLink: SharedLinkResponseDto) => {
|
||||
sharedLinks = sharedLinks.filter(({ id }) => sharedLink.id !== id);
|
||||
};
|
||||
|
||||
const { AddUsers, CreateSharedLink } = $derived(getAlbumActions($t, album));
|
||||
|
||||
let sharedLinks: SharedLinkResponseDto[] = $state([]);
|
||||
|
||||
onMount(async () => {
|
||||
sharedLinks = await getAllSharedLinks({ albumId: album.id });
|
||||
});
|
||||
const query = createQuery(
|
||||
() => getAllSharedLinksQuery({ albumId: album.id }),
|
||||
() => queryClient,
|
||||
);
|
||||
const sharedLinks = $derived(query.data ?? []);
|
||||
</script>
|
||||
|
||||
<OnEvents
|
||||
{onAlbumUserDelete}
|
||||
onAlbumShare={refreshAlbum}
|
||||
{onSharedLinkCreate}
|
||||
{onSharedLinkDelete}
|
||||
onAlbumUpdate={(newAlbum) => (album = newAlbum)}
|
||||
/>
|
||||
<OnEvents {onAlbumUserDelete} onAlbumShare={refreshAlbum} onAlbumUpdate={(newAlbum) => (album = newAlbum)} />
|
||||
|
||||
<Modal title={readOnly ? $t('album') : $t('options')} {onClose} size="small">
|
||||
<ModalBody>
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
<script lang="ts">
|
||||
import SharedLinkFormFields from '$lib/components/SharedLinkFormFields.svelte';
|
||||
import { handleCreateSharedLink } from '$lib/services/shared-link.service';
|
||||
import { executeMutation } from '$lib/queries/client';
|
||||
import { createSharedLinkMutation } from '$lib/queries/shared-link.query';
|
||||
import { showSharedLinkQrCode } from '$lib/services/shared-link.service';
|
||||
import { SharedLinkType } from '@immich/sdk';
|
||||
import { FormModal } from '@immich/ui';
|
||||
import { mdiLink } from '@mdi/js';
|
||||
@@ -25,7 +27,7 @@
|
||||
let type = $derived(albumId ? SharedLinkType.Album : SharedLinkType.Individual);
|
||||
|
||||
const onSubmit = async () => {
|
||||
const success = await handleCreateSharedLink({
|
||||
const sharedLinkCreateDto = {
|
||||
type,
|
||||
albumId,
|
||||
assetIds,
|
||||
@@ -36,10 +38,13 @@
|
||||
allowDownload,
|
||||
showMetadata,
|
||||
slug,
|
||||
};
|
||||
await executeMutation(createSharedLinkMutation, [{ sharedLinkCreateDto }], {
|
||||
onSuccess: (sharedLink) => {
|
||||
onClose();
|
||||
void showSharedLinkQrCode(sharedLink);
|
||||
},
|
||||
});
|
||||
if (success) {
|
||||
onClose();
|
||||
}
|
||||
};
|
||||
</script>
|
||||
|
||||
|
||||
@@ -0,0 +1,8 @@
|
||||
import { getAlbumInfo } from '@immich/sdk';
|
||||
import { queryOptions } from '@tanstack/svelte-query';
|
||||
|
||||
export const getAlbumInfoQuery = (id: string) =>
|
||||
queryOptions({
|
||||
queryKey: ['album', id],
|
||||
queryFn: ({ signal }) => getAlbumInfo({ id }, { signal }),
|
||||
});
|
||||
@@ -0,0 +1,72 @@
|
||||
import {
|
||||
createSharedLink,
|
||||
getAllSharedLinks,
|
||||
removeSharedLink,
|
||||
removeSharedLinkAssets,
|
||||
updateSharedLink,
|
||||
type SharedLinkResponseDto,
|
||||
} from '@immich/sdk';
|
||||
import { queryOptions } from '@tanstack/svelte-query';
|
||||
import { getAlbumInfoQuery } from '$lib/queries/album.query';
|
||||
import { asMutation, queryClient } from '$lib/queries/client';
|
||||
|
||||
const findOrFail = (sharedLinks: SharedLinkResponseDto[], id: string) => {
|
||||
const sharedLink = sharedLinks.find((sharedLink) => sharedLink.id === id);
|
||||
if (!sharedLink) {
|
||||
throw new Error(`Shared link ${id} not found`);
|
||||
}
|
||||
return sharedLink;
|
||||
};
|
||||
|
||||
export const getAllSharedLinksQuery = ({ albumId }: { albumId?: string } = {}) =>
|
||||
queryOptions({
|
||||
queryKey: ['shared-links'],
|
||||
queryFn: ({ signal }) => getAllSharedLinks({}, { signal }),
|
||||
select: (sharedLinks) => (albumId ? sharedLinks.filter(({ album }) => album?.id === albumId) : sharedLinks),
|
||||
});
|
||||
|
||||
export const getSharedLinkQuery = (id: string) =>
|
||||
queryOptions({
|
||||
...getAllSharedLinksQuery(),
|
||||
select: (sharedLinks) => findOrFail(sharedLinks, id),
|
||||
});
|
||||
|
||||
const invalidateAlbum = (albumId?: string | null) =>
|
||||
albumId ? queryClient.invalidateQueries({ queryKey: getAlbumInfoQuery(albumId).queryKey }) : undefined;
|
||||
|
||||
export const createSharedLinkMutation = () =>
|
||||
asMutation(createSharedLink, {
|
||||
onSuccess: async (_, [{ sharedLinkCreateDto }]) => {
|
||||
await Promise.all([
|
||||
queryClient.invalidateQueries({ queryKey: getAllSharedLinksQuery().queryKey, exact: true }),
|
||||
invalidateAlbum(sharedLinkCreateDto.albumId),
|
||||
]);
|
||||
},
|
||||
meta: { error: { toast: 'errors.failed_to_create_shared_link' } },
|
||||
});
|
||||
|
||||
export const updateSharedLinkMutation = () =>
|
||||
asMutation(updateSharedLink, {
|
||||
onSuccess: () => queryClient.invalidateQueries({ queryKey: getAllSharedLinksQuery().queryKey, exact: true }),
|
||||
meta: { success: { toast: 'saved' }, error: { toast: 'errors.failed_to_edit_shared_link' } },
|
||||
});
|
||||
|
||||
export const removeSharedLinkMutation = () =>
|
||||
asMutation(removeSharedLink, {
|
||||
onSuccess: async (_, [{ id }]) => {
|
||||
const albumId = queryClient
|
||||
.getQueryData(getAllSharedLinksQuery().queryKey)
|
||||
?.find((sharedLink) => sharedLink.id === id)?.album?.id;
|
||||
queryClient.setQueryData(getAllSharedLinksQuery().queryKey, (sharedLinks) =>
|
||||
sharedLinks?.filter((sharedLink) => sharedLink.id !== id),
|
||||
);
|
||||
await invalidateAlbum(albumId);
|
||||
},
|
||||
meta: { success: { toast: 'deleted_shared_link' }, error: { toast: 'errors.unable_to_delete_shared_link' } },
|
||||
});
|
||||
|
||||
export const removeSharedLinkAssetsMutation = () =>
|
||||
asMutation(removeSharedLinkAssets, {
|
||||
onSuccess: () => queryClient.invalidateQueries({ queryKey: getAllSharedLinksQuery().queryKey, exact: true }),
|
||||
meta: { error: { toast: 'errors.unable_to_remove_assets_from_shared_link' } },
|
||||
});
|
||||
@@ -1,24 +1,14 @@
|
||||
import {
|
||||
createSharedLink,
|
||||
getSharedLinkById,
|
||||
removeSharedLink,
|
||||
removeSharedLinkAssets,
|
||||
updateSharedLink,
|
||||
type SharedLinkCreateDto,
|
||||
type SharedLinkEditDto,
|
||||
type SharedLinkResponseDto,
|
||||
} from '@immich/sdk';
|
||||
import { modalManager, toastManager, type ActionItem } from '@immich/ui';
|
||||
import { type SharedLinkResponseDto } from '@immich/sdk';
|
||||
import { modalManager, type ActionItem } from '@immich/ui';
|
||||
import { mdiContentCopy, mdiLink, mdiPencilOutline, mdiQrcode, mdiTrashCanOutline } from '@mdi/js';
|
||||
import type { MessageFormatter } from 'svelte-i18n';
|
||||
import { goto } from '$app/navigation';
|
||||
import { eventManager } from '$lib/managers/event-manager.svelte';
|
||||
import QrCodeModal from '$lib/modals/QrCodeModal.svelte';
|
||||
import { readPreloadedQuery } from '$lib/queries/client';
|
||||
import { executeMutation, readPreloadedQuery } from '$lib/queries/client';
|
||||
import { getUserConfigQuery } from '$lib/queries/config-user.query';
|
||||
import { removeSharedLinkMutation } from '$lib/queries/shared-link.query';
|
||||
import { Route } from '$lib/route';
|
||||
import { copyToClipboard } from '$lib/utils';
|
||||
import { handleError } from '$lib/utils/handle-error';
|
||||
import { getFormatter } from '$lib/utils/i18n';
|
||||
|
||||
export const getSharedLinksActions = ($t: MessageFormatter) => {
|
||||
@@ -54,7 +44,7 @@ export const getSharedLinkActions = ($t: MessageFormatter, sharedLink: SharedLin
|
||||
const ViewQrCode: ActionItem = {
|
||||
title: $t('view_qr_code'),
|
||||
icon: mdiQrcode,
|
||||
onAction: () => handleShowSharedLinkQrCode(sharedLink),
|
||||
onAction: () => showSharedLinkQrCode(sharedLink),
|
||||
};
|
||||
|
||||
return { Edit, Delete, Copy, ViewQrCode };
|
||||
@@ -65,42 +55,9 @@ export const asUrl = (sharedLink: SharedLinkResponseDto) => {
|
||||
return new URL(path, readPreloadedQuery(getUserConfigQuery()).server.externalDomain || location.origin).href;
|
||||
};
|
||||
|
||||
export const handleCreateSharedLink = async (dto: SharedLinkCreateDto) => {
|
||||
export const showSharedLinkQrCode = async (sharedLink: SharedLinkResponseDto) => {
|
||||
const $t = await getFormatter();
|
||||
|
||||
try {
|
||||
let sharedLink = await createSharedLink({ sharedLinkCreateDto: dto });
|
||||
if (dto.albumId) {
|
||||
// fetch album details, for event
|
||||
sharedLink = await getSharedLinkById({ id: sharedLink.id });
|
||||
}
|
||||
|
||||
eventManager.emit('SharedLinkCreate', sharedLink);
|
||||
|
||||
// prevent nested modal
|
||||
void handleShowSharedLinkQrCode(sharedLink);
|
||||
|
||||
return true;
|
||||
} catch (error) {
|
||||
handleError(error, $t('errors.failed_to_create_shared_link'));
|
||||
return false;
|
||||
}
|
||||
};
|
||||
|
||||
export const handleUpdateSharedLink = async (sharedLink: SharedLinkResponseDto, dto: SharedLinkEditDto) => {
|
||||
const $t = await getFormatter();
|
||||
|
||||
try {
|
||||
const response = await updateSharedLink({ id: sharedLink.id, sharedLinkEditDto: dto });
|
||||
|
||||
eventManager.emit('SharedLinkUpdate', { album: sharedLink.album, ...response });
|
||||
toastManager.primary($t('saved'));
|
||||
|
||||
return true;
|
||||
} catch (error) {
|
||||
handleError(error, $t('errors.failed_to_edit_shared_link'));
|
||||
return false;
|
||||
}
|
||||
await modalManager.show(QrCodeModal, { title: $t('view_link'), value: asUrl(sharedLink) });
|
||||
};
|
||||
|
||||
const handleDeleteSharedLink = async (sharedLink: SharedLinkResponseDto) => {
|
||||
@@ -114,50 +71,5 @@ const handleDeleteSharedLink = async (sharedLink: SharedLinkResponseDto) => {
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
await removeSharedLink({ id: sharedLink.id });
|
||||
eventManager.emit('SharedLinkDelete', sharedLink);
|
||||
toastManager.primary($t('deleted_shared_link'));
|
||||
} catch (error) {
|
||||
handleError(error, $t('errors.unable_to_delete_shared_link'));
|
||||
}
|
||||
};
|
||||
|
||||
export const handleRemoveSharedLinkAssets = async (sharedLink: SharedLinkResponseDto, assetIds: string[]) => {
|
||||
const $t = await getFormatter();
|
||||
const success = await modalManager.showDialog({
|
||||
title: $t('remove_assets_title'),
|
||||
prompt: $t('remove_assets_shared_link_confirmation', { values: { count: assetIds.length } }),
|
||||
confirmText: $t('remove'),
|
||||
});
|
||||
if (!success) {
|
||||
return false;
|
||||
}
|
||||
|
||||
try {
|
||||
const results = await removeSharedLinkAssets({
|
||||
id: sharedLink.id,
|
||||
assetIdsDto: { assetIds },
|
||||
});
|
||||
|
||||
for (const result of results) {
|
||||
if (!result.success) {
|
||||
continue;
|
||||
}
|
||||
|
||||
sharedLink.assets = sharedLink.assets.filter((asset) => asset.id !== result.assetId);
|
||||
}
|
||||
|
||||
const count = results.filter((item) => item.success).length;
|
||||
toastManager.primary($t('assets_removed_count', { values: { count } }));
|
||||
return true;
|
||||
} catch (error) {
|
||||
handleError(error, $t('errors.unable_to_remove_assets_from_shared_link'));
|
||||
return false;
|
||||
}
|
||||
};
|
||||
|
||||
const handleShowSharedLinkQrCode = async (sharedLink: SharedLinkResponseDto) => {
|
||||
const $t = await getFormatter();
|
||||
await modalManager.show(QrCodeModal, { title: $t('view_link'), value: asUrl(sharedLink) });
|
||||
await executeMutation(removeSharedLinkMutation, [{ id: sharedLink.id }]);
|
||||
};
|
||||
|
||||
+9
-16
@@ -1,6 +1,5 @@
|
||||
<script lang="ts">
|
||||
import { goto, invalidate, onNavigate } from '$app/navigation';
|
||||
import { navigating } from '$app/state';
|
||||
import { goto, onNavigate } from '$app/navigation';
|
||||
import { scrollMemoryClearer } from '$lib/actions/scroll-memory';
|
||||
import AlbumMap from '$lib/components/album-page/AlbumMap.svelte';
|
||||
import AlbumSummary from '$lib/components/album-page/AlbumSummary.svelte';
|
||||
@@ -29,6 +28,8 @@
|
||||
import { assetViewerManager } from '$lib/managers/asset-viewer-manager.svelte';
|
||||
import { authManager } from '$lib/managers/auth-manager.svelte';
|
||||
import { eventManager } from '$lib/managers/event-manager.svelte';
|
||||
import { getAlbumInfoQuery } from '$lib/queries/album.query';
|
||||
import { createPreloadedQuery, queryClient } from '$lib/queries/client';
|
||||
import { TimelineManager } from '$lib/managers/timeline-manager/timeline-manager.svelte';
|
||||
import type { TimelineAsset } from '$lib/managers/timeline-manager/types';
|
||||
import { Route } from '$lib/route';
|
||||
@@ -62,22 +63,17 @@
|
||||
import { onDestroy } from 'svelte';
|
||||
import { t } from 'svelte-i18n';
|
||||
import { fly } from 'svelte/transition';
|
||||
import type { PageData } from './$types';
|
||||
import type { PageProps } from './$types';
|
||||
import AlbumDescription from './AlbumDescription.svelte';
|
||||
import AlbumTitle from './AlbumTitle.svelte';
|
||||
import ActionMenuItem from '$lib/components/ActionMenuItem.svelte';
|
||||
import { delay } from '$lib/utils/asset-utils';
|
||||
import { createPreloadedQuery } from '$lib/queries/client';
|
||||
import { getUserConfigQuery } from '$lib/queries/config-user.query';
|
||||
|
||||
const query = createPreloadedQuery(getUserConfigQuery);
|
||||
const config = $derived(query.data);
|
||||
|
||||
interface Props {
|
||||
data: PageData;
|
||||
}
|
||||
|
||||
let { data = $bindable() }: Props = $props();
|
||||
const { params }: PageProps = $props();
|
||||
let { slideshowState, slideshowNavigation } = slideshowStore;
|
||||
let oldAt: AssetGridRouteSearchParams | null | undefined = $state();
|
||||
let viewMode: AlbumPageViewMode = $state(AlbumPageViewMode.VIEW);
|
||||
@@ -131,12 +127,10 @@
|
||||
if (updated.id !== album.id) {
|
||||
return;
|
||||
}
|
||||
album = updated;
|
||||
queryClient.setQueryData(getAlbumInfoQuery(album.id).queryKey, updated);
|
||||
}
|
||||
|
||||
// invalidating during navigation causes an infinite page load
|
||||
await navigating.complete;
|
||||
await invalidate('album:data');
|
||||
await queryClient.invalidateQueries({ queryKey: getAlbumInfoQuery(album.id).queryKey });
|
||||
};
|
||||
|
||||
const setModeToView = async () => {
|
||||
@@ -218,7 +212,8 @@
|
||||
}
|
||||
});
|
||||
|
||||
let album = $derived(data.album);
|
||||
const albumQuery = createPreloadedQuery(() => getAlbumInfoQuery(params.albumId));
|
||||
let album = $derived(albumQuery.data);
|
||||
const albumId = $derived(album.id);
|
||||
|
||||
const albumHasViewers = $derived(album.albumUsers.some(({ role }) => role === AlbumUserRole.Viewer));
|
||||
@@ -329,8 +324,6 @@
|
||||
</script>
|
||||
|
||||
<OnEvents
|
||||
onSharedLinkCreate={(link) => refreshAlbum(link.album)}
|
||||
onSharedLinkDelete={() => refreshAlbum()}
|
||||
{onAlbumDelete}
|
||||
{onAlbumAddAssets}
|
||||
{onAlbumRemoveAssets}
|
||||
|
||||
@@ -1,16 +1,14 @@
|
||||
import { getAlbumInfo } from '@immich/sdk';
|
||||
import { getAlbumInfoQuery } from '$lib/queries/album.query';
|
||||
import { queryClient } from '$lib/queries/client';
|
||||
import { authenticate } from '$lib/utils/auth';
|
||||
import type { PageLoad } from './$types';
|
||||
|
||||
export const load = (async ({ params, url, depends }) => {
|
||||
export const load = (async ({ params, url }) => {
|
||||
await authenticate(url);
|
||||
|
||||
depends('album:data');
|
||||
|
||||
const album = await getAlbumInfo({ id: params.albumId });
|
||||
const album = await queryClient.query(getAlbumInfoQuery(params.albumId));
|
||||
|
||||
return {
|
||||
album,
|
||||
meta: {
|
||||
title: album.albumName,
|
||||
},
|
||||
|
||||
@@ -2,14 +2,15 @@
|
||||
import { goto } from '$app/navigation';
|
||||
import { page } from '$app/state';
|
||||
import UserPageLayout from '$lib/components/layouts/UserPageLayout.svelte';
|
||||
import OnEvents from '$lib/components/OnEvents.svelte';
|
||||
import SharedLinkCard from './SharedLinkCard.svelte';
|
||||
import { type SharedLinkTab } from '$lib/constants';
|
||||
import GroupTab from '$lib/elements/GroupTab.svelte';
|
||||
import { Route } from '$lib/route';
|
||||
import { getAllSharedLinks, SharedLinkType, type SharedLinkResponseDto } from '@immich/sdk';
|
||||
import { createPreloadedQuery } from '$lib/queries/client';
|
||||
import { getAllSharedLinksQuery } from '$lib/queries/shared-link.query';
|
||||
import { SharedLinkType } from '@immich/sdk';
|
||||
import { Container } from '@immich/ui';
|
||||
import { onMount, type Snippet } from 'svelte';
|
||||
import { type Snippet } from 'svelte';
|
||||
import { t } from 'svelte-i18n';
|
||||
import type { LayoutData } from './$types';
|
||||
|
||||
@@ -20,15 +21,8 @@
|
||||
|
||||
const { children, data }: Props = $props();
|
||||
|
||||
let sharedLinks: SharedLinkResponseDto[] = $state([]);
|
||||
|
||||
const refresh = async () => {
|
||||
sharedLinks = await getAllSharedLinks({});
|
||||
};
|
||||
|
||||
onMount(async () => {
|
||||
await refresh();
|
||||
});
|
||||
const query = createPreloadedQuery(getAllSharedLinksQuery);
|
||||
const sharedLinks = $derived(query.data);
|
||||
|
||||
const filterMap: Record<SharedLinkTab, string> = {
|
||||
all: $t('all'),
|
||||
@@ -54,21 +48,8 @@
|
||||
(type === SharedLinkType.Individual && selectedTab === 'individual'),
|
||||
),
|
||||
);
|
||||
|
||||
const onSharedLinkUpdate = (sharedLink: SharedLinkResponseDto) => {
|
||||
const index = sharedLinks.findIndex((link) => link.id === sharedLink.id);
|
||||
if (index !== -1) {
|
||||
sharedLinks[index] = sharedLink;
|
||||
}
|
||||
};
|
||||
|
||||
const onSharedLinkDelete = (sharedLink: SharedLinkResponseDto) => {
|
||||
sharedLinks = sharedLinks.filter(({ id }) => id !== sharedLink.id);
|
||||
};
|
||||
</script>
|
||||
|
||||
<OnEvents {onSharedLinkUpdate} {onSharedLinkDelete} />
|
||||
|
||||
<UserPageLayout title={data.meta.title}>
|
||||
{#snippet buttons()}
|
||||
<div class="hidden h-10 xl:block">
|
||||
|
||||
@@ -1,9 +1,12 @@
|
||||
import { queryClient } from '$lib/queries/client';
|
||||
import { getAllSharedLinksQuery } from '$lib/queries/shared-link.query';
|
||||
import { authenticate } from '$lib/utils/auth';
|
||||
import { getFormatter } from '$lib/utils/i18n';
|
||||
import type { LayoutLoad } from './$types';
|
||||
|
||||
export const load = (async ({ url }) => {
|
||||
await authenticate(url);
|
||||
await queryClient.query(getAllSharedLinksQuery());
|
||||
const $t = await getFormatter();
|
||||
|
||||
return {
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
import { getAllSharedLinks } from '@immich/sdk';
|
||||
import { redirect } from '@sveltejs/kit';
|
||||
import { UUID_REGEX } from '$lib/constants';
|
||||
import { queryClient } from '$lib/queries/client';
|
||||
import { getSharedLinkQuery } from '$lib/queries/shared-link.query';
|
||||
import { Route } from '$lib/route';
|
||||
import { authenticate } from '$lib/utils/auth';
|
||||
import { getFormatter } from '$lib/utils/i18n';
|
||||
@@ -13,15 +14,11 @@ export const load = (async ({ params, url }) => {
|
||||
redirect(307, Route.sharedLinks());
|
||||
}
|
||||
|
||||
const [sharedLink] = await getAllSharedLinks({ id: params.id });
|
||||
if (!sharedLink) {
|
||||
redirect(307, Route.sharedLinks());
|
||||
}
|
||||
await queryClient.query(getSharedLinkQuery(params.id)).catch(() => redirect(307, Route.sharedLinks()));
|
||||
|
||||
const $t = await getFormatter();
|
||||
|
||||
return {
|
||||
sharedLink,
|
||||
meta: {
|
||||
title: $t('shared_links'),
|
||||
},
|
||||
|
||||
@@ -2,20 +2,18 @@
|
||||
import { goto } from '$app/navigation';
|
||||
import SharedLinkFormFields from '$lib/components/SharedLinkFormFields.svelte';
|
||||
import { Route } from '$lib/route';
|
||||
import { handleUpdateSharedLink } from '$lib/services/shared-link.service';
|
||||
import { createPreloadedQuery, executeMutation } from '$lib/queries/client';
|
||||
import { getSharedLinkQuery, updateSharedLinkMutation } from '$lib/queries/shared-link.query';
|
||||
import { SharedLinkType } from '@immich/sdk';
|
||||
import { FormModal } from '@immich/ui';
|
||||
import { mdiLink } from '@mdi/js';
|
||||
import { t } from 'svelte-i18n';
|
||||
import type { PageData } from './$types';
|
||||
import type { PageProps } from './$types';
|
||||
|
||||
type Props = {
|
||||
data: PageData;
|
||||
};
|
||||
const { params }: PageProps = $props();
|
||||
|
||||
let { data }: Props = $props();
|
||||
|
||||
const sharedLink = $state(data.sharedLink);
|
||||
const query = createPreloadedQuery(() => getSharedLinkQuery(params.id));
|
||||
const sharedLink = $derived(query.data);
|
||||
|
||||
let description = $state(sharedLink.description ?? '');
|
||||
let allowDownload = $state(sharedLink.allowDownload);
|
||||
@@ -26,12 +24,9 @@
|
||||
let shareType = sharedLink.album ? SharedLinkType.Album : SharedLinkType.Individual;
|
||||
let expiresAt = $state(sharedLink.expiresAt);
|
||||
|
||||
const onClose = async () => {
|
||||
await goto(Route.sharedLinks());
|
||||
};
|
||||
|
||||
const onClose = () => void goto(Route.sharedLinks());
|
||||
const onSubmit = async () => {
|
||||
const success = await handleUpdateSharedLink(sharedLink, {
|
||||
const sharedLinkEditDto = {
|
||||
description,
|
||||
password: password ?? null,
|
||||
expiresAt,
|
||||
@@ -39,10 +34,8 @@
|
||||
allowDownload,
|
||||
showMetadata,
|
||||
slug: slug.trim() ?? null,
|
||||
});
|
||||
if (success) {
|
||||
await onClose();
|
||||
}
|
||||
};
|
||||
await executeMutation(updateSharedLinkMutation, [{ id: sharedLink.id, sharedLinkEditDto }], { onSuccess: onClose });
|
||||
};
|
||||
</script>
|
||||
|
||||
|
||||
Reference in New Issue
Block a user