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

feat(web): add share link on asset-viewer (#7595)

* feat(web): add share link on asset-viewer

* PR feedback: move download to context, make share first button
This commit is contained in:
Sam Holton 2024-03-03 16:15:35 -05:00 committed by GitHub
parent 29a4389aac
commit 2bb7b3e60f
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 35 additions and 11 deletions

View File

@ -9,7 +9,6 @@
import { import {
mdiAlertOutline, mdiAlertOutline,
mdiArrowLeft, mdiArrowLeft,
mdiCloudDownloadOutline,
mdiContentCopy, mdiContentCopy,
mdiDeleteOutline, mdiDeleteOutline,
mdiDotsVertical, mdiDotsVertical,
@ -20,6 +19,7 @@
mdiMagnifyPlusOutline, mdiMagnifyPlusOutline,
mdiMotionPauseOutline, mdiMotionPauseOutline,
mdiPlaySpeed, mdiPlaySpeed,
mdiShareVariantOutline,
} from '@mdi/js'; } from '@mdi/js';
import { createEventDispatcher } from 'svelte'; import { createEventDispatcher } from 'svelte';
import ContextMenu from '../shared-components/context-menu/context-menu.svelte'; import ContextMenu from '../shared-components/context-menu/context-menu.svelte';
@ -32,12 +32,20 @@
export let isMotionPhotoPlaying = false; export let isMotionPhotoPlaying = false;
export let showDownloadButton: boolean; export let showDownloadButton: boolean;
export let showDetailButton: boolean; export let showDetailButton: boolean;
export let showShareButton: boolean;
export let showSlideshow = false; export let showSlideshow = false;
export let hasStackChildren = false; export let hasStackChildren = false;
$: isOwner = asset.ownerId === $user?.id; $: isOwner = asset.ownerId === $user?.id;
type MenuItemEvent = 'addToAlbum' | 'addToSharedAlbum' | 'asProfileImage' | 'runJob' | 'playSlideShow' | 'unstack'; type MenuItemEvent =
| 'addToAlbum'
| 'addToSharedAlbum'
| 'asProfileImage'
| 'download'
| 'playSlideShow'
| 'runJob'
| 'unstack';
const dispatch = createEventDispatcher<{ const dispatch = createEventDispatcher<{
back: void; back: void;
@ -54,6 +62,7 @@
runJob: AssetJobName; runJob: AssetJobName;
playSlideShow: void; playSlideShow: void;
unstack: void; unstack: void;
showShareModal: void;
}>(); }>();
let contextMenuPosition = { x: 0, y: 0 }; let contextMenuPosition = { x: 0, y: 0 };
@ -82,6 +91,14 @@
<CircleIconButton isOpacity={true} icon={mdiArrowLeft} on:click={() => dispatch('back')} /> <CircleIconButton isOpacity={true} icon={mdiArrowLeft} on:click={() => dispatch('back')} />
</div> </div>
<div class="flex w-[calc(100%-3rem)] justify-end gap-2 overflow-hidden text-white"> <div class="flex w-[calc(100%-3rem)] justify-end gap-2 overflow-hidden text-white">
{#if showShareButton}
<CircleIconButton
isOpacity={true}
icon={mdiShareVariantOutline}
on:click={() => dispatch('showShareModal')}
title="Share"
/>
{/if}
{#if asset.isOffline} {#if asset.isOffline}
<CircleIconButton <CircleIconButton
isOpacity={true} isOpacity={true}
@ -130,15 +147,6 @@
}} }}
/> />
{/if} {/if}
{#if showDownloadButton}
<CircleIconButton
isOpacity={true}
icon={mdiCloudDownloadOutline}
on:click={() => dispatch('download')}
title="Download"
/>
{/if}
{#if showDetailButton} {#if showDetailButton}
<CircleIconButton <CircleIconButton
isOpacity={true} isOpacity={true}
@ -167,6 +175,9 @@
{#if showSlideshow} {#if showSlideshow}
<MenuOption on:click={() => onMenuClick('playSlideShow')} text="Slideshow" /> <MenuOption on:click={() => onMenuClick('playSlideShow')} text="Slideshow" />
{/if} {/if}
{#if showDownloadButton}
<MenuOption on:click={() => onMenuClick('download')} text="Download" />
{/if}
<MenuOption on:click={() => onMenuClick('addToAlbum')} text="Add to Album" /> <MenuOption on:click={() => onMenuClick('addToAlbum')} text="Add to Album" />
<MenuOption on:click={() => onMenuClick('addToSharedAlbum')} text="Add to Shared Album" /> <MenuOption on:click={() => onMenuClick('addToSharedAlbum')} text="Add to Shared Album" />

View File

@ -51,6 +51,7 @@
import PhotoViewer from './photo-viewer.svelte'; import PhotoViewer from './photo-viewer.svelte';
import SlideshowBar from './slideshow-bar.svelte'; import SlideshowBar from './slideshow-bar.svelte';
import VideoViewer from './video-viewer.svelte'; import VideoViewer from './video-viewer.svelte';
import CreateSharedLinkModal from '$lib/components/shared-components/create-share-link-modal/create-shared-link-modal.svelte';
export let assetStore: AssetStore | null = null; export let assetStore: AssetStore | null = null;
export let asset: AssetResponseDto; export let asset: AssetResponseDto;
@ -81,11 +82,13 @@
let appearsInAlbums: AlbumResponseDto[] = []; let appearsInAlbums: AlbumResponseDto[] = [];
let isShowAlbumPicker = false; let isShowAlbumPicker = false;
let isShowDeleteConfirmation = false; let isShowDeleteConfirmation = false;
let isShowShareModal = false;
let addToSharedAlbum = true; let addToSharedAlbum = true;
let shouldPlayMotionPhoto = false; let shouldPlayMotionPhoto = false;
let isShowProfileImageCrop = false; let isShowProfileImageCrop = false;
let shouldShowDownloadButton = sharedLink ? sharedLink.allowDownload : !asset.isOffline; let shouldShowDownloadButton = sharedLink ? sharedLink.allowDownload : !asset.isOffline;
let shouldShowDetailButton = asset.hasMetadata; let shouldShowDetailButton = asset.hasMetadata;
let shouldShowShareModal = !asset.isTrashed;
let canCopyImagesToClipboard: boolean; let canCopyImagesToClipboard: boolean;
let slideshowStateUnsubscribe: () => void; let slideshowStateUnsubscribe: () => void;
let shuffleSlideshowUnsubscribe: () => void; let shuffleSlideshowUnsubscribe: () => void;
@ -292,6 +295,10 @@
isShowDeleteConfirmation = false; isShowDeleteConfirmation = false;
return; return;
} }
if (isShowShareModal) {
isShowShareModal = false;
return;
}
closeViewer(); closeViewer();
return; return;
} }
@ -563,6 +570,7 @@
showDetailButton={shouldShowDetailButton} showDetailButton={shouldShowDetailButton}
showSlideshow={!!assetStore} showSlideshow={!!assetStore}
hasStackChildren={$stackAssetsStore.length > 0} hasStackChildren={$stackAssetsStore.length > 0}
showShareButton={shouldShowShareModal}
on:back={closeViewer} on:back={closeViewer}
on:showDetail={showDetailInfoHandler} on:showDetail={showDetailInfoHandler}
on:download={() => downloadFile(asset)} on:download={() => downloadFile(asset)}
@ -577,6 +585,7 @@
on:runJob={({ detail: job }) => handleRunJob(job)} on:runJob={({ detail: job }) => handleRunJob(job)}
on:playSlideShow={() => ($slideshowState = SlideshowState.PlaySlideshow)} on:playSlideShow={() => ($slideshowState = SlideshowState.PlaySlideshow)}
on:unstack={handleUnstack} on:unstack={handleUnstack}
on:showShareModal={() => (isShowShareModal = true)}
/> />
</div> </div>
{/if} {/if}
@ -767,6 +776,10 @@
{#if isShowProfileImageCrop} {#if isShowProfileImageCrop}
<ProfileImageCropper {asset} on:close={() => (isShowProfileImageCrop = false)} /> <ProfileImageCropper {asset} on:close={() => (isShowProfileImageCrop = false)} />
{/if} {/if}
{#if isShowShareModal}
<CreateSharedLinkModal assetIds={[asset.id]} on:close={() => (isShowShareModal = false)} />
{/if}
</section> </section>
<style> <style>