diff --git a/web/src/lib/components/asset-viewer/asset-viewer-nav-bar.svelte b/web/src/lib/components/asset-viewer/asset-viewer-nav-bar.svelte index f7d4c30ec8..b0ac455bc8 100644 --- a/web/src/lib/components/asset-viewer/asset-viewer-nav-bar.svelte +++ b/web/src/lib/components/asset-viewer/asset-viewer-nav-bar.svelte @@ -7,6 +7,7 @@ import DeleteAction from '$lib/components/asset-viewer/actions/delete-action.svelte'; import DownloadAction from '$lib/components/asset-viewer/actions/download-action.svelte'; import FavoriteAction from '$lib/components/asset-viewer/actions/favorite-action.svelte'; + import KeepThisDeleteOthersAction from '$lib/components/asset-viewer/actions/keep-this-delete-others.svelte'; import RestoreAction from '$lib/components/asset-viewer/actions/restore-action.svelte'; import SetAlbumCoverAction from '$lib/components/asset-viewer/actions/set-album-cover-action.svelte'; import SetFeaturedPhotoAction from '$lib/components/asset-viewer/actions/set-person-featured-action.svelte'; @@ -14,7 +15,6 @@ import ShareAction from '$lib/components/asset-viewer/actions/share-action.svelte'; import ShowDetailAction from '$lib/components/asset-viewer/actions/show-detail-action.svelte'; import UnstackAction from '$lib/components/asset-viewer/actions/unstack-action.svelte'; - import KeepThisDeleteOthersAction from '$lib/components/asset-viewer/actions/keep-this-delete-others.svelte'; import CircleIconButton from '$lib/components/elements/buttons/circle-icon-button.svelte'; import ButtonContextMenu from '$lib/components/shared-components/context-menu/button-context-menu.svelte'; import MenuOption from '$lib/components/shared-components/context-menu/menu-option.svelte'; @@ -22,6 +22,7 @@ import { user } from '$lib/stores/user.store'; import { photoZoomState } from '$lib/stores/zoom-image.store'; import { getAssetJobName, getSharedLink } from '$lib/utils'; + import { canCopyImageToClipboard } from '$lib/utils/asset-utils'; import { openFileUploadDialog } from '$lib/utils/file-uploader'; import { AssetJobName, @@ -45,9 +46,8 @@ mdiPresentationPlay, mdiUpload, } from '@mdi/js'; - import { canCopyImageToClipboard } from '$lib/utils/asset-utils'; - import { t } from 'svelte-i18n'; import type { Snippet } from 'svelte'; + import { t } from 'svelte-i18n'; interface Props { asset: AssetResponseDto; @@ -104,7 +104,7 @@ </script> <div - class="z-[1001] flex h-16 place-items-center justify-between bg-gradient-to-b from-black/40 px-3 transition-transform duration-200" + class="flex h-16 place-items-center justify-between bg-gradient-to-b from-black/40 px-3 transition-transform duration-200" > <div class="text-white"> {#if showCloseButton} diff --git a/web/src/lib/components/asset-viewer/asset-viewer.svelte b/web/src/lib/components/asset-viewer/asset-viewer.svelte index 08772bcec4..5606da31a9 100644 --- a/web/src/lib/components/asset-viewer/asset-viewer.svelte +++ b/web/src/lib/components/asset-viewer/asset-viewer.svelte @@ -4,6 +4,7 @@ import MotionPhotoAction from '$lib/components/asset-viewer/actions/motion-photo-action.svelte'; import NextAssetAction from '$lib/components/asset-viewer/actions/next-asset-action.svelte'; import PreviousAssetAction from '$lib/components/asset-viewer/actions/previous-asset-action.svelte'; + import AssetViewerNavBar from '$lib/components/asset-viewer/asset-viewer-nav-bar.svelte'; import { AssetAction, ProjectionType } from '$lib/constants'; import { activityManager } from '$lib/managers/activity-manager.svelte'; import { authManager } from '$lib/managers/auth-manager.svelte'; @@ -34,7 +35,6 @@ import { NotificationType, notificationController } from '../shared-components/notification/notification'; import ActivityStatus from './activity-status.svelte'; import ActivityViewer from './activity-viewer.svelte'; - import AssetViewerNavBar from './asset-viewer-nav-bar.svelte'; import DetailPanel from './detail-panel.svelte'; import CropArea from './editor/crop-tool/crop-area.svelte'; import EditorPanel from './editor/editor-panel.svelte'; @@ -379,12 +379,13 @@ <section id="immich-asset-viewer" - class="fixed start-0 top-0 z-[1001] grid size-full grid-cols-4 grid-rows-[64px_1fr] overflow-hidden bg-black" + class="fixed start-0 top-0 grid size-full grid-cols-4 grid-rows-[64px_1fr] overflow-hidden bg-black" use:focusTrap + bind:this={assetViewerHtmlElement} > <!-- Top navigation bar --> {#if $slideshowState === SlideshowState.None && !isShowEditor} - <div class="z-[1002] col-span-4 col-start-1 row-span-1 row-start-1 transition-transform"> + <div class="col-span-4 col-start-1 row-span-1 row-start-1 transition-transform"> <AssetViewerNavBar {asset} {album} @@ -412,26 +413,26 @@ </div> {/if} + {#if $slideshowState != SlideshowState.None} + <div class="absolute w-full flex"> + <SlideshowBar + {isFullScreen} + onSetToFullScreen={() => assetViewerHtmlElement?.requestFullscreen?.()} + onPrevious={() => navigateAsset('previous')} + onNext={() => navigateAsset('next')} + onClose={() => ($slideshowState = SlideshowState.StopSlideshow)} + /> + </div> + {/if} + {#if $slideshowState === SlideshowState.None && showNavigation && !isShowEditor} - <div class="z-[1001] my-auto column-span-1 col-start-1 row-span-full row-start-1 justify-self-start"> + <div class="my-auto column-span-1 col-start-1 row-span-full row-start-1 justify-self-start"> <PreviousAssetAction onPreviousAsset={() => navigateAsset('previous')} /> </div> {/if} <!-- Asset Viewer --> - <div class="z-[1000] relative col-start-1 col-span-4 row-start-1 row-span-full" bind:this={assetViewerHtmlElement}> - {#if $slideshowState != SlideshowState.None} - <div class="z-[1000] absolute w-full flex"> - <SlideshowBar - {isFullScreen} - onSetToFullScreen={() => assetViewerHtmlElement?.requestFullscreen?.()} - onPrevious={() => navigateAsset('previous')} - onNext={() => navigateAsset('next')} - onClose={() => ($slideshowState = SlideshowState.StopSlideshow)} - /> - </div> - {/if} - + <div class="z-[-1] relative col-start-1 col-span-4 row-start-1 row-span-full"> {#if previewStackedAsset} {#key previewStackedAsset.id} {#if previewStackedAsset.type === AssetTypeEnum.Image} @@ -504,7 +505,7 @@ /> {/if} {#if $slideshowState === SlideshowState.None && isShared && ((album && album.isActivityEnabled) || activityManager.commentCount > 0)} - <div class="z-[9999] absolute bottom-0 end-0 mb-20 me-8"> + <div class="absolute bottom-0 end-0 mb-20 me-8"> <ActivityStatus disabled={!album?.isActivityEnabled} isLiked={activityManager.isLiked} @@ -519,7 +520,7 @@ </div> {#if $slideshowState === SlideshowState.None && showNavigation && !isShowEditor} - <div class="z-[1001] my-auto col-span-1 col-start-4 row-span-full row-start-1 justify-self-end"> + <div class="my-auto col-span-1 col-start-4 row-span-full row-start-1 justify-self-end"> <NextAssetAction onNextAsset={() => navigateAsset('next')} /> </div> {/if} @@ -528,7 +529,7 @@ <div transition:fly={{ duration: 150 }} id="detail-panel" - class="z-[1002] row-start-1 row-span-4 w-[360px] overflow-y-auto bg-immich-bg transition-all dark:border-l dark:border-s-immich-dark-gray dark:bg-immich-dark-bg" + class="row-start-1 row-span-4 w-[360px] overflow-y-auto bg-immich-bg transition-all dark:border-l dark:border-s-immich-dark-gray dark:bg-immich-dark-bg" translate="yes" > <DetailPanel {asset} currentAlbum={album} albums={appearsInAlbums} onClose={() => ($isShowDetail = false)} /> @@ -539,7 +540,7 @@ <div transition:fly={{ duration: 150 }} id="editor-panel" - class="z-[1002] row-start-1 row-span-4 w-[400px] overflow-y-auto bg-immich-bg transition-all dark:border-l dark:border-s-immich-dark-gray dark:bg-immich-dark-bg" + class="row-start-1 row-span-4 w-[400px] overflow-y-auto bg-immich-bg transition-all dark:border-l dark:border-s-immich-dark-gray dark:bg-immich-dark-bg" translate="yes" > <EditorPanel {asset} onUpdateSelectedType={handleUpdateSelectedEditType} onClose={closeEditor} /> @@ -550,7 +551,7 @@ {@const stackedAssets = stack.assets} <div id="stack-slideshow" - class="z-[1002] flex place-item-center place-content-center absolute bottom-0 w-full col-span-4 col-start-1 overflow-x-auto horizontal-scrollbar" + class="flex place-item-center place-content-center absolute bottom-0 w-full col-span-4 col-start-1 overflow-x-auto horizontal-scrollbar" > <div class="relative w-full"> {#each stackedAssets as stackedAsset (stackedAsset.id)} @@ -588,7 +589,7 @@ <div transition:fly={{ duration: 150 }} id="activity-panel" - class="z-[1002] row-start-1 row-span-5 w-[360px] md:w-[460px] overflow-y-auto bg-immich-bg transition-all dark:border-l dark:border-s-immich-dark-gray dark:bg-immich-dark-bg" + class="row-start-1 row-span-5 w-[360px] md:w-[460px] overflow-y-auto bg-immich-bg transition-all dark:border-l dark:border-s-immich-dark-gray dark:bg-immich-dark-bg" translate="yes" > <ActivityViewer diff --git a/web/src/lib/components/asset-viewer/detail-panel.svelte b/web/src/lib/components/asset-viewer/detail-panel.svelte index d672b1a8b0..aa5909f717 100644 --- a/web/src/lib/components/asset-viewer/detail-panel.svelte +++ b/web/src/lib/components/asset-viewer/detail-panel.svelte @@ -6,7 +6,6 @@ import DetailPanelTags from '$lib/components/asset-viewer/detail-panel-tags.svelte'; import Icon from '$lib/components/elements/icon.svelte'; import ChangeDate from '$lib/components/shared-components/change-date.svelte'; - import Portal from '$lib/components/shared-components/portal/portal.svelte'; import { AppRoute, QueryParameter, timeToLoadTheMap } from '$lib/constants'; import { authManager } from '$lib/managers/auth-manager.svelte'; import { isFaceEditMode } from '$lib/stores/face-edit.svelte'; @@ -355,14 +354,12 @@ {/if} {#if isShowChangeDate} - <Portal> - <ChangeDate - initialDate={dateTime} - initialTimeZone={timeZone ?? ''} - onConfirm={handleConfirmChangeDate} - onCancel={() => (isShowChangeDate = false)} - /> - </Portal> + <ChangeDate + initialDate={dateTime} + initialTimeZone={timeZone ?? ''} + onConfirm={handleConfirmChangeDate} + onCancel={() => (isShowChangeDate = false)} + /> {/if} <div class="flex gap-4 py-4"> diff --git a/web/src/lib/components/asset-viewer/photo-viewer.svelte b/web/src/lib/components/asset-viewer/photo-viewer.svelte index 531f075b86..4838ee1fc6 100644 --- a/web/src/lib/components/asset-viewer/photo-viewer.svelte +++ b/web/src/lib/components/asset-viewer/photo-viewer.svelte @@ -1,27 +1,27 @@ <script lang="ts"> import { shortcuts } from '$lib/actions/shortcut'; import { zoomImageAction, zoomed } from '$lib/actions/zoom-image'; + import FaceEditor from '$lib/components/asset-viewer/face-editor/face-editor.svelte'; import BrokenAsset from '$lib/components/assets/broken-asset.svelte'; + import { photoViewerImgElement } from '$lib/stores/assets-store.svelte'; + import { isFaceEditMode } from '$lib/stores/face-edit.svelte'; import { boundingBoxesArray } from '$lib/stores/people.store'; import { alwaysLoadOriginalFile } from '$lib/stores/preferences.store'; import { SlideshowLook, SlideshowState, slideshowLookCssMapping, slideshowStore } from '$lib/stores/slideshow.store'; import { photoZoomState } from '$lib/stores/zoom-image.store'; import { getAssetOriginalUrl, getAssetThumbnailUrl, handlePromiseError } from '$lib/utils'; import { canCopyImageToClipboard, copyImageToClipboard, isWebCompatibleImage } from '$lib/utils/asset-utils'; + import { handleError } from '$lib/utils/handle-error'; import { getBoundingBox } from '$lib/utils/people-utils'; + import { cancelImageUrl, preloadImageUrl } from '$lib/utils/sw-messaging'; import { getAltText } from '$lib/utils/thumbnail-util'; import { AssetMediaSize, AssetTypeEnum, type AssetResponseDto, type SharedLinkResponseDto } from '@immich/sdk'; import { onDestroy, onMount } from 'svelte'; + import { swipe, type SwipeCustomEvent } from 'svelte-gestures'; import { t } from 'svelte-i18n'; - import { type SwipeCustomEvent, swipe } from 'svelte-gestures'; import { fade } from 'svelte/transition'; import LoadingSpinner from '../shared-components/loading-spinner.svelte'; import { NotificationType, notificationController } from '../shared-components/notification/notification'; - import { handleError } from '$lib/utils/handle-error'; - import FaceEditor from '$lib/components/asset-viewer/face-editor/face-editor.svelte'; - import { photoViewerImgElement } from '$lib/stores/assets-store.svelte'; - import { isFaceEditMode } from '$lib/stores/face-edit.svelte'; - import { cancelImageUrl, preloadImageUrl } from '$lib/utils/sw-messaging'; interface Props { asset: AssetResponseDto; diff --git a/web/src/lib/components/asset-viewer/video-native-viewer.svelte b/web/src/lib/components/asset-viewer/video-native-viewer.svelte index 07760b3c6b..a8b0abe5eb 100644 --- a/web/src/lib/components/asset-viewer/video-native-viewer.svelte +++ b/web/src/lib/components/asset-viewer/video-native-viewer.svelte @@ -1,16 +1,16 @@ <script lang="ts"> + import FaceEditor from '$lib/components/asset-viewer/face-editor/face-editor.svelte'; import LoadingSpinner from '$lib/components/shared-components/loading-spinner.svelte'; + import { isFaceEditMode } from '$lib/stores/face-edit.svelte'; import { loopVideo as loopVideoPreference, videoViewerMuted, videoViewerVolume } from '$lib/stores/preferences.store'; import { getAssetPlaybackUrl, getAssetThumbnailUrl } from '$lib/utils'; import { handleError } from '$lib/utils/handle-error'; import { AssetMediaSize } from '@immich/sdk'; import { onDestroy, onMount } from 'svelte'; - import { swipe } from 'svelte-gestures'; import type { SwipeCustomEvent } from 'svelte-gestures'; - import { fade } from 'svelte/transition'; + import { swipe } from 'svelte-gestures'; import { t } from 'svelte-i18n'; - import { isFaceEditMode } from '$lib/stores/face-edit.svelte'; - import FaceEditor from '$lib/components/asset-viewer/face-editor/face-editor.svelte'; + import { fade } from 'svelte/transition'; interface Props { assetId: string; diff --git a/web/src/lib/components/asset-viewer/video-panorama-viewer.svelte b/web/src/lib/components/asset-viewer/video-panorama-viewer.svelte index a205ffce3c..2cf8e65871 100644 --- a/web/src/lib/components/asset-viewer/video-panorama-viewer.svelte +++ b/web/src/lib/components/asset-viewer/video-panorama-viewer.svelte @@ -1,8 +1,8 @@ <script lang="ts"> - import { getAssetPlaybackUrl, getAssetOriginalUrl } from '$lib/utils'; + import { getAssetOriginalUrl, getAssetPlaybackUrl } from '$lib/utils'; + import { t } from 'svelte-i18n'; import { fade } from 'svelte/transition'; import LoadingSpinner from '../shared-components/loading-spinner.svelte'; - import { t } from 'svelte-i18n'; interface Props { assetId: string; diff --git a/web/src/lib/components/shared-components/dialog/confirm-dialog.svelte b/web/src/lib/components/shared-components/dialog/confirm-dialog.svelte index 75c07aebc6..3d6582d65f 100644 --- a/web/src/lib/components/shared-components/dialog/confirm-dialog.svelte +++ b/web/src/lib/components/shared-components/dialog/confirm-dialog.svelte @@ -44,7 +44,7 @@ </ModalBody> <ModalFooter> - <div class="flex gap-3 w-full"> + <div class="flex gap-3 w-full my-3"> {#if !hideCancelButton} <Button shape="round" color={cancelColor} fullWidth onclick={() => onClose(false)}> {cancelText}