热键覆盖逻辑由插件类转移到视图类

This commit is contained in:
街角小林 2025-09-03 08:53:37 +08:00
parent c702676605
commit bc138da385
5 changed files with 53 additions and 69 deletions

View file

@ -1,6 +1,6 @@
【[English](./README_en.md) | 简体中文】
# SimpleMindMap Obsidian 插件
# SimpleMindMap 插件
为 Obsidian 提供一个好用的思维导图插件。

View file

@ -1,6 +1,6 @@
【English | [简体中文](./README_zh.md)】
# SimpleMindMap Obsidian Plugin
# SimpleMindMap Plugin
Provides a user-friendly mind map plugin for Obsidian.

View file

@ -62,6 +62,7 @@ class SmmEditView extends TextFileView {
this.savingTipEl = null
this.isReadonlyMode = false
this.toggleReadonlyButton = null
this.popScope = null
}
// 获取视图类型
@ -130,6 +131,9 @@ class SmmEditView extends TextFileView {
}
})
}
// 注册热键覆盖
this._registerHotkeyOverrides()
}
// 获取视图数据(保存到文件)
@ -155,9 +159,8 @@ class SmmEditView extends TextFileView {
this.parsedMindMapData = parseMarkdownText(rawData)
const content = this.parsedMindMapData.metadata.content
if (content) {
this.parsedMindMapData.metadata.content = LZString.decompressFromBase64(
content
)
this.parsedMindMapData.metadata.content =
LZString.decompressFromBase64(content)
} else {
throw new Error('文件格式错误')
}
@ -521,6 +524,8 @@ class SmmEditView extends TextFileView {
const nowActive = leaf?.view === this
if (nowActive && !this.isActive) {
// 标签被激活
// 注册热键覆盖
this._registerHotkeyOverrides()
this.isActive = true
// 激活后刷新视图
if (this.mindMapAPP) {
@ -540,6 +545,8 @@ class SmmEditView extends TextFileView {
}
} else if (!nowActive && this.isActive) {
// 标签失去激活
// 清理热键覆盖
this._clearPopScope()
const rect = this.warpEl.getBoundingClientRect()
this.isHidden = rect.width === 0 || rect.height === 0
if (this.mindMapAPP) {
@ -596,6 +603,7 @@ class SmmEditView extends TextFileView {
}
async onClose() {
this._clearPopScope()
await this.save() // 手动保存
this.clear()
this.saveButton = null
@ -843,6 +851,38 @@ class SmmEditView extends TextFileView {
return ''
}
}
// 清理之前的热键覆盖
_clearPopScope() {
if (this.popScope) {
this.popScope()
this.popScope = null
}
}
// 注册热键覆盖
_registerHotkeyOverrides() {
this._clearPopScope()
const scope = this.app.keymap.getRootScope()
const ctrlFHandler = scope.register(['Mod'], 'f', evt => {
evt.preventDefault()
return true
})
const ctrlSHandler = scope.register(['Mod'], 's', evt => {
evt.preventDefault()
const view = this.plugin._getActiveSmmView()
if (view) {
view.forceSave()
}
return true
})
scope.keys.unshift(scope.keys.pop())
scope.keys.unshift(scope.keys.pop())
this.popScope = () => {
scope.unregister(ctrlFHandler)
scope.unregister(ctrlSHandler)
}
}
}
export default SmmEditView

View file

@ -328,6 +328,11 @@ export default class SimpleMindMapPlugin extends Plugin {
})
}
// 获取当前激活的思维导图视图
_getActiveSmmView() {
return this.app.workspace.getActiveViewOfType(SmmEditView, IGNORE_CHECK_SMM)
}
// 判断文件是否为思维导图
_isSmmFile(file) {
if (!file) {

View file

@ -1,72 +1,15 @@
import { Notice } from 'obsidian'
import { IGNORE_CHECK_SMM } from './constant.js'
import SmmEditView from '../SmmEditView.js'
export default class Commands {
constructor(plugin) {
this.plugin = plugin
this.app = plugin.app
this.popScope = null
this._initHotkeyOverrides()
this._addCreatesCommand()
this._addActionsCommand()
}
clear() {
if (this.popScope) this.popScope()
}
_initHotkeyOverrides() {
this._registerHotkeyOverrides()
// 监听视图切换事件
this.plugin.registerEvent(
this.app.workspace.on('active-leaf-change', leaf => {
this._registerHotkeyOverrides()
})
)
}
_registerHotkeyOverrides() {
// 清理之前的覆盖
if (this.popScope) {
this.popScope()
this.popScope = null
}
const activeView = this.app.workspace.activeLeaf?.view
if (!(activeView instanceof SmmEditView)) {
return
}
const scope = this.app.keymap.getRootScope()
// 1. 覆盖 Ctrl+F
const ctrlFHandler = scope.register(['Mod'], 'f', evt => {
evt.preventDefault() // 阻止浏览器默认查找
return true // 表示已处理
})
// 2. 覆盖 Ctrl+S
const ctrlSHandler = scope.register(['Mod'], 's', evt => {
evt.preventDefault() // 阻止浏览器保存对话框
const view = this._getActiveSmmView()
if (view) {
view.forceSave()
}
return true
})
// 提升处理器优先级
scope.keys.unshift(scope.keys.pop()) // 移动 Ctrl+S
scope.keys.unshift(scope.keys.pop()) // 移动 Ctrl+F
// 设置清理函数
this.popScope = () => {
scope.unregister(ctrlFHandler)
scope.unregister(ctrlSHandler)
}
}
clear() {}
addCommand(command) {
this.plugin.addCommand(command)
@ -120,7 +63,7 @@ export default class Commands {
id: 'enter-smm-mindmap-demonstrate',
name: this._t('action.enterDemonstrate'),
checkCallback: checking => {
const view = this._getActiveSmmView()
const view = this.plugin._getActiveSmmView()
if (view) {
if (!checking) {
view.mindMapAPP.$bus.$emit('enter_demonstrate')
@ -141,7 +84,7 @@ export default class Commands {
}
],
checkCallback: checking => {
const view = this._getActiveSmmView()
const view = this.plugin._getActiveSmmView()
if (view) {
if (!checking) {
view.forceSaveAndUpdateImage()
@ -152,8 +95,4 @@ export default class Commands {
}
})
}
_getActiveSmmView() {
return this.app.workspace.getActiveViewOfType(SmmEditView, IGNORE_CHECK_SMM)
}
}