Skip to content

Commit

Permalink
add: magic key command palette
Browse files Browse the repository at this point in the history
  • Loading branch information
windingwind committed Nov 11, 2024
1 parent 968eb0e commit e44e07e
Show file tree
Hide file tree
Showing 27 changed files with 803 additions and 89 deletions.
10 changes: 10 additions & 0 deletions addon/chrome/content/preferences.xhtml
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,16 @@
<radio data-l10n-id="editor-noteLinkPreview-disable" value="disable" />
</radiogroup>
</hbox>
<checkbox
data-l10n-id="editor-useMagicKey"
native="true"
preference="__prefsPrefix__.editor.useMagicKey"
/>
<checkbox
data-l10n-id="editor-useMarkdownPaste"
native="true"
preference="__prefsPrefix__.editor.useMarkdownPaste"
/>
</groupbox>
<groupbox>
<label><html:h2 data-l10n-id="sync-title"></html:h2></label>
Expand Down
4 changes: 4 additions & 0 deletions addon/locale/en-US/preferences.ftl
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,10 @@ editor-noteLinkPreview-ctrl =
}
editor-noteLinkPreview-disable =
.label = Never
editor-useMagicKey =
.label = Use magic key "/" to show command palette
editor-useMarkdownPaste =
.label = Use enhanced markdown paste
sync-title = Sync
sync-period-label = Auto-sync period (seconds)
Expand Down
4 changes: 4 additions & 0 deletions addon/locale/it-IT/preferences.ftl
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,10 @@ editor-noteLinkPreview-ctrl =
}
editor-noteLinkPreview-disable =
.label = Never
editor-useMagicKey =
.label = Usa il tasto magico "/" per mostrare il pannello dei comandi
editor-useMarkdownPaste =
.label = Usa l'incolla markdown avanzato
sync-title = Sincronizzazione
sync-period-label = Intervallo della sincronizzazione automatica (secondi)
Expand Down
4 changes: 4 additions & 0 deletions addon/locale/ru-RU/preferences.ftl
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,10 @@ editor-noteLinkPreview-ctrl =
}
editor-noteLinkPreview-disable =
.label = Never
editor-useMagicKey =
.label = Использовать магическую клавишу "/" для отображения панели команд
editor-useMarkdownPaste =
.label = Использовать расширенное вставление Markdown
sync-title = Синк
sync-period-label = Авто-синк период (сек)
Expand Down
4 changes: 4 additions & 0 deletions addon/locale/tr-TR/preferences.ftl
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,10 @@ editor-noteLinkPreview-ctrl =
}
editor-noteLinkPreview-disable =
.label = Never
editor-useMagicKey =
.label = Komut panelini göstermek için sihirli tuş "/" kullan
editor-useMarkdownPaste =
.label = Gelişmiş markdown yapıştırma kullan
sync-title = Eşitle
sync-period-label = Otomatik Eşitleme Sıklığı (saniye)
Expand Down
4 changes: 4 additions & 0 deletions addon/locale/zh-CN/preferences.ftl
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,10 @@ editor-noteLinkPreview-ctrl =
}
editor-noteLinkPreview-disable =
.label = 从不
editor-useMagicKey =
.label = 使用魔法键 "/" 显示命令面板
editor-useMarkdownPaste =
.label = 使用增强的Markdown粘贴
sync-title = 同步
sync-period-label = 自动同步周期 (秒)
Expand Down
14 changes: 2 additions & 12 deletions addon/prefs.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,22 +6,12 @@ pref("__prefsPrefix__.autoAnnotation", false);

pref("__prefsPrefix__.insertLinkPosition", "end");

pref("__prefsPrefix__.embedLink", true);
pref("__prefsPrefix__.standaloneLink", false);
pref("__prefsPrefix__.keepLink", true);
pref("__prefsPrefix__.exportMD", true);
pref("__prefsPrefix__.setAutoSync", false);
pref("__prefsPrefix__.withYAMLHeader", false);
pref("__prefsPrefix__.autoMDFileName", false);
pref("__prefsPrefix__.exportDocx", false);
pref("__prefsPrefix__.exportPDF", false);
pref("__prefsPrefix__.exportFreeMind", false);
pref("__prefsPrefix__.exportNote", false);

pref("__prefsPrefix__.workspace.outline.expandLevel", 2);
pref("__prefsPrefix__.workspace.outline.keepLinks", true);

pref("__prefsPrefix__.editor.noteLinkPreviewType", "hover");
pref("__prefsPrefix__.editor.useMagicKey", true);
pref("__prefsPrefix__.editor.useMarkdownPaste", true);

pref("__prefsPrefix__.openNote.takeover", true);
pref("__prefsPrefix__.openNote.defaultAsWindow", false);
Expand Down
14 changes: 7 additions & 7 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

23 changes: 23 additions & 0 deletions src/elements/linkCreator/notePicker.ts
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,8 @@ export class NotePicker extends PluginCEBase {

_prefObserverID!: symbol;

_cachedLibraryIDs: number[] = [];

get content() {
return MozXULElement.parseXULToFragment(`
<linkset>
Expand Down Expand Up @@ -394,6 +396,12 @@ export class NotePicker extends PluginCEBase {

onItemSelected() {
this.activeSelectionType = "library";
const selectedIDs = this.itemsView.getSelectedItems(true) as number[];
// Compare the selected IDs with the cached IDs
// Since the library selection change can be triggered multiple times or with no change
if (arraysEqual(this._cachedLibraryIDs, selectedIDs)) {
return;
}
this.dispatchSelectionChange();
}

Expand Down Expand Up @@ -483,3 +491,18 @@ export class NotePicker extends PluginCEBase {
}
}
}

function arraysEqual(arr1: number[], arr2: number[]): boolean {
if (arr1.length !== arr2.length) return false;

const set1 = new Set(arr1);
const set2 = new Set(arr2);

if (set1.size !== set2.size) return false;

for (const item of set1) {
if (!set2.has(item)) return false;
}

return true;
}
2 changes: 1 addition & 1 deletion src/elements/linkCreator/outboundCreator.ts
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,7 @@ export class OutboundCreator extends PluginCEBase {
await this.notePicker.load();

this.notePicker.addEventListener("selectionchange", (event: any) => {
this.targetNotes = event.detail.selectedNotes;
this.targetNotes = this.notePicker.getSelectedNotes();
this.updatePickerTitle(this.targetNotes);
this.updateNotePreview();
if (this.targetNotes) this.scrollToSection("outline");
Expand Down
75 changes: 75 additions & 0 deletions src/extras/editor/editorStrings.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
import { insert } from "../../utils/editor";

export { formatMessage };

function formatMessage(message: string, locale: string) {
const stringObj = editorStrings[message as keyof typeof editorStrings];
if (!stringObj) {
return message;
}

return stringObj[locale as "en-US" | "zh-CN"] || message;
}

const editorStrings = {
insertTemplate: {
"en-US": "Insert Template",
"zh-CN": "插入模板",
},
outboundLink: {
"en-US": "Insert Outbound Link (Link to another note)",
"zh-CN": "插入出链 (链接到另一个笔记)",
},
inboundLink: {
"en-US": "Insert Inbound Link in another note (Link to this note)",
"zh-CN": "插入入链到另一笔记 (链接到本笔记)",
},
insertCitation: {
"en-US": "Insert Citation",
"zh-CN": "插入引用",
},
heading1: {
"en-US": "Heading 1",
"zh-CN": "一级标题",
},
heading2: {
"en-US": "Heading 2",
"zh-CN": "二级标题",
},
heading3: {
"en-US": "Heading 3",
"zh-CN": "三级标题",
},
paragraph: {
"en-US": "Paragraph",
"zh-CN": "段落",
},
monospaced: {
"en-US": "Monospaced",
"zh-CN": "等宽",
},
bulletList: {
"en-US": "Bullet List",
"zh-CN": "无序列表",
},
orderedList: {
"en-US": "Ordered List",
"zh-CN": "有序列表",
},
blockquote: {
"en-US": "Blockquote",
"zh-CN": "引用",
},
mathBlock: {
"en-US": "Math Block",
"zh-CN": "数学",
},
clearFormatting: {
"en-US": "Clear Format",
"zh-CN": "清除格式",
},
table: {
"en-US": "Table",
"zh-CN": "表格",
},
};
32 changes: 20 additions & 12 deletions src/extras/editor/linkPreview.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,10 +15,10 @@ interface LinkPreviewOptions {

openURL: (url: string) => void;

requireCtrl: boolean;
previewType: "hover" | "ctrl" | "disable";
}

class LinkPreviewState {
class PluginState {
state: EditorState;

options: LinkPreviewOptions;
Expand All @@ -40,6 +40,10 @@ class LinkPreviewState {
update(state: EditorState, prevState?: EditorState) {
this.state = state;

if (this.options.previewType === "disable") {
return;
}

if (
prevState &&
prevState.doc.eq(state.doc) &&
Expand All @@ -58,6 +62,10 @@ class LinkPreviewState {
}

handleMouseMove = async (event: MouseEvent) => {
if (this.options.previewType === "disable") {
return;
}

const { target } = event;

let isValid = false;
Expand All @@ -82,9 +90,10 @@ class LinkPreviewState {
};

handleKeydown = async (event: KeyboardEvent) => {
if (!this.options.requireCtrl) {
if (this.options.previewType !== "ctrl") {
return;
}

if (!this.hasHover || !this.currentLink) {
return;
}
Expand All @@ -96,9 +105,10 @@ class LinkPreviewState {
};

tryOpenPopupByHover() {
if (this.options.requireCtrl) {
if (this.options.previewType !== "hover") {
return;
}

const href = this.currentLink!;
setTimeout(() => {
if (this.currentLink === href) {
Expand Down Expand Up @@ -204,7 +214,7 @@ function initLinkPreviewPlugin(
key,
state: {
init(config, state) {
return new LinkPreviewState(state, options);
return new PluginState(state, options);
},
apply: (tr, pluginState, oldState, newState) => {
pluginState.update(newState, oldState);
Expand All @@ -214,30 +224,28 @@ function initLinkPreviewPlugin(
props: {
handleDOMEvents: {
mousemove: (view, event) => {
const pluginState = key.getState(view.state) as LinkPreviewState;
const pluginState = key.getState(view.state) as PluginState;
pluginState.update(view.state);
pluginState.handleMouseMove(event);
},
keydown: (view, event) => {
const pluginState = key.getState(view.state) as LinkPreviewState;
const pluginState = key.getState(view.state) as PluginState;
pluginState.handleKeydown(event);
},
wheel: (view, event) => {
const pluginState = key.getState(view.state) as LinkPreviewState;
const pluginState = key.getState(view.state) as PluginState;
pluginState.popup?.layoutPopup(pluginState);
},
},
},
view: (editorView) => {
return {
update(view, prevState) {
const pluginState = key.getState(view.state) as LinkPreviewState;
const pluginState = key.getState(view.state) as PluginState;
pluginState.update(view.state, prevState);
},
destroy() {
const pluginState = key.getState(
editorView.state,
) as LinkPreviewState;
const pluginState = key.getState(editorView.state) as PluginState;
pluginState.destroy();
},
};
Expand Down
Loading

0 comments on commit e44e07e

Please sign in to comment.