Compare commits

...

11 Commits

Author SHA1 Message Date
zsviczian
c3809c409d autosave tweaks 2024-08-30 08:32:27 +00:00
zsviczian
dfdca90ca5 2.4.0-rc-2 2024-08-29 23:18:01 +02:00
zsviczian
6a8e1735db update nvmrc to 18 2024-08-29 20:29:54 +02:00
zsviczian
c0e9a0553e minor build changes 2024-08-29 20:24:59 +02:00
zsviczian
e1501165d9 Merge pull request #1971 from dmscode/master
Update zh-cn.ts to hotekey override, hide spalsh, save active tool, r…
2024-08-29 15:04:15 +02:00
dmscode
3b0f706059 Update zh-cn.ts to hotekey override, hide spalsh, save active tool, remove comments in p… … 2024-08-29 18:27:50 +08:00
zsviczian
7d19662f68 Merge pull request #1970 from zsviczian/hotkey-override
hotekey override, hide spalsh, save active tool, remove comments in p…
2024-08-29 11:58:30 +02:00
zsviczian
5c949dc71c hotekey override, hide spalsh, save active tool, remove comments in prod build 2024-08-29 09:57:53 +00:00
zsviczian
0439d67a0c Merge pull request #1966 from dmscode/master
Update zh-cn.ts to 2.4.0-rc-1
2024-08-29 09:00:59 +02:00
dmscode
d3446a20b1 Update zh-cn.ts to 2.4.0-rc-1 2024-08-28 20:45:21 +08:00
zsviczian
5b37dc2e38 save on contentEl mouseleave 2024-08-28 12:34:56 +02:00
17 changed files with 360 additions and 107 deletions

2
.nvmrc
View File

@@ -1 +1 @@
16
18

View File

@@ -2,31 +2,3 @@ The project runs with `node 18`.
After running `npm -i` you'll need to make two manual changes:
## postprocess
postprocess is used in rollup.config.js.
However, the version available on npmjs does not work, after installing packages you need this update:
`npm install brettz9/rollup-plugin-postprocess#update --save-dev``
More info here: https://github.com/developit/rollup-plugin-postprocess/issues/10
## colormaster
1.2.1 misses 3 plugin references after installing the package you need to update
`node_modules/colormaster/package.json` adding the following to the `exports:` section:
```typescript
,
"./plugins/luv": {
"import": "./plugins/luv.mjs",
"require": "./plugins/luv.js",
"default": "./plugins/luv.mjs"
},
"./plugins/uvw": {
"import": "./plugins/uvw.mjs",
"require": "./plugins/uvw.js",
"default": "./plugins/uvw.mjs"
},
"./plugins/ryb": {
"import": "./plugins/ryb.mjs",
"require": "./plugins/ryb.js",
"default": "./plugins/ryb.mjs"
}
```

View File

@@ -1,7 +1,7 @@
{
"id": "obsidian-excalidraw-plugin",
"name": "Excalidraw",
"version": "2.4.0-rc-1",
"version": "2.4.0-rc-2",
"minAppVersion": "1.1.6",
"description": "An Obsidian plugin to edit and view Excalidraw drawings",
"author": "Zsolt Viczian",

View File

@@ -19,28 +19,32 @@
"license": "MIT",
"dependencies": {
"@popperjs/core": "^2.11.8",
"@zsviczian/excalidraw": "0.17.1-obsidian-43",
"@zsviczian/excalidraw": "0.17.1-obsidian-45",
"chroma-js": "^2.4.2",
"clsx": "^2.0.0",
"colormaster": "^1.2.1",
"@zsviczian/colormaster": "^1.2.2",
"gl-matrix": "^3.4.3",
"js-yaml": "^4.1.0",
"lucide-react": "^0.263.1",
"mathjax-full": "^3.2.2",
"monkey-around": "^2.3.0",
"nanoid": "^4.0.2",
"opentype.js": "^1.3.4",
"polybooljs": "^1.2.0",
"react": "^18.2.0",
"react-dom": "^18.2.0",
"roughjs": "^4.5.2",
"js-yaml": "^4.1.0",
"opentype.js": "^1.3.4",
"woff2sfnt-sfnt2woff": "^1.0.0"
},
"devDependencies": {
"dotenv": "^16.4.5",
"@babel/core": "^7.22.9",
"@babel/preset-env": "^7.22.10",
"@babel/preset-react": "^7.22.5",
"@codemirror/commands": "^6.3.3",
"@codemirror/language": "^6.10.0",
"@codemirror/search": "^6.5.5",
"@codemirror/state": "^6.4.0",
"@codemirror/view": "^6.23.0",
"@excalidraw/eslint-config": "^1.0.3",
"@excalidraw/prettier-config": "^1.0.2",
"@rollup/plugin-babel": "^6.0.3",
@@ -50,14 +54,15 @@
"@rollup/plugin-typescript": "^11.1.6",
"@types/chroma-js": "^2.4.0",
"@types/js-beautify": "^1.14.0",
"@types/js-yaml": "^4.0.9",
"@types/node": "^20.10.5",
"@types/opentype.js": "^1.3.8",
"@types/react": "^18.2.45",
"@types/react-dom": "^18.2.18",
"@types/js-yaml": "^4.0.9",
"@types/opentype.js": "^1.3.8",
"@zerollup/ts-transform-paths": "^1.7.18",
"cross-env": "^7.0.3",
"cssnano": "^6.0.2",
"dotenv": "^16.4.5",
"eslint-config-prettier": "^9.0.0",
"eslint-plugin-prettier": "^5.0.0",
"lz-string": "^1.5.0",
@@ -65,17 +70,12 @@
"prettier": "^3.0.1",
"rollup": "^2.70.1",
"rollup-plugin-copy": "^3.5.0",
"rollup-plugin-postprocess": "github:brettz9/rollup-plugin-postprocess#update",
"@zsviczian/rollup-plugin-postprocess": "^1.0.3",
"rollup-plugin-terser": "^7.0.2",
"rollup-plugin-typescript2": "^0.34.1",
"tslib": "^2.6.1",
"ttypescript": "^1.5.15",
"typescript": "^5.2.2",
"@codemirror/commands": "^6.3.3",
"@codemirror/language": "^6.10.0",
"@codemirror/search": "^6.5.5",
"@codemirror/state": "^6.4.0",
"@codemirror/view": "^6.23.0"
"typescript": "^5.2.2"
},
"resolutions": {
"@typescript-eslint/typescript-estree": "5.3.0"

View File

@@ -6,7 +6,7 @@ import copy from "rollup-plugin-copy";
import typescript2 from "rollup-plugin-typescript2";
import fs from 'fs';
import LZString from 'lz-string';
import postprocess from 'rollup-plugin-postprocess';
import postprocess from '@zsviczian/rollup-plugin-postprocess';
import cssnano from 'cssnano';
// Load environment variables
@@ -100,10 +100,13 @@ const BUILD_CONFIG = {
plugins: getRollupPlugins(
{tsconfig: isProd ? "tsconfig.json" : "tsconfig.dev.json"},
...(isProd ? [
terser({ toplevel: false, compress: { passes: 2 } }),
//!postprocess - the version available on npmjs does not work, need this update:
// npm install brettz9/rollup-plugin-postprocess#update --save-dev
// https://github.com/developit/rollup-plugin-postprocess/issues/10
terser({
toplevel: false,
compress: { passes: 2 },
format: {
comments: false, // Remove all comments
},
}),
postprocess([
[/React=require\("react"\),state=require\("@codemirror\/state"\),view=require\("@codemirror\/view"\)/,
`state=require("@codemirror/state"),view=require("@codemirror/view")` + packageString],

View File

@@ -473,6 +473,8 @@ export class EmbeddedFilesLoader {
return null;
}
const app = this.plugin.app;
const isHyperLink = inFile instanceof EmbeddedFile ? inFile.isHyperLink : false;
const isLocalLink = inFile instanceof EmbeddedFile ? inFile.isLocalLink : false;
const hyperlink = inFile instanceof EmbeddedFile ? inFile.hyperlink : "";

View File

@@ -63,21 +63,21 @@ import { GenericInputPrompt, NewFileActions } from "src/dialogs/Prompt";
import { t } from "src/lang/helpers";
import { ScriptEngine } from "src/Scripts";
import { ConnectionPoint, DeviceType } from "src/types/types";
import CM, { ColorMaster, extendPlugins } from "colormaster";
import HarmonyPlugin from "colormaster/plugins/harmony";
import MixPlugin from "colormaster/plugins/mix"
import A11yPlugin from "colormaster/plugins/accessibility"
import NamePlugin from "colormaster/plugins/name"
import LCHPlugin from "colormaster/plugins/lch";
import LUVPlugin from "colormaster/plugins/luv";
import LABPlugin from "colormaster/plugins/lab";
import UVWPlugin from "colormaster/plugins/uvw";
import XYZPlugin from "colormaster/plugins/xyz";
import HWBPlugin from "colormaster/plugins/hwb";
import HSVPlugin from "colormaster/plugins/hsv";
import RYBPlugin from "colormaster/plugins/ryb";
import CMYKPlugin from "colormaster/plugins/cmyk";
import { TInput } from "colormaster/types";
import CM, { ColorMaster, extendPlugins } from "@zsviczian/colormaster";
import HarmonyPlugin from "@zsviczian/colormaster/plugins/harmony";
import MixPlugin from "@zsviczian/colormaster/plugins/mix"
import A11yPlugin from "@zsviczian/colormaster/plugins/accessibility"
import NamePlugin from "@zsviczian/colormaster/plugins/name"
import LCHPlugin from "@zsviczian/colormaster/plugins/lch";
import LUVPlugin from "@zsviczian/colormaster/plugins/luv";
import LABPlugin from "@zsviczian/colormaster/plugins/lab";
import UVWPlugin from "@zsviczian/colormaster/plugins/uvw";
import XYZPlugin from "@zsviczian/colormaster/plugins/xyz";
import HWBPlugin from "@zsviczian/colormaster/plugins/hwb";
import HSVPlugin from "@zsviczian/colormaster/plugins/hsv";
import RYBPlugin from "@zsviczian/colormaster/plugins/ryb";
import CMYKPlugin from "@zsviczian/colormaster/plugins/cmyk";
import { TInput } from "@zsviczian/colormaster/types";
import {ConversionResult, svgToExcalidraw} from "src/svgToExcalidraw/parser"
import { ROUNDNESS } from "src/constants/constants";
import { ClipboardData } from "@zsviczian/excalidraw/types/excalidraw/clipboard";

View File

@@ -838,6 +838,7 @@ export default class ExcalidrawView extends TextFileView {
if(triggerReload) {
this.reload(true, this.file);
}
this.resetAutosaveTimer(); //next autosave period starts after save
}
// get the new file content
@@ -1534,8 +1535,16 @@ export default class ExcalidrawView extends TextFileView {
}
};
const onMouseLeave = () => {
if(!this.excalidrawAPI || !this.excalidrawData.loaded || !this.isDirty()) {
return;
}
this.save();
};
this.registerDomEvent(this.ownerWindow, "keydown", onKeyDown, false);
this.registerDomEvent(this.ownerWindow, "keyup", onKeyUp, false);
this.registerDomEvent(this.contentEl, "mouseleave", onMouseLeave, false);
});
this.setupAutosaveTimer();
@@ -1728,7 +1737,7 @@ export default class ExcalidrawView extends TextFileView {
this.semaphores.autosaving = true;
//changed from await to then to avoid lag during saving of large file
this.save().then(()=>this.semaphores.autosaving = false);
}
}
this.autosaveTimer = window.setTimeout(
timer,
this.autosaveInterval,
@@ -1762,7 +1771,6 @@ export default class ExcalidrawView extends TextFileView {
this.autosaveFunction,
this.autosaveInterval,
);
}
unload(): void {
@@ -3342,6 +3350,7 @@ export default class ExcalidrawView extends TextFileView {
currentStrokeOptions: st.currentStrokeOptions,
frameRendering: st.frameRendering,
objectsSnapModeEnabled: st.objectsSnapModeEnabled,
activeTool: st.activeTool,
},
prevTextMode: this.prevTextMode,
files,
@@ -5246,6 +5255,7 @@ export default class ExcalidrawView extends TextFileView {
}
private renderWelcomeScreen () {
if(!this.plugin.settings.showSplashscreen) return null;
const React = this.packages.react;
const {WelcomeScreen} = this.packages.excalidrawLib;
const filecount = this.app.vault.getFiles().filter(f=>this.plugin.isExcalidrawFile(f)).length;

162
src/dialogs/HotkeyEditor.ts Normal file
View File

@@ -0,0 +1,162 @@
import { BaseComponent, Setting, Modifier } from 'obsidian';
import { DEVICE } from 'src/constants/constants';
import { t } from 'src/lang/helpers';
import { ExcalidrawSettings } from 'src/settings';
import { modifierLabel } from 'src/utils/ModifierkeyHelper';
import { fragWithHTML } from 'src/utils/Utils';
export class HotkeyEditor extends BaseComponent {
private settings: ExcalidrawSettings;
private containerEl: HTMLElement;
private capturing: boolean = false;
private activeModifiers: Modifier[] = [];
public isDirty: boolean = false;
private applySettingsUpdate: Function;
// Store bound event handlers
private boundKeydownHandler: (event: KeyboardEvent) => void;
private boundKeyupHandler: (event: KeyboardEvent) => void;
constructor(containerEl: HTMLElement, settings: ExcalidrawSettings, applySettingsUpdate: Function) {
super();
this.containerEl = containerEl.createDiv();
this.settings = settings;
this.applySettingsUpdate = applySettingsUpdate;
// Bind the event handlers once in the constructor
this.boundKeydownHandler = this.onKeydown.bind(this);
this.boundKeyupHandler = this.onKeyup.bind(this);
}
onload(): void {
this.render();
}
private render(): void {
// Clear previous content
this.containerEl.empty();
// Render current overrides
this.settings.modifierKeyOverrides.forEach((override, index) => {
const key = override.key.toUpperCase();
new Setting(this.containerEl)
.setDesc(fragWithHTML(`<b>Code:</b> <kbd>${override.modifiers.join("+")} + ${key}</kbd> | ` +
`<b>Apple:</b> <kbd>${modifierLabel(override.modifiers, "Mac")} + ${key}</kbd> | ` +
`<b>Windows:</b> <kbd>${modifierLabel(override.modifiers, "Other")} + ${key}</kbd>`))
.addButton((button) =>
button
.setButtonText(t("HOTKEY_BUTTON_REMOVE"))
.setCta()
.onClick(() => {
this.settings.modifierKeyOverrides.splice(index, 1);
this.isDirty = true;
this.applySettingsUpdate();
this.render();
})
);
});
// Render Add New Override or Capture Instruction
if (this.capturing) {
new Setting(this.containerEl)
.setName(t("HOTKEY_PRESS_COMBO_NANE"))
.setDesc(t("HOTKEY_PRESS_COMBO_DESC"))
.controlEl.style.cursor = 'pointer';
} else {
new Setting(this.containerEl)
.addButton((button) =>
button
.setButtonText(t("HOTKEY_BUTTON_ADD_OVERRIDE"))
.setCta()
.onClick(() => this.startCapture())
);
}
}
private startCapture(): void {
this.capturing = true;
this.activeModifiers = [];
this.render();
// Use the pre-bound handlers
window.addEventListener('keydown', this.boundKeydownHandler);
window.addEventListener('keyup', this.boundKeyupHandler);
}
private onKeydown(event: KeyboardEvent): void {
event.preventDefault();
event.stopPropagation();
const modifiers = this.getModifiersFromEvent(event);
// If only modifiers are pressed, update activeModifiers and continue listening
if (['Control', 'Shift', 'Alt', 'Meta'].includes(event.key)) {
this.activeModifiers = modifiers;
return;
}
const key = event.key.length === 1 ? event.key.toLowerCase() : event.key;
// Check for duplicate overrides
const exists = this.settings.modifierKeyOverrides.some(
(override) =>
override.key === key &&
override.modifiers.length === modifiers.length &&
override.modifiers.every((mod) => modifiers.includes(mod))
);
if (!exists) {
this.settings.modifierKeyOverrides.push({ modifiers, key });
this.isDirty = true;
this.applySettingsUpdate();
}
this.stopCapture();
}
private onKeyup(event: KeyboardEvent): void {
// If all modifier keys are released, stop capturing
if (!event.ctrlKey && !event.shiftKey && !event.altKey && !event.metaKey) {
this.stopCapture();
}
}
private stopCapture(): void {
this.capturing = false;
// Use the pre-bound handlers for removal
window.removeEventListener('keydown', this.boundKeydownHandler);
window.removeEventListener('keyup', this.boundKeyupHandler);
this.render();
}
public unload(): void {
// Ensure listeners are removed when the component is unloaded
this.stopCapture();
}
private getModifiersFromEvent(event: KeyboardEvent): Modifier[] {
const modifiers: Modifier[] = [];
if (DEVICE.isMacOS && event.metaKey) {
modifiers.push('Mod');
} else if (!DEVICE.isMacOS && event.ctrlKey) {
modifiers.push('Mod');
}
if (DEVICE.isMacOS && event.ctrlKey) {
modifiers.push('Ctrl');
}
if (!DEVICE.isMacOS && event.metaKey) {
modifiers.push('Meta');
}
if (event.shiftKey) {
modifiers.push('Shift');
}
if (event.altKey) {
modifiers.push('Alt');
}
return modifiers;
}
}

View File

@@ -37,6 +37,7 @@ export default {
TRANSCLUDE: "Embed a drawing",
TRANSCLUDE_MOST_RECENT: "Embed the most recently edited drawing",
TOGGLE_LEFTHANDED_MODE: "Toggle left-handed mode",
TOGGLE_SPLASHSCREEN: "Show splash screen in new drawings",
FLIP_IMAGE: "Open the back-of-the-note of the selected excalidraw image",
NEW_IN_NEW_PANE: "Create new drawing - IN AN ADJACENT WINDOW",
NEW_IN_NEW_TAB: "Create new drawing - IN A NEW TAB",
@@ -352,6 +353,10 @@ FILENAME_HEAD: "Filename",
"<li>When <b>disabled</b> the PDF will show the markdown side of the document.</li></ul>" +
"See the other related setting for <a href='#"+TAG_MDREADINGMODE+"'>Markdown Reading Mode</a> under 'Appearnace and Behavior' further above.<br>" +
"⚠️ Note, you must close the active excalidraw/markdown file and reopen for this change to take effect. ⚠️",
HOTKEY_OVERRIDE_HEAD: "Hotkey overrides",
HOTKEY_OVERRIDE_DESC: `Some of the Excalidraw hotkeys such as <code>${labelCTRL()}+Enter</code> to edit text or <code>${labelCTRL()}+K</code> to create an element link ` +
"conflict with Obsidian hotkey settings. The hotkey combinations you add below will override Obsidian's hotkey settings while useing Excalidraw, thus " +
`you can add <code>${labelCTRL()}+G</code> if you want to default to Group Object in Excalidraw instead of opening Graph View.`,
THEME_HEAD: "Theme and styling",
ZOOM_HEAD: "Zoom",
DEFAULT_PINCHZOOM_NAME: "Allow pinch zoom in pen mode",
@@ -739,6 +744,12 @@ FILENAME_HEAD: "Filename",
"the developer of Taskbone (as you can imagine, there is no such thing as 'free', providing this awesome OCR service costs some money to the developer of Taskbone), you can " +
"purchase a paid API key from <a href='https://www.taskbone.com/' target='_blank'>taskbone.com</a>. In case you have purchased a key, simply overwrite this auto generated free-tier API-key with your paid key.",
//HotkeyEditor
HOTKEY_PRESS_COMBO_NANE: "Press your hotkey combination",
HOTKEY_PRESS_COMBO_DESC: "Please press the desired key combination",
HOTKEY_BUTTON_ADD_OVERRIDE: "Add New Override",
HOTKEY_BUTTON_REMOVE: "Remove",
//openDrawings.ts
SELECT_FILE: "Select a file then press enter.",
SELECT_COMMAND: "Select a command then press enter.",

View File

@@ -37,6 +37,7 @@ export default {
TRANSCLUDE: "嵌入绘图(形如 ![[drawing]])到当前 Markdown 文档中",
TRANSCLUDE_MOST_RECENT: "嵌入最近编辑过的绘图(形如 ![[drawing]])到当前 Markdown 文档中",
TOGGLE_LEFTHANDED_MODE: "切换为左手模式",
TOGGLE_SPLASHSCREEN: "在新绘图中显示启动画面",
FLIP_IMAGE: "打开当前所选 excalidraw 图像的“背景笔记”",
NEW_IN_NEW_PANE: "新建绘图 - 于新面板",
NEW_IN_NEW_TAB: "新建绘图 - 于新页签",
@@ -352,6 +353,10 @@ FILENAME_HEAD: "文件名",
"<li>当 <b>禁用</b> 时PDF 将显示文档的 Markdown 部分(背景笔记)。</li></ul>" +
"请参阅上面‘外观和行为’部分的 <<a href='#"+TAG_MDREADINGMODE+"'>>Markdown 阅读模式</a> 相关设置。" +
"⚠️ 注意,您必须关闭当前的 Excalidraw/Markdown 文件并重新打开,以使此更改生效。⚠️",
HOTKEY_OVERRIDE_HEAD: "热键覆盖",
HOTKEY_OVERRIDE_DESC: `一些 Excalidraw 的热键,例如 ${labelCTRL()}+Enter 用于编辑文本,或 ${labelCTRL()}+K 用于创建元素链接。` +
"与 Obsidian 的热键设置发生冲突。您在下面添加的热键组合将在使用 Excalidraw 时覆盖 Obsidian 的热键设置," +
`因此如果您希望在 Excalidraw 中默认选择“组合对象”,而不是打开“图形视图”,您可以添加 ${labelCTRL()}+G。`,
THEME_HEAD: "主题和样式",
ZOOM_HEAD: "缩放",
DEFAULT_PINCHZOOM_NAME: "允许在触控笔模式下进行双指缩放",
@@ -477,7 +482,11 @@ FILENAME_HEAD: "文件名",
EMBED_TOEXCALIDRAW_DESC: "包括:以图像形式嵌入到绘图中的 PDF 文档、以交互形式嵌入到绘图中的 Markdown 文档MD-Embeddable、以图像形式嵌入的 Markdown 文档MD-Embed等。",
MD_HEAD: "以图像形式嵌入到绘图中的 Markdown 文档MD-Embed",
MD_EMBED_CUSTOMDATA_HEAD_NAME: "以交互形式嵌入到绘图中的 Markdown 文档MD-Embeddable",
MD_EMBED_CUSTOMDATA_HEAD_DESC: `这些选项不会影响到已存在的 MD-Embeddable。MD-Embeddable 的主题风格在“显示 & 行为”小节设置`,
MD_EMBED_CUSTOMDATA_HEAD_DESC: `以下设置只会影响以后的嵌入。已存在的嵌入保持不变。嵌入框的主题设置位于 “Excalidraw 外观和行为” 部分`,
MD_EMBED_SINGLECLICK_EDIT_NAME: "单击以编辑嵌入的 markdown。",
MD_EMBED_SINGLECLICK_EDIT_DESC:
"单击嵌入的 markdown 文件以进行编辑。 " +
"当此功能关闭时markdown 文件将首先以预览模式打开,然后在您再次单击时切换到编辑模式。",
MD_TRANSCLUDE_WIDTH_NAME: "MD-Embed 的默认宽度",
MD_TRANSCLUDE_WIDTH_DESC:
"MD-Embed 的宽度。该选项会影响到折行,以及图像元素的宽度。<br>" +
@@ -735,6 +744,12 @@ FILENAME_HEAD: "文件名",
"Taskbone 的开发者您懂的没有人能用爱发电Taskbone 开发者也需要投入资金来维持这项 OCR 服务)您可以" +
"到 <a href='https://www.taskbone.com/' target='_blank'>taskbone.com</a> 购买一个商用 API key。购买后请将它填写到旁边这个文本框里替换掉原本自动生成的免费 API key。",
//HotkeyEditor
HOTKEY_PRESS_COMBO_NANE: "按下您的组合键",
HOTKEY_PRESS_COMBO_DESC: "请按下所需的组合键",
HOTKEY_BUTTON_ADD_OVERRIDE: "添加新的(热键)覆写",
HOTKEY_BUTTON_REMOVE: "移除",
//openDrawings.ts
SELECT_FILE: "选择一个文件后按回车。",
SELECT_COMMAND: "选择一个命令后按回车。",

View File

@@ -2826,37 +2826,53 @@ export default class ExcalidrawPlugin extends Plugin {
this.popScope = null;
}
if (newActiveviewEV) {
const scope = this.app.keymap.getRootScope();
const handler_ctrlEnter = scope.register(["Mod"], "Enter", () => true);
scope.keys.unshift(scope.keys.pop()); // Force our handler to the front of the list
const handler_ctrlK = scope.register(["Mod"], "k", () => true);
scope.keys.unshift(scope.keys.pop()); // Force our handler to the front of the list
const handler_ctrlF = scope.register(["Mod"], "f", () => {
const view = this.app.workspace.getActiveViewOfType(ExcalidrawView);
if (view) {
search(view);
return true;
}
return false;
});
scope.keys.unshift(scope.keys.pop()); // Force our handler to the front of the list
const overridSaveShortcut = (
this.forceSaveCommand &&
this.forceSaveCommand.hotkeys[0].key === "s" &&
this.forceSaveCommand.hotkeys[0].modifiers.includes("Ctrl")
)
const saveHandler = overridSaveShortcut
? scope.register(["Ctrl"], "s", () => this.forceSaveActiveView(false))
: undefined;
if(saveHandler) {
scope.keys.unshift(scope.keys.pop()); // Force our handler to the front of the list
}
this.popScope = () => {
scope.unregister(handler_ctrlEnter);
scope.unregister(handler_ctrlK);
scope.unregister(handler_ctrlF);
Boolean(saveHandler) && scope.unregister(saveHandler);
this.registerHotkeyOverrides();
}
}
public registerHotkeyOverrides() {
//this is repeated here because the same function is called when settings is closed after hotkeys have changed
if (this.popScope) {
this.popScope();
this.popScope = null;
}
if(!this.activeExcalidrawView) {
return;
}
const scope = this.app.keymap.getRootScope();
// Register overrides from settings
const overrideHandlers = this.settings.modifierKeyOverrides.map(override => {
return scope.register(override.modifiers, override.key, () => true);
});
// Force handlers to the front of the list
overrideHandlers.forEach(() => scope.keys.unshift(scope.keys.pop()));
const handler_ctrlF = scope.register(["Mod"], "f", () => {
const view = this.app.workspace.getActiveViewOfType(ExcalidrawView);
if (view) {
search(view);
return true;
}
return false;
});
scope.keys.unshift(scope.keys.pop()); // Force our handler to the front of the list
const overridSaveShortcut = (
this.forceSaveCommand &&
this.forceSaveCommand.hotkeys[0].key === "s" &&
this.forceSaveCommand.hotkeys[0].modifiers.includes("Ctrl")
)
const saveHandler = overridSaveShortcut
? scope.register(["Ctrl"], "s", () => this.forceSaveActiveView(false))
: undefined;
if(saveHandler) {
scope.keys.unshift(scope.keys.pop()); // Force our handler to the front of the list
}
this.popScope = () => {
overrideHandlers.forEach(handler => scope.unregister(handler));
scope.unregister(handler_ctrlF);
Boolean(saveHandler) && scope.unregister(saveHandler);
}
}

View File

@@ -3,6 +3,7 @@ import {
ButtonComponent,
DropdownComponent,
getIcon,
Modifier,
normalizePath,
PluginSettingTab,
Setting,
@@ -39,6 +40,7 @@ import { EDITOR_FADEOUT } from "./CodeMirrorExtension/EditorHandler";
import { setDebugging } from "./utils/DebugHelper";
import { Rank } from "./menu/ActionIcons";
import { TAG_AUTOEXPORT, TAG_MDREADINGMODE, TAG_PDFEXPORT } from "src/constants/constSettingsTags";
import { HotkeyEditor } from "./dialogs/HotkeyEditor";
export interface ExcalidrawSettings {
folder: string;
@@ -204,6 +206,8 @@ export interface ExcalidrawSettings {
longPressMobile: number;
isDebugMode: boolean;
rank: Rank;
modifierKeyOverrides: {modifiers: Modifier[], key: string}[];
showSplashscreen: boolean;
}
declare const PLUGIN_VERSION:string;
@@ -220,8 +224,8 @@ export const DEFAULT_SETTINGS: ExcalidrawSettings = {
onceOffCompressFlagReset: false,
onceOffGPTVersionReset: false,
autosave: true,
autosaveIntervalDesktop: 15000,
autosaveIntervalMobile: 10000,
autosaveIntervalDesktop: 30000,
autosaveIntervalMobile: 20000,
drawingFilenamePrefix: "Drawing ",
drawingEmbedPrefixWithFilename: true,
drawingFilnameEmbedPostfix: " ",
@@ -464,6 +468,12 @@ export const DEFAULT_SETTINGS: ExcalidrawSettings = {
longPressMobile: 500,
isDebugMode: false,
rank: "Bronze",
modifierKeyOverrides: [
{modifiers: ["Mod"], key:"Enter"},
{modifiers: ["Mod"], key:"k"},
{modifiers: ["Mod"], key:"G"},
],
showSplashscreen: true,
};
export class ExcalidrawSettingTab extends PluginSettingTab {
@@ -472,6 +482,7 @@ export class ExcalidrawSettingTab extends PluginSettingTab {
private requestReloadDrawings: boolean = false;
private requestUpdatePinnedPens: boolean = false;
private requestUpdateDynamicStyling: boolean = false;
private hotkeyEditor: HotkeyEditor;
//private reloadMathJax: boolean = false;
//private applyDebounceTimer: number = 0;
@@ -498,21 +509,25 @@ export class ExcalidrawSettingTab extends PluginSettingTab {
}
this.plugin.saveSettings();
if (this.requestUpdatePinnedPens) {
app.workspace.getLeavesOfType(VIEW_TYPE_EXCALIDRAW).forEach(v=> {
this.app.workspace.getLeavesOfType(VIEW_TYPE_EXCALIDRAW).forEach(v=> {
if (v.view instanceof ExcalidrawView) v.view.updatePinnedCustomPens()
})
}
if (this.requestUpdateDynamicStyling) {
app.workspace.getLeavesOfType(VIEW_TYPE_EXCALIDRAW).forEach(v=> {
this.app.workspace.getLeavesOfType(VIEW_TYPE_EXCALIDRAW).forEach(v=> {
if (v.view instanceof ExcalidrawView) {
setDynamicStyle(this.plugin.ea,v.view,v.view.previousBackgroundColor,this.plugin.settings.dynamicStyling);
}
})
}
this.hotkeyEditor.unload();
if (this.hotkeyEditor.isDirty) {
this.plugin.registerHotkeyOverrides();
}
if (this.requestReloadDrawings) {
const exs =
app.workspace.getLeavesOfType(VIEW_TYPE_EXCALIDRAW);
this.app.workspace.getLeavesOfType(VIEW_TYPE_EXCALIDRAW);
for (const v of exs) {
if (v.view instanceof ExcalidrawView) {
await v.view.save(false);
@@ -747,7 +762,8 @@ export class ExcalidrawSettingTab extends PluginSettingTab {
.setDesc(fragWithHTML(t("AUTOSAVE_INTERVAL_DESKTOP_DESC")))
.addDropdown((dropdown) =>
dropdown
.addOption("15000", "Frequent (every 15 seconds)")
.addOption("15000", "Very frequent (every 15 seconds)")
.addOption("30000", "Frequent (every 30 seconds)")
.addOption("60000", "Moderate (every 60 seconds)")
.addOption("300000", "Rare (every 5 minutes)")
.addOption("900000", "Practically never (every 15 minutes)")
@@ -763,7 +779,8 @@ export class ExcalidrawSettingTab extends PluginSettingTab {
.setDesc(fragWithHTML(t("AUTOSAVE_INTERVAL_MOBILE_DESC")))
.addDropdown((dropdown) =>
dropdown
.addOption("10000", "Frequent (every 10 seconds)")
.addOption("10000", "Very frequent (every 10 seconds)")
.addOption("20000", "Frequent (every 20 seconds)")
.addOption("30000", "Moderate (every 30 seconds)")
.addOption("60000", "Rare (every 1 minute)")
.addOption("300000", "Practically never (every 5 minutes)")
@@ -1095,6 +1112,29 @@ export class ExcalidrawSettingTab extends PluginSettingTab {
);
addIframe(detailsEl, "H8Njp7ZXYag",999);
new Setting(detailsEl)
.setName(t("TOGGLE_SPLASHSCREEN"))
.addToggle((toggle) =>
toggle
.setValue(this.plugin.settings.showSplashscreen)
.onChange((value)=> {
this.plugin.settings.showSplashscreen = value;
this.applySettingsUpdate();
})
)
detailsEl = displayDetailsEl.createEl("details");
detailsEl.createEl("summary", {
text: t("HOTKEY_OVERRIDE_HEAD"),
cls: "excalidraw-setting-h3",
});
detailsEl.createEl("span", {}, (el) => {
el.innerHTML = t("HOTKEY_OVERRIDE_DESC");
});
this.hotkeyEditor = new HotkeyEditor(detailsEl, this.plugin.settings, this.applySettingsUpdate);
this.hotkeyEditor.onload();
detailsEl = displayDetailsEl.createEl("details");
detailsEl.createEl("summary", {
text: t("THEME_HEAD"),

View File

@@ -28,6 +28,7 @@ export type DeviceType = {
declare global {
interface Window {
ExcalidrawAutomate: ExcalidrawAutomate;
pdfjsLib: any;
}
}

View File

@@ -1,5 +1,5 @@
import { ExcalidrawImperativeAPI } from "@zsviczian/excalidraw/types/excalidraw/types";
import { ColorMaster } from "colormaster";
import { ColorMaster } from "@zsviczian/colormaster";
import { ExcalidrawAutomate } from "src/ExcalidrawAutomate";
import ExcalidrawView from "src/ExcalidrawView";
import { DynamicStyle } from "src/types/types";

View File

@@ -291,9 +291,7 @@ export const blobToBase64 = async (blob: Blob): Promise<string> => {
}
export const getPDFDoc = async (f: TFile): Promise<any> => {
//@ts-ignore
if(typeof window.pdfjsLib === "undefined") await loadPdfJs();
//@ts-ignore
return await window.pdfjsLib.getDocument(app.vault.getResourcePath(f)).promise;
}

View File

@@ -1,3 +1,4 @@
import { Modifier } from "obsidian";
import { DEVICE } from "src/constants/constants";
import { ExcalidrawSettings } from "src/settings";
export type ModifierKeys = {shiftKey:boolean, ctrlKey: boolean, metaKey: boolean, altKey: boolean};
@@ -177,4 +178,26 @@ export const emulateKeysForLinkClick = (action: PaneTarget): ModifierKeys => {
export const anyModifierKeysPressed = (e: ModifierKeys): boolean => {
return e.shiftKey || e.ctrlKey || e.metaKey || e.altKey;
}
export function modifierLabel(modifiers: Modifier[], platform?: "Mac" | "Other"): string {
const isMacPlatform = platform === "Mac" ||
(platform === undefined && (DEVICE.isIOS || DEVICE.isMacOS));
return modifiers.map(modifier => {
switch (modifier) {
case "Mod":
return isMacPlatform ? "CMD" : "CTRL";
case "Ctrl":
return "CTRL";
case "Meta":
return isMacPlatform ? "CMD" : "WIN";
case "Shift":
return "SHIFT";
case "Alt":
return isMacPlatform ? "OPTION" : "ALT";
default:
return modifier;
}
}).join("+");
}