feat(scenes): add scene darkness reveal and fix project reopen crash
Add darkenScene with Opening brush in presentation, persist reveal strokes per scene during a session, and close projects properly on return to home. Harden dnd asset streaming to avoid Windows main-process crashes when reopening projects. Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -0,0 +1,80 @@
|
||||
import type { SceneDarknessEvent, SceneDarknessRevealStroke, SceneDarknessState } from '../../shared/types';
|
||||
|
||||
function emptyState(): SceneDarknessState {
|
||||
return {
|
||||
revision: 1,
|
||||
enabled: false,
|
||||
cacheKey: null,
|
||||
strokes: [],
|
||||
draft: null,
|
||||
};
|
||||
}
|
||||
|
||||
export class SceneDarknessStore {
|
||||
private state: SceneDarknessState = emptyState();
|
||||
/** Кэш раскрытых областей по ключу (graphNodeId или sceneId) на время сессии показа. */
|
||||
private cache = new Map<string, SceneDarknessRevealStroke[]>();
|
||||
private currentKey: string | null = null;
|
||||
|
||||
getState(): SceneDarknessState {
|
||||
return { ...this.state, strokes: [...this.state.strokes] };
|
||||
}
|
||||
|
||||
/** Сброс кэша при новом запуске показа (кнопка «Запустить»). */
|
||||
resetSession(): void {
|
||||
this.cache.clear();
|
||||
this.currentKey = null;
|
||||
this.state = emptyState();
|
||||
}
|
||||
|
||||
/**
|
||||
* Переключение сцены: сохраняем текущие штрихи в кэш и загружаем состояние новой сцены.
|
||||
*/
|
||||
switchScene(cacheKey: string | null, enabled: boolean): SceneDarknessState {
|
||||
if (this.currentKey !== null) {
|
||||
this.cache.set(this.currentKey, [...this.state.strokes]);
|
||||
}
|
||||
this.currentKey = cacheKey;
|
||||
const strokes =
|
||||
cacheKey && enabled ? [...(this.cache.get(cacheKey) ?? [])] : [];
|
||||
this.state = {
|
||||
revision: this.state.revision + 1,
|
||||
enabled,
|
||||
cacheKey,
|
||||
strokes,
|
||||
draft: null,
|
||||
};
|
||||
return this.getState();
|
||||
}
|
||||
|
||||
dispatch(event: SceneDarknessEvent): SceneDarknessState {
|
||||
if (!this.state.enabled) return this.getState();
|
||||
switch (event.kind) {
|
||||
case 'draft.set':
|
||||
this.state = {
|
||||
...this.state,
|
||||
revision: this.state.revision + 1,
|
||||
draft: event.draft,
|
||||
};
|
||||
return this.getState();
|
||||
case 'stroke.add': {
|
||||
const strokes = [...this.state.strokes, event.stroke];
|
||||
if (this.currentKey) {
|
||||
this.cache.set(this.currentKey, strokes);
|
||||
}
|
||||
this.state = {
|
||||
...this.state,
|
||||
revision: this.state.revision + 1,
|
||||
strokes,
|
||||
draft: null,
|
||||
};
|
||||
return this.getState();
|
||||
}
|
||||
default: {
|
||||
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
||||
const _x: never = event;
|
||||
return this.getState();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user