mirror of
https://github.com/heyman/heynote.git
synced 2025-02-08 14:31:37 +01:00
Refactor editior instance creation and settings management
- Refactor settings management into separate pinia store - Move creation of editor instances into editorCacheStore - Read settings directly from the settingsStore instead of passing it from App to Editor to the editor instance
This commit is contained in:
parent
574dcfdc24
commit
f356e3b249
@ -1,9 +1,10 @@
|
||||
<script>
|
||||
import { mapState, mapActions } from 'pinia'
|
||||
|
||||
import { mapWritableState } from 'pinia'
|
||||
import { mapWritableState, mapStores } from 'pinia'
|
||||
import { useHeynoteStore } from "../stores/heynote-store"
|
||||
import { useErrorStore } from "../stores/error-store"
|
||||
import { useSettingsStore } from "../stores/settings-store"
|
||||
|
||||
import { OPEN_SETTINGS_EVENT, SETTINGS_CHANGE_EVENT } from '@/src/common/constants'
|
||||
|
||||
@ -30,9 +31,6 @@
|
||||
|
||||
data() {
|
||||
return {
|
||||
theme: window.heynote.themeMode.initial,
|
||||
initialTheme: window.heynote.themeMode.initial,
|
||||
themeSetting: 'system',
|
||||
development: window.location.href.indexOf("dev=1") !== -1,
|
||||
showSettings: false,
|
||||
settings: window.heynote.settings,
|
||||
@ -40,30 +38,15 @@
|
||||
},
|
||||
|
||||
mounted() {
|
||||
window.heynote.themeMode.get().then((mode) => {
|
||||
this.theme = mode.computed
|
||||
this.themeSetting = mode.theme
|
||||
})
|
||||
const onThemeChange = (theme) => {
|
||||
this.theme = theme
|
||||
if (theme === "system") {
|
||||
document.documentElement.setAttribute("theme", window.matchMedia("(prefers-color-scheme: dark)").matches ? "dark" : "light")
|
||||
} else {
|
||||
document.documentElement.setAttribute("theme", theme)
|
||||
}
|
||||
}
|
||||
onThemeChange(window.heynote.themeMode.initial)
|
||||
window.heynote.themeMode.onChange(onThemeChange)
|
||||
window.heynote.mainProcess.on(SETTINGS_CHANGE_EVENT, (event, settings) => {
|
||||
this.settings = settings
|
||||
})
|
||||
this.settingsStore.setUp()
|
||||
|
||||
window.heynote.mainProcess.on(OPEN_SETTINGS_EVENT, () => {
|
||||
this.showSettings = true
|
||||
})
|
||||
},
|
||||
|
||||
beforeUnmount() {
|
||||
window.heynote.themeMode.removeListener()
|
||||
this.settingsStore.tearDown()
|
||||
},
|
||||
|
||||
watch: {
|
||||
@ -83,6 +66,7 @@
|
||||
},
|
||||
|
||||
computed: {
|
||||
...mapStores(useSettingsStore),
|
||||
...mapState(useHeynoteStore, [
|
||||
"currentBufferPath",
|
||||
"currentBufferName",
|
||||
@ -131,24 +115,6 @@
|
||||
this.focusEditor()
|
||||
},
|
||||
|
||||
toggleTheme() {
|
||||
let newTheme
|
||||
// when the "system" theme is used, make sure that the first click always results in amn actual theme change
|
||||
if (this.initialTheme === "light") {
|
||||
newTheme = this.themeSetting === "system" ? "dark" : (this.themeSetting === "dark" ? "light" : "system")
|
||||
} else {
|
||||
newTheme = this.themeSetting === "system" ? "light" : (this.themeSetting === "light" ? "dark" : "system")
|
||||
}
|
||||
window.heynote.themeMode.set(newTheme)
|
||||
this.themeSetting = newTheme
|
||||
this.$refs.editor.focus()
|
||||
},
|
||||
|
||||
setTheme(theme) {
|
||||
window.heynote.themeMode.set(theme)
|
||||
this.themeSetting = theme
|
||||
},
|
||||
|
||||
onSelectLanguage(language) {
|
||||
this.closeDialog()
|
||||
this.$refs.editor.setLanguage(language)
|
||||
@ -165,18 +131,9 @@
|
||||
<template>
|
||||
<div class="container">
|
||||
<Editor
|
||||
:theme="theme"
|
||||
:theme="settingsStore.theme"
|
||||
:development="development"
|
||||
:debugSyntaxTree="false"
|
||||
:keymap="settings.keymap"
|
||||
:emacsMetaKey="settings.emacsMetaKey"
|
||||
:showLineNumberGutter="settings.showLineNumberGutter"
|
||||
:showFoldGutter="settings.showFoldGutter"
|
||||
:bracketClosing="settings.bracketClosing"
|
||||
:fontFamily="settings.fontFamily"
|
||||
:fontSize="settings.fontSize"
|
||||
:defaultBlockLanguage="settings.defaultBlockLanguage || 'text'"
|
||||
:defaultBlockLanguageAutoDetect="settings.defaultBlockLanguageAutoDetect === undefined ? true : settings.defaultBlockLanguageAutoDetect"
|
||||
:inert="editorInert"
|
||||
class="editor"
|
||||
ref="editor"
|
||||
@ -204,10 +161,10 @@
|
||||
/>
|
||||
<Settings
|
||||
v-if="showSettings"
|
||||
:initialSettings="settings"
|
||||
:themeSetting="themeSetting"
|
||||
:initialSettings="settingsStore.settings"
|
||||
:themeSetting="settingsStore.themeSetting"
|
||||
@closeSettings="closeSettings"
|
||||
@setTheme="setTheme"
|
||||
@setTheme="settingsStore.setTheme"
|
||||
/>
|
||||
<NewBuffer
|
||||
v-if="showCreateBuffer"
|
||||
|
@ -2,7 +2,7 @@
|
||||
import { HeynoteEditor } from '../editor/editor.js'
|
||||
import { syntaxTree } from "@codemirror/language"
|
||||
import { toRaw } from 'vue';
|
||||
import { mapState, mapWritableState, mapActions } from 'pinia'
|
||||
import { mapState, mapWritableState, mapActions, mapStores } from 'pinia'
|
||||
import { useErrorStore } from "../stores/error-store"
|
||||
import { useHeynoteStore } from "../stores/heynote-store.js"
|
||||
import { useEditorCacheStore } from "../stores/editor-cache"
|
||||
@ -12,33 +12,8 @@
|
||||
|
||||
export default {
|
||||
props: {
|
||||
theme: String,
|
||||
development: Boolean,
|
||||
debugSyntaxTree: Boolean,
|
||||
keymap: {
|
||||
type: String,
|
||||
default: "default",
|
||||
},
|
||||
emacsMetaKey: {
|
||||
type: String,
|
||||
default: "alt",
|
||||
},
|
||||
showLineNumberGutter: {
|
||||
type: Boolean,
|
||||
default: true,
|
||||
},
|
||||
showFoldGutter: {
|
||||
type: Boolean,
|
||||
default: true,
|
||||
},
|
||||
bracketClosing: {
|
||||
type: Boolean,
|
||||
default: false,
|
||||
},
|
||||
fontFamily: String,
|
||||
fontSize: Number,
|
||||
defaultBlockLanguage: String,
|
||||
defaultBlockLanguageAutoDetect: Boolean,
|
||||
},
|
||||
|
||||
components: {},
|
||||
@ -70,7 +45,9 @@
|
||||
|
||||
window.heynote.mainProcess.on(WINDOW_CLOSE_EVENT, this.onWindowClose)
|
||||
window.heynote.mainProcess.on(REDO_EVENT, this.onRedo)
|
||||
window.document.addEventListener("currenciesLoaded", this.onCurrenciesLoaded)
|
||||
|
||||
// initialize editorCacheStore (sets up watchers for settings changes, propagating them to all editors)
|
||||
this.editorCacheStore.setUp();
|
||||
|
||||
// if debugSyntaxTree prop is set, display syntax tree for debugging
|
||||
if (this.debugSyntaxTree) {
|
||||
@ -95,7 +72,7 @@
|
||||
beforeUnmount() {
|
||||
window.heynote.mainProcess.off(WINDOW_CLOSE_EVENT, this.onWindowClose)
|
||||
window.heynote.mainProcess.off(REDO_EVENT, this.onRedo)
|
||||
window.document.removeEventListener("currenciesLoaded", this.onCurrenciesLoaded)
|
||||
this.editorCacheStore.tearDown();
|
||||
},
|
||||
|
||||
watch: {
|
||||
@ -103,66 +80,10 @@
|
||||
//console.log("currentBufferPath changed to", path)
|
||||
this.loadBuffer(this.currentBufferPath)
|
||||
},
|
||||
|
||||
theme(newTheme) {
|
||||
this.eachEditor(editor => {
|
||||
editor.setTheme(newTheme)
|
||||
})
|
||||
},
|
||||
|
||||
keymap() {
|
||||
this.eachEditor(editor => {
|
||||
editor.setKeymap(this.keymap, this.emacsMetaKey)
|
||||
})
|
||||
},
|
||||
|
||||
emacsMetaKey() {
|
||||
this.eachEditor(editor => {
|
||||
editor.setKeymap(this.keymap, this.emacsMetaKey)
|
||||
})
|
||||
},
|
||||
|
||||
showLineNumberGutter(show) {
|
||||
this.eachEditor(editor => {
|
||||
editor.setLineNumberGutter(show)
|
||||
})
|
||||
},
|
||||
|
||||
showFoldGutter(show) {
|
||||
this.eachEditor(editor => {
|
||||
editor.setFoldGutter(show)
|
||||
})
|
||||
},
|
||||
|
||||
bracketClosing(value) {
|
||||
this.eachEditor(editor => {
|
||||
editor.setBracketClosing(value)
|
||||
})
|
||||
},
|
||||
|
||||
fontFamily() {
|
||||
this.eachEditor(editor => {
|
||||
editor.setFont(this.fontFamily, this.fontSize)
|
||||
})
|
||||
},
|
||||
fontSize() {
|
||||
this.eachEditor(editor => {
|
||||
editor.setFont(this.fontFamily, this.fontSize)
|
||||
})
|
||||
},
|
||||
defaultBlockLanguage() {
|
||||
this.eachEditor(editor => {
|
||||
editor.setDefaultBlockLanguage(this.defaultBlockLanguage, this.defaultBlockLanguageAutoDetect)
|
||||
})
|
||||
},
|
||||
defaultBlockLanguageAutoDetect() {
|
||||
this.eachEditor(editor => {
|
||||
editor.setDefaultBlockLanguage(this.defaultBlockLanguage, this.defaultBlockLanguageAutoDetect)
|
||||
})
|
||||
},
|
||||
},
|
||||
|
||||
computed: {
|
||||
...mapStores(useEditorCacheStore),
|
||||
...mapState(useHeynoteStore, [
|
||||
"currentBufferPath",
|
||||
"libraryId",
|
||||
@ -178,42 +99,21 @@
|
||||
},
|
||||
|
||||
methods: {
|
||||
...mapActions(useErrorStore, ["addError"]),
|
||||
...mapActions(useEditorCacheStore, ["getEditor", "addEditor", "eachEditor"]),
|
||||
|
||||
loadBuffer(path) {
|
||||
//console.log("loadBuffer", path)
|
||||
if (this.editor) {
|
||||
this.editor.hide()
|
||||
}
|
||||
|
||||
let cachedEditor = this.getEditor(path)
|
||||
let cachedEditor = this.editorCacheStore.getEditor(path)
|
||||
if (cachedEditor) {
|
||||
//console.log("show cached editor")
|
||||
this.editor = cachedEditor
|
||||
toRaw(this.editor).show()
|
||||
} else {
|
||||
//console.log("create new editor")
|
||||
try {
|
||||
this.editor = new HeynoteEditor({
|
||||
element: this.$refs.editor,
|
||||
path: path,
|
||||
theme: this.theme,
|
||||
keymap: this.keymap,
|
||||
emacsMetaKey: this.emacsMetaKey,
|
||||
showLineNumberGutter: this.showLineNumberGutter,
|
||||
showFoldGutter: this.showFoldGutter,
|
||||
bracketClosing: this.bracketClosing,
|
||||
fontFamily: this.fontFamily,
|
||||
fontSize: this.fontSize,
|
||||
defaultBlockToken: this.defaultBlockLanguage,
|
||||
defaultBlockAutoDetect: this.defaultBlockLanguageAutoDetect,
|
||||
})
|
||||
} catch (e) {
|
||||
this.addError("Error! " + e.message)
|
||||
throw e
|
||||
}
|
||||
this.addEditor(path, toRaw(this.editor))
|
||||
this.editor = this.editorCacheStore.createEditor(path, this.$refs.editor)
|
||||
this.editorCacheStore.addEditor(path, toRaw(this.editor))
|
||||
}
|
||||
|
||||
this.currentEditor = toRaw(this.editor)
|
||||
@ -236,12 +136,6 @@
|
||||
editor.focus()
|
||||
},
|
||||
|
||||
onCurrenciesLoaded() {
|
||||
if (this.editor) {
|
||||
toRaw(this.editor).currenciesLoaded()
|
||||
}
|
||||
},
|
||||
|
||||
focus() {
|
||||
toRaw(this.editor).focus()
|
||||
},
|
||||
|
@ -330,8 +330,8 @@ export class HeynoteEditor {
|
||||
}
|
||||
|
||||
setDefaultBlockLanguage(token, autoDetect) {
|
||||
this.defaultBlockToken = token
|
||||
this.defaultBlockAutoDetect = autoDetect
|
||||
this.defaultBlockToken = token || "text"
|
||||
this.defaultBlockAutoDetect = autoDetect === undefined ? true : autoDetect
|
||||
}
|
||||
|
||||
formatCurrentBlock() {
|
||||
|
@ -1,7 +1,11 @@
|
||||
import { toRaw } from 'vue';
|
||||
import { toRaw, watch } from 'vue';
|
||||
import { defineStore } from "pinia"
|
||||
import { NoteFormat } from "../common/note-format"
|
||||
|
||||
import { useSettingsStore } from './settings-store'
|
||||
import { useErrorStore } from './error-store'
|
||||
import { HeynoteEditor } from '../editor/editor'
|
||||
|
||||
const NUM_EDITOR_INSTANCES = 5
|
||||
|
||||
export const useEditorCacheStore = defineStore("editorCache", {
|
||||
@ -9,10 +13,36 @@ export const useEditorCacheStore = defineStore("editorCache", {
|
||||
editorCache: {
|
||||
lru: [],
|
||||
cache: {},
|
||||
watchHandler: null,
|
||||
themeWatchHandler: null,
|
||||
},
|
||||
}),
|
||||
|
||||
actions: {
|
||||
createEditor(path, element) {
|
||||
const settingsStore = useSettingsStore()
|
||||
const errorStore = useErrorStore()
|
||||
try {
|
||||
return new HeynoteEditor({
|
||||
element: element,
|
||||
path: path,
|
||||
theme: settingsStore.theme,
|
||||
keymap: settingsStore.settings.keymap,
|
||||
emacsMetaKey: settingsStore.settings.emacsMetaKey,
|
||||
showLineNumberGutter: settingsStore.settings.showLineNumberGutter,
|
||||
showFoldGutter: settingsStore.settings.showFoldGutter,
|
||||
bracketClosing: settingsStore.settings.bracketClosing,
|
||||
fontFamily: settingsStore.settings.fontFamily,
|
||||
fontSize: settingsStore.settings.fontSize,
|
||||
defaultBlockToken: settingsStore.settings.defaultBlockLanguage,
|
||||
defaultBlockAutoDetect: settingsStore.settings.defaultBlockLanguageAutoDetect,
|
||||
})
|
||||
} catch (e) {
|
||||
errorStore.addError("Error! " + e.message)
|
||||
throw e
|
||||
}
|
||||
},
|
||||
|
||||
getEditor(path) {
|
||||
// move to end of LRU
|
||||
this.editorCache.lru = this.editorCache.lru.filter(p => p !== path)
|
||||
@ -53,5 +83,66 @@ export const useEditorCacheStore = defineStore("editorCache", {
|
||||
this.editorCache.cache = {}
|
||||
this.editorCache.lru = []
|
||||
},
|
||||
|
||||
onCurrenciesLoaded() {
|
||||
this.eachEditor((editor) => {
|
||||
editor.currenciesLoaded()
|
||||
})
|
||||
},
|
||||
|
||||
setUp() {
|
||||
const settingsStore = useSettingsStore()
|
||||
this.watchHandler = watch(() => settingsStore.settings, (newSettings, oldSettings) => {
|
||||
//console.log("Settings changed (watch)", newSettings, oldSettings)
|
||||
const changedKeys = Object.keys(newSettings).filter(key => newSettings[key] !== oldSettings[key])
|
||||
|
||||
for (const key of changedKeys) {
|
||||
this.eachEditor((editor) => {
|
||||
switch (key) {
|
||||
case "keymap":
|
||||
case "emacsMetaKey":
|
||||
editor.setKeymap(newSettings.keymap, newSettings.emacsMetaKey)
|
||||
break
|
||||
case "showLineNumberGutter":
|
||||
editor.setLineNumberGutter(newSettings.showLineNumberGutter)
|
||||
break
|
||||
case "showFoldGutter":
|
||||
editor.setFoldGutter(newSettings.showFoldGutter)
|
||||
break
|
||||
case "bracketClosing":
|
||||
editor.setBracketClosing(newSettings.bracketClosing)
|
||||
break
|
||||
case "fontFamily":
|
||||
case "fontSize":
|
||||
editor.setFont(newSettings.fontFamily, newSettings.fontSize)
|
||||
break
|
||||
case "defaultBlockLanguage":
|
||||
case "defaultBlockLanguageAutoDetect":
|
||||
editor.setDefaultBlockLanguage(newSettings.defaultBlockLanguage, newSettings.defaultBlockLanguageAutoDetect)
|
||||
break
|
||||
}
|
||||
})
|
||||
}
|
||||
})
|
||||
|
||||
this.themeWatchHandler = watch(() => settingsStore.theme, (theme) => {
|
||||
this.eachEditor((editor) => {
|
||||
editor.setTheme(theme)
|
||||
})
|
||||
})
|
||||
|
||||
window.document.addEventListener("currenciesLoaded", this.onCurrenciesLoaded)
|
||||
},
|
||||
|
||||
tearDown() {
|
||||
if (this.watchHandler) {
|
||||
this.watchHandler()
|
||||
}
|
||||
if (this.themeWatchHandler) {
|
||||
this.themeWatchHandler()
|
||||
}
|
||||
|
||||
window.document.removeEventListener("currenciesLoaded", this.onCurrenciesLoaded)
|
||||
},
|
||||
},
|
||||
})
|
||||
|
49
src/stores/settings-store.js
Normal file
49
src/stores/settings-store.js
Normal file
@ -0,0 +1,49 @@
|
||||
import { defineStore } from "pinia"
|
||||
|
||||
import { SETTINGS_CHANGE_EVENT } from '@/src/common/constants'
|
||||
|
||||
export const useSettingsStore = defineStore("settings", {
|
||||
state: () => {
|
||||
return {
|
||||
settings: window.heynote.settings,
|
||||
themeSetting: "system",
|
||||
theme: window.heynote.themeMode.initial,
|
||||
}
|
||||
},
|
||||
|
||||
actions: {
|
||||
onSettingsChange(settings) {
|
||||
this.settings = settings
|
||||
},
|
||||
|
||||
setTheme(theme) {
|
||||
window.heynote.themeMode.set(theme)
|
||||
this.themeSetting = theme
|
||||
},
|
||||
|
||||
setUp() {
|
||||
window.heynote.mainProcess.on(SETTINGS_CHANGE_EVENT, (event, settings) => {
|
||||
this.onSettingsChange(settings)
|
||||
})
|
||||
|
||||
window.heynote.themeMode.get().then((mode) => {
|
||||
this.theme = mode.computed
|
||||
this.themeSetting = mode.theme
|
||||
})
|
||||
const onThemeChange = (theme) => {
|
||||
this.theme = theme
|
||||
if (theme === "system") {
|
||||
document.documentElement.setAttribute("theme", window.matchMedia("(prefers-color-scheme: dark)").matches ? "dark" : "light")
|
||||
} else {
|
||||
document.documentElement.setAttribute("theme", theme)
|
||||
}
|
||||
}
|
||||
onThemeChange(window.heynote.themeMode.initial)
|
||||
window.heynote.themeMode.onChange(onThemeChange)
|
||||
},
|
||||
|
||||
tearDown() {
|
||||
window.heynote.themeMode.removeListener()
|
||||
}
|
||||
},
|
||||
})
|
Loading…
Reference in New Issue
Block a user