Files
immich/web/src/lib/modals/SlideshowSettingsModal.svelte
2025-12-22 18:44:53 +00:00

113 lines
3.8 KiB
Svelte

<script lang="ts">
import type { RenderedOption } from '$lib/elements/Dropdown.svelte';
import { Field, FormModal, HelperText, NumberInput, Switch } from '@immich/ui';
import {
mdiArrowDownThin,
mdiArrowUpThin,
mdiFitToPageOutline,
mdiFitToScreenOutline,
mdiPanorama,
mdiShuffle,
} from '@mdi/js';
import { t } from 'svelte-i18n';
import SettingDropdown from '../components/shared-components/settings/setting-dropdown.svelte';
import { SlideshowLook, SlideshowNavigation, SlideshowState, slideshowStore } from '../stores/slideshow.store';
const {
slideshowDelay,
showProgressBar,
slideshowNavigation,
slideshowLook,
slideshowTransition,
slideshowAutoplay,
slideshowState,
} = slideshowStore;
type Props = {
onClose: () => void;
};
let { onClose }: Props = $props();
// Temporary variables to hold the settings - marked as reactive with $state() but initialized with store values
let tempSlideshowDelay = $state($slideshowDelay);
let tempShowProgressBar = $state($showProgressBar);
let tempSlideshowNavigation = $state($slideshowNavigation);
let tempSlideshowLook = $state($slideshowLook);
let tempSlideshowTransition = $state($slideshowTransition);
let tempSlideshowAutoplay = $state($slideshowAutoplay);
const navigationOptions: Record<SlideshowNavigation, RenderedOption> = {
[SlideshowNavigation.Shuffle]: { icon: mdiShuffle, title: $t('shuffle') },
[SlideshowNavigation.AscendingOrder]: { icon: mdiArrowUpThin, title: $t('backward') },
[SlideshowNavigation.DescendingOrder]: { icon: mdiArrowDownThin, title: $t('forward') },
};
const lookOptions: Record<SlideshowLook, RenderedOption> = {
[SlideshowLook.Contain]: { icon: mdiFitToScreenOutline, title: $t('contain') },
[SlideshowLook.Cover]: { icon: mdiFitToPageOutline, title: $t('cover') },
[SlideshowLook.BlurredBackground]: { icon: mdiPanorama, title: $t('blurred_background') },
};
const handleToggle = <Type extends SlideshowNavigation | SlideshowLook>(
record: RenderedOption,
options: Record<Type, RenderedOption>,
): undefined | Type => {
for (const [key, option] of Object.entries(options)) {
if (option === record) {
return key as Type;
}
}
};
const onSubmit = () => {
$slideshowDelay = tempSlideshowDelay;
$showProgressBar = tempShowProgressBar;
$slideshowNavigation = tempSlideshowNavigation;
$slideshowLook = tempSlideshowLook;
$slideshowTransition = tempSlideshowTransition;
$slideshowAutoplay = tempSlideshowAutoplay;
$slideshowState = SlideshowState.PlaySlideshow;
onClose();
};
</script>
<FormModal size="small" title={$t('slideshow_settings')} {onClose} {onSubmit}>
<div class="flex flex-col gap-4">
<SettingDropdown
title={$t('direction')}
options={Object.values(navigationOptions)}
selectedOption={navigationOptions[tempSlideshowNavigation]}
onToggle={(option) => {
tempSlideshowNavigation = handleToggle(option, navigationOptions) || tempSlideshowNavigation;
}}
/>
<SettingDropdown
title={$t('look')}
options={Object.values(lookOptions)}
selectedOption={lookOptions[tempSlideshowLook]}
onToggle={(option) => {
tempSlideshowLook = handleToggle(option, lookOptions) || tempSlideshowLook;
}}
/>
<Field label={$t('autoplay_slideshow')}>
<Switch bind:checked={tempSlideshowAutoplay} />
</Field>
<Field label={$t('show_progress_bar')}>
<Switch bind:checked={tempShowProgressBar} />
</Field>
<Field label={$t('show_slideshow_transition')}>
<Switch bind:checked={tempSlideshowTransition} />
</Field>
<Field label={$t('duration')}>
<NumberInput min={1} bind:value={tempSlideshowDelay} />
<HelperText>{$t('admin.slideshow_duration_description')}</HelperText>
</Field>
</div>
</FormModal>