mirror of
https://github.com/immich-app/immich.git
synced 2026-01-28 07:44:56 -08:00
Compare commits
1 Commits
renovate/m
...
refactor/e
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
8388f578f7 |
@@ -5,7 +5,7 @@ export const zoomImageAction = (node: HTMLElement, options?: { disabled?: boolea
|
||||
const zoomInstance = createZoomImageWheel(node, { maxZoom: 10, initialState: assetViewerManager.zoomState });
|
||||
|
||||
const unsubscribes = [
|
||||
assetViewerManager.on('ZoomChange', (state) => zoomInstance.setState(state)),
|
||||
assetViewerManager.on({ ZoomChange: (state) => zoomInstance.setState(state) }),
|
||||
zoomInstance.subscribe(({ state }) => assetViewerManager.onZoomChange(state)),
|
||||
];
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
<script lang="ts">
|
||||
import { assetViewerManager, type Events } from '$lib/managers/asset-viewer-manager.svelte';
|
||||
import type { EventCallback } from '$lib/utils/base-event-manager.svelte';
|
||||
import type { EventCallback, EventMap } from '$lib/utils/base-event-manager.svelte';
|
||||
import { onMount } from 'svelte';
|
||||
|
||||
type Props = {
|
||||
@@ -10,22 +10,17 @@
|
||||
const props: Props = $props();
|
||||
|
||||
onMount(() => {
|
||||
const unsubscribes: Array<() => void> = [];
|
||||
const events: EventMap<Events> = {};
|
||||
|
||||
for (const name of Object.keys(props)) {
|
||||
const event = name.slice(2) as keyof Events;
|
||||
const listener = props[name as keyof Props] as EventCallback<Events, typeof event> | undefined;
|
||||
if (!listener) {
|
||||
continue;
|
||||
for (const [name, listener] of Object.entries(props)) {
|
||||
if (listener) {
|
||||
const event = name.slice(2) as keyof Events;
|
||||
events[event] = listener as EventCallback<Events, typeof event>;
|
||||
}
|
||||
|
||||
unsubscribes.push(assetViewerManager.on(event, listener));
|
||||
}
|
||||
|
||||
return () => {
|
||||
for (const unsubscribe of unsubscribes) {
|
||||
unsubscribe();
|
||||
}
|
||||
};
|
||||
return assetViewerManager.on(events);
|
||||
});
|
||||
</script>
|
||||
|
||||
const event = name.slice(2) as keyof Events;
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
<script lang="ts">
|
||||
import { eventManager, type Events } from '$lib/managers/event-manager.svelte';
|
||||
import type { EventCallback, EventMap } from '$lib/utils/base-event-manager.svelte';
|
||||
import { onMount } from 'svelte';
|
||||
|
||||
type Props = {
|
||||
@@ -9,25 +10,15 @@
|
||||
const props: Props = $props();
|
||||
|
||||
onMount(() => {
|
||||
const unsubscribes: Array<() => void> = [];
|
||||
const events: EventMap<Events> = {};
|
||||
|
||||
for (const name of Object.keys(props)) {
|
||||
const event = name.slice(2) as keyof Events;
|
||||
const listener = props[name as keyof Props];
|
||||
|
||||
if (!listener) {
|
||||
continue;
|
||||
for (const [name, listener] of Object.entries(props)) {
|
||||
if (listener) {
|
||||
const event = name.slice(2) as keyof Events;
|
||||
events[event] = listener as EventCallback<Events, typeof event>;
|
||||
}
|
||||
|
||||
const args = [event, listener as (...args: Events[typeof event]) => void] as const;
|
||||
|
||||
unsubscribes.push(eventManager.on(...args));
|
||||
}
|
||||
|
||||
return () => {
|
||||
for (const unsubscribe of unsubscribes) {
|
||||
unsubscribe();
|
||||
}
|
||||
};
|
||||
return eventManager.on(events);
|
||||
});
|
||||
</script>
|
||||
|
||||
@@ -37,9 +37,11 @@ class AssetCacheManager {
|
||||
#ocrCache = new AsyncCache<AssetOcrResponseDto[]>();
|
||||
|
||||
constructor() {
|
||||
eventManager.on('AssetEditsApplied', () => {
|
||||
this.#assetCache.clear();
|
||||
this.#ocrCache.clear();
|
||||
eventManager.on({
|
||||
AssetEditsApplied: () => {
|
||||
this.#assetCache.clear();
|
||||
this.#ocrCache.clear();
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
@@ -59,7 +59,9 @@ class CastManager {
|
||||
// Add other cast destinations here (ie FCast)
|
||||
];
|
||||
|
||||
eventManager.on('AppInit', () => void this.initialize());
|
||||
eventManager.on({
|
||||
AppInit: () => void this.initialize(),
|
||||
});
|
||||
}
|
||||
|
||||
private async initialize() {
|
||||
|
||||
@@ -5,7 +5,9 @@ class FeatureFlagsManager {
|
||||
#value?: ServerFeaturesDto = $state();
|
||||
|
||||
constructor() {
|
||||
eventManager.on('SystemConfigUpdate', () => void this.#loadFeatureFlags());
|
||||
eventManager.on({
|
||||
SystemConfigUpdate: () => void this.#loadFeatureFlags(),
|
||||
});
|
||||
}
|
||||
|
||||
async init() {
|
||||
|
||||
@@ -4,7 +4,9 @@ import { lang } from '$lib/stores/preferences.store';
|
||||
|
||||
class LanguageManager {
|
||||
constructor() {
|
||||
eventManager.on('AppInit', () => lang.subscribe((lang) => this.setLanguage(lang)));
|
||||
eventManager.on({
|
||||
AppInit: () => lang.subscribe((lang) => this.setLanguage(lang)),
|
||||
});
|
||||
}
|
||||
|
||||
rtl = $state(false);
|
||||
|
||||
@@ -19,7 +19,9 @@ export class QueueManager {
|
||||
}
|
||||
|
||||
constructor() {
|
||||
eventManager.on('QueueUpdate', () => this.refresh());
|
||||
eventManager.on({
|
||||
QueueUpdate: () => this.refresh(),
|
||||
});
|
||||
}
|
||||
|
||||
listen() {
|
||||
|
||||
@@ -5,7 +5,9 @@ class ReleaseManager {
|
||||
value = $state<ReleaseEvent | undefined>();
|
||||
|
||||
constructor() {
|
||||
eventManager.on('ReleaseEvent', (event) => (this.value = event));
|
||||
eventManager.on({
|
||||
ReleaseEvent: (event) => (this.value = event),
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -5,7 +5,9 @@ class ServerConfigManager {
|
||||
#value?: ServerConfigDto = $state();
|
||||
|
||||
constructor() {
|
||||
eventManager.on('SystemConfigUpdate', () => this.loadServerConfig());
|
||||
eventManager.on({
|
||||
SystemConfigUpdate: () => this.loadServerConfig(),
|
||||
});
|
||||
}
|
||||
|
||||
async init() {
|
||||
|
||||
@@ -7,7 +7,9 @@ class SystemConfigManager {
|
||||
#defaultValue?: SystemConfigDto = $state();
|
||||
|
||||
constructor() {
|
||||
eventManager.on('SystemConfigUpdate', (config) => (this.#value = config));
|
||||
eventManager.on({
|
||||
SystemConfigUpdate: (config) => (this.#value = config),
|
||||
});
|
||||
}
|
||||
|
||||
async init() {
|
||||
|
||||
@@ -37,7 +37,9 @@ class ThemeManager {
|
||||
isDark = $derived(this.value === Theme.DARK);
|
||||
|
||||
constructor() {
|
||||
eventManager.on('AppInit', () => this.#onAppInit());
|
||||
eventManager.on({
|
||||
AppInit: () => this.#onAppInit(),
|
||||
});
|
||||
}
|
||||
|
||||
setSystem(system: boolean) {
|
||||
|
||||
@@ -111,9 +111,11 @@ export class TimelineManager extends VirtualScrollManager {
|
||||
constructor() {
|
||||
super();
|
||||
|
||||
const onAssetUpdate = (asset: AssetResponseDto) => this.upsertAssets([toTimelineAsset(asset)]);
|
||||
|
||||
this.#unsubscribes.push(eventManager.on('AssetUpdate', onAssetUpdate));
|
||||
this.#unsubscribes.push(
|
||||
eventManager.on({
|
||||
AssetUpdate: (asset: AssetResponseDto) => this.upsertAssets([toTimelineAsset(asset)]),
|
||||
}),
|
||||
);
|
||||
}
|
||||
|
||||
override get scrollTop(): number {
|
||||
|
||||
@@ -6,7 +6,7 @@ class UploadManager {
|
||||
mediaTypes = $state<ServerMediaTypesResponseDto>({ image: [], sidecar: [], video: [] });
|
||||
|
||||
constructor() {
|
||||
eventManager.onMany({
|
||||
eventManager.on({
|
||||
AppInit: () => this.#loadExtensions(),
|
||||
AuthLogout: () => this.reset(),
|
||||
});
|
||||
|
||||
@@ -19,7 +19,9 @@ class FoldersStore {
|
||||
private assets = $state<AssetCache>({});
|
||||
|
||||
constructor() {
|
||||
eventManager.on('AuthLogout', () => this.clearCache());
|
||||
eventManager.on({
|
||||
AuthLogout: () => this.clearCache(),
|
||||
});
|
||||
}
|
||||
|
||||
async fetchTree(): Promise<TreeNode> {
|
||||
|
||||
@@ -23,7 +23,7 @@ class MemoryStoreSvelte {
|
||||
#loading: Promise<void> | undefined;
|
||||
|
||||
constructor() {
|
||||
eventManager.onMany({
|
||||
eventManager.on({
|
||||
AuthLogout: () => this.clearCache(),
|
||||
AuthUserLoaded: () => this.initialize(),
|
||||
});
|
||||
|
||||
@@ -8,7 +8,7 @@ class NotificationStore {
|
||||
notifications = $state<NotificationDto[]>([]);
|
||||
|
||||
constructor() {
|
||||
eventManager.onMany({
|
||||
eventManager.on({
|
||||
AuthLogin: () => this.refresh(),
|
||||
AuthLogout: () => this.clear(),
|
||||
});
|
||||
|
||||
@@ -5,7 +5,9 @@ class SearchStore {
|
||||
isSearchEnabled = $state(false);
|
||||
|
||||
constructor() {
|
||||
eventManager.on('AuthLogout', () => this.clearCache());
|
||||
eventManager.on({
|
||||
AuthLogout: () => this.clearCache(),
|
||||
});
|
||||
}
|
||||
|
||||
clearCache() {
|
||||
|
||||
@@ -16,4 +16,6 @@ export const resetSavedUser = () => {
|
||||
purchaseStore.setPurchaseStatus(false);
|
||||
};
|
||||
|
||||
eventManager.on('AuthLogout', () => resetSavedUser());
|
||||
eventManager.on({
|
||||
AuthLogout: () => resetSavedUser(),
|
||||
});
|
||||
|
||||
@@ -26,4 +26,6 @@ const reset = () => {
|
||||
Object.assign(userInteraction, defaultUserInteraction);
|
||||
};
|
||||
|
||||
eventManager.on('AuthLogout', () => reset());
|
||||
eventManager.on({
|
||||
AuthLogout: () => reset(),
|
||||
});
|
||||
|
||||
@@ -1,8 +1,9 @@
|
||||
type EventMap = Record<string, unknown[]>;
|
||||
type EventsBase = Record<string, unknown[]>;
|
||||
type PromiseLike<T> = Promise<T> | T;
|
||||
|
||||
export type EventCallback<E extends EventMap, T extends keyof E> = (...args: E[T]) => PromiseLike<unknown>;
|
||||
export type EventItem<E extends EventMap, T extends keyof E = keyof E> = {
|
||||
export type EventMap<E extends EventsBase> = { [K in keyof E]?: EventCallback<E, K> };
|
||||
export type EventCallback<E extends EventsBase, T extends keyof E> = (...args: E[T]) => PromiseLike<unknown>;
|
||||
export type EventItem<E extends EventsBase, T extends keyof E = keyof E> = {
|
||||
id: number;
|
||||
event: T;
|
||||
callback: EventCallback<E, T>;
|
||||
@@ -13,10 +14,22 @@ const nextId = () => count++;
|
||||
|
||||
const noop = () => {};
|
||||
|
||||
export class BaseEventManager<Events extends EventMap> {
|
||||
export class BaseEventManager<Events extends EventsBase> {
|
||||
#callbacks: EventItem<Events>[] = $state([]);
|
||||
|
||||
on<T extends keyof Events>(event: T, callback?: EventCallback<Events, T>) {
|
||||
on(subscriptions: EventMap<Events>): () => void {
|
||||
const cleanups = Object.entries(subscriptions).map(([event, callback]) =>
|
||||
this.#onEvent(event as keyof Events, callback as EventCallback<Events, keyof Events>),
|
||||
);
|
||||
|
||||
return () => {
|
||||
for (const cleanup of cleanups) {
|
||||
cleanup();
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
#onEvent<T extends keyof Events>(event: T, callback?: EventCallback<Events, T>) {
|
||||
if (!callback) {
|
||||
return noop;
|
||||
}
|
||||
@@ -30,17 +43,6 @@ export class BaseEventManager<Events extends EventMap> {
|
||||
};
|
||||
}
|
||||
|
||||
onMany(subscriptions: { [T in keyof Events]?: EventCallback<Events, T> }) {
|
||||
const cleanups = Object.entries(subscriptions).map(([event, callback]) =>
|
||||
this.on(event as keyof Events, callback as EventCallback<Events, keyof Events>),
|
||||
);
|
||||
return () => {
|
||||
for (const cleanup of cleanups) {
|
||||
cleanup();
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
emit<T extends keyof Events>(event: T, ...params: Events[T]) {
|
||||
const listeners = this.getListeners(event);
|
||||
for (const listener of listeners) {
|
||||
|
||||
Reference in New Issue
Block a user