Skip to content

Commit d3a58e8

Browse files
committed
refine
1 parent 61a910f commit d3a58e8

File tree

6 files changed

+82
-61
lines changed

6 files changed

+82
-61
lines changed

web/src/lib/components/asset-viewer/asset-viewer.svelte

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -169,7 +169,7 @@
169169
onMount(async () => {
170170
console.log('on mount - assetviwer');
171171
eventManager.emit('AssetViewerLoaded');
172-
eventManager.once('StartViewTransition', () => {
172+
eventManager.on('Finished', () => {
173173
debugger;
174174
transitionName = null;
175175
console.log('clearning tasnition name in asset viwer');

web/src/lib/components/timeline/Timeline.svelte

Lines changed: 3 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
import HotModuleReload from '$lib/elements/HotModuleReload.svelte';
1010
import Portal from '$lib/elements/Portal.svelte';
1111
import Skeleton from '$lib/elements/Skeleton.svelte';
12+
1213
import { eventManager } from '$lib/managers/event-manager.svelte';
1314
import type { DayGroup } from '$lib/managers/timeline-manager/day-group.svelte';
1415
import { isIntersecting } from '$lib/managers/timeline-manager/internal/intersection-support.svelte';
@@ -265,34 +266,11 @@
265266
// and a new route is being navigated to. It will never be called on direct
266267
// navigations by the browser.
267268
beforeNavigate(({ from, to }) => {
268-
eventManager.on('asdf', () => void 0);
269269
timelineManager.suspendTransitions = true;
270270
const isNavigatingToAssetViewer = isAssetViewerRoute(to);
271271
const isNavigatingFromAssetViewer = isAssetViewerRoute(from);
272272
hasNavigatedToOrFromAssetViewer = isNavigatingToAssetViewer !== isNavigatingFromAssetViewer;
273273
if (!isNavigatingFromAssetViewer && isNavigatingToAssetViewer) {
274-
const navigatingPromise = new Promise((resolve) => {
275-
console.log('hi');
276-
eventManager.once('AssetViewerLoaded', () => {
277-
resolve();
278-
});
279-
280-
console.log('BEFORE VIEW TRANS');
281-
const transition = document.startViewTransition(async () => {
282-
console.log('IN VIEW TRANS');
283-
console.log('emit', 'StartViewTransition');
284-
eventManager.emit('StartViewTransition');
285-
console.log('starting');
286-
287-
await navigatingPromise;
288-
console.log('AFTER VIEW TRANS!');
289-
});
290-
transition.updateCallbackDone.then(() => {
291-
console.log('DONE VIEW TRANS!');
292-
eventManager.emit('EndViewTransition');
293-
});
294-
});
295-
} else if (isNavigatingFromAssetViewer && isNavigatingToAssetViewer) {
296274
}
297275
});
298276
@@ -311,9 +289,9 @@
311289
312290
void scrollAfterNavigate();
313291
if (!isAssetViewerPage) {
314-
const scrollTarget = $gridScrollTarget?.at;
292+
const scrollTarget = $gridScrollTarget?.at ?? null;
315293
await tick();
316-
eventManager.emit('TimelineLoaded', scrollTarget);
294+
eventManager.emit('TimelineLoaded', { id: scrollTarget });
317295
}
318296
});
319297
});

web/src/lib/components/timeline/TimelineAssetViewer.svelte

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -84,9 +84,9 @@
8484
};
8585
8686
const handleClose = async (asset: { id: string }) => {
87-
const awaitInit = new Promise((resolve) => eventManager.once('WaitForInit', resolve));
87+
const awaitInit = new Promise<void>((resolve) => eventManager.once('StartViewTransition', resolve));
8888
console.log('emit back to timeline');
89-
eventManager.emit('BackToTimeline', { assetId: asset.id });
89+
eventManager.emit('TransitionToTimeline', { id: asset.id });
9090
console.log('waitint for init');
9191
await awaitInit;
9292
console.log('done with for init');

web/src/lib/components/timeline/TimelineDateGroup.svelte

Lines changed: 35 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
import { TimelineManager } from '$lib/managers/timeline-manager/timeline-manager.svelte';
88
import type { TimelineAsset } from '$lib/managers/timeline-manager/types';
99
import { assetSnapshot, assetsSnapshot } from '$lib/managers/timeline-manager/utils.svelte';
10+
import { viewTransitionManager } from '$lib/managers/ViewTransitionManager.svelte';
1011
import type { AssetInteraction } from '$lib/stores/asset-interaction.svelte';
1112
import { assetViewingStore } from '$lib/stores/asset-viewing.store';
1213
import { isSelectingAllAssets } from '$lib/stores/assets-store.svelte';
@@ -68,7 +69,7 @@
6869
let hoveredDayGroup = $state();
6970
const send = shared.send;
7071
71-
let clickedThumb = $state<string | null>(null);
72+
let animationTargetAssetId = $state<string | null>(null);
7273
7374
const transitionDuration = $derived.by(() =>
7475
monthGroup.timelineManager.suspendTransitions && !$isUploading ? 0 : 150,
@@ -138,36 +139,28 @@
138139
});
139140
return getDateLocaleString(date);
140141
};
141-
let animateTarget = $state<string | null>(null);
142-
$inspect(clickedThumb).with((a, b) => console.log('clicked', a, b));
143-
$inspect(animateTarget).with((a, b) => console.log('clicked', a, b));
142+
let transitionTargetAssetId = $state<string | null>(null);
144143
145-
eventManager.on('BackToTimeline', async ({ assetId }) => {
146-
const asset = await monthGroup.findAssetById({ id: assetId });
144+
eventManager.on('TransitionToTimeline', ({ id }) => {
145+
const asset = monthGroup.findAssetById({ id });
147146
if (!asset) {
148147
return;
149148
}
150-
console.log('BACK TO TIMLEINE');
151-
152-
debugger;
153-
const navigatingPromise = new Promise((resolve) => {
154-
eventManager.once('TimelineLoaded', (assetId) => {
155-
console.log('timeline loaded', assetId);
156-
animateTarget = assetId;
157-
resolve();
158-
});
159-
console.log('hi');
160-
const transition = document.startViewTransition(async () => {
161-
console.log('start view transition - 2');
162-
eventManager.emit('StartViewTransition');
163-
console.log('starting2');
164-
eventManager.emit('WaitForInit');
165-
await navigatingPromise;
166-
console.log('AFTER VIEW TRANS - 2!');
167-
debugger;
168-
});
169-
transition.updateCallbackDone.then(() => ((animateTarget = null), eventManager.emit('EndViewTransition')));
170-
});
149+
150+
viewTransitionManager.startTransition(
151+
new Promise<void>((resolve) => {
152+
console.log('BACK TO TIMLEINE');
153+
eventManager.once('TimelineLoaded', ({ id }) => {
154+
console.log('timeline loaded', id);
155+
transitionTargetAssetId = id;
156+
resolve();
157+
});
158+
}),
159+
() => {
160+
console.log('finished loaded', id);
161+
transitionTargetAssetId = null;
162+
},
163+
);
171164
});
172165
</script>
173166

@@ -228,13 +221,16 @@
228221
{#each filterIntersecting(dayGroup.viewerAssets) as viewerAsset (viewerAsset.id)}
229222
{@const position = viewerAsset.position!}
230223
{@const asset = viewerAsset.asset!}
231-
{@const transitionName = clickedThumb === asset.id || animateTarget === asset.id ? 'good' : undefined}
224+
{@const transitionName =
225+
animationTargetAssetId === asset.id || transitionTargetAssetId === asset.id ? 'good' : undefined}
232226

233227
<!-- {#if viewerAsset.intersecting} -->
234228
<!-- note: don't remove data-asset-id - its used by web e2e tests -->
235229
<div
236230
data-asset-id={asset.id}
237-
data-transition-thumb={clickedThumb === asset.id || animateTarget === asset.id ? true : undefined}
231+
data-transition-thumb={animationTargetAssetId === asset.id || transitionTargetAssetId === asset.id
232+
? true
233+
: undefined}
238234
style:view-transition-name={transitionName}
239235
class="absolute"
240236
style:top={position.top + 'px'}
@@ -250,10 +246,18 @@
250246
{groupIndex}
251247
onClick={async (asset) => {
252248
console.log('adding clickedThumb', asset.id);
253-
clickedThumb = asset.id;
249+
250+
// tag target on the 'old' snaptho
251+
animationTargetAssetId = asset.id;
252+
viewTransitionManager.startTransition(
253+
new Promise<void>((resolve) => eventManager.once('AssetViewerLoaded', () => resolve())),
254+
);
255+
254256
eventManager.once('StartViewTransition', () => {
255257
console.log('removing clickedThumb');
256-
clickedThumb = null;
258+
// remove target on the 'old' view,
259+
// asset-viewer will tag new target element for 'new' snapshot
260+
animationTargetAssetId = null;
257261
});
258262

259263
if (typeof onThumbnailClick === 'function') {
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
import { eventManager } from '$lib/managers/event-manager.svelte';
2+
3+
class ViewTransitionManager {
4+
startTransition(domUpdateComplete: Promise<unknown>, finishedCallback?: () => void) {
5+
console.log('STARING it');
6+
// good time to add view-transition-name styles (if needed)
7+
eventManager.emit('BeforeStartViewTransition');
8+
// next call will create the 'old' view snapshot
9+
const transition = document.startViewTransition(async () => {
10+
// Good time to remove any view-transition-name styles created during
11+
// BeforeStartViewTransition, then trigger the actual view transition.
12+
eventManager.emit('StartViewTransition');
13+
await domUpdateComplete;
14+
});
15+
// UpdateCallbackDone is a good time to add any view-transition-name styles
16+
// to the new DOM state, before the 'new' view snapshot is creatd
17+
transition.updateCallbackDone.then(() => eventManager.emit('UpdateCallbackDone'));
18+
// Both old/new snapshots are taken - pseudo elements are created, transition is
19+
// about to start
20+
transition.ready.then(() => eventManager.emit('Ready'));
21+
// Transition is complete
22+
transition.finished.then(() => eventManager.emit('Finished'));
23+
transition.finished.then(() => finishedCallback?.());
24+
}
25+
}
26+
27+
export const viewTransitionManager = new ViewTransitionManager();

web/src/lib/managers/event-manager.svelte.ts

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,18 @@ export type Events = {
4040
LibraryDelete: [{ id: string }];
4141

4242
ReleaseEvent: [ReleaseEvent];
43+
44+
TransitionToTimeline: [{ id: string }];
45+
TimelineLoaded: [{ id: string | null }];
46+
47+
TransitionToAssetViewer: [];
48+
AssetViewerLoaded: [];
49+
50+
BeforeStartViewTransition: [];
51+
Finished: [];
52+
Ready: [];
53+
UpdateCallbackDone: [];
54+
StartViewTransition: [];
4355
};
4456

4557
type Listener<EventMap extends Record<string, unknown[]>, K extends keyof EventMap> = (...params: EventMap[K]) => void;
@@ -52,11 +64,11 @@ class EventManager<EventMap extends Record<string, unknown[]>> {
5264
}[];
5365
} = {};
5466

55-
on<T extends keyof EventMap>(key: T, listener: (...params: EventMap[T]) => void) {
67+
on<T extends keyof EventMap>(key: T, listener: (...params: EventMap[T]) => unknown) {
5668
return this.addListener(key, listener, false);
5769
}
5870

59-
once<T extends keyof EventMap>(key: T, listener: (...params: EventMap[T]) => void) {
71+
once<T extends keyof EventMap>(key: T, listener: (...params: EventMap[T]) => unknown) {
6072
return this.addListener(key, listener, true);
6173
}
6274

0 commit comments

Comments
 (0)