mirror of
https://github.com/immich-app/immich
synced 2025-11-07 17:27:20 +00:00
chore: migrate away from event dispatcher (#12820)
This commit is contained in:
parent
529d49471f
commit
124eb8251b
72 changed files with 360 additions and 656 deletions
|
|
@ -2,7 +2,7 @@
|
|||
import Icon from '$lib/components/elements/icon.svelte';
|
||||
import { getAllAlbums, type AlbumResponseDto } from '@immich/sdk';
|
||||
import { mdiPlus } from '@mdi/js';
|
||||
import { createEventDispatcher, onMount } from 'svelte';
|
||||
import { onMount } from 'svelte';
|
||||
import AlbumListItem from '../asset-viewer/album-list-item.svelte';
|
||||
import { normalizeSearchString } from '$lib/utils/string-utils';
|
||||
import FullScreenModal from '$lib/components/shared-components/full-screen-modal.svelte';
|
||||
|
|
@ -11,17 +11,15 @@
|
|||
import { sortAlbums } from '$lib/utils/album-utils';
|
||||
import { albumViewSettings } from '$lib/stores/preferences.store';
|
||||
|
||||
export let onNewAlbum: (search: string) => void;
|
||||
export let onAlbumClick: (album: AlbumResponseDto) => void;
|
||||
|
||||
let albums: AlbumResponseDto[] = [];
|
||||
let recentAlbums: AlbumResponseDto[] = [];
|
||||
let filteredAlbums: AlbumResponseDto[] = [];
|
||||
let loading = true;
|
||||
let search = '';
|
||||
|
||||
const dispatch = createEventDispatcher<{
|
||||
newAlbum: string;
|
||||
album: AlbumResponseDto;
|
||||
}>();
|
||||
|
||||
export let shared: boolean;
|
||||
export let onClose: () => void;
|
||||
|
||||
|
|
@ -40,14 +38,6 @@
|
|||
{ sortBy: $albumViewSettings.sortBy, orderBy: $albumViewSettings.sortOrder },
|
||||
);
|
||||
|
||||
const handleSelect = (album: AlbumResponseDto) => {
|
||||
dispatch('album', album);
|
||||
};
|
||||
|
||||
const handleNew = () => {
|
||||
dispatch('newAlbum', search.length > 0 ? search : '');
|
||||
};
|
||||
|
||||
const getTitle = () => {
|
||||
if (shared) {
|
||||
return $t('add_to_shared_album');
|
||||
|
|
@ -81,7 +71,7 @@
|
|||
<div class="immich-scrollbar overflow-y-auto">
|
||||
<button
|
||||
type="button"
|
||||
on:click={handleNew}
|
||||
on:click={() => onNewAlbum(search)}
|
||||
class="flex w-full items-center gap-4 px-6 py-2 transition-colors hover:bg-gray-200 dark:hover:bg-gray-700 rounded-xl"
|
||||
>
|
||||
<div class="flex h-12 w-12 items-center justify-center">
|
||||
|
|
@ -96,7 +86,7 @@
|
|||
{#if !shared && search.length === 0}
|
||||
<p class="px-5 py-3 text-xs">{$t('recent').toUpperCase()}</p>
|
||||
{#each recentAlbums as album (album.id)}
|
||||
<AlbumListItem {album} on:album={() => handleSelect(album)} />
|
||||
<AlbumListItem {album} onAlbumClick={() => onAlbumClick(album)} />
|
||||
{/each}
|
||||
{/if}
|
||||
|
||||
|
|
@ -106,7 +96,7 @@
|
|||
</p>
|
||||
{/if}
|
||||
{#each filteredAlbums as album (album.id)}
|
||||
<AlbumListItem {album} searchQuery={search} on:album={() => handleSelect(album)} />
|
||||
<AlbumListItem {album} searchQuery={search} onAlbumClick={() => onAlbumClick(album)} />
|
||||
{/each}
|
||||
{:else if albums.length > 0}
|
||||
<p class="px-5 py-1 text-sm">{$t('no_albums_with_name_yet')}</p>
|
||||
|
|
|
|||
|
|
@ -1,5 +1,4 @@
|
|||
<script lang="ts">
|
||||
import { createEventDispatcher } from 'svelte';
|
||||
import { DateTime } from 'luxon';
|
||||
import ConfirmDialog from './dialog/confirm-dialog.svelte';
|
||||
import Combobox from './combobox.svelte';
|
||||
|
|
@ -8,6 +7,8 @@
|
|||
|
||||
export let initialDate: DateTime = DateTime.now();
|
||||
export let initialTimeZone: string = '';
|
||||
export let onCancel: () => void;
|
||||
export let onConfirm: (date: string) => void;
|
||||
|
||||
type ZoneOption = {
|
||||
/**
|
||||
|
|
@ -118,17 +119,10 @@
|
|||
return zoneA.value.localeCompare(zoneB.value, undefined, { sensitivity: 'base' });
|
||||
}
|
||||
|
||||
const dispatch = createEventDispatcher<{
|
||||
cancel: void;
|
||||
confirm: string;
|
||||
}>();
|
||||
|
||||
const handleCancel = () => dispatch('cancel');
|
||||
|
||||
const handleConfirm = () => {
|
||||
const value = date.toISO();
|
||||
if (value) {
|
||||
dispatch('confirm', value);
|
||||
onConfirm(value);
|
||||
}
|
||||
};
|
||||
</script>
|
||||
|
|
@ -139,7 +133,7 @@
|
|||
prompt="Please select a new date:"
|
||||
disabled={!date.isValid}
|
||||
onConfirm={handleConfirm}
|
||||
onCancel={handleCancel}
|
||||
{onCancel}
|
||||
>
|
||||
<div class="flex flex-col text-left gap-2" slot="prompt">
|
||||
<div class="flex flex-col">
|
||||
|
|
|
|||
|
|
@ -1,5 +1,4 @@
|
|||
<script lang="ts">
|
||||
import { createEventDispatcher } from 'svelte';
|
||||
import ConfirmDialog from './dialog/confirm-dialog.svelte';
|
||||
import { timeDebounceOnSearch } from '$lib/constants';
|
||||
import { handleError } from '$lib/utils/handle-error';
|
||||
|
|
@ -14,13 +13,15 @@
|
|||
import { t } from 'svelte-i18n';
|
||||
import CoordinatesInput from '$lib/components/shared-components/coordinates-input.svelte';
|
||||
|
||||
export let asset: AssetResponseDto | undefined = undefined;
|
||||
|
||||
interface Point {
|
||||
lng: number;
|
||||
lat: number;
|
||||
}
|
||||
|
||||
export let asset: AssetResponseDto | undefined = undefined;
|
||||
export let onCancel: () => void;
|
||||
export let onConfirm: (point: Point) => void;
|
||||
|
||||
let places: PlacesResponseDto[] = [];
|
||||
let suggestedPlaces: PlacesResponseDto[] = [];
|
||||
let searchWord: string;
|
||||
|
|
@ -30,11 +31,6 @@
|
|||
let hideSuggestion = false;
|
||||
let addClipMapMarker: (long: number, lat: number) => void;
|
||||
|
||||
const dispatch = createEventDispatcher<{
|
||||
cancel: void;
|
||||
confirm: Point;
|
||||
}>();
|
||||
|
||||
$: lat = asset?.exifInfo?.latitude ?? undefined;
|
||||
$: lng = asset?.exifInfo?.longitude ?? undefined;
|
||||
$: zoom = lat !== undefined && lng !== undefined ? 12.5 : 1;
|
||||
|
|
@ -50,17 +46,11 @@
|
|||
|
||||
let point: Point | null = null;
|
||||
|
||||
const handleCancel = () => dispatch('cancel');
|
||||
|
||||
const handleSelect = (selected: Point) => {
|
||||
point = selected;
|
||||
};
|
||||
|
||||
const handleConfirm = () => {
|
||||
if (point) {
|
||||
dispatch('confirm', point);
|
||||
onConfirm(point);
|
||||
} else {
|
||||
dispatch('cancel');
|
||||
onCancel();
|
||||
}
|
||||
};
|
||||
|
||||
|
|
@ -108,13 +98,7 @@
|
|||
};
|
||||
</script>
|
||||
|
||||
<ConfirmDialog
|
||||
confirmColor="primary"
|
||||
title={$t('change_location')}
|
||||
width="wide"
|
||||
onConfirm={handleConfirm}
|
||||
onCancel={handleCancel}
|
||||
>
|
||||
<ConfirmDialog confirmColor="primary" title={$t('change_location')} width="wide" onConfirm={handleConfirm} {onCancel}>
|
||||
<div slot="prompt" class="flex flex-col w-full h-full gap-2">
|
||||
<div
|
||||
class="relative w-64 sm:w-96"
|
||||
|
|
@ -126,10 +110,8 @@
|
|||
placeholder={$t('search_places')}
|
||||
bind:name={searchWord}
|
||||
{showLoadingSpinner}
|
||||
on:reset={() => {
|
||||
suggestedPlaces = [];
|
||||
}}
|
||||
on:search={handleSearchPlaces}
|
||||
onReset={() => (suggestedPlaces = [])}
|
||||
onSearch={handleSearchPlaces}
|
||||
roundedBottom={suggestedPlaces.length === 0 || hideSuggestion}
|
||||
/>
|
||||
</button>
|
||||
|
|
@ -180,7 +162,7 @@
|
|||
center={lat && lng ? { lat, lng } : undefined}
|
||||
simplified={true}
|
||||
clickable={true}
|
||||
on:clickedPoint={({ detail: point }) => handleSelect(point)}
|
||||
onClickPoint={(selected) => (point = selected)}
|
||||
/>
|
||||
{/await}
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -21,7 +21,7 @@
|
|||
import { fly } from 'svelte/transition';
|
||||
import Icon from '$lib/components/elements/icon.svelte';
|
||||
import { mdiMagnify, mdiUnfoldMoreHorizontal, mdiClose } from '@mdi/js';
|
||||
import { createEventDispatcher, tick } from 'svelte';
|
||||
import { tick } from 'svelte';
|
||||
import type { FormEventHandler } from 'svelte/elements';
|
||||
import { shortcuts } from '$lib/actions/shortcut';
|
||||
import { focusOutside } from '$lib/actions/focus-outside';
|
||||
|
|
@ -35,6 +35,7 @@
|
|||
export let options: ComboBoxOption[] = [];
|
||||
export let selectedOption: ComboBoxOption | undefined = undefined;
|
||||
export let placeholder = '';
|
||||
export let onSelect: (option: ComboBoxOption | undefined) => void = () => {};
|
||||
|
||||
/**
|
||||
* Unique identifier for the combobox.
|
||||
|
|
@ -61,10 +62,6 @@
|
|||
searchQuery = selectedOption ? selectedOption.label : '';
|
||||
}
|
||||
|
||||
const dispatch = createEventDispatcher<{
|
||||
select: ComboBoxOption | undefined;
|
||||
}>();
|
||||
|
||||
const activate = () => {
|
||||
isActive = true;
|
||||
searchQuery = '';
|
||||
|
|
@ -105,10 +102,10 @@
|
|||
optionRefs[0]?.scrollIntoView({ block: 'nearest' });
|
||||
};
|
||||
|
||||
let onSelect = (option: ComboBoxOption) => {
|
||||
let handleSelect = (option: ComboBoxOption) => {
|
||||
selectedOption = option;
|
||||
searchQuery = option.label;
|
||||
dispatch('select', option);
|
||||
onSelect(option);
|
||||
closeDropdown();
|
||||
};
|
||||
|
||||
|
|
@ -117,7 +114,7 @@
|
|||
selectedIndex = undefined;
|
||||
selectedOption = undefined;
|
||||
searchQuery = '';
|
||||
dispatch('select', selectedOption);
|
||||
onSelect(selectedOption);
|
||||
};
|
||||
</script>
|
||||
|
||||
|
|
@ -188,7 +185,7 @@
|
|||
shortcut: { key: 'Enter' },
|
||||
onShortcut: () => {
|
||||
if (selectedIndex !== undefined && filteredOptions.length > 0) {
|
||||
onSelect(filteredOptions[selectedIndex]);
|
||||
handleSelect(filteredOptions[selectedIndex]);
|
||||
}
|
||||
closeDropdown();
|
||||
},
|
||||
|
|
@ -245,7 +242,7 @@
|
|||
bind:this={optionRefs[index]}
|
||||
class="text-left w-full px-4 py-2 hover:bg-gray-100 dark:hover:bg-gray-700 transition-all cursor-pointer aria-selected:bg-gray-100 aria-selected:dark:bg-gray-700"
|
||||
id={`${listboxId}-${index}`}
|
||||
on:click={() => onSelect(option)}
|
||||
on:click={() => handleSelect(option)}
|
||||
role="option"
|
||||
>
|
||||
{option.label}
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
<script lang="ts">
|
||||
import { browser } from '$app/environment';
|
||||
|
||||
import { createEventDispatcher, onDestroy, onMount } from 'svelte';
|
||||
import { onDestroy, onMount } from 'svelte';
|
||||
import CircleIconButton from '../elements/buttons/circle-icon-button.svelte';
|
||||
import { fly } from 'svelte/transition';
|
||||
import { mdiClose } from '@mdi/js';
|
||||
|
|
@ -12,13 +12,10 @@
|
|||
export let backIcon = mdiClose;
|
||||
export let tailwindClasses = '';
|
||||
export let forceDark = false;
|
||||
export let onClose: () => void = () => {};
|
||||
|
||||
let appBarBorder = 'bg-immich-bg border border-transparent';
|
||||
|
||||
const dispatch = createEventDispatcher<{
|
||||
close: void;
|
||||
}>();
|
||||
|
||||
const onScroll = () => {
|
||||
if (window.pageYOffset > 80) {
|
||||
appBarBorder = 'border border-gray-200 bg-gray-50 dark:border-gray-600';
|
||||
|
|
@ -33,7 +30,7 @@
|
|||
|
||||
const handleClose = () => {
|
||||
$isSelectingAllAssets = false;
|
||||
dispatch('close');
|
||||
onClose();
|
||||
};
|
||||
|
||||
onMount(() => {
|
||||
|
|
|
|||
|
|
@ -7,7 +7,6 @@
|
|||
import { handleError } from '$lib/utils/handle-error';
|
||||
import { SharedLinkType, createSharedLink, updateSharedLink, type SharedLinkResponseDto } from '@immich/sdk';
|
||||
import { mdiContentCopy, mdiLink } from '@mdi/js';
|
||||
import { createEventDispatcher } from 'svelte';
|
||||
import { NotificationType, notificationController } from '../notification/notification';
|
||||
import SettingInputField, { SettingInputFieldType } from '../settings/setting-input-field.svelte';
|
||||
import SettingSwitch from '../settings/setting-switch.svelte';
|
||||
|
|
@ -21,6 +20,7 @@
|
|||
export let albumId: string | undefined = undefined;
|
||||
export let assetIds: string[] = [];
|
||||
export let editingLink: SharedLinkResponseDto | undefined = undefined;
|
||||
export let onCreated: () => void = () => {};
|
||||
|
||||
let sharedLink: string | null = null;
|
||||
let description = '';
|
||||
|
|
@ -32,10 +32,6 @@
|
|||
let shouldChangeExpirationTime = false;
|
||||
let enablePassword = false;
|
||||
|
||||
const dispatch = createEventDispatcher<{
|
||||
created: void;
|
||||
}>();
|
||||
|
||||
const expirationOptions: [number, Intl.RelativeTimeFormatUnit][] = [
|
||||
[30, 'minutes'],
|
||||
[1, 'hour'],
|
||||
|
|
@ -97,7 +93,7 @@
|
|||
},
|
||||
});
|
||||
sharedLink = makeSharedLinkUrl($serverConfig.externalDomain, data.key);
|
||||
dispatch('created');
|
||||
onCreated();
|
||||
} catch (error) {
|
||||
handleError(error, $t('errors.failed_to_create_shared_link'));
|
||||
}
|
||||
|
|
|
|||
|
|
@ -163,9 +163,9 @@
|
|||
<AssetViewer
|
||||
asset={$viewingAsset}
|
||||
onAction={handleAction}
|
||||
on:previous={handlePrevious}
|
||||
on:next={handleNext}
|
||||
on:close={() => {
|
||||
onPrevious={handlePrevious}
|
||||
onNext={handleNext}
|
||||
onClose={() => {
|
||||
assetViewingStore.showAssetViewer(false);
|
||||
handlePromiseError(navigate({ targetRoute: 'current', assetId: null }));
|
||||
}}
|
||||
|
|
|
|||
|
|
@ -13,7 +13,6 @@
|
|||
import type { Feature, GeoJsonProperties, Geometry, Point } from 'geojson';
|
||||
import type { GeoJSONSource, LngLatLike, StyleSpecification } from 'maplibre-gl';
|
||||
import maplibregl from 'maplibre-gl';
|
||||
import { createEventDispatcher } from 'svelte';
|
||||
import { t } from 'svelte-i18n';
|
||||
import {
|
||||
AttributionControl,
|
||||
|
|
@ -52,6 +51,8 @@
|
|||
}
|
||||
|
||||
export let onOpenInMapView: (() => Promise<void> | void) | undefined = undefined;
|
||||
export let onSelect: (assetIds: string[]) => void = () => {};
|
||||
export let onClickPoint: ({ lat, lng }: { lat: number; lng: number }) => void = () => {};
|
||||
|
||||
let map: maplibregl.Map;
|
||||
let marker: maplibregl.Marker | null = null;
|
||||
|
|
@ -62,16 +63,11 @@
|
|||
key: getKey(),
|
||||
}) as Promise<StyleSpecification>)();
|
||||
|
||||
const dispatch = createEventDispatcher<{
|
||||
selected: string[];
|
||||
clickedPoint: { lat: number; lng: number };
|
||||
}>();
|
||||
|
||||
function handleAssetClick(assetId: string, map: Map | null) {
|
||||
if (!map) {
|
||||
return;
|
||||
}
|
||||
dispatch('selected', [assetId]);
|
||||
onSelect([assetId]);
|
||||
}
|
||||
|
||||
async function handleClusterClick(clusterId: number, map: Map | null) {
|
||||
|
|
@ -82,13 +78,13 @@
|
|||
const mapSource = map?.getSource('geojson') as GeoJSONSource;
|
||||
const leaves = await mapSource.getClusterLeaves(clusterId, 10_000, 0);
|
||||
const ids = leaves.map((leaf) => leaf.properties?.id);
|
||||
dispatch('selected', ids);
|
||||
onSelect(ids);
|
||||
}
|
||||
|
||||
function handleMapClick(event: maplibregl.MapMouseEvent) {
|
||||
if (clickable) {
|
||||
const { lng, lat } = event.lngLat;
|
||||
dispatch('clickedPoint', { lng, lat });
|
||||
onClickPoint({ lng, lat });
|
||||
|
||||
if (marker) {
|
||||
marker.remove();
|
||||
|
|
|
|||
|
|
@ -9,19 +9,16 @@
|
|||
import { handleError } from '$lib/utils/handle-error';
|
||||
import { deleteProfileImage, updateMyPreferences, type UserAvatarColor } from '@immich/sdk';
|
||||
import { mdiCog, mdiLogout, mdiPencil, mdiWrench } from '@mdi/js';
|
||||
import { createEventDispatcher } from 'svelte';
|
||||
import { t } from 'svelte-i18n';
|
||||
import { fade } from 'svelte/transition';
|
||||
import { NotificationType, notificationController } from '../notification/notification';
|
||||
import UserAvatar from '../user-avatar.svelte';
|
||||
import AvatarSelector from './avatar-selector.svelte';
|
||||
|
||||
let isShowSelectAvatar = false;
|
||||
export let onLogout: () => void;
|
||||
export let onClose: () => void = () => {};
|
||||
|
||||
const dispatch = createEventDispatcher<{
|
||||
logout: void;
|
||||
close: void;
|
||||
}>();
|
||||
let isShowSelectAvatar = false;
|
||||
|
||||
const handleSaveProfile = async (color: UserAvatarColor) => {
|
||||
try {
|
||||
|
|
@ -75,14 +72,7 @@
|
|||
</div>
|
||||
|
||||
<div class="flex flex-col gap-1">
|
||||
<Button
|
||||
href={AppRoute.USER_SETTINGS}
|
||||
on:click={() => dispatch('close')}
|
||||
color="dark-gray"
|
||||
size="sm"
|
||||
shadow={false}
|
||||
border
|
||||
>
|
||||
<Button href={AppRoute.USER_SETTINGS} on:click={onClose} color="dark-gray" size="sm" shadow={false} border>
|
||||
<div class="flex place-content-center place-items-center text-center gap-2 px-2">
|
||||
<Icon path={mdiCog} size="18" ariaHidden />
|
||||
{$t('account_settings')}
|
||||
|
|
@ -91,7 +81,7 @@
|
|||
{#if $user.isAdmin}
|
||||
<Button
|
||||
href={AppRoute.ADMIN_USER_MANAGEMENT}
|
||||
on:click={() => dispatch('close')}
|
||||
on:click={onClose}
|
||||
color="dark-gray"
|
||||
size="sm"
|
||||
shadow={false}
|
||||
|
|
@ -111,7 +101,7 @@
|
|||
<button
|
||||
type="button"
|
||||
class="flex w-full place-content-center place-items-center gap-2 py-3 font-medium text-gray-500 hover:bg-immich-primary/10 dark:text-gray-300"
|
||||
on:click={() => dispatch('logout')}
|
||||
on:click={onLogout}
|
||||
>
|
||||
<Icon path={mdiLogout} size={24} />
|
||||
{$t('sign_out')}</button
|
||||
|
|
|
|||
|
|
@ -10,7 +10,6 @@
|
|||
import { handleLogout } from '$lib/utils/auth';
|
||||
import { logout } from '@immich/sdk';
|
||||
import { mdiMagnify, mdiTrayArrowUp } from '@mdi/js';
|
||||
import { createEventDispatcher } from 'svelte';
|
||||
import { t } from 'svelte-i18n';
|
||||
import { fade } from 'svelte/transition';
|
||||
import { AppRoute } from '../../../constants';
|
||||
|
|
@ -21,13 +20,11 @@
|
|||
import AccountInfoPanel from './account-info-panel.svelte';
|
||||
|
||||
export let showUploadButton = true;
|
||||
export let onUploadClick: () => void;
|
||||
|
||||
let shouldShowAccountInfo = false;
|
||||
let shouldShowAccountInfoPanel = false;
|
||||
let innerWidth: number;
|
||||
const dispatch = createEventDispatcher<{
|
||||
uploadClicked: void;
|
||||
}>();
|
||||
|
||||
const onLogout = async () => {
|
||||
const { redirectUri } = await logout();
|
||||
|
|
@ -67,14 +64,14 @@
|
|||
<ThemeButton padding="2" />
|
||||
|
||||
{#if !$page.url.pathname.includes('/admin') && showUploadButton}
|
||||
<LinkButton on:click={() => dispatch('uploadClicked')} class="hidden lg:block">
|
||||
<LinkButton on:click={onUploadClick} class="hidden lg:block">
|
||||
<div class="flex gap-2">
|
||||
<Icon path={mdiTrayArrowUp} size="1.5em" />
|
||||
<span>{$t('upload')}</span>
|
||||
</div>
|
||||
</LinkButton>
|
||||
<CircleIconButton
|
||||
on:click={() => dispatch('uploadClicked')}
|
||||
on:click={onUploadClick}
|
||||
title={$t('upload')}
|
||||
icon={mdiTrayArrowUp}
|
||||
class="lg:hidden"
|
||||
|
|
@ -114,7 +111,7 @@
|
|||
{/if}
|
||||
|
||||
{#if shouldShowAccountInfoPanel}
|
||||
<AccountInfoPanel on:logout={onLogout} />
|
||||
<AccountInfoPanel {onLogout} />
|
||||
{/if}
|
||||
</div>
|
||||
</section>
|
||||
|
|
|
|||
|
|
@ -8,7 +8,7 @@
|
|||
<script lang="ts">
|
||||
import { handlePromiseError } from '$lib/utils';
|
||||
|
||||
import { createEventDispatcher, onMount } from 'svelte';
|
||||
import { onMount } from 'svelte';
|
||||
import { tweened } from 'svelte/motion';
|
||||
|
||||
/**
|
||||
|
|
@ -26,6 +26,10 @@
|
|||
|
||||
export let duration = 5;
|
||||
|
||||
export let onDone: () => void;
|
||||
export let onPlaying: () => void = () => {};
|
||||
export let onPaused: () => void = () => {};
|
||||
|
||||
const onChange = async () => {
|
||||
progress = setDuration(duration);
|
||||
await play();
|
||||
|
|
@ -39,16 +43,10 @@
|
|||
|
||||
$: {
|
||||
if ($progress === 1) {
|
||||
dispatch('done');
|
||||
onDone();
|
||||
}
|
||||
}
|
||||
|
||||
const dispatch = createEventDispatcher<{
|
||||
done: void;
|
||||
playing: void;
|
||||
paused: void;
|
||||
}>();
|
||||
|
||||
onMount(async () => {
|
||||
if (autoplay) {
|
||||
await play();
|
||||
|
|
@ -57,13 +55,13 @@
|
|||
|
||||
export const play = async () => {
|
||||
status = ProgressBarStatus.Playing;
|
||||
dispatch('playing');
|
||||
onPlaying();
|
||||
await progress.set(1);
|
||||
};
|
||||
|
||||
export const pause = async () => {
|
||||
status = ProgressBarStatus.Paused;
|
||||
dispatch('paused');
|
||||
onPaused();
|
||||
await progress.set($progress);
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -43,7 +43,7 @@
|
|||
icon: option.icon,
|
||||
};
|
||||
}}
|
||||
on:select={({ detail }) => onToggle(detail)}
|
||||
onSelect={onToggle}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -1,7 +1,6 @@
|
|||
<script lang="ts">
|
||||
import { quintOut } from 'svelte/easing';
|
||||
import { fly } from 'svelte/transition';
|
||||
import { createEventDispatcher } from 'svelte';
|
||||
import { t } from 'svelte-i18n';
|
||||
import Icon from '$lib/components/elements/icon.svelte';
|
||||
import { mdiChevronDown } from '@mdi/js';
|
||||
|
|
@ -14,15 +13,14 @@
|
|||
export let isEdited = false;
|
||||
export let number = false;
|
||||
export let disabled = false;
|
||||
|
||||
const dispatch = createEventDispatcher<{ select: string | number }>();
|
||||
export let onSelect: (setting: string | number) => void = () => {};
|
||||
|
||||
const handleChange = (e: Event) => {
|
||||
value = (e.target as HTMLInputElement).value;
|
||||
if (number) {
|
||||
value = Number.parseInt(value);
|
||||
}
|
||||
dispatch('select', value);
|
||||
onSelect(value);
|
||||
};
|
||||
</script>
|
||||
|
||||
|
|
|
|||
|
|
@ -1,7 +1,6 @@
|
|||
<script lang="ts">
|
||||
import { quintOut } from 'svelte/easing';
|
||||
import { fly } from 'svelte/transition';
|
||||
import { createEventDispatcher } from 'svelte';
|
||||
import Slider from '$lib/components/elements/slider.svelte';
|
||||
import { generateId } from '$lib/utils/generate-id';
|
||||
import { t } from 'svelte-i18n';
|
||||
|
|
@ -11,14 +10,12 @@
|
|||
export let checked = false;
|
||||
export let disabled = false;
|
||||
export let isEdited = false;
|
||||
export let onToggle: (isChecked: boolean) => void = () => {};
|
||||
|
||||
let id: string = generateId();
|
||||
|
||||
$: sliderId = `${id}-slider`;
|
||||
$: subtitleId = subtitle ? `${id}-subtitle` : undefined;
|
||||
|
||||
const dispatch = createEventDispatcher<{ toggle: boolean }>();
|
||||
const onToggle = (isChecked: boolean) => dispatch('toggle', isChecked);
|
||||
</script>
|
||||
|
||||
<div class="flex place-items-center justify-between">
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue