mirror of
https://github.com/immich-app/immich.git
synced 2025-07-07 18:24:10 -04:00
Remove generics from AssetInteraction
This commit is contained in:
parent
9b7e9bc7b8
commit
f3fe043c22
@ -4,7 +4,7 @@
|
||||
import AssetSelectControlBar from '$lib/components/photos-page/asset-select-control-bar.svelte';
|
||||
import { AssetInteraction } from '$lib/stores/asset-interaction.svelte';
|
||||
import { assetViewingStore } from '$lib/stores/asset-viewing.store';
|
||||
import { AssetStore, type TimelineAsset } from '$lib/stores/assets-store.svelte';
|
||||
import { AssetStore } from '$lib/stores/assets-store.svelte';
|
||||
import { dragAndDropFilesStore } from '$lib/stores/drag-and-drop-files.store';
|
||||
import { handlePromiseError } from '$lib/utils';
|
||||
import { cancelMultiselect, downloadAlbum } from '$lib/utils/asset-utils';
|
||||
@ -36,7 +36,7 @@
|
||||
$effect(() => void assetStore.updateOptions({ albumId: album.id, order: album.order }));
|
||||
onDestroy(() => assetStore.destroy());
|
||||
|
||||
const assetInteraction = new AssetInteraction<TimelineAsset>();
|
||||
const assetInteraction = new AssetInteraction();
|
||||
|
||||
dragAndDropFilesStore.subscribe((value) => {
|
||||
if (value.isDragging && value.files.length > 0) {
|
||||
|
@ -3,8 +3,7 @@
|
||||
import CircleIconButton from '$lib/components/elements/buttons/circle-icon-button.svelte';
|
||||
import { getKey } from '$lib/utils';
|
||||
import { downloadArchive, downloadFile } from '$lib/utils/asset-utils';
|
||||
import { isTimelineAsset } from '$lib/utils/timeline-util';
|
||||
import { getAssetInfo, type AssetResponseDto } from '@immich/sdk';
|
||||
import { getAssetInfo } from '@immich/sdk';
|
||||
import { mdiCloudDownloadOutline, mdiFileDownloadOutline, mdiFolderDownloadOutline } from '@mdi/js';
|
||||
import { t } from 'svelte-i18n';
|
||||
import MenuOption from '../../shared-components/context-menu/menu-option.svelte';
|
||||
@ -23,10 +22,7 @@
|
||||
const assets = [...getAssets()];
|
||||
if (assets.length === 1) {
|
||||
clearSelect();
|
||||
let asset: AssetResponseDto = assets[0] as AssetResponseDto;
|
||||
if (isTimelineAsset(assets[0])) {
|
||||
asset = await getAssetInfo({ id: assets[0].id, key: getKey() });
|
||||
}
|
||||
let asset = await getAssetInfo({ id: assets[0].id, key: getKey() });
|
||||
await downloadFile(asset);
|
||||
return;
|
||||
}
|
||||
|
@ -1,6 +1,6 @@
|
||||
<script lang="ts">
|
||||
import CircleIconButton from '$lib/components/elements/buttons/circle-icon-button.svelte';
|
||||
import type { AssetInteraction, BaseInteractionAsset } from '$lib/stores/asset-interaction.svelte';
|
||||
import type { AssetInteraction } from '$lib/stores/asset-interaction.svelte';
|
||||
import { type AssetStore, isSelectingAllAssets } from '$lib/stores/assets-store.svelte';
|
||||
import { cancelMultiselect, selectAllAssets } from '$lib/utils/asset-utils';
|
||||
import { mdiSelectAll, mdiSelectRemove } from '@mdi/js';
|
||||
@ -8,7 +8,7 @@
|
||||
|
||||
interface Props {
|
||||
assetStore: AssetStore;
|
||||
assetInteraction: AssetInteraction<BaseInteractionAsset>;
|
||||
assetInteraction: AssetInteraction;
|
||||
}
|
||||
|
||||
let { assetStore, assetInteraction }: Props = $props();
|
||||
|
@ -11,7 +11,7 @@
|
||||
import { navigate } from '$lib/utils/navigation';
|
||||
import { getDateLocaleString } from '$lib/utils/timeline-util';
|
||||
|
||||
import type { AssetInteraction, BaseInteractionAsset } from '$lib/stores/asset-interaction.svelte';
|
||||
import type { AssetInteraction } from '$lib/stores/asset-interaction.svelte';
|
||||
import { mdiCheckCircle, mdiCircleOutline } from '@mdi/js';
|
||||
import { fly, scale } from 'svelte/transition';
|
||||
import Thumbnail from '../assets/thumbnail/thumbnail.svelte';
|
||||
@ -29,7 +29,7 @@
|
||||
showArchiveIcon: boolean;
|
||||
bucket: AssetBucket;
|
||||
assetStore: AssetStore;
|
||||
assetInteraction: AssetInteraction<BaseInteractionAsset>;
|
||||
assetInteraction: AssetInteraction;
|
||||
|
||||
onSelect: ({ title, assets }: { title: string; assets: TimelineAsset[] }) => void;
|
||||
onSelectAssets: (asset: TimelineAsset) => void;
|
||||
|
@ -41,7 +41,7 @@
|
||||
additionally, update the page location/url with the asset as the asset-grid is scrolled */
|
||||
enableRouting: boolean;
|
||||
assetStore: AssetStore;
|
||||
assetInteraction: AssetInteraction<TimelineAsset>;
|
||||
assetInteraction: AssetInteraction;
|
||||
removeAction?: AssetAction.UNARCHIVE | AssetAction.ARCHIVE | AssetAction.FAVORITE | AssetAction.UNFAVORITE | null;
|
||||
withStacked?: boolean;
|
||||
showArchiveIcon?: boolean;
|
||||
|
@ -4,8 +4,8 @@
|
||||
|
||||
export interface AssetControlContext {
|
||||
// Wrap assets in a function, because context isn't reactive.
|
||||
getAssets: () => BaseInteractionAsset[]; // All assets includes partners' assets
|
||||
getOwnedAssets: () => BaseInteractionAsset[]; // Only assets owned by the user
|
||||
getAssets: () => TimelineAsset[]; // All assets includes partners' assets
|
||||
getOwnedAssets: () => TimelineAsset[]; // Only assets owned by the user
|
||||
clearSelect: () => void;
|
||||
}
|
||||
|
||||
@ -14,13 +14,13 @@
|
||||
</script>
|
||||
|
||||
<script lang="ts">
|
||||
import type { BaseInteractionAsset } from '$lib/stores/asset-interaction.svelte';
|
||||
import type { TimelineAsset } from '$lib/stores/assets-store.svelte';
|
||||
import { mdiClose } from '@mdi/js';
|
||||
import type { Snippet } from 'svelte';
|
||||
import ControlAppBar from '../shared-components/control-app-bar.svelte';
|
||||
|
||||
interface Props {
|
||||
assets: BaseInteractionAsset[];
|
||||
assets: TimelineAsset[];
|
||||
clearSelect: () => void;
|
||||
ownerId?: string | undefined;
|
||||
children?: Snippet;
|
||||
|
@ -1,18 +1,18 @@
|
||||
import { AssetInteraction, type BaseInteractionAsset } from '$lib/stores/asset-interaction.svelte';
|
||||
import { AssetInteraction } from '$lib/stores/asset-interaction.svelte';
|
||||
import { resetSavedUser, user } from '$lib/stores/user.store';
|
||||
import { assetFactory } from '@test-data/factories/asset-factory';
|
||||
import { timelineAssetFactory } from '@test-data/factories/asset-factory';
|
||||
import { userAdminFactory } from '@test-data/factories/user-factory';
|
||||
|
||||
describe('AssetInteraction', () => {
|
||||
let assetInteraction: AssetInteraction<BaseInteractionAsset>;
|
||||
let assetInteraction: AssetInteraction;
|
||||
|
||||
beforeEach(() => {
|
||||
assetInteraction = new AssetInteraction();
|
||||
});
|
||||
|
||||
it('calculates derived values from selection', () => {
|
||||
assetInteraction.selectAsset(assetFactory.build({ isFavorite: true, isArchived: true, isTrashed: true }));
|
||||
assetInteraction.selectAsset(assetFactory.build({ isFavorite: true, isArchived: false, isTrashed: false }));
|
||||
assetInteraction.selectAsset(timelineAssetFactory.build({ isFavorite: true, isArchived: true, isTrashed: true }));
|
||||
assetInteraction.selectAsset(timelineAssetFactory.build({ isFavorite: true, isArchived: false, isTrashed: false }));
|
||||
|
||||
expect(assetInteraction.selectionActive).toBe(true);
|
||||
expect(assetInteraction.isAllTrashed).toBe(false);
|
||||
@ -22,7 +22,7 @@ describe('AssetInteraction', () => {
|
||||
|
||||
it('updates isAllUserOwned when the active user changes', () => {
|
||||
const [user1, user2] = userAdminFactory.buildList(2);
|
||||
assetInteraction.selectAsset(assetFactory.build({ ownerId: user1.id }));
|
||||
assetInteraction.selectAsset(timelineAssetFactory.build({ ownerId: user1.id }));
|
||||
|
||||
const cleanup = $effect.root(() => {
|
||||
expect(assetInteraction.isAllUserOwned).toBe(false);
|
||||
|
@ -3,8 +3,13 @@ import FormatBoldMessage from '$lib/components/i18n/format-bold-message.svelte';
|
||||
import type { InterpolationValues } from '$lib/components/i18n/format-message';
|
||||
import { NotificationType, notificationController } from '$lib/components/shared-components/notification/notification';
|
||||
import { AppRoute } from '$lib/constants';
|
||||
import type { AssetInteraction, BaseInteractionAsset } from '$lib/stores/asset-interaction.svelte';
|
||||
import { assetsSnapshot, isSelectingAllAssets, type AssetStore } from '$lib/stores/assets-store.svelte';
|
||||
import type { AssetInteraction } from '$lib/stores/asset-interaction.svelte';
|
||||
import {
|
||||
assetsSnapshot,
|
||||
isSelectingAllAssets,
|
||||
type AssetStore,
|
||||
type TimelineAsset,
|
||||
} from '$lib/stores/assets-store.svelte';
|
||||
import { downloadManager } from '$lib/stores/download-store.svelte';
|
||||
import { preferences } from '$lib/stores/user.store';
|
||||
import { downloadRequest, getKey, withError } from '$lib/utils';
|
||||
@ -364,7 +369,7 @@ export const getAssetType = (type: AssetTypeEnum) => {
|
||||
}
|
||||
};
|
||||
|
||||
export const getSelectedAssets = (assets: BaseInteractionAsset[], user: UserResponseDto | null): string[] => {
|
||||
export const getSelectedAssets = (assets: TimelineAsset[], user: UserResponseDto | null): string[] => {
|
||||
const ids = [...assets].filter((a) => user && a.ownerId === user.id).map((a) => a.id);
|
||||
|
||||
const numberOfIssues = [...assets].filter((a) => user && a.ownerId !== user.id).length;
|
||||
@ -467,10 +472,7 @@ export const keepThisDeleteOthers = async (keepAsset: AssetResponseDto, stack: S
|
||||
}
|
||||
};
|
||||
|
||||
export const selectAllAssets = async (
|
||||
assetStore: AssetStore,
|
||||
assetInteraction: AssetInteraction<BaseInteractionAsset>,
|
||||
) => {
|
||||
export const selectAllAssets = async (assetStore: AssetStore, assetInteraction: AssetInteraction) => {
|
||||
if (get(isSelectingAllAssets)) {
|
||||
// Selection is already ongoing
|
||||
return;
|
||||
@ -498,7 +500,7 @@ export const selectAllAssets = async (
|
||||
}
|
||||
};
|
||||
|
||||
export const cancelMultiselect = (assetInteraction: AssetInteraction<BaseInteractionAsset>) => {
|
||||
export const cancelMultiselect = (assetInteraction: AssetInteraction) => {
|
||||
isSelectingAllAssets.set(false);
|
||||
assetInteraction.clearMultiselect();
|
||||
};
|
||||
|
@ -38,7 +38,7 @@
|
||||
import { numberOfComments, setNumberOfComments, updateNumberOfComments } from '$lib/stores/activity.store';
|
||||
import { AssetInteraction } from '$lib/stores/asset-interaction.svelte';
|
||||
import { assetViewingStore } from '$lib/stores/asset-viewing.store';
|
||||
import { AssetStore, type TimelineAsset } from '$lib/stores/assets-store.svelte';
|
||||
import { AssetStore } from '$lib/stores/assets-store.svelte';
|
||||
import { SlideshowNavigation, SlideshowState, slideshowStore } from '$lib/stores/slideshow.store';
|
||||
import { preferences, user } from '$lib/stores/user.store';
|
||||
import { handlePromiseError } from '$lib/utils';
|
||||
@ -107,8 +107,8 @@
|
||||
let reactions: ActivityResponseDto[] = $state([]);
|
||||
let albumOrder: AssetOrder | undefined = $state(data.album.order);
|
||||
|
||||
const assetInteraction = new AssetInteraction<TimelineAsset>();
|
||||
const timelineInteraction = new AssetInteraction<TimelineAsset>();
|
||||
const assetInteraction = new AssetInteraction();
|
||||
const timelineInteraction = new AssetInteraction();
|
||||
|
||||
afterNavigate(({ from }) => {
|
||||
let url: string | undefined = from?.url?.pathname;
|
||||
|
@ -14,7 +14,7 @@
|
||||
|
||||
import AssetSelectControlBar from '$lib/components/photos-page/asset-select-control-bar.svelte';
|
||||
import { AssetInteraction } from '$lib/stores/asset-interaction.svelte';
|
||||
import { AssetStore, type TimelineAsset } from '$lib/stores/assets-store.svelte';
|
||||
import { AssetStore } from '$lib/stores/assets-store.svelte';
|
||||
import { mdiDotsVertical, mdiPlus } from '@mdi/js';
|
||||
import { onDestroy } from 'svelte';
|
||||
import { t } from 'svelte-i18n';
|
||||
@ -29,7 +29,7 @@
|
||||
void assetStore.updateOptions({ isArchived: true });
|
||||
onDestroy(() => assetStore.destroy());
|
||||
|
||||
const assetInteraction = new AssetInteraction<TimelineAsset>();
|
||||
const assetInteraction = new AssetInteraction();
|
||||
|
||||
const handleEscape = () => {
|
||||
if (assetInteraction.selectionActive) {
|
||||
|
@ -16,7 +16,7 @@
|
||||
import EmptyPlaceholder from '$lib/components/shared-components/empty-placeholder.svelte';
|
||||
import { AssetAction } from '$lib/constants';
|
||||
import { AssetInteraction } from '$lib/stores/asset-interaction.svelte';
|
||||
import { AssetStore, type TimelineAsset } from '$lib/stores/assets-store.svelte';
|
||||
import { AssetStore } from '$lib/stores/assets-store.svelte';
|
||||
import { preferences } from '$lib/stores/user.store';
|
||||
import { mdiDotsVertical, mdiPlus } from '@mdi/js';
|
||||
import { onDestroy } from 'svelte';
|
||||
@ -33,7 +33,7 @@
|
||||
void assetStore.updateOptions({ isFavorite: true, withStacked: true });
|
||||
onDestroy(() => assetStore.destroy());
|
||||
|
||||
const assetInteraction = new AssetInteraction<TimelineAsset>();
|
||||
const assetInteraction = new AssetInteraction();
|
||||
|
||||
const handleEscape = () => {
|
||||
if (assetInteraction.selectionActive) {
|
||||
|
@ -9,7 +9,7 @@
|
||||
import ControlAppBar from '$lib/components/shared-components/control-app-bar.svelte';
|
||||
import { AppRoute } from '$lib/constants';
|
||||
import { AssetInteraction } from '$lib/stores/asset-interaction.svelte';
|
||||
import { AssetStore, type TimelineAsset } from '$lib/stores/assets-store.svelte';
|
||||
import { AssetStore } from '$lib/stores/assets-store.svelte';
|
||||
import { mdiArrowLeft, mdiPlus } from '@mdi/js';
|
||||
import { onDestroy } from 'svelte';
|
||||
import { t } from 'svelte-i18n';
|
||||
@ -24,7 +24,7 @@
|
||||
const assetStore = new AssetStore();
|
||||
$effect(() => void assetStore.updateOptions({ userId: data.partner.id, isArchived: false, withStacked: true }));
|
||||
onDestroy(() => assetStore.destroy());
|
||||
const assetInteraction = new AssetInteraction<TimelineAsset>();
|
||||
const assetInteraction = new AssetInteraction();
|
||||
|
||||
const handleEscape = () => {
|
||||
if (assetInteraction.selectionActive) {
|
||||
|
@ -71,7 +71,7 @@
|
||||
$effect(() => void assetStore.updateOptions({ isArchived: false, personId: data.person.id }));
|
||||
onDestroy(() => assetStore.destroy());
|
||||
|
||||
const assetInteraction = new AssetInteraction<TimelineAsset>();
|
||||
const assetInteraction = new AssetInteraction();
|
||||
|
||||
let viewMode: PersonPageViewMode = $state(PersonPageViewMode.VIEW_ASSETS);
|
||||
let isEditingName = $state(false);
|
||||
|
@ -17,7 +17,7 @@
|
||||
import TreeItems from '$lib/components/shared-components/tree/tree-items.svelte';
|
||||
import { AppRoute, AssetAction, QueryParameter, SettingInputFieldType } from '$lib/constants';
|
||||
import { AssetInteraction } from '$lib/stores/asset-interaction.svelte';
|
||||
import { AssetStore, type TimelineAsset } from '$lib/stores/assets-store.svelte';
|
||||
import { AssetStore } from '$lib/stores/assets-store.svelte';
|
||||
import { buildTree, normalizeTreePath } from '$lib/utils/tree-utils';
|
||||
import { deleteTag, getAllTags, updateTag, upsertTags, type TagResponseDto } from '@immich/sdk';
|
||||
import { Button, HStack, Text } from '@immich/ui';
|
||||
@ -35,7 +35,7 @@
|
||||
let pathSegments = $derived(data.path ? data.path.split('/') : []);
|
||||
let currentPath = $derived($page.url.searchParams.get(QueryParameter.PATH) || '');
|
||||
|
||||
const assetInteraction = new AssetInteraction<TimelineAsset>();
|
||||
const assetInteraction = new AssetInteraction();
|
||||
|
||||
const buildMap = (tags: TagResponseDto[]) => {
|
||||
return Object.fromEntries(tags.map((tag) => [tag.value, tag]));
|
||||
|
@ -15,7 +15,7 @@
|
||||
} from '$lib/components/shared-components/notification/notification';
|
||||
import { AppRoute } from '$lib/constants';
|
||||
import { AssetInteraction } from '$lib/stores/asset-interaction.svelte';
|
||||
import { AssetStore, type TimelineAsset } from '$lib/stores/assets-store.svelte';
|
||||
import { AssetStore } from '$lib/stores/assets-store.svelte';
|
||||
import { featureFlags, serverConfig } from '$lib/stores/server-config.store';
|
||||
import { handlePromiseError } from '$lib/utils';
|
||||
import { handleError } from '$lib/utils/handle-error';
|
||||
@ -40,7 +40,7 @@
|
||||
void assetStore.updateOptions({ isTrashed: true });
|
||||
onDestroy(() => assetStore.destroy());
|
||||
|
||||
const assetInteraction = new AssetInteraction<TimelineAsset>();
|
||||
const assetInteraction = new AssetInteraction();
|
||||
|
||||
const handleEmptyTrash = async () => {
|
||||
const isConfirmed = await dialogController.show({
|
||||
|
Loading…
x
Reference in New Issue
Block a user