mirror of
https://github.com/GraphiteEditor/Graphite.git
synced 2026-09-25 19:58:11 +08:00
Make the document auto-save system initially restore the last-viewed tab before loading the rest (#2194)
* Fixes last tab being opened instead of last active tab Fixes https://discord.com/channels/731730685944922173/881073965047636018/937518022548131891 * Defers node initialisation to SelectDocument message instead of load_document * Fix warning regarding attempt to load closed document * Defer loading resources and running nodes to selection time * Make last active tab load before others * Load last active saved document instead of last autosaved doc * Fix failing tests * Code review --------- Co-authored-by: Keavon Chambers <keavon@keavon.com>
This commit is contained in:
co-authored by
Keavon Chambers
parent
de36d4967d
commit
9954e49530
@@ -2,7 +2,15 @@ import { createStore, del, get, set, update } from "idb-keyval";
|
||||
import { get as getFromStore } from "svelte/store";
|
||||
|
||||
import { type Editor } from "@graphite/editor";
|
||||
import { TriggerIndexedDbWriteDocument, TriggerIndexedDbRemoveDocument, TriggerSavePreferences, TriggerLoadAutoSaveDocuments, TriggerLoadPreferences } from "@graphite/messages";
|
||||
import {
|
||||
TriggerIndexedDbWriteDocument,
|
||||
TriggerIndexedDbRemoveDocument,
|
||||
TriggerSavePreferences,
|
||||
TriggerLoadPreferences,
|
||||
TriggerLoadFirstAutoSaveDocument,
|
||||
TriggerLoadRestAutoSaveDocuments,
|
||||
TriggerSaveActiveDocument,
|
||||
} from "@graphite/messages";
|
||||
import { type PortfolioState } from "@graphite/state-providers/portfolio";
|
||||
|
||||
const graphiteStore = createStore("graphite", "store");
|
||||
@@ -12,10 +20,13 @@ export function createPersistenceManager(editor: Editor, portfolio: PortfolioSta
|
||||
|
||||
async function storeDocumentOrder() {
|
||||
const documentOrder = getFromStore(portfolio).documents.map((doc) => String(doc.id));
|
||||
|
||||
await set("documents_tab_order", documentOrder, graphiteStore);
|
||||
}
|
||||
|
||||
async function storeCurrentDocumentId(documentId: string) {
|
||||
await set("current_document_id", String(documentId), graphiteStore);
|
||||
}
|
||||
|
||||
async function storeDocument(autoSaveDocument: TriggerIndexedDbWriteDocument) {
|
||||
await update<Record<string, TriggerIndexedDbWriteDocument>>(
|
||||
"documents",
|
||||
@@ -28,6 +39,7 @@ export function createPersistenceManager(editor: Editor, portfolio: PortfolioSta
|
||||
);
|
||||
|
||||
await storeDocumentOrder();
|
||||
await storeCurrentDocumentId(autoSaveDocument.details.id);
|
||||
}
|
||||
|
||||
async function removeDocument(id: string) {
|
||||
@@ -41,19 +53,80 @@ export function createPersistenceManager(editor: Editor, portfolio: PortfolioSta
|
||||
graphiteStore,
|
||||
);
|
||||
|
||||
const documentCount = getFromStore(portfolio).documents.length;
|
||||
if (documentCount > 0) {
|
||||
const documentIndex = getFromStore(portfolio).activeDocumentIndex;
|
||||
const documentId = getFromStore(portfolio).documents[documentIndex].id;
|
||||
|
||||
await storeCurrentDocumentId(String(documentId));
|
||||
} else {
|
||||
await del("current_document_id", graphiteStore);
|
||||
}
|
||||
|
||||
await storeDocumentOrder();
|
||||
}
|
||||
|
||||
async function loadDocuments() {
|
||||
async function loadFirstDocument() {
|
||||
const previouslySavedDocuments = await get<Record<string, TriggerIndexedDbWriteDocument>>("documents", graphiteStore);
|
||||
const documentOrder = await get<string[]>("documents_tab_order", graphiteStore);
|
||||
const currentDocumentId = await get<string>("current_document_id", graphiteStore);
|
||||
if (!previouslySavedDocuments || !documentOrder) return;
|
||||
|
||||
const orderedSavedDocuments = documentOrder.flatMap((id) => (previouslySavedDocuments[id] ? [previouslySavedDocuments[id]] : []));
|
||||
|
||||
orderedSavedDocuments?.forEach(async (doc: TriggerIndexedDbWriteDocument) => {
|
||||
editor.handle.openAutoSavedDocument(BigInt(doc.details.id), doc.details.name, doc.details.isSaved, doc.document);
|
||||
});
|
||||
if (currentDocumentId) {
|
||||
const doc = previouslySavedDocuments[currentDocumentId];
|
||||
editor.handle.openAutoSavedDocument(BigInt(doc.details.id), doc.details.name, doc.details.isSaved, doc.document, false);
|
||||
editor.handle.selectDocument(BigInt(currentDocumentId));
|
||||
} else {
|
||||
const len = orderedSavedDocuments.length;
|
||||
if (len > 0) {
|
||||
const doc = orderedSavedDocuments[len - 1];
|
||||
editor.handle.openAutoSavedDocument(BigInt(doc.details.id), doc.details.name, doc.details.isSaved, doc.document, false);
|
||||
editor.handle.selectDocument(BigInt(doc.details.id));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
async function loadRestDocuments() {
|
||||
const previouslySavedDocuments = await get<Record<string, TriggerIndexedDbWriteDocument>>("documents", graphiteStore);
|
||||
const documentOrder = await get<string[]>("documents_tab_order", graphiteStore);
|
||||
const currentDocumentId = await get<string>("current_document_id", graphiteStore);
|
||||
if (!previouslySavedDocuments || !documentOrder) return;
|
||||
|
||||
const orderedSavedDocuments = documentOrder.flatMap((id) => (previouslySavedDocuments[id] ? [previouslySavedDocuments[id]] : []));
|
||||
|
||||
if (currentDocumentId) {
|
||||
const currentIndex = orderedSavedDocuments.findIndex((doc) => doc.details.id === currentDocumentId);
|
||||
const beforeCurrentIndex = currentIndex - 1;
|
||||
const afterCurrentIndex = currentIndex + 1;
|
||||
|
||||
for (let i = beforeCurrentIndex; i >= 0; i--) {
|
||||
const { document, details } = orderedSavedDocuments[i];
|
||||
const { id, name, isSaved } = details;
|
||||
editor.handle.openAutoSavedDocument(BigInt(id), name, isSaved, document, true);
|
||||
}
|
||||
for (let i = afterCurrentIndex; i < orderedSavedDocuments.length; i++) {
|
||||
const { document, details } = orderedSavedDocuments[i];
|
||||
const { id, name, isSaved } = details;
|
||||
editor.handle.openAutoSavedDocument(BigInt(id), name, isSaved, document, false);
|
||||
}
|
||||
|
||||
editor.handle.selectDocument(BigInt(currentDocumentId));
|
||||
} else {
|
||||
const length = orderedSavedDocuments.length;
|
||||
|
||||
for (let i = length - 2; i >= 0; i--) {
|
||||
const { document, details } = orderedSavedDocuments[i];
|
||||
const { id, name, isSaved } = details;
|
||||
editor.handle.openAutoSavedDocument(BigInt(id), name, isSaved, document, true);
|
||||
}
|
||||
|
||||
if (length > 0) {
|
||||
const id = orderedSavedDocuments[length - 1].details.id;
|
||||
editor.handle.selectDocument(BigInt(id));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// PREFERENCES
|
||||
@@ -84,12 +157,24 @@ export function createPersistenceManager(editor: Editor, portfolio: PortfolioSta
|
||||
editor.subscriptions.subscribeJsMessage(TriggerIndexedDbRemoveDocument, async (removeAutoSaveDocument) => {
|
||||
await removeDocument(removeAutoSaveDocument.documentId);
|
||||
});
|
||||
editor.subscriptions.subscribeJsMessage(TriggerLoadAutoSaveDocuments, async () => {
|
||||
await loadDocuments();
|
||||
editor.subscriptions.subscribeJsMessage(TriggerLoadFirstAutoSaveDocument, async () => {
|
||||
await loadFirstDocument();
|
||||
});
|
||||
editor.subscriptions.subscribeJsMessage(TriggerLoadRestAutoSaveDocuments, async () => {
|
||||
await loadRestDocuments();
|
||||
});
|
||||
editor.subscriptions.subscribeJsMessage(TriggerSaveActiveDocument, async (triggerSaveActiveDocument) => {
|
||||
const documentId = String(triggerSaveActiveDocument.documentId);
|
||||
const previouslySavedDocuments = await get<Record<string, TriggerIndexedDbWriteDocument>>("documents", graphiteStore);
|
||||
if (!previouslySavedDocuments) return;
|
||||
if (documentId in previouslySavedDocuments) {
|
||||
await storeCurrentDocumentId(documentId);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
export async function wipeDocuments() {
|
||||
await del("documents_tab_order", graphiteStore);
|
||||
await del("current_document_id", graphiteStore);
|
||||
await del("documents", graphiteStore);
|
||||
}
|
||||
|
||||
@@ -768,7 +768,8 @@ export class UpdateMouseCursor extends JsMessage {
|
||||
readonly cursor!: MouseCursorIcon;
|
||||
}
|
||||
|
||||
export class TriggerLoadAutoSaveDocuments extends JsMessage {}
|
||||
export class TriggerLoadFirstAutoSaveDocument extends JsMessage {}
|
||||
export class TriggerLoadRestAutoSaveDocuments extends JsMessage {}
|
||||
|
||||
export class TriggerLoadPreferences extends JsMessage {}
|
||||
|
||||
@@ -807,6 +808,10 @@ export class TriggerSavePreferences extends JsMessage {
|
||||
readonly preferences!: Record<string, unknown>;
|
||||
}
|
||||
|
||||
export class TriggerSaveActiveDocument extends JsMessage {
|
||||
readonly documentId!: bigint;
|
||||
}
|
||||
|
||||
export class DocumentChanged extends JsMessage {}
|
||||
|
||||
export type DataBuffer = {
|
||||
@@ -1574,10 +1579,12 @@ export const messageMakers: Record<string, MessageMaker> = {
|
||||
TriggerImport,
|
||||
TriggerIndexedDbRemoveDocument,
|
||||
TriggerIndexedDbWriteDocument,
|
||||
TriggerLoadAutoSaveDocuments,
|
||||
TriggerLoadFirstAutoSaveDocument,
|
||||
TriggerLoadPreferences,
|
||||
TriggerLoadRestAutoSaveDocuments,
|
||||
TriggerOpenDocument,
|
||||
TriggerPaste,
|
||||
TriggerSaveActiveDocument,
|
||||
TriggerSavePreferences,
|
||||
TriggerTextCommit,
|
||||
TriggerTextCopy,
|
||||
@@ -1597,14 +1604,14 @@ export const messageMakers: Record<string, MessageMaker> = {
|
||||
UpdateDocumentModeLayout,
|
||||
UpdateDocumentRulers,
|
||||
UpdateDocumentScrollbars,
|
||||
UpdateExportReorderIndex,
|
||||
UpdateEyedropperSamplingState,
|
||||
UpdateGraphFadeArtwork,
|
||||
UpdateGraphViewOverlay,
|
||||
UpdateImportReorderIndex,
|
||||
UpdateImportsExports,
|
||||
UpdateInputHints,
|
||||
UpdateInSelectedNetwork,
|
||||
UpdateExportReorderIndex,
|
||||
UpdateImportReorderIndex,
|
||||
UpdateLayersPanelControlBarLayout,
|
||||
UpdateLayerWidths,
|
||||
UpdateMenuBarLayout,
|
||||
|
||||
Reference in New Issue
Block a user