mirror of
https://github.com/purocean/yn.git
synced 2026-09-24 15:46:02 +08:00
feat(editor-restore-state): enhance view state management with debounced saving and reactive storage
This commit is contained in:
@@ -1,35 +1,64 @@
|
||||
import type { Plugin } from '@fe/context'
|
||||
import { registerHook } from '@fe/core/hook'
|
||||
|
||||
const viewStateCache = new Map<string, any>()
|
||||
import type { editor } from 'monaco-editor'
|
||||
|
||||
export default {
|
||||
name: 'editor-restore-state',
|
||||
register: (ctx) => {
|
||||
const logger = ctx.utils.getLogger('plugin:editor-restore-state')
|
||||
const storageKey = 'plugin.editor-state'
|
||||
|
||||
const viewStateCache = ctx.lib.vue.shallowReactive<Record<string, { _t: number, v: any }>>(ctx.storage.get<any>(storageKey, {}))
|
||||
|
||||
ctx.lib.vue.watch(viewStateCache, () => {
|
||||
// keep recent 10 view states
|
||||
const entries = Object.entries(viewStateCache)
|
||||
.sort((a, b) => b[1]._t - a[1]._t)
|
||||
.slice(0, 10)
|
||||
|
||||
ctx.storage.set(storageKey, Object.fromEntries(entries))
|
||||
})
|
||||
|
||||
function saveState (uri: editor.ITextModel['uri'] | null | undefined, viewState: editor.ICodeEditorViewState | null) {
|
||||
if (!uri) return
|
||||
|
||||
const uriStr = uri.toString()
|
||||
logger.debug('save view state', uriStr)
|
||||
viewStateCache[uriStr] = {
|
||||
_t: Date.now(),
|
||||
v: viewState
|
||||
}
|
||||
}
|
||||
|
||||
const saveStateDebounced = ctx.lib.lodash.debounce(saveState, 500)
|
||||
|
||||
registerHook('DOC_BEFORE_SWITCH', () => {
|
||||
ctx.editor.whenEditorReady().then(({ editor }) => {
|
||||
const currentDoc = ctx.store.state.currentFile
|
||||
const uri = ctx.doc.toUri(currentDoc)
|
||||
const uri = editor.getModel()?.uri
|
||||
if (!uri) return
|
||||
const viewState = editor.saveViewState()
|
||||
|
||||
logger.debug('save view state', uri)
|
||||
viewStateCache.set(uri, viewState)
|
||||
saveState(uri, viewState)
|
||||
})
|
||||
})
|
||||
|
||||
ctx.editor.whenEditorReady().then(({ editor }) => {
|
||||
editor.onDidChangeModel(() => {
|
||||
// restore view state
|
||||
const currentDoc = ctx.store.state.currentFile
|
||||
const uri = ctx.doc.toUri(currentDoc)
|
||||
const viewState = viewStateCache.get(ctx.doc.toUri(currentDoc))
|
||||
if (viewState) {
|
||||
editor.onDidChangeModel((e) => {
|
||||
const uri = e.newModelUrl?.toString()
|
||||
if (!uri) return
|
||||
const viewState = viewStateCache[uri]
|
||||
if (viewState && viewState.v) {
|
||||
logger.debug('restore view state', uri)
|
||||
editor.restoreViewState(viewState)
|
||||
editor.restoreViewState(viewState.v)
|
||||
}
|
||||
})
|
||||
|
||||
editor.onDidChangeCursorPosition(() => {
|
||||
saveStateDebounced(editor.getModel()?.uri, editor.saveViewState())
|
||||
})
|
||||
|
||||
editor.onDidScrollChange(() => {
|
||||
saveStateDebounced(editor.getModel()?.uri, editor.saveViewState())
|
||||
})
|
||||
})
|
||||
|
||||
ctx.lib.vue.watch(() => ctx.store.state.tabs, () => {
|
||||
@@ -37,10 +66,10 @@ export default {
|
||||
const uris = ctx.store.state.tabs.map(x => x.key)
|
||||
|
||||
// clean view state
|
||||
for (const uri of viewStateCache.keys()) {
|
||||
for (const uri of Object.keys(viewStateCache)) {
|
||||
if (!uris.includes(uri)) {
|
||||
logger.debug('dispose view state', uri)
|
||||
viewStateCache.delete(uri)
|
||||
delete viewStateCache[uri]
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user