Compare commits

...

2 Commits

Author SHA1 Message Date
Brandon Wees
b5c3d87290 fix: clear ocr and asset cache when edits are applied (#25533)
* fix: clear ocr and asset cache when edits are applied

* use event manager

* fix: undefined check
2026-01-26 18:48:34 +00:00
Brandon Wees
97220102e4 fix: deep link service when user is null (#25530)
* fix: deep link service when user is null

* fix: nit
2026-01-26 17:33:46 +00:00
4 changed files with 35 additions and 12 deletions

View File

@@ -33,7 +33,7 @@ final deepLinkServiceProvider = Provider(
ref.watch(beta_asset_provider.assetServiceProvider),
ref.watch(remoteAlbumServiceProvider),
ref.watch(driftMemoryServiceProvider),
ref.watch(currentUserProvider.select((user) => user!)),
ref.watch(currentUserProvider),
),
);
@@ -51,7 +51,7 @@ class DeepLinkService {
final RemoteAlbumService _betaRemoteAlbumService;
final DriftMemoryService _betaMemoryServiceProvider;
final UserDto _currentUser;
final UserDto? _currentUser;
const DeepLinkService(
this._memoryService,
@@ -131,9 +131,18 @@ class DeepLinkService {
if (Store.isBetaTimelineEnabled) {
List<DriftMemory> memories = [];
memories = memoryId == null
? await _betaMemoryServiceProvider.getMemoryLane(_currentUser.id)
: [await _betaMemoryServiceProvider.get(memoryId)].whereType<DriftMemory>().toList();
if (memoryId == null) {
if (_currentUser == null) {
return null;
}
memories = await _betaMemoryServiceProvider.getMemoryLane(_currentUser.id);
} else {
final memory = await _betaMemoryServiceProvider.get(memoryId);
if (memory != null) {
memories = [memory];
}
}
if (memories.isEmpty) {
return null;

View File

@@ -1,3 +1,4 @@
import { eventManager } from '$lib/managers/event-manager.svelte';
import { getAssetInfo, getAssetOcr, type AssetOcrResponseDto, type AssetResponseDto } from '@immich/sdk';
const defaultSerializer = <K>(params: K) => JSON.stringify(params);
@@ -35,6 +36,13 @@ class AssetCacheManager {
#assetCache = new AsyncCache<AssetResponseDto>();
#ocrCache = new AsyncCache<AssetOcrResponseDto[]>();
constructor() {
eventManager.on('AssetEditsApplied', () => {
this.#assetCache.clear();
this.#ocrCache.clear();
});
}
async getAsset(assetIdentifier: { key?: string; slug?: string; id: string }, updateCache = true) {
return this.#assetCache.getOrFetch(assetIdentifier, getAssetInfo, defaultSerializer, updateCache);
}

View File

@@ -1,5 +1,6 @@
import TransformTool from '$lib/components/asset-viewer/editor/transform-tool/transform-tool.svelte';
import { transformManager } from '$lib/managers/edit/transform-manager.svelte';
import { eventManager } from '$lib/managers/event-manager.svelte';
import { waitForWebsocketEvent } from '$lib/stores/websocket';
import { editAsset, removeAssetEdits, type AssetEditsDto, type AssetResponseDto } from '@immich/sdk';
import { ConfirmModal, modalManager, toastManager } from '@immich/ui';
@@ -110,25 +111,29 @@ export class EditManager {
this.isApplyingEdits = true;
const edits = this.tools.flatMap((tool) => tool.manager.edits);
if (!this.currentAsset) {
return false;
}
const assetId = this.currentAsset.id;
try {
// Setup the websocket listener before sending the edit request
const editCompleted = waitForWebsocketEvent(
'AssetEditReadyV1',
(event) => event.asset.id === this.currentAsset!.id,
10_000,
);
const editCompleted = waitForWebsocketEvent('AssetEditReadyV1', (event) => event.asset.id === assetId, 10_000);
await (edits.length === 0
? removeAssetEdits({ id: this.currentAsset!.id })
? removeAssetEdits({ id: assetId })
: editAsset({
id: this.currentAsset!.id,
id: assetId,
assetEditActionListDto: {
edits,
},
}));
await editCompleted;
eventManager.emit('AssetEditsApplied', assetId);
toastManager.success('Edits applied successfully');
this.hasAppliedEdits = true;

View File

@@ -36,6 +36,7 @@ export type Events = {
AssetReplace: [{ oldAssetId: string; newAssetId: string }];
AssetsArchive: [string[]];
AssetsDelete: [string[]];
AssetEditsApplied: [string];
AlbumAddAssets: [];
AlbumUpdate: [AlbumResponseDto];