undo / redo behaviour, workspace concept
This commit is contained in:
84
src/workspace/workspaceCommands.ts
Normal file
84
src/workspace/workspaceCommands.ts
Normal file
@@ -0,0 +1,84 @@
|
||||
import type { PageRef } from '../pdf/pdfTypes';
|
||||
|
||||
export interface WorkspaceCommandState {
|
||||
pages: PageRef[];
|
||||
selectedPageIds: string[];
|
||||
lastSelectedVisualIndex: number | null;
|
||||
}
|
||||
|
||||
export interface WorkspaceCommandPayload {
|
||||
before: WorkspaceCommandState;
|
||||
after: WorkspaceCommandState;
|
||||
details?: Record<string, unknown>;
|
||||
}
|
||||
|
||||
export interface WorkspaceCommandRecord {
|
||||
id: string;
|
||||
type: string;
|
||||
label: string;
|
||||
timestamp: string;
|
||||
payload: WorkspaceCommandPayload;
|
||||
}
|
||||
|
||||
export interface WorkspaceCommand extends WorkspaceCommandRecord {
|
||||
do: (state: WorkspaceCommandState) => WorkspaceCommandState;
|
||||
undo: (state: WorkspaceCommandState) => WorkspaceCommandState;
|
||||
}
|
||||
|
||||
export function cloneCommandState(
|
||||
state: WorkspaceCommandState
|
||||
): WorkspaceCommandState {
|
||||
return {
|
||||
pages: state.pages.map((page) => ({ ...page })),
|
||||
selectedPageIds: [...state.selectedPageIds],
|
||||
lastSelectedVisualIndex: state.lastSelectedVisualIndex,
|
||||
};
|
||||
}
|
||||
|
||||
export function createSnapshotCommand(params: {
|
||||
id: string;
|
||||
type: string;
|
||||
label: string;
|
||||
timestamp?: string;
|
||||
before: WorkspaceCommandState;
|
||||
after: WorkspaceCommandState;
|
||||
details?: Record<string, unknown>;
|
||||
}): WorkspaceCommand {
|
||||
return reviveWorkspaceCommand({
|
||||
id: params.id,
|
||||
type: params.type,
|
||||
label: params.label,
|
||||
timestamp: params.timestamp ?? new Date().toISOString(),
|
||||
payload: {
|
||||
before: cloneCommandState(params.before),
|
||||
after: cloneCommandState(params.after),
|
||||
details: params.details,
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
export function reviveWorkspaceCommand(
|
||||
record: WorkspaceCommandRecord
|
||||
): WorkspaceCommand {
|
||||
return {
|
||||
...record,
|
||||
do: () => cloneCommandState(record.payload.after),
|
||||
undo: () => cloneCommandState(record.payload.before),
|
||||
};
|
||||
}
|
||||
|
||||
export function toWorkspaceCommandRecord(
|
||||
command: WorkspaceCommand
|
||||
): WorkspaceCommandRecord {
|
||||
return {
|
||||
id: command.id,
|
||||
type: command.type,
|
||||
label: command.label,
|
||||
timestamp: command.timestamp,
|
||||
payload: {
|
||||
before: cloneCommandState(command.payload.before),
|
||||
after: cloneCommandState(command.payload.after),
|
||||
details: command.payload.details,
|
||||
},
|
||||
};
|
||||
}
|
||||
Reference in New Issue
Block a user