mirror of
https://github.com/immich-app/immich.git
synced 2025-05-24 01:12:58 -04:00
refactor: web stores => managers (1)
This commit is contained in:
parent
205260d31c
commit
d1e62c3736
@ -1,7 +1,6 @@
|
|||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import SelectAllAssets from '$lib/components/photos-page/actions/select-all-assets.svelte';
|
import SelectAllAssets from '$lib/components/photos-page/actions/select-all-assets.svelte';
|
||||||
import { assetViewingStore } from '$lib/stores/asset-viewing.store';
|
import { assetViewingStore } from '$lib/stores/asset-viewing.store';
|
||||||
import { dragAndDropFilesStore } from '$lib/stores/drag-and-drop-files.store';
|
|
||||||
import { fileUploadHandler, openFileUploadDialog } from '$lib/utils/file-uploader';
|
import { fileUploadHandler, openFileUploadDialog } from '$lib/utils/file-uploader';
|
||||||
import type { AlbumResponseDto, SharedLinkResponseDto, UserResponseDto } from '@immich/sdk';
|
import type { AlbumResponseDto, SharedLinkResponseDto, UserResponseDto } from '@immich/sdk';
|
||||||
import { AssetStore } from '$lib/stores/assets-store.svelte';
|
import { AssetStore } from '$lib/stores/assets-store.svelte';
|
||||||
@ -20,6 +19,7 @@
|
|||||||
import { t } from 'svelte-i18n';
|
import { t } from 'svelte-i18n';
|
||||||
import { onDestroy } from 'svelte';
|
import { onDestroy } from 'svelte';
|
||||||
import { AssetInteraction } from '$lib/stores/asset-interaction.svelte';
|
import { AssetInteraction } from '$lib/stores/asset-interaction.svelte';
|
||||||
|
import { dragAndDropManager } from '$lib/managers/drag-and-drop.manager.svelte';
|
||||||
|
|
||||||
interface Props {
|
interface Props {
|
||||||
sharedLink: SharedLinkResponseDto;
|
sharedLink: SharedLinkResponseDto;
|
||||||
@ -38,10 +38,10 @@
|
|||||||
|
|
||||||
const assetInteraction = new AssetInteraction();
|
const assetInteraction = new AssetInteraction();
|
||||||
|
|
||||||
dragAndDropFilesStore.subscribe((value) => {
|
$effect(() => {
|
||||||
if (value.isDragging && value.files.length > 0) {
|
if (dragAndDropManager.isDragging && dragAndDropManager.files.length > 0) {
|
||||||
handlePromiseError(fileUploadHandler(value.files, album.id));
|
handlePromiseError(fileUploadHandler(dragAndDropManager.files, album.id));
|
||||||
dragAndDropFilesStore.set({ isDragging: false, files: [] });
|
dragAndDropManager.reset();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
</script>
|
</script>
|
||||||
|
@ -5,7 +5,6 @@
|
|||||||
import NextAssetAction from '$lib/components/asset-viewer/actions/next-asset-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 PreviousAssetAction from '$lib/components/asset-viewer/actions/previous-asset-action.svelte';
|
||||||
import { AssetAction, ProjectionType } from '$lib/constants';
|
import { AssetAction, ProjectionType } from '$lib/constants';
|
||||||
import { updateNumberOfComments } from '$lib/stores/activity.store';
|
|
||||||
import { closeEditorCofirm } from '$lib/stores/asset-editor.store';
|
import { closeEditorCofirm } from '$lib/stores/asset-editor.store';
|
||||||
import { assetViewingStore } from '$lib/stores/asset-viewing.store';
|
import { assetViewingStore } from '$lib/stores/asset-viewing.store';
|
||||||
import { isShowDetail } from '$lib/stores/preferences.store';
|
import { isShowDetail } from '$lib/stores/preferences.store';
|
||||||
@ -47,6 +46,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-wrapper-viewer.svelte';
|
import VideoViewer from './video-wrapper-viewer.svelte';
|
||||||
|
import { activityManager } from '$lib/managers/activity.manager.svelte';
|
||||||
|
|
||||||
type HasAsset = boolean;
|
type HasAsset = boolean;
|
||||||
|
|
||||||
@ -137,12 +137,12 @@
|
|||||||
|
|
||||||
const handleAddComment = () => {
|
const handleAddComment = () => {
|
||||||
numberOfComments++;
|
numberOfComments++;
|
||||||
updateNumberOfComments(1);
|
activityManager.updateNumberOfComments(1);
|
||||||
};
|
};
|
||||||
|
|
||||||
const handleRemoveComment = () => {
|
const handleRemoveComment = () => {
|
||||||
numberOfComments--;
|
numberOfComments--;
|
||||||
updateNumberOfComments(-1);
|
activityManager.updateNumberOfComments(-1);
|
||||||
};
|
};
|
||||||
|
|
||||||
const handleFavorite = async () => {
|
const handleFavorite = async () => {
|
||||||
|
@ -46,7 +46,7 @@
|
|||||||
import AlbumListItemDetails from './album-list-item-details.svelte';
|
import AlbumListItemDetails from './album-list-item-details.svelte';
|
||||||
import Portal from '$lib/components/shared-components/portal/portal.svelte';
|
import Portal from '$lib/components/shared-components/portal/portal.svelte';
|
||||||
import { getMetadataSearchQuery } from '$lib/utils/metadata-search';
|
import { getMetadataSearchQuery } from '$lib/utils/metadata-search';
|
||||||
import { isFaceEditMode } from '$lib/stores/face-edit.svelte';
|
import { faceManager } from '$lib/managers/face.manager.svelte';
|
||||||
|
|
||||||
interface Props {
|
interface Props {
|
||||||
asset: AssetResponseDto;
|
asset: AssetResponseDto;
|
||||||
@ -207,7 +207,7 @@
|
|||||||
padding="1"
|
padding="1"
|
||||||
size="20"
|
size="20"
|
||||||
buttonSize="32"
|
buttonSize="32"
|
||||||
onclick={() => (isFaceEditMode.value = !isFaceEditMode.value)}
|
onclick={() => (faceManager.isEditMode = !faceManager.isEditMode)}
|
||||||
/>
|
/>
|
||||||
|
|
||||||
{#if people.length > 0 || unassignedFaces.length > 0}
|
{#if people.length > 0 || unassignedFaces.length > 0}
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import { type DownloadProgress, downloadManager, downloadStore } from '$lib/stores/download-store.svelte';
|
import { downloadManager, type DownloadProgress } from '$lib/managers/download.manager.svelte';
|
||||||
import { locale } from '$lib/stores/preferences.store';
|
import { locale } from '$lib/stores/preferences.store';
|
||||||
import { fly, slide } from 'svelte/transition';
|
import { fly, slide } from 'svelte/transition';
|
||||||
import { getByteUnitString } from '../../utils/byte-units';
|
import { getByteUnitString } from '../../utils/byte-units';
|
||||||
@ -13,15 +13,15 @@
|
|||||||
};
|
};
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
{#if downloadStore.isDownloading}
|
{#if downloadManager.isDownloading}
|
||||||
<div
|
<div
|
||||||
transition:fly={{ x: -100, duration: 350 }}
|
transition:fly={{ x: -100, duration: 350 }}
|
||||||
class="fixed bottom-10 left-2 z-[10000] max-h-[270px] w-[315px] rounded-2xl border bg-immich-bg p-4 text-sm shadow-sm"
|
class="fixed bottom-10 left-2 z-[10000] max-h-[270px] w-[315px] rounded-2xl border bg-immich-bg p-4 text-sm shadow-sm"
|
||||||
>
|
>
|
||||||
<p class="mb-2 text-xs text-gray-500">{$t('downloading').toUpperCase()}</p>
|
<p class="mb-2 text-xs text-gray-500">{$t('downloading').toUpperCase()}</p>
|
||||||
<div class="my-2 mb-2 flex max-h-[200px] flex-col overflow-y-auto text-sm">
|
<div class="my-2 mb-2 flex max-h-[200px] flex-col overflow-y-auto text-sm">
|
||||||
{#each Object.keys(downloadStore.assets) as downloadKey (downloadKey)}
|
{#each Object.keys(downloadManager.assets) as downloadKey (downloadKey)}
|
||||||
{@const download = downloadStore.assets[downloadKey]}
|
{@const download = downloadManager.assets[downloadKey]}
|
||||||
<div class="mb-2 flex place-items-center" transition:slide>
|
<div class="mb-2 flex place-items-center" transition:slide>
|
||||||
<div class="w-full pr-10">
|
<div class="w-full pr-10">
|
||||||
<div class="flex place-items-center justify-between gap-2 text-xs font-medium">
|
<div class="flex place-items-center justify-between gap-2 text-xs font-medium">
|
||||||
|
@ -2,7 +2,6 @@
|
|||||||
import ImageThumbnail from '$lib/components/assets/thumbnail/image-thumbnail.svelte';
|
import ImageThumbnail from '$lib/components/assets/thumbnail/image-thumbnail.svelte';
|
||||||
import { dialogController } from '$lib/components/shared-components/dialog/dialog';
|
import { dialogController } from '$lib/components/shared-components/dialog/dialog';
|
||||||
import { notificationController } from '$lib/components/shared-components/notification/notification';
|
import { notificationController } from '$lib/components/shared-components/notification/notification';
|
||||||
import { isFaceEditMode } from '$lib/stores/face-edit.svelte';
|
|
||||||
import { getPeopleThumbnailUrl } from '$lib/utils';
|
import { getPeopleThumbnailUrl } from '$lib/utils';
|
||||||
import { getAllPeople, createFace, type PersonResponseDto } from '@immich/sdk';
|
import { getAllPeople, createFace, type PersonResponseDto } from '@immich/sdk';
|
||||||
import { Button, Input } from '@immich/ui';
|
import { Button, Input } from '@immich/ui';
|
||||||
@ -10,6 +9,7 @@
|
|||||||
import { onMount } from 'svelte';
|
import { onMount } from 'svelte';
|
||||||
import { assetViewingStore } from '$lib/stores/asset-viewing.store';
|
import { assetViewingStore } from '$lib/stores/asset-viewing.store';
|
||||||
import { handleError } from '$lib/utils/handle-error';
|
import { handleError } from '$lib/utils/handle-error';
|
||||||
|
import { faceManager } from '$lib/managers/face.manager.svelte';
|
||||||
|
|
||||||
interface Props {
|
interface Props {
|
||||||
htmlElement: HTMLImageElement | HTMLVideoElement;
|
htmlElement: HTMLImageElement | HTMLVideoElement;
|
||||||
@ -140,7 +140,7 @@
|
|||||||
};
|
};
|
||||||
|
|
||||||
const cancel = () => {
|
const cancel = () => {
|
||||||
isFaceEditMode.value = false;
|
faceManager.isEditMode = false;
|
||||||
};
|
};
|
||||||
|
|
||||||
const getPeople = async () => {
|
const getPeople = async () => {
|
||||||
@ -303,7 +303,7 @@
|
|||||||
} catch (error) {
|
} catch (error) {
|
||||||
handleError(error, 'Error tagging face');
|
handleError(error, 'Error tagging face');
|
||||||
} finally {
|
} finally {
|
||||||
isFaceEditMode.value = false;
|
faceManager.isEditMode = false;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
</script>
|
</script>
|
||||||
|
@ -20,7 +20,7 @@
|
|||||||
import { handleError } from '$lib/utils/handle-error';
|
import { handleError } from '$lib/utils/handle-error';
|
||||||
import FaceEditor from '$lib/components/asset-viewer/face-editor/face-editor.svelte';
|
import FaceEditor from '$lib/components/asset-viewer/face-editor/face-editor.svelte';
|
||||||
import { photoViewerImgElement } from '$lib/stores/assets-store.svelte';
|
import { photoViewerImgElement } from '$lib/stores/assets-store.svelte';
|
||||||
import { isFaceEditMode } from '$lib/stores/face-edit.svelte';
|
import { faceManager } from '$lib/managers/face.manager.svelte';
|
||||||
|
|
||||||
interface Props {
|
interface Props {
|
||||||
asset: AssetResponseDto;
|
asset: AssetResponseDto;
|
||||||
@ -109,7 +109,7 @@
|
|||||||
};
|
};
|
||||||
|
|
||||||
$effect(() => {
|
$effect(() => {
|
||||||
if (isFaceEditMode.value && $photoZoomState.currentZoom > 1) {
|
if (faceManager.isEditMode && $photoZoomState.currentZoom > 1) {
|
||||||
zoomToggle();
|
zoomToggle();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
@ -235,7 +235,7 @@
|
|||||||
{/each}
|
{/each}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{#if isFaceEditMode.value}
|
{#if faceManager.isEditMode}
|
||||||
<FaceEditor htmlElement={$photoViewerImgElement} {containerWidth} {containerHeight} assetId={asset.id} />
|
<FaceEditor htmlElement={$photoViewerImgElement} {containerWidth} {containerHeight} assetId={asset.id} />
|
||||||
{/if}
|
{/if}
|
||||||
{/if}
|
{/if}
|
||||||
|
@ -9,8 +9,8 @@
|
|||||||
import type { SwipeCustomEvent } from 'svelte-gestures';
|
import type { SwipeCustomEvent } from 'svelte-gestures';
|
||||||
import { fade } from 'svelte/transition';
|
import { fade } from 'svelte/transition';
|
||||||
import { t } from 'svelte-i18n';
|
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 FaceEditor from '$lib/components/asset-viewer/face-editor/face-editor.svelte';
|
||||||
|
import { faceManager } from '$lib/managers/face.manager.svelte';
|
||||||
|
|
||||||
interface Props {
|
interface Props {
|
||||||
assetId: string;
|
assetId: string;
|
||||||
@ -94,7 +94,7 @@
|
|||||||
let containerHeight = $state(0);
|
let containerHeight = $state(0);
|
||||||
|
|
||||||
$effect(() => {
|
$effect(() => {
|
||||||
if (isFaceEditMode.value) {
|
if (faceManager.isEditMode) {
|
||||||
videoPlayer?.pause();
|
videoPlayer?.pause();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
@ -141,7 +141,7 @@
|
|||||||
</div>
|
</div>
|
||||||
{/if}
|
{/if}
|
||||||
|
|
||||||
{#if isFaceEditMode.value}
|
{#if faceManager.isEditMode}
|
||||||
<FaceEditor htmlElement={videoPlayer} {containerWidth} {containerHeight} {assetId} />
|
<FaceEditor htmlElement={videoPlayer} {containerWidth} {containerHeight} {assetId} />
|
||||||
{/if}
|
{/if}
|
||||||
</div>
|
</div>
|
||||||
|
@ -2,7 +2,6 @@
|
|||||||
import { goto } from '$app/navigation';
|
import { goto } from '$app/navigation';
|
||||||
import type { Action } from '$lib/components/asset-viewer/actions/action';
|
import type { Action } from '$lib/components/asset-viewer/actions/action';
|
||||||
import { AppRoute, AssetAction } from '$lib/constants';
|
import { AppRoute, AssetAction } from '$lib/constants';
|
||||||
import { dragAndDropFilesStore } from '$lib/stores/drag-and-drop-files.store';
|
|
||||||
import { getKey, handlePromiseError } from '$lib/utils';
|
import { getKey, handlePromiseError } from '$lib/utils';
|
||||||
import { downloadArchive } from '$lib/utils/asset-utils';
|
import { downloadArchive } from '$lib/utils/asset-utils';
|
||||||
import { fileUploadHandler, openFileUploadDialog } from '$lib/utils/file-uploader';
|
import { fileUploadHandler, openFileUploadDialog } from '$lib/utils/file-uploader';
|
||||||
@ -22,6 +21,7 @@
|
|||||||
import type { Viewport } from '$lib/stores/assets-store.svelte';
|
import type { Viewport } from '$lib/stores/assets-store.svelte';
|
||||||
import { t } from 'svelte-i18n';
|
import { t } from 'svelte-i18n';
|
||||||
import { AssetInteraction } from '$lib/stores/asset-interaction.svelte';
|
import { AssetInteraction } from '$lib/stores/asset-interaction.svelte';
|
||||||
|
import { dragAndDropManager } from '$lib/managers/drag-and-drop.manager.svelte';
|
||||||
|
|
||||||
interface Props {
|
interface Props {
|
||||||
sharedLink: SharedLinkResponseDto;
|
sharedLink: SharedLinkResponseDto;
|
||||||
@ -35,10 +35,10 @@
|
|||||||
|
|
||||||
let assets = $derived(sharedLink.assets);
|
let assets = $derived(sharedLink.assets);
|
||||||
|
|
||||||
dragAndDropFilesStore.subscribe((value) => {
|
$effect(() => {
|
||||||
if (value.isDragging && value.files.length > 0) {
|
if (dragAndDropManager.isDragging && dragAndDropManager.files.length > 0) {
|
||||||
handlePromiseError(handleUploadAssets(value.files));
|
handlePromiseError(handleUploadAssets(dragAndDropManager.files));
|
||||||
dragAndDropFilesStore.set({ isDragging: false, files: [] });
|
dragAndDropManager.reset();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -6,7 +6,7 @@
|
|||||||
type Padding,
|
type Padding,
|
||||||
} from '$lib/components/elements/buttons/circle-icon-button.svelte';
|
} from '$lib/components/elements/buttons/circle-icon-button.svelte';
|
||||||
import ContextMenu from '$lib/components/shared-components/context-menu/context-menu.svelte';
|
import ContextMenu from '$lib/components/shared-components/context-menu/context-menu.svelte';
|
||||||
import { optionClickCallbackStore, selectedIdStore } from '$lib/stores/context-menu.store';
|
import { contextMenuManager } from '$lib/managers/context-menu.manager.svelte';
|
||||||
import {
|
import {
|
||||||
getContextMenuPositionFromBoundingRect,
|
getContextMenuPositionFromBoundingRect,
|
||||||
getContextMenuPositionFromEvent,
|
getContextMenuPositionFromEvent,
|
||||||
@ -97,7 +97,7 @@
|
|||||||
}
|
}
|
||||||
focusButton();
|
focusButton();
|
||||||
isOpen = false;
|
isOpen = false;
|
||||||
$selectedIdStore = undefined;
|
contextMenuManager.selectedId = undefined;
|
||||||
};
|
};
|
||||||
|
|
||||||
const handleOptionClick = () => {
|
const handleOptionClick = () => {
|
||||||
@ -124,7 +124,7 @@
|
|||||||
|
|
||||||
$effect(() => {
|
$effect(() => {
|
||||||
if (isOpen) {
|
if (isOpen) {
|
||||||
$optionClickCallbackStore = handleOptionClick;
|
contextMenuManager.optionClickCallback = handleOptionClick;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
</script>
|
</script>
|
||||||
@ -139,8 +139,8 @@
|
|||||||
isOpen,
|
isOpen,
|
||||||
onEscape,
|
onEscape,
|
||||||
openDropdown,
|
openDropdown,
|
||||||
selectedId: $selectedIdStore,
|
selectedId: contextMenuManager.selectedId,
|
||||||
selectionChanged: (id) => ($selectedIdStore = id),
|
selectionChanged: (id) => (contextMenuManager.selectedId = id),
|
||||||
}}
|
}}
|
||||||
onresize={onResize}
|
onresize={onResize}
|
||||||
{...restProps}
|
{...restProps}
|
||||||
@ -178,7 +178,7 @@
|
|||||||
<ContextMenu
|
<ContextMenu
|
||||||
{...contextMenuPosition}
|
{...contextMenuPosition}
|
||||||
{direction}
|
{direction}
|
||||||
ariaActiveDescendant={$selectedIdStore}
|
ariaActiveDescendant={contextMenuManager.selectedId}
|
||||||
ariaLabelledBy={buttonId}
|
ariaLabelledBy={buttonId}
|
||||||
bind:menuElement={menuContainer}
|
bind:menuElement={menuContainer}
|
||||||
id={menuId}
|
id={menuId}
|
||||||
|
@ -1,9 +1,9 @@
|
|||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import Icon from '$lib/components/elements/icon.svelte';
|
import Icon from '$lib/components/elements/icon.svelte';
|
||||||
import { generateId } from '$lib/utils/generate-id';
|
import { generateId } from '$lib/utils/generate-id';
|
||||||
import { optionClickCallbackStore, selectedIdStore } from '$lib/stores/context-menu.store';
|
|
||||||
import type { Shortcut } from '$lib/actions/shortcut';
|
import type { Shortcut } from '$lib/actions/shortcut';
|
||||||
import { shortcutLabel as computeShortcutLabel, shortcut as bindShortcut } from '$lib/actions/shortcut';
|
import { shortcutLabel as computeShortcutLabel, shortcut as bindShortcut } from '$lib/actions/shortcut';
|
||||||
|
import { contextMenuManager } from '$lib/managers/context-menu.manager.svelte';
|
||||||
|
|
||||||
interface Props {
|
interface Props {
|
||||||
text: string;
|
text: string;
|
||||||
@ -29,10 +29,10 @@
|
|||||||
|
|
||||||
let id: string = generateId();
|
let id: string = generateId();
|
||||||
|
|
||||||
let isActive = $derived($selectedIdStore === id);
|
let isActive = $derived(contextMenuManager.selectedId === id);
|
||||||
|
|
||||||
const handleClick = () => {
|
const handleClick = () => {
|
||||||
$optionClickCallbackStore?.();
|
contextMenuManager.optionClickCallback?.();
|
||||||
onClick();
|
onClick();
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -51,8 +51,8 @@
|
|||||||
<li
|
<li
|
||||||
{id}
|
{id}
|
||||||
onclick={handleClick}
|
onclick={handleClick}
|
||||||
onmouseover={() => ($selectedIdStore = id)}
|
onmouseover={() => (contextMenuManager.selectedId = id)}
|
||||||
onmouseleave={() => ($selectedIdStore = undefined)}
|
onmouseleave={() => (contextMenuManager.selectedId = undefined)}
|
||||||
class="w-full p-4 text-left text-sm font-medium {textColor} focus:outline-none focus:ring-2 focus:ring-inset cursor-pointer border-gray-200 flex gap-2 items-center {isActive
|
class="w-full p-4 text-left text-sm font-medium {textColor} focus:outline-none focus:ring-2 focus:ring-inset cursor-pointer border-gray-200 flex gap-2 items-center {isActive
|
||||||
? activeColor
|
? activeColor
|
||||||
: 'bg-slate-100'}"
|
: 'bg-slate-100'}"
|
||||||
|
@ -4,7 +4,7 @@
|
|||||||
import { shortcuts } from '$lib/actions/shortcut';
|
import { shortcuts } from '$lib/actions/shortcut';
|
||||||
import { generateId } from '$lib/utils/generate-id';
|
import { generateId } from '$lib/utils/generate-id';
|
||||||
import { contextMenuNavigation } from '$lib/actions/context-menu-navigation';
|
import { contextMenuNavigation } from '$lib/actions/context-menu-navigation';
|
||||||
import { optionClickCallbackStore, selectedIdStore } from '$lib/stores/context-menu.store';
|
import { contextMenuManager } from '$lib/managers/context-menu.manager.svelte';
|
||||||
|
|
||||||
interface Props {
|
interface Props {
|
||||||
title: string;
|
title: string;
|
||||||
@ -60,7 +60,7 @@
|
|||||||
if (isOpen && menuContainer) {
|
if (isOpen && menuContainer) {
|
||||||
triggerElement = document.activeElement as HTMLElement;
|
triggerElement = document.activeElement as HTMLElement;
|
||||||
menuContainer.focus();
|
menuContainer.focus();
|
||||||
$optionClickCallbackStore = closeContextMenu;
|
contextMenuManager.optionClickCallback = closeContextMenu;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -77,8 +77,8 @@
|
|||||||
closeDropdown: closeContextMenu,
|
closeDropdown: closeContextMenu,
|
||||||
container: menuContainer,
|
container: menuContainer,
|
||||||
isOpen,
|
isOpen,
|
||||||
selectedId: $selectedIdStore,
|
selectedId: contextMenuManager.selectedId,
|
||||||
selectionChanged: (id) => ($selectedIdStore = id),
|
selectionChanged: (id) => (contextMenuManager.selectedId = id),
|
||||||
}}
|
}}
|
||||||
use:shortcuts={[
|
use:shortcuts={[
|
||||||
{
|
{
|
||||||
@ -96,7 +96,7 @@
|
|||||||
{direction}
|
{direction}
|
||||||
{x}
|
{x}
|
||||||
{y}
|
{y}
|
||||||
ariaActiveDescendant={$selectedIdStore}
|
ariaActiveDescendant={contextMenuManager.selectedId}
|
||||||
ariaLabel={title}
|
ariaLabel={title}
|
||||||
bind:menuElement={menuContainer}
|
bind:menuElement={menuContainer}
|
||||||
id={menuId}
|
id={menuId}
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import { page } from '$app/state';
|
import { page } from '$app/state';
|
||||||
import { shouldIgnoreEvent } from '$lib/actions/shortcut';
|
import { shouldIgnoreEvent } from '$lib/actions/shortcut';
|
||||||
import { dragAndDropFilesStore } from '$lib/stores/drag-and-drop-files.store';
|
import { dragAndDropManager } from '$lib/managers/drag-and-drop.manager.svelte';
|
||||||
import { fileUploadHandler } from '$lib/utils/file-uploader';
|
import { fileUploadHandler } from '$lib/utils/file-uploader';
|
||||||
import { isAlbumsRoute, isSharedLinkRoute } from '$lib/utils/navigation';
|
import { isAlbumsRoute, isSharedLinkRoute } from '$lib/utils/navigation';
|
||||||
import { t } from 'svelte-i18n';
|
import { t } from 'svelte-i18n';
|
||||||
@ -124,7 +124,8 @@
|
|||||||
|
|
||||||
const filesArray: File[] = Array.from<File>(files);
|
const filesArray: File[] = Array.from<File>(files);
|
||||||
if (isShare) {
|
if (isShare) {
|
||||||
dragAndDropFilesStore.set({ isDragging: true, files: filesArray });
|
dragAndDropManager.isDragging = true;
|
||||||
|
dragAndDropManager.files = filesArray;
|
||||||
} else {
|
} else {
|
||||||
await fileUploadHandler(filesArray, albumId);
|
await fileUploadHandler(filesArray, albumId);
|
||||||
}
|
}
|
||||||
|
@ -10,7 +10,7 @@
|
|||||||
import ImmichLogo from '$lib/components/shared-components/immich-logo.svelte';
|
import ImmichLogo from '$lib/components/shared-components/immich-logo.svelte';
|
||||||
import SearchBar from '$lib/components/shared-components/search-bar/search-bar.svelte';
|
import SearchBar from '$lib/components/shared-components/search-bar/search-bar.svelte';
|
||||||
import { AppRoute } from '$lib/constants';
|
import { AppRoute } from '$lib/constants';
|
||||||
import { authManager } from '$lib/stores/auth-manager.svelte';
|
import { authManager } from '$lib/managers/auth-manager.svelte';
|
||||||
import { mobileDevice } from '$lib/stores/mobile-device.svelte';
|
import { mobileDevice } from '$lib/stores/mobile-device.svelte';
|
||||||
import { featureFlags } from '$lib/stores/server-config.store';
|
import { featureFlags } from '$lib/stores/server-config.store';
|
||||||
import { sidebarStore } from '$lib/stores/sidebar.svelte';
|
import { sidebarStore } from '$lib/stores/sidebar.svelte';
|
||||||
|
17
web/src/lib/managers/activity.manager.svelte.ts
Normal file
17
web/src/lib/managers/activity.manager.svelte.ts
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
class ActivityManager {
|
||||||
|
#numberOfComments = $state<number>(0);
|
||||||
|
|
||||||
|
get numberOfComments() {
|
||||||
|
return this.#numberOfComments;
|
||||||
|
}
|
||||||
|
|
||||||
|
set numberOfComments(number: number) {
|
||||||
|
this.#numberOfComments = number;
|
||||||
|
}
|
||||||
|
|
||||||
|
updateNumberOfComments(addOrRemove: 1 | -1) {
|
||||||
|
this.#numberOfComments += addOrRemove;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export const activityManager = new ActivityManager();
|
@ -1,6 +1,6 @@
|
|||||||
import { goto } from '$app/navigation';
|
import { goto } from '$app/navigation';
|
||||||
import { AppRoute } from '$lib/constants';
|
import { AppRoute } from '$lib/constants';
|
||||||
import { eventManager } from '$lib/stores/event-manager.svelte';
|
import { eventManager } from '$lib/managers/event.manager.svelte';
|
||||||
import { logout } from '@immich/sdk';
|
import { logout } from '@immich/sdk';
|
||||||
|
|
||||||
class AuthManager {
|
class AuthManager {
|
22
web/src/lib/managers/context-menu.manager.svelte.ts
Normal file
22
web/src/lib/managers/context-menu.manager.svelte.ts
Normal file
@ -0,0 +1,22 @@
|
|||||||
|
class ContextMenuManager {
|
||||||
|
#selectedId = $state<string | undefined>(undefined);
|
||||||
|
#optionClickCallback = $state<(() => void) | undefined>(undefined);
|
||||||
|
|
||||||
|
get selectedId() {
|
||||||
|
return this.#selectedId;
|
||||||
|
}
|
||||||
|
|
||||||
|
set selectedId(id: string | undefined) {
|
||||||
|
this.#selectedId = id;
|
||||||
|
}
|
||||||
|
|
||||||
|
get optionClickCallback() {
|
||||||
|
return this.#optionClickCallback;
|
||||||
|
}
|
||||||
|
|
||||||
|
set optionClickCallback(callback: (() => void) | undefined) {
|
||||||
|
this.#optionClickCallback = callback;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export const contextMenuManager = new ContextMenuManager();
|
47
web/src/lib/managers/download.manager.svelte.ts
Normal file
47
web/src/lib/managers/download.manager.svelte.ts
Normal file
@ -0,0 +1,47 @@
|
|||||||
|
export interface DownloadProgress {
|
||||||
|
progress: number;
|
||||||
|
total: number;
|
||||||
|
percentage: number;
|
||||||
|
abort: AbortController | null;
|
||||||
|
}
|
||||||
|
|
||||||
|
class DownloadManager {
|
||||||
|
#assets = $state<Record<string, DownloadProgress>>({});
|
||||||
|
#isDownloading = $derived(Object.keys(this.#assets).length > 0);
|
||||||
|
|
||||||
|
#update(key: string, value: Partial<DownloadProgress>) {
|
||||||
|
if (!this.#assets[key]) {
|
||||||
|
this.#assets[key] = { progress: 0, total: 0, percentage: 0, abort: null };
|
||||||
|
}
|
||||||
|
|
||||||
|
const item = this.#assets[key];
|
||||||
|
Object.assign(item, value);
|
||||||
|
item.percentage = Math.min(Math.floor((item.progress / item.total) * 100), 100);
|
||||||
|
}
|
||||||
|
|
||||||
|
get assets() {
|
||||||
|
return this.#assets;
|
||||||
|
}
|
||||||
|
|
||||||
|
get isDownloading() {
|
||||||
|
return this.#isDownloading;
|
||||||
|
}
|
||||||
|
|
||||||
|
add(key: string, total: number, abort?: AbortController) {
|
||||||
|
this.#update(key, { total, abort });
|
||||||
|
}
|
||||||
|
|
||||||
|
clear(key: string) {
|
||||||
|
delete this.#assets[key];
|
||||||
|
}
|
||||||
|
|
||||||
|
update(key: string, progress: number, total?: number) {
|
||||||
|
const download: Partial<DownloadProgress> = { progress };
|
||||||
|
if (total !== undefined) {
|
||||||
|
download.total = total;
|
||||||
|
}
|
||||||
|
this.#update(key, download);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export const downloadManager = new DownloadManager();
|
27
web/src/lib/managers/drag-and-drop.manager.svelte.ts
Normal file
27
web/src/lib/managers/drag-and-drop.manager.svelte.ts
Normal file
@ -0,0 +1,27 @@
|
|||||||
|
class DragAndDropManager {
|
||||||
|
#isDragging = $state<boolean>(false);
|
||||||
|
#files = $state<File[]>([]);
|
||||||
|
|
||||||
|
get isDragging() {
|
||||||
|
return this.#isDragging;
|
||||||
|
}
|
||||||
|
|
||||||
|
get files() {
|
||||||
|
return this.#files;
|
||||||
|
}
|
||||||
|
|
||||||
|
set isDragging(isDragging: boolean) {
|
||||||
|
this.#isDragging = isDragging;
|
||||||
|
}
|
||||||
|
|
||||||
|
set files(files: File[]) {
|
||||||
|
this.#files = files;
|
||||||
|
}
|
||||||
|
|
||||||
|
reset() {
|
||||||
|
this.#isDragging = false;
|
||||||
|
this.#files = [];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export const dragAndDropManager = new DragAndDropManager();
|
13
web/src/lib/managers/face.manager.svelte.ts
Normal file
13
web/src/lib/managers/face.manager.svelte.ts
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
class FaceManager {
|
||||||
|
#isEditMode = $state(false);
|
||||||
|
|
||||||
|
get isEditMode() {
|
||||||
|
return this.#isEditMode;
|
||||||
|
}
|
||||||
|
|
||||||
|
set isEditMode(isEditMode: boolean) {
|
||||||
|
this.#isEditMode = isEditMode;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export const faceManager = new FaceManager();
|
@ -1,11 +0,0 @@
|
|||||||
import { writable } from 'svelte/store';
|
|
||||||
|
|
||||||
export const numberOfComments = writable<number>(0);
|
|
||||||
|
|
||||||
export const setNumberOfComments = (number: number) => {
|
|
||||||
numberOfComments.set(number);
|
|
||||||
};
|
|
||||||
|
|
||||||
export const updateNumberOfComments = (addOrRemove: 1 | -1) => {
|
|
||||||
numberOfComments.update((n) => n + addOrRemove);
|
|
||||||
};
|
|
@ -1,6 +0,0 @@
|
|||||||
import { writable } from 'svelte/store';
|
|
||||||
|
|
||||||
const selectedIdStore = writable<string | undefined>(undefined);
|
|
||||||
const optionClickCallbackStore = writable<(() => void) | undefined>(undefined);
|
|
||||||
|
|
||||||
export { optionClickCallbackStore, selectedIdStore };
|
|
@ -1,51 +0,0 @@
|
|||||||
export interface DownloadProgress {
|
|
||||||
progress: number;
|
|
||||||
total: number;
|
|
||||||
percentage: number;
|
|
||||||
abort: AbortController | null;
|
|
||||||
}
|
|
||||||
|
|
||||||
class DownloadStore {
|
|
||||||
assets = $state<Record<string, DownloadProgress>>({});
|
|
||||||
|
|
||||||
isDownloading = $derived(Object.keys(this.assets).length > 0);
|
|
||||||
|
|
||||||
#update(key: string, value: Partial<DownloadProgress> | null) {
|
|
||||||
if (value === null) {
|
|
||||||
delete this.assets[key];
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!this.assets[key]) {
|
|
||||||
this.assets[key] = { progress: 0, total: 0, percentage: 0, abort: null };
|
|
||||||
}
|
|
||||||
|
|
||||||
const item = this.assets[key];
|
|
||||||
Object.assign(item, value);
|
|
||||||
item.percentage = Math.min(Math.floor((item.progress / item.total) * 100), 100);
|
|
||||||
}
|
|
||||||
|
|
||||||
add(key: string, total: number, abort?: AbortController) {
|
|
||||||
this.#update(key, { total, abort });
|
|
||||||
}
|
|
||||||
|
|
||||||
clear(key: string) {
|
|
||||||
this.#update(key, null);
|
|
||||||
}
|
|
||||||
|
|
||||||
update(key: string, progress: number, total?: number) {
|
|
||||||
const download: Partial<DownloadProgress> = { progress };
|
|
||||||
if (total !== undefined) {
|
|
||||||
download.total = total;
|
|
||||||
}
|
|
||||||
this.#update(key, download);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
export const downloadStore = new DownloadStore();
|
|
||||||
|
|
||||||
export const downloadManager = {
|
|
||||||
add: (key: string, total: number, abort?: AbortController) => downloadStore.add(key, total, abort),
|
|
||||||
clear: (key: string) => downloadStore.clear(key),
|
|
||||||
update: (key: string, progress: number, total?: number) => downloadStore.update(key, progress, total),
|
|
||||||
};
|
|
@ -1,7 +0,0 @@
|
|||||||
//store to track the state of the drag and drop and the files
|
|
||||||
import { writable } from 'svelte/store';
|
|
||||||
|
|
||||||
export const dragAndDropFilesStore = writable({
|
|
||||||
isDragging: false as boolean,
|
|
||||||
files: [] as File[],
|
|
||||||
});
|
|
@ -1 +0,0 @@
|
|||||||
export const isFaceEditMode = $state({ value: false });
|
|
@ -1,4 +1,4 @@
|
|||||||
import { eventManager } from '$lib/stores/event-manager.svelte';
|
import { eventManager } from '$lib/managers/event.manager.svelte';
|
||||||
import {
|
import {
|
||||||
getAssetsByOriginalPath,
|
getAssetsByOriginalPath,
|
||||||
getUniqueOriginalPaths,
|
getUniqueOriginalPaths,
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
import { eventManager } from '$lib/stores/event-manager.svelte';
|
import { eventManager } from '$lib/managers/event.manager.svelte';
|
||||||
import { asLocalTimeISO } from '$lib/utils/date-time';
|
import { asLocalTimeISO } from '$lib/utils/date-time';
|
||||||
import {
|
import {
|
||||||
type AssetResponseDto,
|
type AssetResponseDto,
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
import { eventManager } from '$lib/stores/event-manager.svelte';
|
import { eventManager } from '$lib/managers/event.manager.svelte';
|
||||||
|
|
||||||
class SearchStore {
|
class SearchStore {
|
||||||
savedSearchTerms = $state<string[]>([]);
|
savedSearchTerms = $state<string[]>([]);
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
import { eventManager } from '$lib/stores/event-manager.svelte';
|
import { eventManager } from '$lib/managers/event.manager.svelte';
|
||||||
import { purchaseStore } from '$lib/stores/purchase.store';
|
import { purchaseStore } from '$lib/stores/purchase.store';
|
||||||
import { type UserAdminResponseDto, type UserPreferencesResponseDto } from '@immich/sdk';
|
import { type UserAdminResponseDto, type UserPreferencesResponseDto } from '@immich/sdk';
|
||||||
import { writable } from 'svelte/store';
|
import { writable } from 'svelte/store';
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
import { eventManager } from '$lib/stores/event-manager.svelte';
|
import { eventManager } from '$lib/managers/event.manager.svelte';
|
||||||
import type {
|
import type {
|
||||||
AlbumResponseDto,
|
AlbumResponseDto,
|
||||||
ServerAboutResponseDto,
|
ServerAboutResponseDto,
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
import { authManager } from '$lib/stores/auth-manager.svelte';
|
import { authManager } from '$lib/managers/auth-manager.svelte';
|
||||||
import { createEventEmitter } from '$lib/utils/eventemitter';
|
import { createEventEmitter } from '$lib/utils/eventemitter';
|
||||||
import type { AssetResponseDto, ServerVersionResponseDto } from '@immich/sdk';
|
import type { AssetResponseDto, ServerVersionResponseDto } from '@immich/sdk';
|
||||||
import { io, type Socket } from 'socket.io-client';
|
import { io, type Socket } from 'socket.io-client';
|
||||||
|
@ -3,9 +3,9 @@ import FormatBoldMessage from '$lib/components/i18n/format-bold-message.svelte';
|
|||||||
import type { InterpolationValues } from '$lib/components/i18n/format-message';
|
import type { InterpolationValues } from '$lib/components/i18n/format-message';
|
||||||
import { NotificationType, notificationController } from '$lib/components/shared-components/notification/notification';
|
import { NotificationType, notificationController } from '$lib/components/shared-components/notification/notification';
|
||||||
import { AppRoute } from '$lib/constants';
|
import { AppRoute } from '$lib/constants';
|
||||||
|
import { downloadManager } from '$lib/managers/download.manager.svelte';
|
||||||
import type { AssetInteraction } from '$lib/stores/asset-interaction.svelte';
|
import type { AssetInteraction } from '$lib/stores/asset-interaction.svelte';
|
||||||
import { assetsSnapshot, isSelectingAllAssets, type AssetStore } from '$lib/stores/assets-store.svelte';
|
import { assetsSnapshot, isSelectingAllAssets, type AssetStore } from '$lib/stores/assets-store.svelte';
|
||||||
import { downloadManager } from '$lib/stores/download-store.svelte';
|
|
||||||
import { preferences } from '$lib/stores/user.store';
|
import { preferences } from '$lib/stores/user.store';
|
||||||
import { downloadRequest, getKey, withError } from '$lib/utils';
|
import { downloadRequest, getKey, withError } from '$lib/utils';
|
||||||
import { createAlbum } from '$lib/utils/album-utils';
|
import { createAlbum } from '$lib/utils/album-utils';
|
||||||
|
@ -34,7 +34,6 @@
|
|||||||
} from '$lib/components/shared-components/notification/notification';
|
} from '$lib/components/shared-components/notification/notification';
|
||||||
import UserAvatar from '$lib/components/shared-components/user-avatar.svelte';
|
import UserAvatar from '$lib/components/shared-components/user-avatar.svelte';
|
||||||
import { AppRoute, AlbumPageViewMode } from '$lib/constants';
|
import { AppRoute, AlbumPageViewMode } from '$lib/constants';
|
||||||
import { numberOfComments, setNumberOfComments, updateNumberOfComments } from '$lib/stores/activity.store';
|
|
||||||
import { assetViewingStore } from '$lib/stores/asset-viewing.store';
|
import { assetViewingStore } from '$lib/stores/asset-viewing.store';
|
||||||
import { AssetStore } from '$lib/stores/assets-store.svelte';
|
import { AssetStore } from '$lib/stores/assets-store.svelte';
|
||||||
import { SlideshowNavigation, SlideshowState, slideshowStore } from '$lib/stores/slideshow.store';
|
import { SlideshowNavigation, SlideshowState, slideshowStore } from '$lib/stores/slideshow.store';
|
||||||
@ -87,6 +86,7 @@
|
|||||||
import { confirmAlbumDelete } from '$lib/utils/album-utils';
|
import { confirmAlbumDelete } from '$lib/utils/album-utils';
|
||||||
import TagAction from '$lib/components/photos-page/actions/tag-action.svelte';
|
import TagAction from '$lib/components/photos-page/actions/tag-action.svelte';
|
||||||
import { AssetInteraction } from '$lib/stores/asset-interaction.svelte';
|
import { AssetInteraction } from '$lib/stores/asset-interaction.svelte';
|
||||||
|
import { activityManager } from '$lib/managers/activity.manager.svelte';
|
||||||
|
|
||||||
interface Props {
|
interface Props {
|
||||||
data: PageData;
|
data: PageData;
|
||||||
@ -191,7 +191,7 @@
|
|||||||
const getNumberOfComments = async () => {
|
const getNumberOfComments = async () => {
|
||||||
try {
|
try {
|
||||||
const { comments } = await getActivityStatistics({ albumId: album.id });
|
const { comments } = await getActivityStatistics({ albumId: album.id });
|
||||||
setNumberOfComments(comments);
|
activityManager.numberOfComments = comments;
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
handleError(error, $t('errors.cant_get_number_of_comments'));
|
handleError(error, $t('errors.cant_get_number_of_comments'));
|
||||||
}
|
}
|
||||||
@ -398,7 +398,7 @@
|
|||||||
let albumId = $derived(album.id);
|
let albumId = $derived(album.id);
|
||||||
|
|
||||||
$effect(() => {
|
$effect(() => {
|
||||||
if (!album.isActivityEnabled && $numberOfComments === 0) {
|
if (!album.isActivityEnabled && activityManager.numberOfComments === 0) {
|
||||||
isShowActivity = false;
|
isShowActivity = false;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
@ -420,7 +420,9 @@
|
|||||||
let isOwned = $derived($user.id == album.ownerId);
|
let isOwned = $derived($user.id == album.ownerId);
|
||||||
|
|
||||||
let showActivityStatus = $derived(
|
let showActivityStatus = $derived(
|
||||||
album.albumUsers.length > 0 && !$showAssetViewer && (album.isActivityEnabled || $numberOfComments > 0),
|
album.albumUsers.length > 0 &&
|
||||||
|
!$showAssetViewer &&
|
||||||
|
(album.isActivityEnabled || activityManager.numberOfComments > 0),
|
||||||
);
|
);
|
||||||
let isEditor = $derived(
|
let isEditor = $derived(
|
||||||
album.albumUsers.find(({ user: { id } }) => id === $user.id)?.role === AlbumUserRole.Editor ||
|
album.albumUsers.find(({ user: { id } }) => id === $user.id)?.role === AlbumUserRole.Editor ||
|
||||||
@ -712,7 +714,7 @@
|
|||||||
<ActivityStatus
|
<ActivityStatus
|
||||||
disabled={!album.isActivityEnabled}
|
disabled={!album.isActivityEnabled}
|
||||||
{isLiked}
|
{isLiked}
|
||||||
numberOfComments={$numberOfComments}
|
numberOfComments={activityManager.numberOfComments}
|
||||||
onFavorite={handleFavorite}
|
onFavorite={handleFavorite}
|
||||||
onOpenActivityTab={handleOpenAndCloseActivityTab}
|
onOpenActivityTab={handleOpenAndCloseActivityTab}
|
||||||
/>
|
/>
|
||||||
@ -735,8 +737,8 @@
|
|||||||
albumId={album.id}
|
albumId={album.id}
|
||||||
{isLiked}
|
{isLiked}
|
||||||
bind:reactions
|
bind:reactions
|
||||||
onAddComment={() => updateNumberOfComments(1)}
|
onAddComment={() => activityManager.updateNumberOfComments(1)}
|
||||||
onDeleteComment={() => updateNumberOfComments(-1)}
|
onDeleteComment={() => activityManager.updateNumberOfComments(-1)}
|
||||||
onDeleteLike={() => (isLiked = null)}
|
onDeleteLike={() => (isLiked = null)}
|
||||||
onClose={handleOpenAndCloseActivityTab}
|
onClose={handleOpenAndCloseActivityTab}
|
||||||
/>
|
/>
|
||||||
|
@ -20,10 +20,10 @@
|
|||||||
import ButtonContextMenu from '$lib/components/shared-components/context-menu/button-context-menu.svelte';
|
import ButtonContextMenu from '$lib/components/shared-components/context-menu/button-context-menu.svelte';
|
||||||
import EmptyPlaceholder from '$lib/components/shared-components/empty-placeholder.svelte';
|
import EmptyPlaceholder from '$lib/components/shared-components/empty-placeholder.svelte';
|
||||||
import { AssetAction } from '$lib/constants';
|
import { AssetAction } from '$lib/constants';
|
||||||
|
import { faceManager } from '$lib/managers/face.manager.svelte';
|
||||||
import { AssetInteraction } from '$lib/stores/asset-interaction.svelte';
|
import { AssetInteraction } from '$lib/stores/asset-interaction.svelte';
|
||||||
import { assetViewingStore } from '$lib/stores/asset-viewing.store';
|
import { assetViewingStore } from '$lib/stores/asset-viewing.store';
|
||||||
import { AssetStore } from '$lib/stores/assets-store.svelte';
|
import { AssetStore } from '$lib/stores/assets-store.svelte';
|
||||||
import { isFaceEditMode } from '$lib/stores/face-edit.svelte';
|
|
||||||
import { preferences, user } from '$lib/stores/user.store';
|
import { preferences, user } from '$lib/stores/user.store';
|
||||||
import {
|
import {
|
||||||
updateStackedAssetInTimeline,
|
updateStackedAssetInTimeline,
|
||||||
@ -76,7 +76,7 @@
|
|||||||
};
|
};
|
||||||
|
|
||||||
beforeNavigate(() => {
|
beforeNavigate(() => {
|
||||||
isFaceEditMode.value = false;
|
faceManager.isEditMode = false;
|
||||||
});
|
});
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
@ -7,7 +7,6 @@
|
|||||||
NotificationType,
|
NotificationType,
|
||||||
notificationController,
|
notificationController,
|
||||||
} from '$lib/components/shared-components/notification/notification';
|
} from '$lib/components/shared-components/notification/notification';
|
||||||
import { downloadManager } from '$lib/stores/download-store.svelte';
|
|
||||||
import { locale } from '$lib/stores/preferences.store';
|
import { locale } from '$lib/stores/preferences.store';
|
||||||
import { copyToClipboard } from '$lib/utils';
|
import { copyToClipboard } from '$lib/utils';
|
||||||
import { downloadBlob } from '$lib/utils/asset-utils';
|
import { downloadBlob } from '$lib/utils/asset-utils';
|
||||||
@ -17,6 +16,7 @@
|
|||||||
import { mdiCheckAll, mdiContentCopy, mdiDownload, mdiRefresh, mdiWrench } from '@mdi/js';
|
import { mdiCheckAll, mdiContentCopy, mdiDownload, mdiRefresh, mdiWrench } from '@mdi/js';
|
||||||
import { t } from 'svelte-i18n';
|
import { t } from 'svelte-i18n';
|
||||||
import type { PageData } from './$types';
|
import type { PageData } from './$types';
|
||||||
|
import { downloadManager } from '$lib/managers/download.manager.svelte';
|
||||||
|
|
||||||
interface Props {
|
interface Props {
|
||||||
data: PageData;
|
data: PageData;
|
||||||
|
@ -22,7 +22,6 @@
|
|||||||
import SettingAccordionState from '$lib/components/shared-components/settings/setting-accordion-state.svelte';
|
import SettingAccordionState from '$lib/components/shared-components/settings/setting-accordion-state.svelte';
|
||||||
import SettingAccordion from '$lib/components/shared-components/settings/setting-accordion.svelte';
|
import SettingAccordion from '$lib/components/shared-components/settings/setting-accordion.svelte';
|
||||||
import { QueryParameter } from '$lib/constants';
|
import { QueryParameter } from '$lib/constants';
|
||||||
import { downloadManager } from '$lib/stores/download-store.svelte';
|
|
||||||
import { featureFlags } from '$lib/stores/server-config.store';
|
import { featureFlags } from '$lib/stores/server-config.store';
|
||||||
import { copyToClipboard } from '$lib/utils';
|
import { copyToClipboard } from '$lib/utils';
|
||||||
import { downloadBlob } from '$lib/utils/asset-utils';
|
import { downloadBlob } from '$lib/utils/asset-utils';
|
||||||
@ -53,6 +52,7 @@
|
|||||||
import type { Component } from 'svelte';
|
import type { Component } from 'svelte';
|
||||||
import type { SettingsComponentProps } from '$lib/components/admin-page/settings/admin-settings';
|
import type { SettingsComponentProps } from '$lib/components/admin-page/settings/admin-settings';
|
||||||
import SearchBar from '$lib/components/elements/search-bar.svelte';
|
import SearchBar from '$lib/components/elements/search-bar.svelte';
|
||||||
|
import { downloadManager } from '$lib/managers/download.manager.svelte';
|
||||||
|
|
||||||
interface Props {
|
interface Props {
|
||||||
data: PageData;
|
data: PageData;
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import AuthPageLayout from '$lib/components/layouts/AuthPageLayout.svelte';
|
import AuthPageLayout from '$lib/components/layouts/AuthPageLayout.svelte';
|
||||||
import { authManager } from '$lib/stores/auth-manager.svelte';
|
import { authManager } from '$lib/managers/auth-manager.svelte';
|
||||||
import { user } from '$lib/stores/user.store';
|
import { user } from '$lib/stores/user.store';
|
||||||
import { updateMyUser } from '@immich/sdk';
|
import { updateMyUser } from '@immich/sdk';
|
||||||
import { Alert, Button, Field, HelperText, PasswordInput, Stack, Text } from '@immich/ui';
|
import { Alert, Button, Field, HelperText, PasswordInput, Stack, Text } from '@immich/ui';
|
||||||
|
Loading…
x
Reference in New Issue
Block a user