feat: shared links custom URL (#19999)

* feat: custom url for shared links

* feat: use a separate route and query param

---------

Co-authored-by: Jason Rasmussen <jason@rasm.me>
This commit is contained in:
Jed-Giblin
2025-07-28 14:16:55 -04:00
committed by GitHub
parent 16b14b390f
commit 9b3718120b
65 changed files with 947 additions and 432 deletions

View File

@@ -0,0 +1,58 @@
import { getAssetThumbnailUrl, setSharedLink } from '$lib/utils';
import { authenticate } from '$lib/utils/auth';
import { getFormatter } from '$lib/utils/i18n';
import { getAssetInfoFromParam } from '$lib/utils/navigation';
import { getMySharedLink, isHttpError } from '@immich/sdk';
export const asQueryString = ({ slug, key }: { slug?: string; key?: string }) => {
const params = new URLSearchParams();
if (slug) {
params.set('slug', slug);
}
if (key) {
params.set('key', key);
}
return params.toString();
};
export const loadSharedLink = async ({ url, params }: { url: URL; params: { key?: string; slug?: string } }) => {
const { key, slug } = params;
await authenticate(url, { public: true });
const common = { key, slug };
const $t = await getFormatter();
try {
const [sharedLink, asset] = await Promise.all([getMySharedLink({ key, slug }), getAssetInfoFromParam(params)]);
setSharedLink(sharedLink);
const assetCount = sharedLink.assets.length;
const assetId = sharedLink.album?.albumThumbnailAssetId || sharedLink.assets[0]?.id;
const assetPath = assetId ? getAssetThumbnailUrl(assetId) : '/feature-panel.png';
return {
...common,
sharedLink,
asset,
meta: {
title: sharedLink.album ? sharedLink.album.albumName : $t('public_share'),
description: sharedLink.description || $t('shared_photos_and_videos_count', { values: { assetCount } }),
imageUrl: assetPath,
},
};
} catch (error) {
if (isHttpError(error) && error.data.message === 'Invalid password') {
return {
...common,
passwordRequired: true,
meta: {
title: $t('password_required'),
},
};
}
throw error;
}
};