diff --git a/electron/config.js b/electron/config.js index 7cbd902..856118d 100644 --- a/electron/config.js +++ b/electron/config.js @@ -73,6 +73,19 @@ const schema = { theme: {type: "string", default: "system"}, + openTabsState: { + type: "object", + properties: { + currentBufferPath: {type: "string"}, + openTabs: { + type: "array", + items: { + type: "string", + }, + }, + }, + }, + currency: { type: "object", properties: { diff --git a/electron/main/index.ts b/electron/main/index.ts index a9fcb4e..7619d12 100644 --- a/electron/main/index.ts +++ b/electron/main/index.ts @@ -6,6 +6,7 @@ import fs from "fs" import { WINDOW_CLOSE_EVENT, WINDOW_FULLSCREEN_STATE, WINDOW_FOCUS_STATE, SETTINGS_CHANGE_EVENT, TITLE_BAR_BG_LIGHT, TITLE_BAR_BG_LIGHT_BLURRED, TITLE_BAR_BG_DARK, TITLE_BAR_BG_DARK_BLURRED, + SCRATCH_FILE_NAME, SAVE_TABS_STATE, LOAD_TABS_STATE, } from '@/src/common/constants' import { menu, getTrayMenu, getEditorContextMenu } from './menu' @@ -499,3 +500,11 @@ ipcMain.handle('settings:set', async (event, settings) => { await win.webContents.send("library:pathChanged") } }) + +ipcMain.handle(SAVE_TABS_STATE, async (event, tabsState) => { + CONFIG.set("openTabsState", tabsState) +}) + +ipcMain.handle(LOAD_TABS_STATE, async (event) => { + return CONFIG.get("openTabsState") +}) diff --git a/src/common/constants.js b/src/common/constants.js index 87ef108..68e86a1 100644 --- a/src/common/constants.js +++ b/src/common/constants.js @@ -12,6 +12,8 @@ export const MOVE_BLOCK_EVENT = "move-block" export const DELETE_BLOCK_EVENT = "delete-block" export const CHANGE_BUFFER_EVENT = "change-buffer" export const SELECT_ALL_EVENT = "select-all" +export const SAVE_TABS_STATE = "save-tabs-state" +export const LOAD_TABS_STATE = "load-tabs-state" export const UPDATE_AVAILABLE_EVENT = "update-available" export const UPDATE_NOT_AVAILABLE_EVENT = "update-not-available" diff --git a/src/components/App.vue b/src/components/App.vue index 64b07a1..5ee46e8 100644 --- a/src/components/App.vue +++ b/src/components/App.vue @@ -124,7 +124,7 @@ // we need to wait for the next tick for the cases when we set the inert attribute on the editor // in which case issuing a focus() call immediately would not work this.$nextTick(() => { - this.$refs.editor.focus() + this.$refs.editor?.focus() }) }, @@ -158,6 +158,7 @@
({ buffers: {}, recentBufferPaths: [SCRATCH_FILE_NAME], - openTabs: [SCRATCH_FILE_NAME], + openTabs: [], currentEditor: null, - currentBufferPath: SCRATCH_FILE_NAME, + currentBufferPath: null, currentBufferName: null, currentLanguage: null, currentLanguageAuto: null, @@ -272,6 +272,36 @@ export const useHeynoteStore = defineStore("heynote", { this.currentBufferPath = SCRATCH_FILE_NAME this.libraryId++ }, + + async saveTabsState() { + //console.log("saving tabs state", this.currentBufferPath, this.openTabs) + await window.heynote.mainProcess.invoke(SAVE_TABS_STATE, { + currentBufferPath: this.currentBufferPath, + openTabs: toRaw(this.openTabs), + }) + }, + + async loadTabsState() { + // this function + const state = await window.heynote.mainProcess.invoke(LOAD_TABS_STATE) + //console.log("tabs state:", state) + + if (!!state) { + // make sure all open tabs still exist + const openTabs = state.openTabs.filter((path) => this.buffers[path]) + + this.openTabs = openTabs + if (this.buffers[state.currentBufferPath]) { + this.openBuffer(state.currentBufferPath) + } else { + this.openBuffer(SCRATCH_FILE_NAME) + } + } else { + // no saved state, just open the scratch file + //console.log("No saved tabs state, opening scratch file") + this.openBuffer(SCRATCH_FILE_NAME) + } + }, }, }) @@ -286,6 +316,10 @@ export async function initHeynoteStore() { }) window.heynote.mainProcess.on(WINDOW_FOCUS_STATE, (event, state) => { heynoteStore.isFocused = state - }) + }) await heynoteStore.updateBuffers() + heynoteStore.loadTabsState() + + watch(() => heynoteStore.currentBufferPath, () => heynoteStore.saveTabsState()) + watch(heynoteStore.openTabs, () => heynoteStore.saveTabsState()) } diff --git a/webapp/bridge.js b/webapp/bridge.js index 48944bc..2ee43f8 100644 --- a/webapp/bridge.js +++ b/webapp/bridge.js @@ -1,5 +1,4 @@ -import { Exception } from "sass"; -import { SETTINGS_CHANGE_EVENT, OPEN_SETTINGS_EVENT } from "@/src/common/constants"; +import { SETTINGS_CHANGE_EVENT, OPEN_SETTINGS_EVENT, SAVE_TABS_STATE, LOAD_TABS_STATE } from "@/src/common/constants"; import { NoteFormat } from "../src/common/note-format"; const NOTE_KEY_PREFIX = "heynote-library__" @@ -220,6 +219,10 @@ const Heynote = { }, pathSeparator: "/", + + setLibraryPathChangeCallback(callback) { + + }, }, mainProcess: { @@ -232,7 +235,17 @@ const Heynote = { }, invoke(event, ...args) { - + switch (event) { + case SAVE_TABS_STATE: + localStorage.setItem("openTabsState", JSON.stringify(args[0])) + break; + case LOAD_TABS_STATE: + const tabsState = localStorage.getItem("openTabsState") + if (tabsState) { + return JSON.parse(tabsState) + } + return undefined + } } }, diff --git a/webapp/main.js b/webapp/main.js index 11d9aa8..8969e31 100644 --- a/webapp/main.js +++ b/webapp/main.js @@ -7,6 +7,7 @@ import PrimeVue from 'primevue/config'; import App from '../src/components/App.vue' import { loadCurrencies } from '../src/currency' +import { initHeynoteStore } from '../src/stores/heynote-store' const pinia = createPinia() const app = createApp(App) @@ -15,6 +16,8 @@ app.use(PrimeVue) app.mount('#app') //console.log("test:", app.hej.test) +initHeynoteStore() + // load math.js currencies loadCurrencies() setInterval(loadCurrencies, 1000 * 3600 * 4)