forked from Cutlery/immich
		
	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…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user