mirror of
https://github.com/KevinMidboe/immich.git
synced 2025-10-29 17:40:28 +00:00
feat(web) Individual assets shared mechanism (#1317)
* Create shared link modal for individual asset * Added API to create asset shared link * Added viewer for individual shared link * Added multiselection app bar * Refactor gallery viewer to its own component * Refactor * Refactor * Add and remove asset from shared link * Fixed test * Fixed notification card doesn't wrap * Add check asset access when created asset shared link * pr feedback
This commit is contained in:
@@ -6,9 +6,8 @@
|
||||
import MenuOption from '$lib/components/shared-components/context-menu/menu-option.svelte';
|
||||
import AlbumSelectionModal from '$lib/components/shared-components/album-selection-modal.svelte';
|
||||
import { goto } from '$app/navigation';
|
||||
|
||||
import type { PageData } from './$types';
|
||||
|
||||
import ShareVariantOutline from 'svelte-material-icons/ShareVariantOutline.svelte';
|
||||
import { openFileUploadDialog } from '$lib/utils/file-uploader';
|
||||
import {
|
||||
assetInteractionStore,
|
||||
@@ -21,16 +20,17 @@
|
||||
import CircleIconButton from '$lib/components/shared-components/circle-icon-button.svelte';
|
||||
import DeleteOutline from 'svelte-material-icons/DeleteOutline.svelte';
|
||||
import Plus from 'svelte-material-icons/Plus.svelte';
|
||||
import { AlbumResponseDto, api } from '@api';
|
||||
import { AlbumResponseDto, api, SharedLinkType } from '@api';
|
||||
import {
|
||||
notificationController,
|
||||
NotificationType
|
||||
} from '$lib/components/shared-components/notification/notification';
|
||||
import { assetStore } from '$lib/stores/assets.store';
|
||||
import { addAssetsToAlbum, bulkDownload } from '$lib/utils/asset-utils';
|
||||
import CreateSharedLinkModal from '$lib/components/shared-components/create-share-link-modal/create-shared-link-modal.svelte';
|
||||
|
||||
export let data: PageData;
|
||||
|
||||
let isShowCreateSharedLinkModal = false;
|
||||
const deleteSelectedAssetHandler = async () => {
|
||||
try {
|
||||
if (
|
||||
@@ -114,6 +114,15 @@
|
||||
assetInteractionStore.clearMultiselect();
|
||||
});
|
||||
};
|
||||
|
||||
const handleCreateSharedLink = async () => {
|
||||
isShowCreateSharedLinkModal = true;
|
||||
};
|
||||
|
||||
const handleCloseSharedLinkModal = () => {
|
||||
assetInteractionStore.clearMultiselect();
|
||||
isShowCreateSharedLinkModal = false;
|
||||
};
|
||||
</script>
|
||||
|
||||
<section>
|
||||
@@ -129,6 +138,11 @@
|
||||
</p>
|
||||
</svelte:fragment>
|
||||
<svelte:fragment slot="trailing">
|
||||
<CircleIconButton
|
||||
title="Share"
|
||||
logo={ShareVariantOutline}
|
||||
on:click={handleCreateSharedLink}
|
||||
/>
|
||||
<CircleIconButton
|
||||
title="Download"
|
||||
logo={CloudDownloadOutline}
|
||||
@@ -164,6 +178,14 @@
|
||||
on:close={() => (isShowAlbumPicker = false)}
|
||||
/>
|
||||
{/if}
|
||||
|
||||
{#if isShowCreateSharedLinkModal}
|
||||
<CreateSharedLinkModal
|
||||
sharedAssets={Array.from($selectedAssets)}
|
||||
shareType={SharedLinkType.Individual}
|
||||
on:close={handleCloseSharedLinkModal}
|
||||
/>
|
||||
{/if}
|
||||
</section>
|
||||
|
||||
<section
|
||||
|
||||
@@ -5,7 +5,9 @@ import { getThumbnailUrl } from '$lib/utils/asset-utils';
|
||||
import { serverApi, ThumbnailFormat } from '@api';
|
||||
import type { PageServerLoad } from './$types';
|
||||
|
||||
export const load: PageServerLoad = async ({ params }) => {
|
||||
export const load: PageServerLoad = async ({ params, parent }) => {
|
||||
const { user } = await parent();
|
||||
|
||||
const { key } = params;
|
||||
|
||||
try {
|
||||
@@ -22,7 +24,8 @@ export const load: PageServerLoad = async ({ params }) => {
|
||||
imageUrl: assetId
|
||||
? getThumbnailUrl(assetId, ThumbnailFormat.Webp, sharedLink.key)
|
||||
: 'feature-panel.png'
|
||||
}
|
||||
},
|
||||
user
|
||||
};
|
||||
} catch (e) {
|
||||
throw error(404, {
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
<script lang="ts">
|
||||
import AlbumViewer from '$lib/components/album-page/album-viewer.svelte';
|
||||
import { AlbumResponseDto } from '@api';
|
||||
import IndividualSharedViewer from '$lib/components/share-page/individual-shared-viewer.svelte';
|
||||
import { AlbumResponseDto, SharedLinkType } from '@api';
|
||||
import type { PageData } from './$types';
|
||||
|
||||
export let data: PageData;
|
||||
@@ -8,13 +9,20 @@
|
||||
const { sharedLink } = data;
|
||||
|
||||
let album: AlbumResponseDto | null = null;
|
||||
let isOwned = data.user ? data.user.id === sharedLink.userId : false;
|
||||
if (sharedLink.album) {
|
||||
album = { ...sharedLink.album, assets: sharedLink.assets };
|
||||
}
|
||||
</script>
|
||||
|
||||
{#if album}
|
||||
{#if sharedLink.type == SharedLinkType.Album && album}
|
||||
<div class="immich-scrollbar">
|
||||
<AlbumViewer {album} {sharedLink} />
|
||||
</div>
|
||||
{/if}
|
||||
|
||||
{#if sharedLink.type == SharedLinkType.Individual}
|
||||
<div class="immich-scrollbar">
|
||||
<IndividualSharedViewer {sharedLink} {isOwned} />
|
||||
</div>
|
||||
{/if}
|
||||
|
||||
Reference in New Issue
Block a user