You've already forked immich
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:
@ -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>
|
||||
|
@ -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}
|
||||
|
@ -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}
|
||||
|
@ -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>
|
||||
|
@ -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">
|
||||
|
@ -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}
|
||||
|
@ -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}
|
||||
|
@ -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}
|
||||
|
@ -139,5 +139,5 @@
|
||||
duration={$slideshowDelay}
|
||||
bind:this={progressBar}
|
||||
bind:status={progressBarStatus}
|
||||
on:done={handleDone}
|
||||
onDone={handleDone}
|
||||
/>
|
||||
|
@ -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;
|
||||
|
@ -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}
|
||||
|
Reference in New Issue
Block a user