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:
parent
29a4389aac
commit
2bb7b3e60f
@ -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" />
|
||||||
|
|
||||||
|
@ -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>
|
||||||
|
Loading…
Reference in New Issue
Block a user