1
0
mirror of https://github.com/immich-app/immich.git synced 2025-06-27 05:11:11 +02:00

chore: migrate away from event dispatcher (#12820)

This commit is contained in:
Daniel Dietzler
2024-09-20 23:02:58 +02:00
committed by GitHub
parent 529d49471f
commit 124eb8251b
72 changed files with 360 additions and 656 deletions

View File

@ -40,8 +40,8 @@
<Portal target="body">
<AlbumSelectionModal
{shared}
on:newAlbum={({ detail }) => handleAddToNewAlbum(detail)}
on:album={({ detail }) => handleAddToAlbum(detail)}
onNewAlbum={handleAddToNewAlbum}
onAlbumClick={handleAddToAlbum}
onClose={() => (showSelectionModal = false)}
/>
</Portal>

View File

@ -82,6 +82,6 @@
{#if showConfirmModal}
<Portal target="body">
<DeleteAssetDialog size={1} on:cancel={() => (showConfirmModal = false)} on:confirm={() => deleteAsset()} />
<DeleteAssetDialog size={1} onCancel={() => (showConfirmModal = false)} onConfirm={deleteAsset} />
</Portal>
{/if}

View File

@ -2,26 +2,22 @@
import { locale } from '$lib/stores/preferences.store';
import type { ActivityResponseDto } from '@immich/sdk';
import { mdiCommentOutline, mdiHeart, mdiHeartOutline } from '@mdi/js';
import { createEventDispatcher } from 'svelte';
import Icon from '../elements/icon.svelte';
export let isLiked: ActivityResponseDto | null;
export let numberOfComments: number | undefined;
export let disabled: boolean;
const dispatch = createEventDispatcher<{
openActivityTab: void;
favorite: void;
}>();
export let onOpenActivityTab: () => void;
export let onFavorite: () => void;
</script>
<div class="w-full flex p-4 text-white items-center justify-center rounded-full gap-5 bg-immich-dark-bg bg-opacity-60">
<button type="button" class={disabled ? 'cursor-not-allowed' : ''} on:click={() => dispatch('favorite')} {disabled}>
<button type="button" class={disabled ? 'cursor-not-allowed' : ''} on:click={onFavorite} {disabled}>
<div class="items-center justify-center">
<Icon path={isLiked ? mdiHeart : mdiHeartOutline} size={24} />
</div>
</button>
<button type="button" on:click={() => dispatch('openActivityTab')}>
<button type="button" on:click={onOpenActivityTab}>
<div class="flex gap-2 items-center justify-center">
<Icon path={mdiCommentOutline} class="scale-x-[-1]" size={24} />
{#if numberOfComments}

View File

@ -17,7 +17,7 @@
} from '@immich/sdk';
import { mdiClose, mdiDotsVertical, mdiHeart, mdiSend, mdiDeleteOutline } from '@mdi/js';
import * as luxon from 'luxon';
import { createEventDispatcher, onMount } from 'svelte';
import { onMount } from 'svelte';
import CircleIconButton from '../elements/buttons/circle-icon-button.svelte';
import LoadingSpinner from '../shared-components/loading-spinner.svelte';
import { NotificationType, notificationController } from '../shared-components/notification/notification';
@ -55,6 +55,10 @@
export let albumOwnerId: string;
export let disabled: boolean;
export let isLiked: ActivityResponseDto | null;
export let onDeleteComment: () => void;
export let onDeleteLike: () => void;
export let onAddComment: () => void;
export let onClose: () => void;
let textArea: HTMLTextAreaElement;
let innerHeight: number;
@ -65,13 +69,6 @@
let message = '';
let isSendingMessage = false;
const dispatch = createEventDispatcher<{
deleteComment: void;
deleteLike: void;
addComment: void;
close: void;
}>();
$: {
if (innerHeight && activityHeight) {
divHeight = innerHeight - activityHeight;
@ -111,9 +108,9 @@
reactions.splice(index, 1);
reactions = reactions;
if (isLiked && reaction.type === ReactionType.Like && reaction.id == isLiked.id) {
dispatch('deleteLike');
onDeleteLike();
} else {
dispatch('deleteComment');
onDeleteComment();
}
const deleteMessages: Record<ReactionType, string> = {
@ -141,7 +138,7 @@
reactions.push(data);
textArea.style.height = '18px';
message = '';
dispatch('addComment');
onAddComment();
// Re-render the activity feed
reactions = reactions;
} catch (error) {
@ -160,7 +157,7 @@
bind:clientHeight={activityHeight}
>
<div class="flex place-items-center gap-2">
<CircleIconButton on:click={() => dispatch('close')} icon={mdiClose} title={$t('close')} />
<CircleIconButton on:click={onClose} icon={mdiClose} title={$t('close')} />
<p class="text-lg text-immich-fg dark:text-immich-dark-fg">{$t('activity')}</p>
</div>

View File

@ -1,16 +1,13 @@
<script lang="ts">
import { getAssetThumbnailUrl } from '$lib/utils';
import { type AlbumResponseDto } from '@immich/sdk';
import { createEventDispatcher } from 'svelte';
import { normalizeSearchString } from '$lib/utils/string-utils.js';
import AlbumListItemDetails from './album-list-item-details.svelte';
const dispatch = createEventDispatcher<{
album: void;
}>();
export let album: AlbumResponseDto;
export let searchQuery = '';
export let onAlbumClick: () => void;
let albumNameArray: string[] = ['', '', ''];
// This part of the code is responsible for splitting album name into 3 parts where part 2 is the search query
@ -29,7 +26,7 @@
<button
type="button"
on:click={() => dispatch('album')}
on:click={onAlbumClick}
class="flex w-full gap-4 px-6 py-2 text-left transition-colors hover:bg-gray-200 dark:hover:bg-gray-700 rounded-xl"
>
<span class="h-12 w-12 shrink-0 rounded-xl bg-slate-300">

View File

@ -32,7 +32,7 @@
type AssetResponseDto,
type StackResponseDto,
} from '@immich/sdk';
import { createEventDispatcher, onDestroy, onMount } from 'svelte';
import { onDestroy, onMount } from 'svelte';
import { t } from 'svelte-i18n';
import { fly } from 'svelte/transition';
import Thumbnail from '../assets/thumbnail/thumbnail.svelte';
@ -56,8 +56,10 @@
export let isShared = false;
export let album: AlbumResponseDto | null = null;
export let onAction: OnAction | undefined = undefined;
let reactions: ActivityResponseDto[] = [];
export let reactions: ActivityResponseDto[] = [];
export let onClose: (dto: { asset: AssetResponseDto }) => void;
export let onNext: () => void;
export let onPrevious: () => void;
const { setAsset } = assetViewingStore;
const {
@ -67,13 +69,6 @@
slideshowState,
} = slideshowStore;
const dispatch = createEventDispatcher<{
action: { type: AssetAction; asset: AssetResponseDto };
close: { asset: AssetResponseDto };
next: void;
previous: void;
}>();
let appearsInAlbums: AlbumResponseDto[] = [];
let shouldPlayMotionPhoto = false;
let sharedLink = getSharedLink();
@ -267,7 +262,7 @@
};
const closeViewer = () => {
dispatch('close', { asset });
onClose({ asset });
};
const closeEditor = () => {
@ -316,7 +311,8 @@
}
e?.stopPropagation();
dispatch(order);
// eslint-disable-next-line @typescript-eslint/no-unused-expressions
order === 'previous' ? onPrevious() : onNext();
};
// const showEditorHandler = () => {
@ -533,8 +529,8 @@
disabled={!album?.isActivityEnabled}
{isLiked}
{numberOfComments}
on:favorite={handleFavorite}
on:openActivityTab={handleOpenActivity}
onFavorite={handleFavorite}
onOpenActivityTab={handleOpenActivity}
/>
</div>
{/if}
@ -555,7 +551,7 @@
class="z-[1002] row-start-1 row-span-4 w-[360px] overflow-y-auto bg-immich-bg transition-all dark:border-l dark:border-l-immich-dark-gray dark:bg-immich-dark-bg"
translate="yes"
>
<DetailPanel {asset} currentAlbum={album} albums={appearsInAlbums} on:close={() => ($isShowDetail = false)} />
<DetailPanel {asset} currentAlbum={album} albums={appearsInAlbums} onClose={() => ($isShowDetail = false)} />
</div>
{/if}
@ -625,10 +621,10 @@
assetId={asset.id}
{isLiked}
bind:reactions
on:addComment={handleAddComment}
on:deleteComment={handleRemoveComment}
on:deleteLike={() => (isLiked = null)}
on:close={() => (isShowActivity = false)}
onAddComment={handleAddComment}
onDeleteComment={handleRemoveComment}
onDeleteLike={() => (isLiked = null)}
onClose={() => (isShowActivity = false)}
/>
</div>
{/if}

View File

@ -81,10 +81,6 @@
{#if isShowChangeLocation}
<Portal>
<ChangeLocation
{asset}
on:confirm={({ detail: gps }) => handleConfirmChangeLocation(gps)}
on:cancel={() => (isShowChangeLocation = false)}
/>
<ChangeLocation {asset} onConfirm={handleConfirmChangeLocation} onCancel={() => (isShowChangeLocation = false)} />
</Portal>
{/if}

View File

@ -36,7 +36,6 @@
mdiPencil,
} from '@mdi/js';
import { DateTime } from 'luxon';
import { createEventDispatcher } from 'svelte';
import { t } from 'svelte-i18n';
import { slide } from 'svelte/transition';
import ImageThumbnail from '../assets/thumbnail/image-thumbnail.svelte';
@ -49,6 +48,7 @@
export let asset: AssetResponseDto;
export let albums: AlbumResponseDto[] = [];
export let currentAlbum: AlbumResponseDto | null = null;
export let onClose: () => void;
const getDimensions = (exifInfo: ExifResponseDto) => {
const { exifImageWidth: width, exifImageHeight: height } = exifInfo;
@ -106,10 +106,6 @@
? fromDateTimeOriginal(asset.exifInfo.dateTimeOriginal, timeZone)
: fromLocalDateTime(asset.localDateTime);
const dispatch = createEventDispatcher<{
close: void;
}>();
const getMegapixel = (width: number, height: number): number | undefined => {
const megapixel = Math.round((height * width) / 1_000_000);
@ -144,7 +140,7 @@
<section class="relative p-2 dark:bg-immich-dark-bg dark:text-immich-dark-fg">
<div class="flex place-items-center gap-2">
<CircleIconButton icon={mdiClose} title={$t('close')} on:click={() => dispatch('close')} />
<CircleIconButton icon={mdiClose} title={$t('close')} on:click={onClose} />
<p class="text-lg text-immich-fg dark:text-immich-dark-fg">{$t('info')}</p>
</div>
@ -332,8 +328,8 @@
<ChangeDate
initialDate={dateTime}
initialTimeZone={timeZone ?? ''}
on:confirm={({ detail: date }) => handleConfirmChangeDate(date)}
on:cancel={() => (isShowChangeDate = false)}
onConfirm={handleConfirmChangeDate}
onCancel={() => (isShowChangeDate = false)}
/>
{/if}
@ -511,9 +507,7 @@
<PersonSidePanel
assetId={asset.id}
assetType={asset.type}
on:close={() => {
showEditFaces = false;
}}
on:refresh={handleRefreshPeople}
onClose={() => (showEditFaces = false)}
onRefresh={handleRefreshPeople}
/>
{/if}

View File

@ -139,5 +139,5 @@
duration={$slideshowDelay}
bind:this={progressBar}
bind:status={progressBarStatus}
on:done={handleDone}
onDone={handleDone}
/>

View File

@ -4,7 +4,7 @@
import { getAssetPlaybackUrl, getAssetThumbnailUrl } from '$lib/utils';
import { handleError } from '$lib/utils/handle-error';
import { AssetMediaSize } from '@immich/sdk';
import { createEventDispatcher, tick } from 'svelte';
import { tick } from 'svelte';
import { swipe } from 'svelte-gestures';
import type { SwipeCustomEvent } from 'svelte-gestures';
import { fade } from 'svelte/transition';
@ -13,8 +13,10 @@
export let assetId: string;
export let loopVideo: boolean;
export let checksum: string;
export let onPreviousAsset: () => void;
export let onNextAsset: () => void;
export let onPreviousAsset: () => void = () => {};
export let onNextAsset: () => void = () => {};
export let onVideoEnded: () => void = () => {};
export let onVideoStarted: () => void = () => {};
let element: HTMLVideoElement | undefined = undefined;
let isVideoLoading = true;
@ -27,12 +29,10 @@
element.load();
}
const dispatch = createEventDispatcher<{ onVideoEnded: void; onVideoStarted: void }>();
const handleCanPlay = async (video: HTMLVideoElement) => {
try {
await video.play();
dispatch('onVideoStarted');
onVideoStarted();
} catch (error) {
if (error instanceof DOMException && error.name === 'NotAllowedError' && !forceMuted) {
await tryForceMutedPlay(video);
@ -75,7 +75,7 @@
use:swipe
on:swipe={onSwipe}
on:canplay={(e) => handleCanPlay(e.currentTarget)}
on:ended={() => dispatch('onVideoEnded')}
on:ended={onVideoEnded}
on:volumechange={(e) => {
if (!forceMuted) {
$videoViewerMuted = e.currentTarget.muted;

View File

@ -15,13 +15,5 @@
{#if projectionType === ProjectionType.EQUIRECTANGULAR}
<PanoramaViewer asset={{ id: assetId, type: AssetTypeEnum.Video }} />
{:else}
<VideoNativeViewer
{loopVideo}
{checksum}
{assetId}
{onPreviousAsset}
{onNextAsset}
on:onVideoEnded
on:onVideoStarted
/>
<VideoNativeViewer {loopVideo} {checksum} {assetId} {onPreviousAsset} {onNextAsset} />
{/if}