1
0
mirror of https://github.com/immich-app/immich.git synced 2024-12-25 10:43:13 +02:00

feat(web): meta tags for share links (#1290)

* feat(web): meta tags for share links

* refactor: svelte head tags

* chore: clean up

* chore: linting
This commit is contained in:
Jason Rasmussen 2023-01-10 22:36:50 -05:00 committed by GitHub
parent a3688fe642
commit fa31a6e441
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
34 changed files with 120 additions and 84 deletions

View File

@ -1,10 +1,18 @@
import { api, AddAssetsResponseDto, AssetResponseDto } from '@api'; import { api, AddAssetsResponseDto, AssetResponseDto, ThumbnailFormat } from '@api';
import { import {
notificationController, notificationController,
NotificationType NotificationType
} from '$lib/components/shared-components/notification/notification'; } from '$lib/components/shared-components/notification/notification';
import { downloadAssets } from '$lib/stores/download'; import { downloadAssets } from '$lib/stores/download';
export const getThumbnailUrl = (assetId: string, format: ThumbnailFormat, key?: string) => {
let url = `/api/asset/thumbnail/${assetId}?format=${format}`;
if (key) {
url += `&key=${key}`;
}
return url;
};
export const addAssetsToAlbum = async ( export const addAssetsToAlbum = async (
albumId: string, albumId: string,
assetIds: Array<string>, assetIds: Array<string>,

View File

@ -77,6 +77,25 @@
}; };
</script> </script>
<svelte:head>
<title>{$page.data.meta?.title} - Immich</title>
{#if $page.data.meta}
<meta name="description" content={$page.data.meta.description} />
<!-- Facebook Meta Tags -->
<meta property="og:type" content="website" />
<meta property="og:title" content={$page.data.meta.title} />
<meta property="og:description" content={$page.data.meta.description} />
<meta property="og:image" content={$page.data.meta.imageUrl} />
<!-- Twitter Meta Tags -->
<meta name="twitter:card" content="summary_large_image" />
<meta name="twitter:title" content={$page.data.meta.title} />
<meta name="twitter:description" content={$page.data.meta.description} />
<meta name="twitter:image" content={$page.data.meta.imageUrl} />
{/if}
</svelte:head>
<main on:dragenter={() => (showUploadCover = true)}> <main on:dragenter={() => (showUploadCover = true)}>
{#if canShow} {#if canShow}
<div in:fade={{ duration: 100 }}> <div in:fade={{ duration: 100 }}>

View File

@ -2,11 +2,6 @@
import { goto } from '$app/navigation'; import { goto } from '$app/navigation';
</script> </script>
<svelte:head>
<title>Welcome 🎉 - Immich</title>
<meta name="description" content="Immich Web Interface" />
</svelte:head>
<section class="h-screen w-screen flex place-items-center place-content-center"> <section class="h-screen w-screen flex place-items-center place-content-center">
<div class="flex flex-col place-items-center gap-8 text-center max-w-[350px]"> <div class="flex flex-col place-items-center gap-8 text-center max-w-[350px]">
<div class="flex place-items-center place-content-center "> <div class="flex place-items-center place-content-center ">

View File

@ -7,4 +7,11 @@ export const load: PageLoad = async ({ parent }) => {
if (user) { if (user) {
throw redirect(302, '/photos'); throw redirect(302, '/photos');
} }
return {
meta: {
title: 'Welcome 🎉',
description: 'Immich Web Interface'
}
};
}; };

View File

@ -26,10 +26,6 @@
}; };
</script> </script>
<svelte:head>
<title>Administration - Immich</title>
</svelte:head>
<NavigationBar user={$page.data.user} /> <NavigationBar user={$page.data.user} />
<main> <main>

View File

@ -9,4 +9,10 @@ export const load: PageServerLoad = async ({ parent }) => {
} else if (!user.isAdmin) { } else if (!user.isAdmin) {
throw redirect(302, '/photos'); throw redirect(302, '/photos');
} }
return {
meta: {
title: 'Job Status'
}
};
}; };

View File

@ -2,10 +2,6 @@
import JobsPanel from '$lib/components/admin-page/jobs/jobs-panel.svelte'; import JobsPanel from '$lib/components/admin-page/jobs/jobs-panel.svelte';
</script> </script>
<svelte:head>
<title>Jobs Status - Immich</title>
</svelte:head>
<section> <section>
<JobsPanel /> <JobsPanel />
</section> </section>

View File

@ -13,5 +13,10 @@ export const load: PageServerLoad = async ({ parent }) => {
const { data: allUsers } = await serverApi.userApi.getAllUsers(false); const { data: allUsers } = await serverApi.userApi.getAllUsers(false);
return { allUsers }; return {
allUsers,
meta: {
title: 'Server Status'
}
};
}; };

View File

@ -3,10 +3,6 @@
import { page } from '$app/stores'; import { page } from '$app/stores';
</script> </script>
<svelte:head>
<title>Server Status - Immich</title>
</svelte:head>
{#if $page.data.allUsers} {#if $page.data.allUsers}
<ServerStatsPanel allUsers={$page.data.allUsers} /> <ServerStatsPanel allUsers={$page.data.allUsers} />
{/if} {/if}

View File

@ -10,5 +10,10 @@ export const load: PageServerLoad = async ({ parent }) => {
throw redirect(302, '/photos'); throw redirect(302, '/photos');
} }
return { user }; return {
user,
meta: {
title: 'System Settings'
}
};
}; };

View File

@ -17,10 +17,6 @@
}; };
</script> </script>
<svelte:head>
<title>System Settings - Immich</title>
</svelte:head>
<section class=""> <section class="">
{#await getConfig()} {#await getConfig()}
<LoadingSpinner /> <LoadingSpinner />

View File

@ -13,5 +13,11 @@ export const load: PageServerLoad = async ({ parent }) => {
const { data: allUsers } = await serverApi.userApi.getAllUsers(false); const { data: allUsers } = await serverApi.userApi.getAllUsers(false);
return { user, allUsers }; return {
user,
allUsers,
meta: {
title: 'User Management'
}
};
}; };

View File

@ -101,10 +101,6 @@
}; };
</script> </script>
<svelte:head>
<title>User Management - Immich</title>
</svelte:head>
<section> <section>
{#if shouldShowCreateUserForm} {#if shouldShowCreateUserForm}
<FullScreenModal on:clickOutside={() => (shouldShowCreateUserForm = false)}> <FullScreenModal on:clickOutside={() => (shouldShowCreateUserForm = false)}>

View File

@ -14,7 +14,10 @@ export const load: PageServerLoad = async ({ parent }) => {
return { return {
user: user, user: user,
albums: albums albums: albums,
meta: {
title: 'Albums'
}
}; };
} catch (e) { } catch (e) {
throw redirect(302, '/auth/login'); throw redirect(302, '/auth/login');

View File

@ -34,10 +34,6 @@
}; };
</script> </script>
<svelte:head>
<title>Albums - Immich</title>
</svelte:head>
<section> <section>
<NavigationBar user={data.user} shouldShowUploadButton={false} /> <NavigationBar user={data.user} shouldShowUploadButton={false} />
</section> </section>

View File

@ -15,7 +15,10 @@ export const load: PageServerLoad = async ({ parent, params }) => {
try { try {
const { data: album } = await serverApi.albumApi.getAlbumInfo(albumId); const { data: album } = await serverApi.albumApi.getAlbumInfo(albumId);
return { return {
album album,
meta: {
title: album.albumName
}
}; };
} catch (e) { } catch (e) {
throw redirect(302, '/albums'); throw redirect(302, '/albums');

View File

@ -5,10 +5,6 @@
export let data: PageData; export let data: PageData;
</script> </script>
<svelte:head>
<title>{data.album.albumName} - Immich</title>
</svelte:head>
<div class="immich-scrollbar"> <div class="immich-scrollbar">
<AlbumViewer album={data.album} /> <AlbumViewer album={data.album} />
</div> </div>

View File

@ -14,10 +14,6 @@
}; };
</script> </script>
<svelte:head>
<title>Change Password - Immich</title>
</svelte:head>
<section class="h-screen w-screen flex place-items-center place-content-center"> <section class="h-screen w-screen flex place-items-center place-content-center">
<div in:fade={{ duration: 100 }} out:fade={{ duration: 100 }}> <div in:fade={{ duration: 100 }} out:fade={{ duration: 100 }}>
<ChangePasswordForm user={data.user} on:success={onSuccessHandler} /> <ChangePasswordForm user={data.user} on:success={onSuccessHandler} />

View File

@ -10,7 +10,10 @@ export const load: PageLoad = async () => {
if (userInfo.shouldChangePassword) { if (userInfo.shouldChangePassword) {
return { return {
user: userInfo user: userInfo,
meta: {
title: 'Change Password'
}
}; };
} else { } else {
throw redirect(302, '/photos'); throw redirect(302, '/photos');

View File

@ -9,5 +9,9 @@ export const load: PageServerLoad = async () => {
throw redirect(302, '/auth/register'); throw redirect(302, '/auth/register');
} }
return; return {
meta: {
title: 'Login'
}
};
}; };

View File

@ -5,10 +5,6 @@
import LoginForm from '$lib/components/forms/login-form.svelte'; import LoginForm from '$lib/components/forms/login-form.svelte';
</script> </script>
<svelte:head>
<title>Login - Immich</title>
</svelte:head>
<section class="h-screen w-screen flex place-items-center place-content-center"> <section class="h-screen w-screen flex place-items-center place-content-center">
<div in:fade={{ duration: 100 }} out:fade={{ duration: 100 }}> <div in:fade={{ duration: 100 }} out:fade={{ duration: 100 }}>
<LoginForm <LoginForm

View File

@ -9,5 +9,9 @@ export const load: PageServerLoad = async () => {
throw redirect(302, '/auth/login'); throw redirect(302, '/auth/login');
} }
return; return {
meta: {
title: 'Admin Registration'
}
};
}; };

View File

@ -2,10 +2,6 @@
import AdminRegistrationForm from '$lib/components/forms/admin-registration-form.svelte'; import AdminRegistrationForm from '$lib/components/forms/admin-registration-form.svelte';
</script> </script>
<svelte:head>
<title>Admin Registration - Immich</title>
</svelte:head>
<section class="h-screen w-screen flex place-items-center place-content-center"> <section class="h-screen w-screen flex place-items-center place-content-center">
<AdminRegistrationForm /> <AdminRegistrationForm />
</section> </section>

View File

@ -9,7 +9,10 @@ export const load: PageServerLoad = async ({ parent }) => {
} }
return { return {
user user,
meta: {
title: 'Photos'
}
}; };
} catch (e) { } catch (e) {
console.log('Photo page load error', e); console.log('Photo page load error', e);

View File

@ -116,10 +116,6 @@
}; };
</script> </script>
<svelte:head>
<title>Photos - Immich</title>
</svelte:head>
<section> <section>
{#if $isMultiSelectStoreState} {#if $isMultiSelectStoreState}
<ControlAppBar <ControlAppBar

View File

@ -1,7 +1,8 @@
export const prerender = false; export const prerender = false;
import { error } from '@sveltejs/kit'; import { error } from '@sveltejs/kit';
import { serverApi } from '@api'; import { getThumbnailUrl } from '$lib/utils/asset-utils';
import { serverApi, ThumbnailFormat } from '@api';
import type { PageServerLoad } from './$types'; import type { PageServerLoad } from './$types';
export const load: PageServerLoad = async ({ params }) => { export const load: PageServerLoad = async ({ params }) => {
@ -9,7 +10,20 @@ export const load: PageServerLoad = async ({ params }) => {
try { try {
const { data: sharedLink } = await serverApi.shareApi.getMySharedLink({ params: { key } }); const { data: sharedLink } = await serverApi.shareApi.getMySharedLink({ params: { key } });
return { sharedLink };
const assetCount = sharedLink.assets.length;
const assetId = sharedLink.album?.albumThumbnailAssetId || sharedLink.assets[0]?.id;
return {
sharedLink,
meta: {
title: sharedLink.album ? sharedLink.album.albumName : 'Public Share',
description: sharedLink.description || `${assetCount} shared photos & videos.`,
imageUrl: assetId
? getThumbnailUrl(assetId, ThumbnailFormat.Webp, sharedLink.key)
: 'feature-panel.png'
}
};
} catch (e) { } catch (e) {
throw error(404, { throw error(404, {
message: 'Invalid shared link' message: 'Invalid shared link'

View File

@ -1,22 +1,20 @@
<script lang="ts"> <script lang="ts">
import AlbumViewer from '$lib/components/album-page/album-viewer.svelte'; import AlbumViewer from '$lib/components/album-page/album-viewer.svelte';
import { AlbumResponseDto } from '../../../api'; import { AlbumResponseDto } from '@api';
import type { PageData } from './$types'; import type { PageData } from './$types';
export let data: PageData; export let data: PageData;
const { sharedLink } = data;
let album: AlbumResponseDto | null = null; let album: AlbumResponseDto | null = null;
if (data.sharedLink.album) { if (sharedLink.album) {
album = { ...data.sharedLink.album, assets: data.sharedLink.assets }; album = { ...sharedLink.album, assets: sharedLink.assets };
} }
</script> </script>
<svelte:head>
<title>{data.sharedLink.album?.albumName || 'Public Shared'} - Immich</title>
</svelte:head>
{#if album} {#if album}
<div class="immich-scrollbar"> <div class="immich-scrollbar">
<AlbumViewer {album} sharedLink={data.sharedLink} /> <AlbumViewer {album} {sharedLink} />
</div> </div>
{/if} {/if}

View File

@ -15,7 +15,10 @@ export const load: PageServerLoad = async ({ parent }) => {
return { return {
user: user, user: user,
sharedAlbums: sharedAlbums sharedAlbums,
meta: {
title: 'Albums'
}
}; };
} catch (e) { } catch (e) {
throw redirect(302, '/auth/login'); throw redirect(302, '/auth/login');

View File

@ -33,10 +33,6 @@
}; };
</script> </script>
<svelte:head>
<title>Albums - Immich</title>
</svelte:head>
<section> <section>
<NavigationBar user={data.user} shouldShowUploadButton={false} /> <NavigationBar user={data.user} shouldShowUploadButton={false} />
</section> </section>

View File

@ -10,7 +10,10 @@ export const load: PageServerLoad = async ({ parent }) => {
} }
return { return {
user user,
meta: {
title: 'Shared Links'
}
}; };
} catch (e) { } catch (e) {
throw redirect(302, '/auth/login'); throw redirect(302, '/auth/login');

View File

@ -67,10 +67,6 @@
}; };
</script> </script>
<svelte:head>
<title>Shared links - Immich</title>
</svelte:head>
<ControlAppBar backIcon={ArrowLeft} on:close-button-click={() => goto('/sharing')}> <ControlAppBar backIcon={ArrowLeft} on:close-button-click={() => goto('/sharing')}>
<svelte:fragment slot="leading">Shared links</svelte:fragment> <svelte:fragment slot="leading">Shared links</svelte:fragment>
</ControlAppBar> </ControlAppBar>

View File

@ -10,7 +10,10 @@ export const load: PageServerLoad = async ({ parent }) => {
} }
return { return {
user: user user,
meta: {
title: 'Settings'
}
}; };
} catch (e) { } catch (e) {
throw redirect(302, '/auth/login'); throw redirect(302, '/auth/login');

View File

@ -7,10 +7,6 @@
export let data: PageData; export let data: PageData;
</script> </script>
<svelte:head>
<title>Settings - Immich</title>
</svelte:head>
<section> <section>
<NavigationBar user={data.user} shouldShowUploadButton={false} /> <NavigationBar user={data.user} shouldShowUploadButton={false} />
</section> </section>

Binary file not shown.

After

Width:  |  Height:  |  Size: 48 KiB