1
0
mirror of https://github.com/immich-app/immich.git synced 2024-12-25 10:43:13 +02:00

Update code to svelte 5 and perform cleanup

This commit is contained in:
Toni 2024-11-27 18:50:33 +01:00
parent fafce901aa
commit 3353134ab7
No known key found for this signature in database
GPG Key ID: 159A266B4318F208
4 changed files with 133 additions and 89 deletions

View File

@ -4,42 +4,61 @@
import { getAssetThumbnailUrl } from '$lib/utils';
import { getAssetResolution, getFileSize } from '$lib/utils/asset-utils';
import { getAltText } from '$lib/utils/thumbnail-util';
import { getAllAlbums, type AssetResponseDto } from '@immich/sdk';
import { getAllAlbums, type AssetResponseDto, type AlbumResponseDto } from '@immich/sdk';
import { mdiHeart, mdiMagnifyPlus, mdiImageMultipleOutline, mdiArchiveArrowDownOutline } from '@mdi/js';
import { t } from 'svelte-i18n';
import { fromDateTimeOriginal, fromLocalDateTime } from '$lib/utils/timeline-util';
import { locale } from '$lib/stores/preferences.store';
import type { SelectedSyncData } from '$lib/components/utilities-page/duplicates/duplicates-compare-control.svelte';
import { DateTime } from 'luxon';
interface Props {
asset: AssetResponseDto;
descriptionHeight: number;
isSelected: boolean;
isSynchronizeAlbumsActive: boolean;
isSynchronizeFavoritesActive: boolean;
isSynchronizeArchivesActive: boolean;
locationHeight: number;
selectedSyncData: SelectedSyncData;
onSelectAsset: (asset: AssetResponseDto) => void;
onViewAsset: (asset: AssetResponseDto) => void;
onSelectDate: (dateTime: DateTime) => void;
onSelectDescription: (description: string) => void;
onSelectLocation: (location: SelectedSyncData['location']) => void;
setAlbums: (albums: AlbumResponseDto[]) => void;
setDescriptionHeight: (height: number) => void;
setLocationHeight: (height: number) => void;
}
let { asset, isSelected, onSelectAsset, onViewAsset }: Props = $props();
let {
asset,
descriptionHeight,
isSelected,
isSynchronizeAlbumsActive,
isSynchronizeFavoritesActive,
isSynchronizeArchivesActive,
locationHeight,
selectedSyncData,
onSelectAsset,
onViewAsset,
onSelectDate,
onSelectDescription,
onSelectLocation,
setAlbums,
setDescriptionHeight,
setLocationHeight,
}: Props = $props();
let isFromExternalLibrary = $derived(!!asset.libraryId);
let assetData = $derived(JSON.stringify(asset, null, 2));
export let selectedSyncData;
export let onSelectDate: (dateTime) => void;
export let onSelectDescription: (description) => void;
export let onSelectLocation: (location) => void;
export let descriptionHeight;
export let setDescriptionHeight: (height) => void;
export let locationHeight;
export let setLocationHeight: (height) => void;
export let isSynchronizeAlbumsActive: boolean;
export let isSynchronizeFavoritesActive: boolean;
export let isSynchronizeArchivesActive: boolean;
export let setAlbums: (albums) => void;
selectedSyncData.isFavorite = selectedSyncData.isFavorite || asset.isFavorite;
selectedSyncData.isArchived = selectedSyncData.isArchived || asset.isArchived;
let descriptionItem;
let locationItem;
let albums = [];
let descriptionItem = $state<HTMLButtonElement>();
let locationItem = $state<HTMLButtonElement>();
let albums: AlbumResponseDto[] = $state([]);
onMount(async () => {
setDescriptionHeight(descriptionItem.getBoundingClientRect().height);
setLocationHeight(locationItem.getBoundingClientRect().height);
@ -47,7 +66,7 @@
setAlbums(albums);
});
const getBackgroundColor = (isSelected, syncDataExist, syncIsAssetData) => {
const getBackgroundColor = (isSelected: boolean, syncDataExist: boolean, syncIsAssetData: boolean) => {
let color = 'rounded-xl dark:hover:bg-gray-300';
color += isSelected ? ' hover:bg-gray-300' : ' hover:bg-gray-500';
if (isSelected) {
@ -62,33 +81,39 @@
return color;
};
$: timeZone = asset.exifInfo?.timeZone;
$: dateTime =
let timeZone = $derived(asset.exifInfo?.timeZone);
let dateTime = $derived(
timeZone && asset.exifInfo?.dateTimeOriginal
? fromDateTimeOriginal(asset.exifInfo.dateTimeOriginal, timeZone)
: fromLocalDateTime(asset.localDateTime);
$: description = asset.exifInfo?.description;
$: location = {
: fromLocalDateTime(asset.localDateTime),
);
let description = $derived(asset.exifInfo?.description);
let location = $derived({
latitude: asset.exifInfo?.latitude,
longitude: asset.exifInfo?.longitude,
city: asset.exifInfo?.city,
state: asset.exifInfo?.state,
country: asset.exifInfo?.country,
};
$: displayedDateTime = isSelected && selectedSyncData?.dateTime ? selectedSyncData.dateTime : dateTime;
$: displayedTimeZone = isSelected && selectedSyncData?.timeZone ? selectedSyncData.timeZone : timeZone;
$: displayedLocation = isSelected && selectedSyncData?.location ? selectedSyncData.location : location;
$: displayedDescription = isSelected && selectedSyncData?.description ? selectedSyncData.description : description;
$: displayedFavorite =
});
let displayedDateTime = $derived(isSelected && selectedSyncData?.dateTime ? selectedSyncData.dateTime : dateTime);
let displayedTimeZone = $derived(isSelected && selectedSyncData?.timeZone ? selectedSyncData.timeZone : timeZone);
let displayedLocation = $derived(isSelected && selectedSyncData?.location ? selectedSyncData.location : location);
let displayedDescription = $derived(
isSelected && selectedSyncData?.description ? selectedSyncData.description : description,
);
let displayedFavorite = $derived(
isSelected && isSynchronizeFavoritesActive && selectedSyncData?.isFavorite
? selectedSyncData.isFavorite
: asset.isFavorite;
$: displayedArchived =
: asset.isFavorite,
);
let displayedArchived = $derived(
isSelected && isSynchronizeArchivesActive && selectedSyncData?.isArchived
? selectedSyncData.isArchived
: asset.isArchived;
$: displayedAlbums =
isSelected && isSynchronizeAlbumsActive && selectedSyncData?.albums ? selectedSyncData.albums : albums;
: asset.isArchived,
);
let displayedAlbums = $derived(
isSelected && isSynchronizeAlbumsActive && selectedSyncData?.albums ? selectedSyncData.albums : albums,
);
</script>
<div
@ -196,7 +221,7 @@
type="button"
style="padding: 3px;"
class={getBackgroundColor(isSelected, selectedSyncData?.dateTime, selectedSyncData.dateTime?.ts === dateTime?.ts)}
on:click={() => onSelectDate(displayedDateTime)}
onclick={() => onSelectDate(displayedDateTime)}
>
{displayedDateTime.toLocaleString(
{
@ -222,11 +247,11 @@
style="padding: 3px; {locationHeight ? 'height: ' + locationHeight + 'px' : ''}"
class={getBackgroundColor(
isSelected,
selectedSyncData?.location,
selectedSyncData?.location !== null,
selectedSyncData?.location?.latitude === location.latitude &&
selectedSyncData?.location?.longitude === location.longitude,
)}
on:click={() => onSelectLocation(displayedLocation)}
onclick={() => onSelectLocation(displayedLocation)}
>
{#if displayedLocation?.city}
<div class="text-sm">
@ -246,10 +271,10 @@
style="padding: 3px; {descriptionHeight ? 'height: ' + descriptionHeight + 'px' : ''}"
class={getBackgroundColor(
isSelected,
selectedSyncData?.description,
selectedSyncData?.description !== null,
selectedSyncData?.description === description,
)}
on:click={() => onSelectDescription(displayedDescription)}
onclick={() => onSelectDescription(displayedDescription)}
>
{displayedDescription}
</button>

View File

@ -3,13 +3,24 @@
import SettingSwitch from '$lib/components/shared-components/settings/setting-switch.svelte';
import { t } from 'svelte-i18n';
export let synchronizeAlbums: boolean;
export let synchronizeFavorites: boolean;
export let synchronizeArchives: boolean;
export let onClose: () => void;
export let onToggleSyncAlbum: () => void;
export let onToggleSyncFavorites: () => void;
export let onToggleSyncArchives: () => void;
interface Props {
synchronizeAlbums: boolean;
synchronizeArchives: boolean;
synchronizeFavorites: boolean;
onClose: () => void;
onToggleSyncAlbum: () => void;
onToggleSyncArchives: () => void;
onToggleSyncFavorites: () => void;
}
let {
synchronizeAlbums,
synchronizeArchives,
synchronizeFavorites,
onClose,
onToggleSyncAlbum,
onToggleSyncArchives,
onToggleSyncFavorites,
}: Props = $props();
</script>
<FullScreenModal title={$t('options')} width="auto" {onClose}>

View File

@ -12,31 +12,57 @@
import { onDestroy, onMount } from 'svelte';
import { t } from 'svelte-i18n';
import { SvelteSet } from 'svelte/reactivity';
import { DateTime } from 'luxon';
interface Props {
assets: AssetResponseDto[];
onResolve: (duplicateAssetIds: string[], trashIds: string[], selectedDataToSync) => void;
isSynchronizeAlbumsActive: boolean;
isSynchronizeArchivesActive: boolean;
isSynchronizeFavoritesActive: boolean;
onResolve: (duplicateAssetIds: string[], trashIds: string[], selectedDataToSync: SelectedSyncData) => void;
onStack: (assets: AssetResponseDto[]) => void;
}
let { assets, onResolve, onStack }: Props = $props();
export let isSynchronizeAlbumsActive: boolean;
export let isSynchronizeFavoritesActive: boolean;
export let isSynchronizeArchivesActive: boolean;
let {
assets,
isSynchronizeAlbumsActive,
isSynchronizeArchivesActive,
isSynchronizeFavoritesActive,
onResolve,
onStack,
}: Props = $props();
const { isViewing: showAssetViewer, asset: viewingAsset, setAsset } = assetViewingStore;
const getAssetIndex = (id: string) => assets.findIndex((asset) => asset.id === id);
let descriptionHeight = 0;
let locationHeight = 0;
let descriptionHeight = $state(0);
let locationHeight = $state(0);
let selectedAssetIds = $state(new SvelteSet<string>());
let trashCount = $derived(assets.length - selectedAssetIds.size);
let selectedSyncData = {
export interface SelectedSyncData {
dateTime: DateTime | null;
timeZone: string | null;
description: string | null;
location: {
latitude: number;
longitude: number;
city: string;
state: string;
country: string;
} | null;
albums: AssetResponseDto[];
isArchived: boolean | null;
isFavorite: boolean | null;
}
let selectedSyncData: SelectedSyncData = $state({
dateTime: null,
timeZone: null,
description: null,
location: null,
albums: [],
};
isArchived: null,
isFavorite: null,
});
onMount(() => {
const suggestedAsset = suggestDuplicateByFileSize(assets);
@ -61,37 +87,18 @@
}
};
const onSelectDate = (dateTime) => {
const onSelectDate = (dateTime: DateTime) => {
selectedSyncData.dateTime = selectedSyncData.dateTime?.ts === dateTime.ts ? null : dateTime;
};
const onSelectDescription = (description) => {
const onSelectDescription = (description: string) => {
selectedSyncData.description = selectedSyncData.description === description ? null : description;
};
const onSelectLocation = (location) => {
const onSelectLocation = (location: SelectedSyncData['location']) => {
if (
selectedSyncData.location?.longitude === location.longitude &&
selectedSyncData.location?.latitude === location.latitude
) {
selectedSyncData.location = null;
} else {
selectedSyncData.location = location;
}
};
const onSelectDate = (dateTime) => {
selectedSyncData.dateTime = selectedSyncData.dateTime?.ts === dateTime.ts ? null : dateTime;
};
const onSelectDescription = (description) => {
selectedSyncData.description = selectedSyncData.description === description ? null : description;
};
const onSelectLocation = (location) => {
if (
selectedSyncData.location?.longitude === location.longitude &&
selectedSyncData.location?.latitude === location.latitude
selectedSyncData.location?.longitude === location?.longitude &&
selectedSyncData.location?.latitude === location?.latitude
) {
selectedSyncData.location = null;
} else {

View File

@ -21,17 +21,18 @@
import Icon from '$lib/components/elements/icon.svelte';
import DuplicateOptions from '$lib/components/utilities-page/duplicates/duplicate-options.svelte';
import { locale } from '$lib/stores/preferences.store';
import type { SelectedSyncData } from '$lib/components/utilities-page/duplicates/duplicates-compare-control.svelte';
interface Props {
data: PageData;
isShowKeyboardShortcut?: boolean;
isShowOptions?: boolean;
}
let { data = $bindable(), isShowKeyboardShortcut = $bindable(false) }: Props = $props();
export let isShowOptions = false;
let isSynchronizeAlbumsActive = true;
let isSynchronizeFavoritesActive = true;
let isSynchronizeArchivesActive = true;
let { data = $bindable(), isShowKeyboardShortcut = $bindable(false), isShowOptions }: Props = $props();
let isSynchronizeAlbumsActive = $state(true);
let isSynchronizeFavoritesActive = $state(true);
let isSynchronizeArchivesActive = $state(true);
interface Shortcuts {
general: ExplainedShortcut[];
@ -88,7 +89,7 @@
duplicateId: string,
duplicateAssetIds: string[],
trashIds: string[],
selectedDataToSync,
selectedDataToSync: SelectedSyncData,
) => {
return withConfirmation(
async () => {
@ -112,8 +113,8 @@
assetBulkUpdate.dateTimeOriginal = selectedDataToSync.dateTime;
}
if (selectedDataToSync.location !== null) {
assetBulkUpdate.latitude = selectedDataToSync.location.latitude;
assetBulkUpdate.longitude = selectedDataToSync.location.longitude;
assetBulkUpdate.latitude = selectedDataToSync?.location.latitude;
assetBulkUpdate.longitude = selectedDataToSync?.location.longitude;
}
await deleteAssets({ assetBulkDeleteDto: { ids: trashIds, force: !$featureFlags.trash } });
@ -235,7 +236,7 @@
title={$t('show_keyboard_shortcuts')}
onclick={() => (isShowKeyboardShortcut = !isShowKeyboardShortcut)}
/>
<CircleIconButton icon={mdiCogOutline} title={$t('options')} on:click={() => (isShowOptions = !isShowOptions)} />
<CircleIconButton icon={mdiCogOutline} title={$t('options')} onclick={() => (isShowOptions = !isShowOptions)} />
</div>
{/snippet}