mirror of
https://github.com/immich-app/immich.git
synced 2026-05-18 03:10:24 +03:00
refactor: asset select manager (#27330)
This commit is contained in:
@@ -337,7 +337,7 @@
|
|||||||
{#if assetMultiSelectManager.selectionActive}
|
{#if assetMultiSelectManager.selectionActive}
|
||||||
<div class="sticky top-0 z-1 dark">
|
<div class="sticky top-0 z-1 dark">
|
||||||
<AssetSelectControlBar forceDark>
|
<AssetSelectControlBar forceDark>
|
||||||
{@const Actions = getAssetBulkActions($t, assetMultiSelectManager.asControlContext())}
|
{@const Actions = getAssetBulkActions($t)}
|
||||||
<CreateSharedLink />
|
<CreateSharedLink />
|
||||||
<IconButton
|
<IconButton
|
||||||
shape="round"
|
shape="round"
|
||||||
|
|||||||
@@ -118,7 +118,7 @@
|
|||||||
</aside>
|
</aside>
|
||||||
|
|
||||||
{#if assetMultiSelectManager.selectionActive}
|
{#if assetMultiSelectManager.selectionActive}
|
||||||
{@const Actions = getAssetBulkActions($t, assetMultiSelectManager.asControlContext())}
|
{@const Actions = getAssetBulkActions($t)}
|
||||||
<CommandPaletteDefaultProvider name={$t('assets')} actions={Object.values(Actions)} />
|
<CommandPaletteDefaultProvider name={$t('assets')} actions={Object.values(Actions)} />
|
||||||
|
|
||||||
<Portal target="body">
|
<Portal target="body">
|
||||||
|
|||||||
@@ -1,7 +1,6 @@
|
|||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import ControlAppBar from '$lib/components/shared-components/control-app-bar.svelte';
|
import ControlAppBar from '$lib/components/shared-components/control-app-bar.svelte';
|
||||||
import { assetMultiSelectManager } from '$lib/managers/asset-multi-select-manager.svelte';
|
import { assetMultiSelectManager } from '$lib/managers/asset-multi-select-manager.svelte';
|
||||||
import { setAssetControlContext } from '$lib/utils/context';
|
|
||||||
import { mdiClose } from '@mdi/js';
|
import { mdiClose } from '@mdi/js';
|
||||||
import type { Snippet } from 'svelte';
|
import type { Snippet } from 'svelte';
|
||||||
import { t } from 'svelte-i18n';
|
import { t } from 'svelte-i18n';
|
||||||
@@ -13,8 +12,6 @@
|
|||||||
|
|
||||||
let { children, forceDark }: Props = $props();
|
let { children, forceDark }: Props = $props();
|
||||||
|
|
||||||
setAssetControlContext(assetMultiSelectManager.asControlContext());
|
|
||||||
|
|
||||||
const onClose = () => assetMultiSelectManager.clear();
|
const onClose = () => assetMultiSelectManager.clear();
|
||||||
|
|
||||||
const assets = $derived(assetMultiSelectManager.assets);
|
const assets = $derived(assetMultiSelectManager.assets);
|
||||||
|
|||||||
@@ -1,18 +1,18 @@
|
|||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import MenuOption from '$lib/components/shared-components/context-menu/menu-option.svelte';
|
import MenuOption from '$lib/components/shared-components/context-menu/menu-option.svelte';
|
||||||
|
import { assetMultiSelectManager } from '$lib/managers/asset-multi-select-manager.svelte';
|
||||||
import type { OnArchive } from '$lib/utils/actions';
|
import type { OnArchive } from '$lib/utils/actions';
|
||||||
import { archiveAssets } from '$lib/utils/asset-utils';
|
import { archiveAssets } from '$lib/utils/asset-utils';
|
||||||
import { getAssetControlContext } from '$lib/utils/context';
|
|
||||||
import { AssetVisibility } from '@immich/sdk';
|
import { AssetVisibility } from '@immich/sdk';
|
||||||
import { IconButton } from '@immich/ui';
|
import { IconButton } from '@immich/ui';
|
||||||
import { mdiArchiveArrowDownOutline, mdiArchiveArrowUpOutline, mdiTimerSand } from '@mdi/js';
|
import { mdiArchiveArrowDownOutline, mdiArchiveArrowUpOutline, mdiTimerSand } from '@mdi/js';
|
||||||
import { t } from 'svelte-i18n';
|
import { t } from 'svelte-i18n';
|
||||||
|
|
||||||
interface Props {
|
type Props = {
|
||||||
onArchive?: OnArchive;
|
onArchive?: OnArchive;
|
||||||
menuItem?: boolean;
|
menuItem?: boolean;
|
||||||
unarchive?: boolean;
|
unarchive?: boolean;
|
||||||
}
|
};
|
||||||
|
|
||||||
let { onArchive, menuItem = false, unarchive = false }: Props = $props();
|
let { onArchive, menuItem = false, unarchive = false }: Props = $props();
|
||||||
|
|
||||||
@@ -21,16 +21,14 @@
|
|||||||
|
|
||||||
let loading = $state(false);
|
let loading = $state(false);
|
||||||
|
|
||||||
const { clearSelect, getOwnedAssets } = getAssetControlContext();
|
|
||||||
|
|
||||||
const handleArchive = async () => {
|
const handleArchive = async () => {
|
||||||
const visibility = unarchive ? AssetVisibility.Timeline : AssetVisibility.Archive;
|
const visibility = unarchive ? AssetVisibility.Timeline : AssetVisibility.Archive;
|
||||||
const assets = [...getOwnedAssets()].filter((asset) => asset.visibility !== visibility);
|
const assets = assetMultiSelectManager.getOwnedAssets().filter((asset) => asset.visibility !== visibility);
|
||||||
loading = true;
|
loading = true;
|
||||||
const ids = await archiveAssets(assets, visibility as AssetVisibility);
|
const ids = await archiveAssets(assets, visibility as AssetVisibility);
|
||||||
if (ids) {
|
if (ids) {
|
||||||
onArchive?.(ids, visibility);
|
onArchive?.(ids, visibility);
|
||||||
clearSelect();
|
assetMultiSelectManager.clear();
|
||||||
}
|
}
|
||||||
loading = false;
|
loading = false;
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -1,28 +1,28 @@
|
|||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import MenuOption from '$lib/components/shared-components/context-menu/menu-option.svelte';
|
import MenuOption from '$lib/components/shared-components/context-menu/menu-option.svelte';
|
||||||
|
import { assetMultiSelectManager } from '$lib/managers/asset-multi-select-manager.svelte';
|
||||||
import AssetSelectionChangeDateModal from '$lib/modals/AssetSelectionChangeDateModal.svelte';
|
import AssetSelectionChangeDateModal from '$lib/modals/AssetSelectionChangeDateModal.svelte';
|
||||||
import { getAssetControlContext } from '$lib/utils/context';
|
|
||||||
import { fromTimelinePlainDateTime } from '$lib/utils/timeline-util';
|
import { fromTimelinePlainDateTime } from '$lib/utils/timeline-util';
|
||||||
import { modalManager } from '@immich/ui';
|
import { modalManager } from '@immich/ui';
|
||||||
import { mdiCalendarEditOutline } from '@mdi/js';
|
import { mdiCalendarEditOutline } from '@mdi/js';
|
||||||
import { DateTime } from 'luxon';
|
import { DateTime } from 'luxon';
|
||||||
import { t } from 'svelte-i18n';
|
import { t } from 'svelte-i18n';
|
||||||
interface Props {
|
|
||||||
|
type Props = {
|
||||||
menuItem?: boolean;
|
menuItem?: boolean;
|
||||||
}
|
};
|
||||||
|
|
||||||
let { menuItem = false }: Props = $props();
|
let { menuItem = false }: Props = $props();
|
||||||
const { clearSelect, getOwnedAssets } = getAssetControlContext();
|
|
||||||
|
|
||||||
const handleChangeDate = async () => {
|
const handleChangeDate = async () => {
|
||||||
const assets = getOwnedAssets();
|
const assets = assetMultiSelectManager.ownedAssets;
|
||||||
const initialDate = assets.length === 1 ? fromTimelinePlainDateTime(assets[0].localDateTime) : DateTime.now();
|
const initialDate = assets.length === 1 ? fromTimelinePlainDateTime(assets[0].localDateTime) : DateTime.now();
|
||||||
const success = await modalManager.show(AssetSelectionChangeDateModal, {
|
const success = await modalManager.show(AssetSelectionChangeDateModal, {
|
||||||
initialDate,
|
initialDate,
|
||||||
assets,
|
assets,
|
||||||
});
|
});
|
||||||
if (success) {
|
if (success) {
|
||||||
clearSelect();
|
assetMultiSelectManager.clear();
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
</script>
|
</script>
|
||||||
|
|||||||
@@ -1,8 +1,8 @@
|
|||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
|
import { assetMultiSelectManager } from '$lib/managers/asset-multi-select-manager.svelte';
|
||||||
import AssetUpdateDescriptionConfirmModal from '$lib/modals/AssetUpdateDescriptionConfirmModal.svelte';
|
import AssetUpdateDescriptionConfirmModal from '$lib/modals/AssetUpdateDescriptionConfirmModal.svelte';
|
||||||
import { user } from '$lib/stores/user.store';
|
import { user } from '$lib/stores/user.store';
|
||||||
import { getOwnedAssetsWithWarning } from '$lib/utils/asset-utils';
|
import { getOwnedAssetsWithWarning } from '$lib/utils/asset-utils';
|
||||||
import { getAssetControlContext } from '$lib/utils/context';
|
|
||||||
import { handleError } from '$lib/utils/handle-error';
|
import { handleError } from '$lib/utils/handle-error';
|
||||||
import { updateAssets } from '@immich/sdk';
|
import { updateAssets } from '@immich/sdk';
|
||||||
import { modalManager } from '@immich/ui';
|
import { modalManager } from '@immich/ui';
|
||||||
@@ -15,19 +15,18 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
let { menuItem = false }: Props = $props();
|
let { menuItem = false }: Props = $props();
|
||||||
const { clearSelect, getOwnedAssets } = getAssetControlContext();
|
|
||||||
|
|
||||||
const handleUpdateDescription = async () => {
|
const handleUpdateDescription = async () => {
|
||||||
const description = await modalManager.show(AssetUpdateDescriptionConfirmModal);
|
const description = await modalManager.show(AssetUpdateDescriptionConfirmModal);
|
||||||
if (description) {
|
if (description) {
|
||||||
const ids = getOwnedAssetsWithWarning(getOwnedAssets(), $user);
|
const ids = getOwnedAssetsWithWarning(assetMultiSelectManager.assets, $user);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
await updateAssets({ assetBulkUpdateDto: { ids, description } });
|
await updateAssets({ assetBulkUpdateDto: { ids, description } });
|
||||||
|
assetMultiSelectManager.clear();
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
handleError(error, $t('errors.unable_to_change_description'));
|
handleError(error, $t('errors.unable_to_change_description'));
|
||||||
}
|
}
|
||||||
clearSelect();
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
</script>
|
</script>
|
||||||
|
|||||||
@@ -1,9 +1,9 @@
|
|||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import MenuOption from '$lib/components/shared-components/context-menu/menu-option.svelte';
|
import MenuOption from '$lib/components/shared-components/context-menu/menu-option.svelte';
|
||||||
|
import { assetMultiSelectManager } from '$lib/managers/asset-multi-select-manager.svelte';
|
||||||
import GeolocationPointPickerModal from '$lib/modals/GeolocationPointPickerModal.svelte';
|
import GeolocationPointPickerModal from '$lib/modals/GeolocationPointPickerModal.svelte';
|
||||||
import { user } from '$lib/stores/user.store';
|
import { user } from '$lib/stores/user.store';
|
||||||
import { getOwnedAssetsWithWarning } from '$lib/utils/asset-utils';
|
import { getOwnedAssetsWithWarning } from '$lib/utils/asset-utils';
|
||||||
import { getAssetControlContext } from '$lib/utils/context';
|
|
||||||
import { handleError } from '$lib/utils/handle-error';
|
import { handleError } from '$lib/utils/handle-error';
|
||||||
import { updateAssets } from '@immich/sdk';
|
import { updateAssets } from '@immich/sdk';
|
||||||
import { modalManager, toastManager } from '@immich/ui';
|
import { modalManager, toastManager } from '@immich/ui';
|
||||||
@@ -15,7 +15,6 @@
|
|||||||
};
|
};
|
||||||
|
|
||||||
let { menuItem = false }: Props = $props();
|
let { menuItem = false }: Props = $props();
|
||||||
const { clearSelect, getOwnedAssets } = getAssetControlContext();
|
|
||||||
|
|
||||||
const onAction = async () => {
|
const onAction = async () => {
|
||||||
const point = await modalManager.show(GeolocationPointPickerModal, {});
|
const point = await modalManager.show(GeolocationPointPickerModal, {});
|
||||||
@@ -23,12 +22,12 @@
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
const ids = getOwnedAssetsWithWarning(getOwnedAssets(), $user);
|
const ids = getOwnedAssetsWithWarning(assetMultiSelectManager.assets, $user);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
await updateAssets({ assetBulkUpdateDto: { ids, latitude: point.lat, longitude: point.lng } });
|
await updateAssets({ assetBulkUpdateDto: { ids, latitude: point.lat, longitude: point.lng } });
|
||||||
toastManager.primary();
|
toastManager.primary();
|
||||||
clearSelect();
|
assetMultiSelectManager.clear();
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
handleError(error, $t('errors.unable_to_update_location'));
|
handleError(error, $t('errors.unable_to_update_location'));
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,14 +1,12 @@
|
|||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
|
import { assetMultiSelectManager } from '$lib/managers/asset-multi-select-manager.svelte';
|
||||||
import SharedLinkCreateModal from '$lib/modals/SharedLinkCreateModal.svelte';
|
import SharedLinkCreateModal from '$lib/modals/SharedLinkCreateModal.svelte';
|
||||||
import { getAssetControlContext } from '$lib/utils/context';
|
|
||||||
import { IconButton, modalManager } from '@immich/ui';
|
import { IconButton, modalManager } from '@immich/ui';
|
||||||
import { mdiShareVariantOutline } from '@mdi/js';
|
import { mdiShareVariantOutline } from '@mdi/js';
|
||||||
import { t } from 'svelte-i18n';
|
import { t } from 'svelte-i18n';
|
||||||
|
|
||||||
const { getAssets } = getAssetControlContext();
|
|
||||||
|
|
||||||
const handleClick = async () => {
|
const handleClick = async () => {
|
||||||
await modalManager.show(SharedLinkCreateModal, { assetIds: [...getAssets()].map(({ id }) => id) });
|
await modalManager.show(SharedLinkCreateModal, { assetIds: assetMultiSelectManager.assets.map(({ id }) => id) });
|
||||||
};
|
};
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
|||||||
@@ -1,10 +1,10 @@
|
|||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import MenuOption from '$lib/components/shared-components/context-menu/menu-option.svelte';
|
import MenuOption from '$lib/components/shared-components/context-menu/menu-option.svelte';
|
||||||
|
import { assetMultiSelectManager } from '$lib/managers/asset-multi-select-manager.svelte';
|
||||||
import { featureFlagsManager } from '$lib/managers/feature-flags-manager.svelte';
|
import { featureFlagsManager } from '$lib/managers/feature-flags-manager.svelte';
|
||||||
import AssetDeleteConfirmModal from '$lib/modals/AssetDeleteConfirmModal.svelte';
|
import AssetDeleteConfirmModal from '$lib/modals/AssetDeleteConfirmModal.svelte';
|
||||||
import { showDeleteModal } from '$lib/stores/preferences.store';
|
import { showDeleteModal } from '$lib/stores/preferences.store';
|
||||||
import { type OnDelete, type OnUndoDelete, deleteAssets } from '$lib/utils/actions';
|
import { type OnDelete, type OnUndoDelete, deleteAssets } from '$lib/utils/actions';
|
||||||
import { getAssetControlContext } from '$lib/utils/context';
|
|
||||||
import { IconButton, modalManager } from '@immich/ui';
|
import { IconButton, modalManager } from '@immich/ui';
|
||||||
import { mdiDeleteForeverOutline, mdiDeleteOutline, mdiTimerSand } from '@mdi/js';
|
import { mdiDeleteForeverOutline, mdiDeleteOutline, mdiTimerSand } from '@mdi/js';
|
||||||
import { t } from 'svelte-i18n';
|
import { t } from 'svelte-i18n';
|
||||||
@@ -22,10 +22,8 @@
|
|||||||
let label = $derived(force ? $t('permanently_delete') : $t('delete'));
|
let label = $derived(force ? $t('permanently_delete') : $t('delete'));
|
||||||
let loading = $state(false);
|
let loading = $state(false);
|
||||||
|
|
||||||
const { clearSelect, getOwnedAssets } = getAssetControlContext();
|
|
||||||
|
|
||||||
const onAction = async () => {
|
const onAction = async () => {
|
||||||
const assets = getOwnedAssets();
|
const assets = assetMultiSelectManager.ownedAssets;
|
||||||
|
|
||||||
if (force && $showDeleteModal) {
|
if (force && $showDeleteModal) {
|
||||||
const confirmed = await modalManager.show(AssetDeleteConfirmModal, { size: assets.length });
|
const confirmed = await modalManager.show(AssetDeleteConfirmModal, { size: assets.length });
|
||||||
@@ -36,7 +34,7 @@
|
|||||||
|
|
||||||
loading = true;
|
loading = true;
|
||||||
await deleteAssets(force, onAssetDelete, assets, onUndoDelete);
|
await deleteAssets(force, onAssetDelete, assets, onUndoDelete);
|
||||||
clearSelect();
|
assetMultiSelectManager.clear();
|
||||||
loading = false;
|
loading = false;
|
||||||
};
|
};
|
||||||
</script>
|
</script>
|
||||||
|
|||||||
@@ -1,15 +1,15 @@
|
|||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import { shortcut } from '$lib/actions/shortcut';
|
import { shortcut } from '$lib/actions/shortcut';
|
||||||
|
|
||||||
|
import MenuOption from '$lib/components/shared-components/context-menu/menu-option.svelte';
|
||||||
|
import { assetMultiSelectManager } from '$lib/managers/asset-multi-select-manager.svelte';
|
||||||
import { authManager } from '$lib/managers/auth-manager.svelte';
|
import { authManager } from '$lib/managers/auth-manager.svelte';
|
||||||
import { handleDownloadAsset } from '$lib/services/asset.service';
|
import { handleDownloadAsset } from '$lib/services/asset.service';
|
||||||
import { downloadArchive } from '$lib/utils/asset-utils';
|
import { downloadArchive } from '$lib/utils/asset-utils';
|
||||||
import { getAssetControlContext } from '$lib/utils/context';
|
|
||||||
import { getAssetInfo } from '@immich/sdk';
|
import { getAssetInfo } from '@immich/sdk';
|
||||||
import { IconButton } from '@immich/ui';
|
import { IconButton } from '@immich/ui';
|
||||||
import { mdiDownload } from '@mdi/js';
|
import { mdiDownload } from '@mdi/js';
|
||||||
import { t } from 'svelte-i18n';
|
import { t } from 'svelte-i18n';
|
||||||
import MenuOption from '../../shared-components/context-menu/menu-option.svelte';
|
|
||||||
|
|
||||||
interface Props {
|
interface Props {
|
||||||
filename?: string;
|
filename?: string;
|
||||||
@@ -18,18 +18,16 @@
|
|||||||
|
|
||||||
let { filename = 'immich.zip', menuItem = false }: Props = $props();
|
let { filename = 'immich.zip', menuItem = false }: Props = $props();
|
||||||
|
|
||||||
const { getAssets, clearSelect } = getAssetControlContext();
|
|
||||||
|
|
||||||
const handleDownloadFiles = async () => {
|
const handleDownloadFiles = async () => {
|
||||||
const assets = [...getAssets()];
|
const assets = assetMultiSelectManager.assets;
|
||||||
if (assets.length === 1) {
|
if (assets.length === 1) {
|
||||||
clearSelect();
|
assetMultiSelectManager.clear();
|
||||||
let asset = await getAssetInfo({ ...authManager.params, id: assets[0].id });
|
let asset = await getAssetInfo({ ...authManager.params, id: assets[0].id });
|
||||||
await handleDownloadAsset(asset, { edited: true });
|
await handleDownloadAsset(asset, { edited: true });
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
clearSelect();
|
assetMultiSelectManager.clear();
|
||||||
await downloadArchive(filename, { assetIds: assets.map((asset) => asset.id) });
|
await downloadArchive(filename, { assetIds: assets.map((asset) => asset.id) });
|
||||||
};
|
};
|
||||||
</script>
|
</script>
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import MenuOption from '$lib/components/shared-components/context-menu/menu-option.svelte';
|
import MenuOption from '$lib/components/shared-components/context-menu/menu-option.svelte';
|
||||||
|
import { assetMultiSelectManager } from '$lib/managers/asset-multi-select-manager.svelte';
|
||||||
import type { OnFavorite } from '$lib/utils/actions';
|
import type { OnFavorite } from '$lib/utils/actions';
|
||||||
import { getAssetControlContext } from '$lib/utils/context';
|
|
||||||
import { handleError } from '$lib/utils/handle-error';
|
import { handleError } from '$lib/utils/handle-error';
|
||||||
import { updateAssets } from '@immich/sdk';
|
import { updateAssets } from '@immich/sdk';
|
||||||
import { IconButton, toastManager } from '@immich/ui';
|
import { IconButton, toastManager } from '@immich/ui';
|
||||||
@@ -21,14 +21,12 @@
|
|||||||
|
|
||||||
let loading = $state(false);
|
let loading = $state(false);
|
||||||
|
|
||||||
const { clearSelect, getOwnedAssets } = getAssetControlContext();
|
|
||||||
|
|
||||||
const handleFavorite = async () => {
|
const handleFavorite = async () => {
|
||||||
const isFavorite = !removeFavorite;
|
const isFavorite = !removeFavorite;
|
||||||
loading = true;
|
loading = true;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const assets = [...getOwnedAssets()].filter((asset) => asset.isFavorite !== isFavorite);
|
const assets = assetMultiSelectManager.ownedAssets.filter((asset) => asset.isFavorite !== isFavorite);
|
||||||
|
|
||||||
const ids = assets.map(({ id }) => id);
|
const ids = assets.map(({ id }) => id);
|
||||||
|
|
||||||
@@ -48,7 +46,7 @@
|
|||||||
: $t('removed_from_favorites_count', { values: { count: ids.length } }),
|
: $t('removed_from_favorites_count', { values: { count: ids.length } }),
|
||||||
);
|
);
|
||||||
|
|
||||||
clearSelect();
|
assetMultiSelectManager.clear();
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
handleError(error, $t('errors.unable_to_add_remove_favorites', { values: { favorite: isFavorite } }));
|
handleError(error, $t('errors.unable_to_add_remove_favorites', { values: { favorite: isFavorite } }));
|
||||||
} finally {
|
} finally {
|
||||||
|
|||||||
@@ -1,15 +1,15 @@
|
|||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
|
import MenuOption from '$lib/components/shared-components/context-menu/menu-option.svelte';
|
||||||
|
import { assetMultiSelectManager } from '$lib/managers/asset-multi-select-manager.svelte';
|
||||||
import { authManager } from '$lib/managers/auth-manager.svelte';
|
import { authManager } from '$lib/managers/auth-manager.svelte';
|
||||||
import type { TimelineAsset } from '$lib/managers/timeline-manager/types';
|
import type { TimelineAsset } from '$lib/managers/timeline-manager/types';
|
||||||
import type { OnLink, OnUnlink } from '$lib/utils/actions';
|
import type { OnLink, OnUnlink } from '$lib/utils/actions';
|
||||||
import { getAssetControlContext } from '$lib/utils/context';
|
|
||||||
import { handleError } from '$lib/utils/handle-error';
|
import { handleError } from '$lib/utils/handle-error';
|
||||||
import { toTimelineAsset } from '$lib/utils/timeline-util';
|
import { toTimelineAsset } from '$lib/utils/timeline-util';
|
||||||
import { getAssetInfo, updateAsset } from '@immich/sdk';
|
import { getAssetInfo, updateAsset } from '@immich/sdk';
|
||||||
import { IconButton } from '@immich/ui';
|
import { IconButton } from '@immich/ui';
|
||||||
import { mdiLinkOff, mdiMotionPlayOutline, mdiTimerSand } from '@mdi/js';
|
import { mdiLinkOff, mdiMotionPlayOutline, mdiTimerSand } from '@mdi/js';
|
||||||
import { t } from 'svelte-i18n';
|
import { t } from 'svelte-i18n';
|
||||||
import MenuOption from '../../shared-components/context-menu/menu-option.svelte';
|
|
||||||
|
|
||||||
interface Props {
|
interface Props {
|
||||||
onLink: OnLink;
|
onLink: OnLink;
|
||||||
@@ -25,12 +25,10 @@
|
|||||||
let text = $derived(unlink ? $t('unlink_motion_video') : $t('link_motion_video'));
|
let text = $derived(unlink ? $t('unlink_motion_video') : $t('link_motion_video'));
|
||||||
let icon = $derived(unlink ? mdiLinkOff : mdiMotionPlayOutline);
|
let icon = $derived(unlink ? mdiLinkOff : mdiMotionPlayOutline);
|
||||||
|
|
||||||
const { clearSelect, getOwnedAssets } = getAssetControlContext();
|
|
||||||
|
|
||||||
const onClick = () => (unlink ? handleUnlink() : handleLink());
|
const onClick = () => (unlink ? handleUnlink() : handleLink());
|
||||||
|
|
||||||
const handleLink = async () => {
|
const handleLink = async () => {
|
||||||
let [still, motion] = [...getOwnedAssets()];
|
let [still, motion] = assetMultiSelectManager.ownedAssets;
|
||||||
if ((still as TimelineAsset).isVideo) {
|
if ((still as TimelineAsset).isVideo) {
|
||||||
[still, motion] = [motion, still];
|
[still, motion] = [motion, still];
|
||||||
}
|
}
|
||||||
@@ -39,7 +37,7 @@
|
|||||||
loading = true;
|
loading = true;
|
||||||
const stillResponse = await updateAsset({ id: still.id, updateAssetDto: { livePhotoVideoId: motion.id } });
|
const stillResponse = await updateAsset({ id: still.id, updateAssetDto: { livePhotoVideoId: motion.id } });
|
||||||
onLink({ still: toTimelineAsset(stillResponse), motion: motion as TimelineAsset });
|
onLink({ still: toTimelineAsset(stillResponse), motion: motion as TimelineAsset });
|
||||||
clearSelect();
|
assetMultiSelectManager.clear();
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
handleError(error, $t('errors.unable_to_link_motion_video'));
|
handleError(error, $t('errors.unable_to_link_motion_video'));
|
||||||
} finally {
|
} finally {
|
||||||
@@ -48,7 +46,7 @@
|
|||||||
};
|
};
|
||||||
|
|
||||||
const handleUnlink = async () => {
|
const handleUnlink = async () => {
|
||||||
const [still] = [...getOwnedAssets()];
|
const [still] = assetMultiSelectManager.ownedAssets;
|
||||||
if (!still) {
|
if (!still) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -61,7 +59,7 @@
|
|||||||
const stillResponse = await updateAsset({ id: still.id, updateAssetDto: { livePhotoVideoId: null } });
|
const stillResponse = await updateAsset({ id: still.id, updateAssetDto: { livePhotoVideoId: null } });
|
||||||
const motionResponse = await getAssetInfo({ ...authManager.params, id: motionId });
|
const motionResponse = await getAssetInfo({ ...authManager.params, id: motionId });
|
||||||
onUnlink({ still: toTimelineAsset(stillResponse), motion: toTimelineAsset(motionResponse) });
|
onUnlink({ still: toTimelineAsset(stillResponse), motion: toTimelineAsset(motionResponse) });
|
||||||
clearSelect();
|
assetMultiSelectManager.clear();
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
handleError(error, $t('errors.unable_to_unlink_motion_video'));
|
handleError(error, $t('errors.unable_to_unlink_motion_video'));
|
||||||
} finally {
|
} finally {
|
||||||
|
|||||||
@@ -1,11 +1,11 @@
|
|||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import { getAssetControlContext } from '$lib/utils/context';
|
import MenuOption from '$lib/components/shared-components/context-menu/menu-option.svelte';
|
||||||
|
import { assetMultiSelectManager } from '$lib/managers/asset-multi-select-manager.svelte';
|
||||||
import { handleError } from '$lib/utils/handle-error';
|
import { handleError } from '$lib/utils/handle-error';
|
||||||
import { getAlbumInfo, removeAssetFromAlbum, type AlbumResponseDto } from '@immich/sdk';
|
import { getAlbumInfo, removeAssetFromAlbum, type AlbumResponseDto } from '@immich/sdk';
|
||||||
import { IconButton, modalManager, toastManager } from '@immich/ui';
|
import { IconButton, modalManager, toastManager } from '@immich/ui';
|
||||||
import { mdiDeleteOutline, mdiImageRemoveOutline } from '@mdi/js';
|
import { mdiDeleteOutline, mdiImageRemoveOutline } from '@mdi/js';
|
||||||
import { t } from 'svelte-i18n';
|
import { t } from 'svelte-i18n';
|
||||||
import MenuOption from '../../shared-components/context-menu/menu-option.svelte';
|
|
||||||
|
|
||||||
interface Props {
|
interface Props {
|
||||||
album: AlbumResponseDto;
|
album: AlbumResponseDto;
|
||||||
@@ -16,10 +16,8 @@
|
|||||||
|
|
||||||
let { album = $bindable(), onRemove, assetIds, menuItem = false }: Props = $props();
|
let { album = $bindable(), onRemove, assetIds, menuItem = false }: Props = $props();
|
||||||
|
|
||||||
const context = getAssetControlContext();
|
|
||||||
|
|
||||||
const removeFromAlbum = async () => {
|
const removeFromAlbum = async () => {
|
||||||
const ids = assetIds ?? context?.getAssets().map(({ id }) => id) ?? [];
|
const ids = assetIds ?? assetMultiSelectManager.assets.map(({ id }) => id) ?? [];
|
||||||
|
|
||||||
const isConfirmed = await modalManager.showDialog({
|
const isConfirmed = await modalManager.showDialog({
|
||||||
prompt: $t('remove_assets_album_confirmation', { values: { count: ids.length } }),
|
prompt: $t('remove_assets_album_confirmation', { values: { count: ids.length } }),
|
||||||
@@ -42,7 +40,7 @@
|
|||||||
const count = results.filter(({ success }) => success).length;
|
const count = results.filter(({ success }) => success).length;
|
||||||
toastManager.primary($t('assets_removed_count', { values: { count } }));
|
toastManager.primary($t('assets_removed_count', { values: { count } }));
|
||||||
|
|
||||||
context?.clearSelect();
|
assetMultiSelectManager.clear();
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
handleError(error, $t('errors.error_removing_assets_from_album'));
|
handleError(error, $t('errors.error_removing_assets_from_album'));
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import { shortcut } from '$lib/actions/shortcut';
|
import { shortcut } from '$lib/actions/shortcut';
|
||||||
|
import { assetMultiSelectManager } from '$lib/managers/asset-multi-select-manager.svelte';
|
||||||
import { handleRemoveSharedLinkAssets } from '$lib/services/shared-link.service';
|
import { handleRemoveSharedLinkAssets } from '$lib/services/shared-link.service';
|
||||||
import { getAssetControlContext } from '$lib/utils/context';
|
|
||||||
import { type SharedLinkResponseDto } from '@immich/sdk';
|
import { type SharedLinkResponseDto } from '@immich/sdk';
|
||||||
import { IconButton } from '@immich/ui';
|
import { IconButton } from '@immich/ui';
|
||||||
import { mdiDeleteOutline } from '@mdi/js';
|
import { mdiDeleteOutline } from '@mdi/js';
|
||||||
@@ -13,13 +13,11 @@
|
|||||||
|
|
||||||
let { sharedLink = $bindable() }: Props = $props();
|
let { sharedLink = $bindable() }: Props = $props();
|
||||||
|
|
||||||
const { getAssets, clearSelect } = getAssetControlContext();
|
|
||||||
|
|
||||||
const handleSelect = async () => {
|
const handleSelect = async () => {
|
||||||
const assetIds = getAssets().map(({ id }) => id);
|
const assetIds = assetMultiSelectManager.assets.map(({ id }) => id);
|
||||||
const success = await handleRemoveSharedLinkAssets(sharedLink, assetIds);
|
const success = await handleRemoveSharedLinkAssets(sharedLink, assetIds);
|
||||||
if (success) {
|
if (success) {
|
||||||
clearSelect();
|
assetMultiSelectManager.clear();
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
</script>
|
</script>
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
|
import { assetMultiSelectManager } from '$lib/managers/asset-multi-select-manager.svelte';
|
||||||
import type { OnRestore } from '$lib/utils/actions';
|
import type { OnRestore } from '$lib/utils/actions';
|
||||||
import { getAssetControlContext } from '$lib/utils/context';
|
|
||||||
import { handleError } from '$lib/utils/handle-error';
|
import { handleError } from '$lib/utils/handle-error';
|
||||||
import { restoreAssets } from '@immich/sdk';
|
import { restoreAssets } from '@immich/sdk';
|
||||||
import { Button, toastManager } from '@immich/ui';
|
import { Button, toastManager } from '@immich/ui';
|
||||||
@@ -13,19 +13,17 @@
|
|||||||
|
|
||||||
let { onRestore }: Props = $props();
|
let { onRestore }: Props = $props();
|
||||||
|
|
||||||
const { getAssets, clearSelect } = getAssetControlContext();
|
|
||||||
|
|
||||||
let loading = $state(false);
|
let loading = $state(false);
|
||||||
|
|
||||||
const handleRestore = async () => {
|
const handleRestore = async () => {
|
||||||
loading = true;
|
loading = true;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const ids = [...getAssets()].map((a) => a.id);
|
const ids = assetMultiSelectManager.assets.map((a) => a.id);
|
||||||
await restoreAssets({ bulkIdsDto: { ids } });
|
await restoreAssets({ bulkIdsDto: { ids } });
|
||||||
onRestore?.(ids);
|
onRestore?.(ids);
|
||||||
toastManager.primary($t('assets_restored_count', { values: { count: ids.length } }));
|
toastManager.primary($t('assets_restored_count', { values: { count: ids.length } }));
|
||||||
clearSelect();
|
assetMultiSelectManager.clear();
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
handleError(error, $t('errors.unable_to_restore_assets'));
|
handleError(error, $t('errors.unable_to_restore_assets'));
|
||||||
} finally {
|
} finally {
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import MenuOption from '$lib/components/shared-components/context-menu/menu-option.svelte';
|
import MenuOption from '$lib/components/shared-components/context-menu/menu-option.svelte';
|
||||||
|
import { assetMultiSelectManager } from '$lib/managers/asset-multi-select-manager.svelte';
|
||||||
import type { OnSetVisibility } from '$lib/utils/actions';
|
import type { OnSetVisibility } from '$lib/utils/actions';
|
||||||
import { getAssetControlContext } from '$lib/utils/context';
|
|
||||||
import { handleError } from '$lib/utils/handle-error';
|
import { handleError } from '$lib/utils/handle-error';
|
||||||
import { AssetVisibility, updateAssets } from '@immich/sdk';
|
import { AssetVisibility, updateAssets } from '@immich/sdk';
|
||||||
import { Button, modalManager } from '@immich/ui';
|
import { Button, modalManager } from '@immich/ui';
|
||||||
@@ -16,7 +16,6 @@
|
|||||||
|
|
||||||
let { onVisibilitySet, menuItem = false, unlock = false }: Props = $props();
|
let { onVisibilitySet, menuItem = false, unlock = false }: Props = $props();
|
||||||
let loading = $state(false);
|
let loading = $state(false);
|
||||||
const { getAssets } = getAssetControlContext();
|
|
||||||
|
|
||||||
const setLockedVisibility = async () => {
|
const setLockedVisibility = async () => {
|
||||||
const isConfirmed = await modalManager.showDialog({
|
const isConfirmed = await modalManager.showDialog({
|
||||||
@@ -33,7 +32,7 @@
|
|||||||
|
|
||||||
try {
|
try {
|
||||||
loading = true;
|
loading = true;
|
||||||
const assetIds = getAssets().map(({ id }) => id);
|
const assetIds = assetMultiSelectManager.assets.map(({ id }) => id);
|
||||||
|
|
||||||
await updateAssets({
|
await updateAssets({
|
||||||
assetBulkUpdateDto: {
|
assetBulkUpdateDto: {
|
||||||
|
|||||||
@@ -1,8 +1,8 @@
|
|||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import MenuOption from '$lib/components/shared-components/context-menu/menu-option.svelte';
|
import MenuOption from '$lib/components/shared-components/context-menu/menu-option.svelte';
|
||||||
|
import { assetMultiSelectManager } from '$lib/managers/asset-multi-select-manager.svelte';
|
||||||
import type { OnStack, OnUnstack } from '$lib/utils/actions';
|
import type { OnStack, OnUnstack } from '$lib/utils/actions';
|
||||||
import { deleteStack, stackAssets } from '$lib/utils/asset-utils';
|
import { deleteStack, stackAssets } from '$lib/utils/asset-utils';
|
||||||
import { getAssetControlContext } from '$lib/utils/context';
|
|
||||||
import { toTimelineAsset } from '$lib/utils/timeline-util';
|
import { toTimelineAsset } from '$lib/utils/timeline-util';
|
||||||
import { mdiImageMultipleOutline, mdiImageOffOutline } from '@mdi/js';
|
import { mdiImageMultipleOutline, mdiImageOffOutline } from '@mdi/js';
|
||||||
import { t } from 'svelte-i18n';
|
import { t } from 'svelte-i18n';
|
||||||
@@ -15,17 +15,14 @@
|
|||||||
|
|
||||||
let { unstack = false, onStack, onUnstack }: Props = $props();
|
let { unstack = false, onStack, onUnstack }: Props = $props();
|
||||||
|
|
||||||
const { clearSelect, getOwnedAssets } = getAssetControlContext();
|
|
||||||
|
|
||||||
const handleStack = async () => {
|
const handleStack = async () => {
|
||||||
const selectedAssets = [...getOwnedAssets()];
|
const result = await stackAssets(assetMultiSelectManager.ownedAssets);
|
||||||
const result = await stackAssets(selectedAssets);
|
|
||||||
onStack?.(result);
|
onStack?.(result);
|
||||||
clearSelect();
|
assetMultiSelectManager.clear();
|
||||||
};
|
};
|
||||||
|
|
||||||
const handleUnstack = async () => {
|
const handleUnstack = async () => {
|
||||||
const selectedAssets = [...getOwnedAssets()];
|
const selectedAssets = assetMultiSelectManager.ownedAssets;
|
||||||
if (selectedAssets.length !== 1) {
|
if (selectedAssets.length !== 1) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -37,7 +34,7 @@
|
|||||||
if (unstackedAssets) {
|
if (unstackedAssets) {
|
||||||
onUnstack?.(unstackedAssets.map((a) => toTimelineAsset(a)));
|
onUnstack?.(unstackedAssets.map((a) => toTimelineAsset(a)));
|
||||||
}
|
}
|
||||||
clearSelect();
|
assetMultiSelectManager.clear();
|
||||||
};
|
};
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
|||||||
@@ -1,11 +1,11 @@
|
|||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import { shortcut } from '$lib/actions/shortcut';
|
import { shortcut } from '$lib/actions/shortcut';
|
||||||
|
import MenuOption from '$lib/components/shared-components/context-menu/menu-option.svelte';
|
||||||
|
import { assetMultiSelectManager } from '$lib/managers/asset-multi-select-manager.svelte';
|
||||||
import AssetTagModal from '$lib/modals/AssetTagModal.svelte';
|
import AssetTagModal from '$lib/modals/AssetTagModal.svelte';
|
||||||
import { getAssetControlContext } from '$lib/utils/context';
|
|
||||||
import { IconButton, modalManager } from '@immich/ui';
|
import { IconButton, modalManager } from '@immich/ui';
|
||||||
import { mdiTagMultipleOutline } from '@mdi/js';
|
import { mdiTagMultipleOutline } from '@mdi/js';
|
||||||
import { t } from 'svelte-i18n';
|
import { t } from 'svelte-i18n';
|
||||||
import MenuOption from '../../shared-components/context-menu/menu-option.svelte';
|
|
||||||
|
|
||||||
interface Props {
|
interface Props {
|
||||||
menuItem?: boolean;
|
menuItem?: boolean;
|
||||||
@@ -16,13 +16,11 @@
|
|||||||
const text = $t('tag');
|
const text = $t('tag');
|
||||||
const icon = mdiTagMultipleOutline;
|
const icon = mdiTagMultipleOutline;
|
||||||
|
|
||||||
const { clearSelect, getOwnedAssets } = getAssetControlContext();
|
|
||||||
|
|
||||||
const handleTagAssets = async () => {
|
const handleTagAssets = async () => {
|
||||||
const assets = [...getOwnedAssets()];
|
const assets = assetMultiSelectManager.ownedAssets;
|
||||||
const didUpdate = await modalManager.show(AssetTagModal, { assetIds: assets.map(({ id }) => id) });
|
const didUpdate = await modalManager.show(AssetTagModal, { assetIds: assets.map(({ id }) => id) });
|
||||||
if (didUpdate) {
|
if (didUpdate) {
|
||||||
clearSelect();
|
assetMultiSelectManager.clear();
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
</script>
|
</script>
|
||||||
|
|||||||
@@ -1,7 +1,6 @@
|
|||||||
import { eventManager } from '$lib/managers/event-manager.svelte';
|
import { eventManager } from '$lib/managers/event-manager.svelte';
|
||||||
import type { TimelineAsset } from '$lib/managers/timeline-manager/types';
|
import type { TimelineAsset } from '$lib/managers/timeline-manager/types';
|
||||||
import { user } from '$lib/stores/user.store';
|
import { user } from '$lib/stores/user.store';
|
||||||
import type { AssetControlContext } from '$lib/types';
|
|
||||||
import { AssetVisibility, type UserAdminResponseDto } from '@immich/sdk';
|
import { AssetVisibility, type UserAdminResponseDto } from '@immich/sdk';
|
||||||
import { SvelteMap, SvelteSet } from 'svelte/reactivity';
|
import { SvelteMap, SvelteSet } from 'svelte/reactivity';
|
||||||
import { fromStore } from 'svelte/store';
|
import { fromStore } from 'svelte/store';
|
||||||
@@ -22,7 +21,10 @@ export class AssetMultiSelectManager {
|
|||||||
candidates = $state<TimelineAsset[]>([]);
|
candidates = $state<TimelineAsset[]>([]);
|
||||||
|
|
||||||
selectionActive = $derived(this.#selectedMap.size > 0);
|
selectionActive = $derived(this.#selectedMap.size > 0);
|
||||||
|
|
||||||
assets = $derived(Array.from(this.#selectedMap.values()));
|
assets = $derived(Array.from(this.#selectedMap.values()));
|
||||||
|
ownedAssets = $derived(this.#userId ? this.assets.filter((asset) => asset.ownerId === this.#userId) : this.assets);
|
||||||
|
|
||||||
isAllTrashed = $derived(this.assets.every((asset) => asset.isTrashed));
|
isAllTrashed = $derived(this.assets.every((asset) => asset.isTrashed));
|
||||||
isAllArchived = $derived(this.assets.every((asset) => asset.visibility === AssetVisibility.Archive));
|
isAllArchived = $derived(this.assets.every((asset) => asset.visibility === AssetVisibility.Archive));
|
||||||
isAllFavorite = $derived(this.assets.every((asset) => asset.isFavorite));
|
isAllFavorite = $derived(this.assets.every((asset) => asset.isFavorite));
|
||||||
@@ -41,13 +43,8 @@ export class AssetMultiSelectManager {
|
|||||||
this.#unsubscribe?.();
|
this.#unsubscribe?.();
|
||||||
}
|
}
|
||||||
|
|
||||||
asControlContext(): AssetControlContext {
|
getOwnedAssets() {
|
||||||
return {
|
return this.#userId ? this.assets.filter((asset) => asset.ownerId === this.#userId) : this.assets;
|
||||||
getOwnedAssets: () =>
|
|
||||||
this.#userId ? this.assets.filter((asset) => asset.ownerId === this.#userId) : this.assets,
|
|
||||||
getAssets: () => this.assets,
|
|
||||||
clearSelect: () => this.clear(),
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
|
|
||||||
hasSelectedAsset(assetId: string) {
|
hasSelectedAsset(assetId: string) {
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
import { ProjectionType } from '$lib/constants';
|
import { ProjectionType } from '$lib/constants';
|
||||||
|
import { assetMultiSelectManager } from '$lib/managers/asset-multi-select-manager.svelte';
|
||||||
import { assetViewerManager } from '$lib/managers/asset-viewer-manager.svelte';
|
import { assetViewerManager } from '$lib/managers/asset-viewer-manager.svelte';
|
||||||
import { authManager } from '$lib/managers/auth-manager.svelte';
|
import { authManager } from '$lib/managers/auth-manager.svelte';
|
||||||
import { eventManager } from '$lib/managers/event-manager.svelte';
|
import { eventManager } from '$lib/managers/event-manager.svelte';
|
||||||
@@ -6,7 +7,6 @@ import AssetAddToAlbumModal from '$lib/modals/AssetAddToAlbumModal.svelte';
|
|||||||
import AssetTagModal from '$lib/modals/AssetTagModal.svelte';
|
import AssetTagModal from '$lib/modals/AssetTagModal.svelte';
|
||||||
import SharedLinkCreateModal from '$lib/modals/SharedLinkCreateModal.svelte';
|
import SharedLinkCreateModal from '$lib/modals/SharedLinkCreateModal.svelte';
|
||||||
import { user as authUser, preferences } from '$lib/stores/user.store';
|
import { user as authUser, preferences } from '$lib/stores/user.store';
|
||||||
import type { AssetControlContext } from '$lib/types';
|
|
||||||
import { getAssetMediaUrl, getSharedLink, sleep } from '$lib/utils';
|
import { getAssetMediaUrl, getSharedLink, sleep } from '$lib/utils';
|
||||||
import { downloadUrl } from '$lib/utils/asset-utils';
|
import { downloadUrl } from '$lib/utils/asset-utils';
|
||||||
import { handleError } from '$lib/utils/handle-error';
|
import { handleError } from '$lib/utils/handle-error';
|
||||||
@@ -48,14 +48,14 @@ import {
|
|||||||
import type { MessageFormatter } from 'svelte-i18n';
|
import type { MessageFormatter } from 'svelte-i18n';
|
||||||
import { get } from 'svelte/store';
|
import { get } from 'svelte/store';
|
||||||
|
|
||||||
export const getAssetBulkActions = ($t: MessageFormatter, ctx: AssetControlContext) => {
|
export const getAssetBulkActions = ($t: MessageFormatter) => {
|
||||||
const ownedAssets = ctx.getOwnedAssets();
|
const ownedAssets = assetMultiSelectManager.ownedAssets;
|
||||||
const assetIds = ownedAssets.map((asset) => asset.id);
|
const assetIds = ownedAssets.map((asset) => asset.id);
|
||||||
const isAllVideos = ownedAssets.every((asset) => asset.isVideo);
|
const isAllVideos = ownedAssets.every((asset) => asset.isVideo);
|
||||||
|
|
||||||
const onAction = async (name: AssetJobName) => {
|
const onAction = async (name: AssetJobName) => {
|
||||||
await handleRunAssetJob({ name, assetIds });
|
await handleRunAssetJob({ name, assetIds });
|
||||||
ctx.clearSelect();
|
assetMultiSelectManager.clear();
|
||||||
};
|
};
|
||||||
|
|
||||||
const AddToAlbum: ActionItem = {
|
const AddToAlbum: ActionItem = {
|
||||||
|
|||||||
@@ -1,4 +1,3 @@
|
|||||||
import type { AssetControlContext } from '$lib/types';
|
|
||||||
import { getContext, setContext } from 'svelte';
|
import { getContext, setContext } from 'svelte';
|
||||||
|
|
||||||
export function createContext<T>(key: string | symbol = Symbol()) {
|
export function createContext<T>(key: string | symbol = Symbol()) {
|
||||||
@@ -7,5 +6,3 @@ export function createContext<T>(key: string | symbol = Symbol()) {
|
|||||||
set: (context: T) => setContext<T>(key, context),
|
set: (context: T) => setContext<T>(key, context),
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
export const { get: getAssetControlContext, set: setAssetControlContext } = createContext<AssetControlContext>();
|
|
||||||
|
|||||||
+1
-1
@@ -452,7 +452,7 @@
|
|||||||
|
|
||||||
{#if assetMultiSelectManager.selectionActive}
|
{#if assetMultiSelectManager.selectionActive}
|
||||||
<AssetSelectControlBar>
|
<AssetSelectControlBar>
|
||||||
{@const Actions = getAssetBulkActions($t, assetMultiSelectManager.asControlContext())}
|
{@const Actions = getAssetBulkActions($t)}
|
||||||
<CommandPaletteDefaultProvider name={$t('assets')} actions={Object.values(Actions)} />
|
<CommandPaletteDefaultProvider name={$t('assets')} actions={Object.values(Actions)} />
|
||||||
<CreateSharedLink />
|
<CreateSharedLink />
|
||||||
<SelectAllAssets {timelineManager} assetInteraction={assetMultiSelectManager} />
|
<SelectAllAssets {timelineManager} assetInteraction={assetMultiSelectManager} />
|
||||||
|
|||||||
@@ -60,7 +60,7 @@
|
|||||||
|
|
||||||
{#if assetMultiSelectManager.selectionActive}
|
{#if assetMultiSelectManager.selectionActive}
|
||||||
<AssetSelectControlBar>
|
<AssetSelectControlBar>
|
||||||
{@const Actions = getAssetBulkActions($t, assetMultiSelectManager.asControlContext())}
|
{@const Actions = getAssetBulkActions($t)}
|
||||||
<CommandPaletteDefaultProvider name={$t('assets')} actions={Object.values(Actions)} />
|
<CommandPaletteDefaultProvider name={$t('assets')} actions={Object.values(Actions)} />
|
||||||
<ArchiveAction
|
<ArchiveAction
|
||||||
unarchive
|
unarchive
|
||||||
|
|||||||
@@ -64,7 +64,7 @@
|
|||||||
<!-- Multiselection mode app bar -->
|
<!-- Multiselection mode app bar -->
|
||||||
{#if assetMultiSelectManager.selectionActive}
|
{#if assetMultiSelectManager.selectionActive}
|
||||||
<AssetSelectControlBar>
|
<AssetSelectControlBar>
|
||||||
{@const Actions = getAssetBulkActions($t, assetMultiSelectManager.asControlContext())}
|
{@const Actions = getAssetBulkActions($t)}
|
||||||
<CommandPaletteDefaultProvider name={$t('assets')} actions={Object.values(Actions)} />
|
<CommandPaletteDefaultProvider name={$t('assets')} actions={Object.values(Actions)} />
|
||||||
<FavoriteAction removeFavorite onFavorite={(assetIds) => timelineManager.removeAssets(assetIds)} />
|
<FavoriteAction removeFavorite onFavorite={(assetIds) => timelineManager.removeAssets(assetIds)} />
|
||||||
<CreateSharedLink />
|
<CreateSharedLink />
|
||||||
|
|||||||
@@ -111,7 +111,7 @@
|
|||||||
{#if assetMultiSelectManager.selectionActive}
|
{#if assetMultiSelectManager.selectionActive}
|
||||||
<div class="fixed top-0 start-0 w-full">
|
<div class="fixed top-0 start-0 w-full">
|
||||||
<AssetSelectControlBar>
|
<AssetSelectControlBar>
|
||||||
{@const Actions = getAssetBulkActions($t, assetMultiSelectManager.asControlContext())}
|
{@const Actions = getAssetBulkActions($t)}
|
||||||
<CommandPaletteDefaultProvider name={$t('assets')} actions={Object.values(Actions)} />
|
<CommandPaletteDefaultProvider name={$t('assets')} actions={Object.values(Actions)} />
|
||||||
<CreateSharedLink />
|
<CreateSharedLink />
|
||||||
<IconButton
|
<IconButton
|
||||||
|
|||||||
+1
-1
@@ -40,7 +40,7 @@
|
|||||||
|
|
||||||
{#if assetMultiSelectManager.selectionActive}
|
{#if assetMultiSelectManager.selectionActive}
|
||||||
<AssetSelectControlBar>
|
<AssetSelectControlBar>
|
||||||
{@const Actions = getAssetBulkActions($t, assetMultiSelectManager.asControlContext())}
|
{@const Actions = getAssetBulkActions($t)}
|
||||||
<CommandPaletteDefaultProvider name={$t('assets')} actions={Object.values(Actions)} />
|
<CommandPaletteDefaultProvider name={$t('assets')} actions={Object.values(Actions)} />
|
||||||
<CreateSharedLink />
|
<CreateSharedLink />
|
||||||
<ActionButton action={Actions.AddToAlbum} />
|
<ActionButton action={Actions.AddToAlbum} />
|
||||||
|
|||||||
+1
-1
@@ -459,7 +459,7 @@
|
|||||||
<header>
|
<header>
|
||||||
{#if assetMultiSelectManager.selectionActive}
|
{#if assetMultiSelectManager.selectionActive}
|
||||||
<AssetSelectControlBar>
|
<AssetSelectControlBar>
|
||||||
{@const Actions = getAssetBulkActions($t, assetMultiSelectManager.asControlContext())}
|
{@const Actions = getAssetBulkActions($t)}
|
||||||
<CommandPaletteDefaultProvider name={$t('assets')} actions={Object.values(Actions)} />
|
<CommandPaletteDefaultProvider name={$t('assets')} actions={Object.values(Actions)} />
|
||||||
<CreateSharedLink />
|
<CreateSharedLink />
|
||||||
<SelectAllAssets {timelineManager} assetInteraction={assetMultiSelectManager} />
|
<SelectAllAssets {timelineManager} assetInteraction={assetMultiSelectManager} />
|
||||||
|
|||||||
@@ -113,7 +113,7 @@
|
|||||||
|
|
||||||
{#if assetMultiSelectManager.selectionActive}
|
{#if assetMultiSelectManager.selectionActive}
|
||||||
<AssetSelectControlBar>
|
<AssetSelectControlBar>
|
||||||
{@const Actions = getAssetBulkActions($t, assetMultiSelectManager.asControlContext())}
|
{@const Actions = getAssetBulkActions($t)}
|
||||||
<CommandPaletteDefaultProvider name={$t('assets')} actions={Object.values(Actions)} />
|
<CommandPaletteDefaultProvider name={$t('assets')} actions={Object.values(Actions)} />
|
||||||
|
|
||||||
<CreateSharedLink />
|
<CreateSharedLink />
|
||||||
|
|||||||
@@ -319,7 +319,7 @@
|
|||||||
{#if assetMultiSelectManager.selectionActive}
|
{#if assetMultiSelectManager.selectionActive}
|
||||||
<div class="fixed top-0 start-0 w-full z-2">
|
<div class="fixed top-0 start-0 w-full z-2">
|
||||||
<AssetSelectControlBar>
|
<AssetSelectControlBar>
|
||||||
{@const Actions = getAssetBulkActions($t, assetMultiSelectManager.asControlContext())}
|
{@const Actions = getAssetBulkActions($t)}
|
||||||
<CommandPaletteDefaultProvider name={$t('assets')} actions={Object.values(Actions)} />
|
<CommandPaletteDefaultProvider name={$t('assets')} actions={Object.values(Actions)} />
|
||||||
|
|
||||||
<CreateSharedLink />
|
<CreateSharedLink />
|
||||||
|
|||||||
@@ -114,7 +114,7 @@
|
|||||||
{#if assetMultiSelectManager.selectionActive}
|
{#if assetMultiSelectManager.selectionActive}
|
||||||
<div class="fixed top-0 start-0 w-full">
|
<div class="fixed top-0 start-0 w-full">
|
||||||
<AssetSelectControlBar>
|
<AssetSelectControlBar>
|
||||||
{@const Actions = getAssetBulkActions($t, assetMultiSelectManager.asControlContext())}
|
{@const Actions = getAssetBulkActions($t)}
|
||||||
<CommandPaletteDefaultProvider name={$t('assets')} actions={Object.values(Actions)} />
|
<CommandPaletteDefaultProvider name={$t('assets')} actions={Object.values(Actions)} />
|
||||||
<CreateSharedLink />
|
<CreateSharedLink />
|
||||||
<SelectAllAssets {timelineManager} assetInteraction={assetMultiSelectManager} />
|
<SelectAllAssets {timelineManager} assetInteraction={assetMultiSelectManager} />
|
||||||
|
|||||||
Reference in New Issue
Block a user