mirror of
				https://github.com/TriliumNext/Notes.git
				synced 2025-10-31 04:51:31 +08:00 
			
		
		
		
	shortcut improvements
This commit is contained in:
		
							parent
							
								
									70552d58ac
								
							
						
					
					
						commit
						6883b71ce7
					
				
							
								
								
									
										1
									
								
								db/migrations/0203__set_notes_as_doc_type.sql
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										1
									
								
								db/migrations/0203__set_notes_as_doc_type.sql
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1 @@ | |||||||
|  | UPDATE notes SET type = 'doc' WHERE noteId IN ('share, hidden', 'sqlconsole', 'search'); | ||||||
							
								
								
									
										1
									
								
								src/public/app/doc_notes/hidden.html
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										1
									
								
								src/public/app/doc_notes/hidden.html
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1 @@ | |||||||
|  | <p>Hidden tree is used to record various application-level data which can stay most of the time hidden from the user view.</p> | ||||||
							
								
								
									
										1
									
								
								src/public/app/doc_notes/share.html
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										1
									
								
								src/public/app/doc_notes/share.html
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1 @@ | |||||||
|  | <p>Here you can find all shared notes.</p> | ||||||
| @ -21,7 +21,8 @@ const NOTE_TYPE_ICONS = { | |||||||
|     "mermaid": "bx bx-selection", |     "mermaid": "bx bx-selection", | ||||||
|     "canvas": "bx bx-pen", |     "canvas": "bx bx-pen", | ||||||
|     "web-view": "bx bx-globe-alt", |     "web-view": "bx bx-globe-alt", | ||||||
|     "shortcut": "bx bx-up-arrow-circle" |     "shortcut": "bx bx-up-arrow-circle", | ||||||
|  |     "doc": "bx bx-file-doc" | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
| /** | /** | ||||||
|  | |||||||
| @ -1,6 +1,8 @@ | |||||||
| import treeService from '../services/tree.js'; | import treeService from '../services/tree.js'; | ||||||
| import froca from "../services/froca.js"; | import froca from "../services/froca.js"; | ||||||
| import contextMenu from "./context_menu.js"; | import contextMenu from "./context_menu.js"; | ||||||
|  | import dialogService from "../services/dialog.js"; | ||||||
|  | import server from "../services/server.js"; | ||||||
| 
 | 
 | ||||||
| export default class ShortcutContextMenu { | export default class ShortcutContextMenu { | ||||||
|     /** |     /** | ||||||
| @ -25,12 +27,13 @@ export default class ShortcutContextMenu { | |||||||
|         const note = await froca.getNote(this.node.data.noteId); |         const note = await froca.getNote(this.node.data.noteId); | ||||||
|         const parentNoteId = this.node.getParent().data.noteId; |         const parentNoteId = this.node.getParent().data.noteId; | ||||||
| 
 | 
 | ||||||
|         const isLbRoot = note.noteId === 'lb_root'; |  | ||||||
|         const isVisibleRoot = note.noteId === 'lb_visibleshortcuts'; |         const isVisibleRoot = note.noteId === 'lb_visibleshortcuts'; | ||||||
|         const isAvailableRoot = note.noteId === 'lb_availableshortcuts'; |         const isAvailableRoot = note.noteId === 'lb_availableshortcuts'; | ||||||
|         const isVisibleItem = parentNoteId === 'lb_visibleshortcuts'; |         const isVisibleItem = parentNoteId === 'lb_visibleshortcuts'; | ||||||
|         const isAvailableItem = parentNoteId === 'lb_availableshortcuts'; |         const isAvailableItem = parentNoteId === 'lb_availableshortcuts'; | ||||||
|         const isItem = isVisibleItem || isAvailableItem; |         const isItem = isVisibleItem || isAvailableItem; | ||||||
|  |         const canBeDeleted = !note.noteId.startsWith("lb_"); | ||||||
|  |         const canBeReset = note.noteId.startsWith("lb_"); | ||||||
| 
 | 
 | ||||||
|         return [ |         return [ | ||||||
|             (isVisibleRoot || isAvailableRoot) ? { title: 'Add note shortcut', command: 'addNoteShortcut', uiIcon: "bx bx-plus" } : null, |             (isVisibleRoot || isAvailableRoot) ? { title: 'Add note shortcut', command: 'addNoteShortcut', uiIcon: "bx bx-plus" } : null, | ||||||
| @ -38,8 +41,8 @@ export default class ShortcutContextMenu { | |||||||
|             (isVisibleRoot || isAvailableRoot) ? { title: 'Add widget shortcut', command: 'addWidgetShortcut', uiIcon: "bx bx-plus" } : null, |             (isVisibleRoot || isAvailableRoot) ? { title: 'Add widget shortcut', command: 'addWidgetShortcut', uiIcon: "bx bx-plus" } : null, | ||||||
|             (isVisibleRoot || isAvailableRoot) ? { title: 'Add spacer', command: 'addSpacerShortcut', uiIcon: "bx bx-plus" } : null, |             (isVisibleRoot || isAvailableRoot) ? { title: 'Add spacer', command: 'addSpacerShortcut', uiIcon: "bx bx-plus" } : null, | ||||||
|             (isVisibleRoot || isAvailableRoot) ? { title: "----" } : null, |             (isVisibleRoot || isAvailableRoot) ? { title: "----" } : null, | ||||||
|             { title: 'Delete <kbd data-command="deleteNotes"></kbd>', command: "deleteNotes", uiIcon: "bx bx-trash", |             { title: 'Delete <kbd data-command="deleteNotes"></kbd>', command: "deleteNotes", uiIcon: "bx bx-trash", enabled: canBeDeleted }, | ||||||
|                 enabled: !isLbRoot}, // allow everything to be deleted as a form of a reset. Root can't be deleted because it's a hoisted note
 |             { title: 'Reset', command: "resetShortcut", uiIcon: "bx bx-empty", enabled: canBeReset}, | ||||||
|             { title: "----" }, |             { title: "----" }, | ||||||
|             isAvailableItem ? { title: 'Move to visible shortcuts', command: "moveShortcutToVisible", uiIcon: "bx bx-show", enabled: true } : null, |             isAvailableItem ? { title: 'Move to visible shortcuts', command: "moveShortcutToVisible", uiIcon: "bx bx-show", enabled: true } : null, | ||||||
|             isVisibleItem ? { title: 'Move to available shortcuts', command: "moveShortcutToAvailable", uiIcon: "bx bx-hide", enabled: true } : null, |             isVisibleItem ? { title: 'Move to available shortcuts', command: "moveShortcutToAvailable", uiIcon: "bx bx-hide", enabled: true } : null, | ||||||
| @ -49,6 +52,18 @@ export default class ShortcutContextMenu { | |||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     async selectMenuItemHandler({command}) { |     async selectMenuItemHandler({command}) { | ||||||
|  |         if (command === 'resetShortcut') { | ||||||
|  |             const confirmed = await dialogService.confirm(`Do you really want to reset "${this.node.title}"? 
 | ||||||
|  |                        All data / settings in this shortcut (and its children) will be lost  | ||||||
|  |                        and the shortcut will be returned to its original location.`);
 | ||||||
|  | 
 | ||||||
|  |             if (confirmed) { | ||||||
|  |                 await server.post(`special-notes/shortcuts/${this.node.data.noteId}/reset`); | ||||||
|  |             } | ||||||
|  | 
 | ||||||
|  |             return; | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|         this.treeWidget.triggerCommand(command, { |         this.treeWidget.triggerCommand(command, { | ||||||
|             node: this.node, |             node: this.node, | ||||||
|             notePath: treeService.getNotePath(this.node), |             notePath: treeService.getNotePath(this.node), | ||||||
|  | |||||||
| @ -10,8 +10,8 @@ async function moveBeforeBranch(branchIdsToMove, beforeBranchId) { | |||||||
|     branchIdsToMove = filterRootNote(branchIdsToMove); |     branchIdsToMove = filterRootNote(branchIdsToMove); | ||||||
|     branchIdsToMove = filterSearchBranches(branchIdsToMove); |     branchIdsToMove = filterSearchBranches(branchIdsToMove); | ||||||
| 
 | 
 | ||||||
|     if (beforeBranchId === 'root') { |     if (['root', 'lb_root', 'lb_availableshortcuts', 'lb_visibleshortcuts'].includes(beforeBranchId)) { | ||||||
|         toastService.showError('Cannot move notes before root note.'); |         toastService.showError('Cannot move notes here.'); | ||||||
|         return; |         return; | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
| @ -31,8 +31,16 @@ async function moveAfterBranch(branchIdsToMove, afterBranchId) { | |||||||
| 
 | 
 | ||||||
|     const afterNote = await froca.getBranch(afterBranchId).getNote(); |     const afterNote = await froca.getBranch(afterBranchId).getNote(); | ||||||
| 
 | 
 | ||||||
|     if (afterNote.noteId === 'root' || afterNote.noteId === hoistedNoteService.getHoistedNoteId()) { |     const forbiddenNoteIds = [ | ||||||
|         toastService.showError('Cannot move notes after root note.'); |         'root', | ||||||
|  |         hoistedNoteService.getHoistedNoteId(), | ||||||
|  |         'lb_root', | ||||||
|  |         'lb_availableshortcuts', | ||||||
|  |         'lb_visibleshortcuts' | ||||||
|  |     ]; | ||||||
|  | 
 | ||||||
|  |     if (forbiddenNoteIds.includes(afterNote.noteId)) { | ||||||
|  |         toastService.showError('Cannot move notes here.'); | ||||||
|         return; |         return; | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
| @ -49,6 +57,11 @@ async function moveAfterBranch(branchIdsToMove, afterBranchId) { | |||||||
| } | } | ||||||
| 
 | 
 | ||||||
| async function moveToParentNote(branchIdsToMove, newParentBranchId) { | async function moveToParentNote(branchIdsToMove, newParentBranchId) { | ||||||
|  |     if (newParentBranchId === 'lb_root') { | ||||||
|  |         toastService.showError('Cannot move notes here.'); | ||||||
|  |         return; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|     branchIdsToMove = filterRootNote(branchIdsToMove); |     branchIdsToMove = filterRootNote(branchIdsToMove); | ||||||
| 
 | 
 | ||||||
|     for (const branchIdToMove of branchIdsToMove) { |     for (const branchIdToMove of branchIdsToMove) { | ||||||
|  | |||||||
| @ -1,4 +1,4 @@ | |||||||
| import appContext from "../services/app_context.js"; | import appContext from "./app_context.js"; | ||||||
| 
 | 
 | ||||||
| async function info(message) { | async function info(message) { | ||||||
|     return new Promise(res => |     return new Promise(res => | ||||||
| @ -1,6 +1,6 @@ | |||||||
| import appContext from "./app_context.js"; | import appContext from "./app_context.js"; | ||||||
| import treeService from "./tree.js"; | import treeService from "./tree.js"; | ||||||
| import dialogService from "../widgets/dialog.js"; | import dialogService from "./dialog.js"; | ||||||
| import froca from "./froca.js"; | import froca from "./froca.js"; | ||||||
| 
 | 
 | ||||||
| function getHoistedNoteId() { | function getHoistedNoteId() { | ||||||
|  | |||||||
| @ -74,7 +74,13 @@ export default class RootCommandExecutor extends Component { | |||||||
| 
 | 
 | ||||||
|     async showLaunchBarShortcutsCommand() { |     async showLaunchBarShortcutsCommand() { | ||||||
|         await appContext.tabManager.openContextWithNote('lb_root', true, null, 'lb_root'); |         await appContext.tabManager.openContextWithNote('lb_root', true, null, 'lb_root'); | ||||||
|  |     } | ||||||
| 
 | 
 | ||||||
|  |     async showShareSubtreeCommand() { | ||||||
|  |         await appContext.tabManager.openContextWithNote('share', true, null, 'share'); | ||||||
|  |     } | ||||||
| 
 | 
 | ||||||
|  |     async showHiddenSubtreeCommand() { | ||||||
|  |         await appContext.tabManager.openContextWithNote('hidden', true, null, 'hidden'); | ||||||
|     } |     } | ||||||
| } | } | ||||||
|  | |||||||
							
								
								
									
										40
									
								
								src/public/app/widgets/buttons/button_from_note.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										40
									
								
								src/public/app/widgets/buttons/button_from_note.js
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,40 @@ | |||||||
|  | import ButtonWidget from "./button_widget.js"; | ||||||
|  | import froca from "../../services/froca.js"; | ||||||
|  | import attributeService from "../../services/attributes.js"; | ||||||
|  | 
 | ||||||
|  | export default class ButtonFromNoteWidget extends ButtonWidget { | ||||||
|  |     constructor() { | ||||||
|  |         super(); | ||||||
|  | 
 | ||||||
|  |         this.settings.buttonNoteId = null; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     buttonNoteId(noteId) { | ||||||
|  |         this.settings.buttonNoteId = noteId; | ||||||
|  |         return this; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     doRender() { | ||||||
|  |         super.doRender(); | ||||||
|  | 
 | ||||||
|  |         this.updateIcon(); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     updateIcon() { | ||||||
|  |         froca.getNote(this.settings.buttonNoteId).then(note => { | ||||||
|  |             this.settings.icon = note.getLabelValue("iconClass"); | ||||||
|  | 
 | ||||||
|  |             this.refreshIcon(); | ||||||
|  |         }); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     entitiesReloadedEvent({loadResults}) { | ||||||
|  |         if (loadResults.getAttributes(this.componentId).find(attr => | ||||||
|  |             attr.type === 'label' | ||||||
|  |             && attr.name === 'iconClass' | ||||||
|  |             && attributeService.isAffecting(attr, this.note))) { | ||||||
|  | 
 | ||||||
|  |             this.updateIcon(); | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  | } | ||||||
| @ -18,7 +18,12 @@ export default class ButtonWidget extends NoteContextAwareWidget { | |||||||
|         super(); |         super(); | ||||||
| 
 | 
 | ||||||
|         this.settings = { |         this.settings = { | ||||||
|             titlePlacement: 'right' |             titlePlacement: 'right', | ||||||
|  |             title: null, | ||||||
|  |             icon: null, | ||||||
|  |             command: null, | ||||||
|  |             onClick: null, | ||||||
|  |             onContextMenu: null | ||||||
|         }; |         }; | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
| @ -39,6 +44,14 @@ export default class ButtonWidget extends NoteContextAwareWidget { | |||||||
|             }); |             }); | ||||||
|         } |         } | ||||||
| 
 | 
 | ||||||
|  |         if (this.settings.onContextMenu) { | ||||||
|  |             this.$widget.on("contextmenu", e => { | ||||||
|  |                 this.$widget.tooltip("hide"); | ||||||
|  | 
 | ||||||
|  |                 this.settings.onContextMenu(e); | ||||||
|  |             }); | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|         this.$widget.attr("data-placement", this.settings.titlePlacement); |         this.$widget.attr("data-placement", this.settings.titlePlacement); | ||||||
| 
 | 
 | ||||||
|         this.$widget.tooltip({ |         this.$widget.tooltip({ | ||||||
| @ -70,8 +83,7 @@ export default class ButtonWidget extends NoteContextAwareWidget { | |||||||
|             } |             } | ||||||
|         } |         } | ||||||
| 
 | 
 | ||||||
|         this.$widget |         this.$widget.addClass(this.settings.icon); | ||||||
|             .addClass(this.settings.icon); |  | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     initialRenderCompleteEvent() { |     initialRenderCompleteEvent() { | ||||||
| @ -102,4 +114,8 @@ export default class ButtonWidget extends NoteContextAwareWidget { | |||||||
|         this.settings.onClick = handler; |         this.settings.onClick = handler; | ||||||
|         return this; |         return this; | ||||||
|     } |     } | ||||||
|  | 
 | ||||||
|  |     onContextMenu(handler) { | ||||||
|  |         this.settings.onContextMenu = handler; | ||||||
|  |     } | ||||||
| } | } | ||||||
|  | |||||||
| @ -124,11 +124,16 @@ const TPL = ` | |||||||
|             <kbd ></kbd> |             <kbd ></kbd> | ||||||
|         </li> |         </li> | ||||||
|          |          | ||||||
|         <li class="dropdown-item options-button" data-trigger-command="showLaunchBarShortcuts"> |         <li class="dropdown-item" data-trigger-command="showLaunchBarShortcuts"> | ||||||
|             <span class="bx bx-sidebar"></span> |             <span class="bx bx-sidebar"></span> | ||||||
|             Configure launchbar shortcuts |             Configure launchbar shortcuts | ||||||
|         </li> |         </li> | ||||||
|          |          | ||||||
|  |         <li class="dropdown-item" data-trigger-command="showShareSubtree"> | ||||||
|  |             <span class="bx bx-share-alt"></span> | ||||||
|  |             Show share subtree | ||||||
|  |         </li> | ||||||
|  |          | ||||||
|         <li class="dropdown-item dropdown-submenu"> |         <li class="dropdown-item dropdown-submenu"> | ||||||
|             <span class="dropdown-toggle"> |             <span class="dropdown-toggle"> | ||||||
|                 <span class="bx bx-empty"></span> |                 <span class="bx bx-empty"></span> | ||||||
| @ -160,6 +165,11 @@ const TPL = ` | |||||||
|                     Reload frontend |                     Reload frontend | ||||||
|                     <kbd data-command="reloadFrontendApp"></kbd> |                     <kbd data-command="reloadFrontendApp"></kbd> | ||||||
|                 </li> |                 </li> | ||||||
|  |                  | ||||||
|  |                 <li class="dropdown-item" data-trigger-command="showHiddenSubtree"> | ||||||
|  |                     <span class="bx bx-empty"></span> | ||||||
|  |                     Show hidden subtree | ||||||
|  |                 </li> | ||||||
|             </ul> |             </ul> | ||||||
|         </li> |         </li> | ||||||
| 
 | 
 | ||||||
|  | |||||||
| @ -1,48 +1,17 @@ | |||||||
| import BasicWidget from "./basic_widget.js"; | import utils from "../../../services/utils.js"; | ||||||
| import utils from "../services/utils.js"; | import contextMenu from "../../../menus/context_menu.js"; | ||||||
| import contextMenu from "../menus/context_menu.js"; | import treeService from "../../../services/tree.js"; | ||||||
| import treeService from "../services/tree.js"; | import ButtonFromNoteWidget from "../button_from_note.js"; | ||||||
| 
 | 
 | ||||||
| const TPL = ` | export default class AbstractHistoryNavigationWidget extends ButtonFromNoteWidget { | ||||||
| <div class="history-navigation"> |     isEnabled() { | ||||||
|     <style> |         return super.isEnabled() && utils.isElectron(); | ||||||
|     .history-navigation { |  | ||||||
|         margin: 0 15px 0 5px; |  | ||||||
|     } |     } | ||||||
|     </style> |  | ||||||
| 
 | 
 | ||||||
|     <a title="Go to previous note." data-trigger-command="backInNoteHistory" class="icon-action bx bx-left-arrow-circle"></a> |  | ||||||
| 
 |  | ||||||
|     <a title="Go to next note." data-trigger-command="forwardInNoteHistory" class="icon-action bx bx-right-arrow-circle"></a> |  | ||||||
| </div> |  | ||||||
| `;
 |  | ||||||
| 
 |  | ||||||
| export default class HistoryNavigationWidget extends BasicWidget { |  | ||||||
|     doRender() { |     doRender() { | ||||||
|         if (!utils.isElectron()) { |         super.doRender(); | ||||||
|             this.$widget = $("<div>"); |  | ||||||
|             return; |  | ||||||
|         } |  | ||||||
| 
 | 
 | ||||||
|         this.$widget = $(TPL); |         this.webContents = utils.dynamicRequire('@electron/remote').getCurrentWebContents(); | ||||||
| 
 |  | ||||||
|         const contextMenuHandler = e => { |  | ||||||
|             e.preventDefault(); |  | ||||||
| 
 |  | ||||||
|             if (this.webContents.history.length < 2) { |  | ||||||
|                 return; |  | ||||||
|             } |  | ||||||
| 
 |  | ||||||
|             this.showContextMenu(e); |  | ||||||
|         }; |  | ||||||
| 
 |  | ||||||
|         this.$backInHistory = this.$widget.find("[data-trigger-command='backInNoteHistory']"); |  | ||||||
|         this.$backInHistory.on('contextmenu', contextMenuHandler); |  | ||||||
| 
 |  | ||||||
|         this.$forwardInHistory = this.$widget.find("[data-trigger-command='forwardInNoteHistory']"); |  | ||||||
|         this.$forwardInHistory.on('contextmenu', contextMenuHandler); |  | ||||||
| 
 |  | ||||||
|         this.webContents = utils.dynamicRequire('@electron/remote').webContents; |  | ||||||
| 
 | 
 | ||||||
|         // without this the history is preserved across frontend reloads
 |         // without this the history is preserved across frontend reloads
 | ||||||
|         this.webContents.clearHistory(); |         this.webContents.clearHistory(); | ||||||
| @ -51,6 +20,16 @@ export default class HistoryNavigationWidget extends BasicWidget { | |||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     async showContextMenu(e) { |     async showContextMenu(e) { | ||||||
|  |         e.preventDefault(); | ||||||
|  | 
 | ||||||
|  |         // API is broken and will be replaced: https://github.com/electron/electron/issues/33899
 | ||||||
|  |         // until then no context menu
 | ||||||
|  |         return; | ||||||
|  | 
 | ||||||
|  |         if (this.webContents.history.length < 2) { | ||||||
|  |             return; | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|         let items = []; |         let items = []; | ||||||
| 
 | 
 | ||||||
|         const activeIndex = this.webContents.getActiveIndex(); |         const activeIndex = this.webContents.getActiveIndex(); | ||||||
							
								
								
									
										14
									
								
								src/public/app/widgets/buttons/history/history_back.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										14
									
								
								src/public/app/widgets/buttons/history/history_back.js
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,14 @@ | |||||||
|  | import AbstractHistoryNavigationWidget from "./abstract_history.js"; | ||||||
|  | 
 | ||||||
|  | export default class BackInHistoryButtonWidget extends AbstractHistoryNavigationWidget { | ||||||
|  |     constructor() { | ||||||
|  |         super(); | ||||||
|  | 
 | ||||||
|  |         this.icon('bx-left-arrow-circle') | ||||||
|  |             .title("Go to previous note.") | ||||||
|  |             .command("backInNoteHistory") | ||||||
|  |             .titlePlacement("right") | ||||||
|  |             .buttonNoteId('lb_backinhistory') | ||||||
|  |             .onContextMenu(e => this.showContextMenu(e)); | ||||||
|  |     } | ||||||
|  | } | ||||||
							
								
								
									
										14
									
								
								src/public/app/widgets/buttons/history/history_forward.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										14
									
								
								src/public/app/widgets/buttons/history/history_forward.js
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,14 @@ | |||||||
|  | import AbstractHistoryNavigationWidget from "./abstract_history.js"; | ||||||
|  | 
 | ||||||
|  | export default class ForwardInHistoryButtonWidget extends AbstractHistoryNavigationWidget { | ||||||
|  |     constructor() { | ||||||
|  |         super(); | ||||||
|  | 
 | ||||||
|  |         this.icon('bx-left-arrow-circle') | ||||||
|  |             .title("Go to next note.") | ||||||
|  |             .command("forwardInNoteHistory") | ||||||
|  |             .titlePlacement("right") | ||||||
|  |             .buttonNoteId('lb_forwardinhistory') | ||||||
|  |             .onContextMenu(e => this.showContextMenu(e)); | ||||||
|  |     } | ||||||
|  | } | ||||||
| @ -11,6 +11,6 @@ export default class NoteRevisionsButton extends ButtonWidget { | |||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     isEnabled() { |     isEnabled() { | ||||||
|         return super.isEnabled() && this.note?.type !== 'shortcut'; |         return super.isEnabled() && !['shortcut', 'doc'].includes(this.note?.type); | ||||||
|     } |     } | ||||||
| } | } | ||||||
| @ -1,16 +0,0 @@ | |||||||
| import ButtonWidget from "./button_widget.js"; |  | ||||||
| 
 |  | ||||||
| export default class ShowNoteSourceButton extends ButtonWidget { |  | ||||||
|     isEnabled() { |  | ||||||
|         return super.isEnabled() && this.note && ['text', 'relation-map'].includes(this.note.type); |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     constructor() { |  | ||||||
|         super(); |  | ||||||
| 
 |  | ||||||
|         this.icon('bx bx-code') |  | ||||||
|             .title("Show Note Source") |  | ||||||
|             .command("openNoteSourceDialog") |  | ||||||
|             .titlePlacement("bottom"); |  | ||||||
|     } |  | ||||||
| } |  | ||||||
| @ -7,6 +7,8 @@ import SpacerWidget from "../spacer.js"; | |||||||
| import BookmarkButtons from "../bookmark_buttons.js"; | import BookmarkButtons from "../bookmark_buttons.js"; | ||||||
| import ProtectedSessionStatusWidget from "../buttons/protected_session_status.js"; | import ProtectedSessionStatusWidget from "../buttons/protected_session_status.js"; | ||||||
| import SyncStatusWidget from "../sync_status.js"; | import SyncStatusWidget from "../sync_status.js"; | ||||||
|  | import BackInHistoryButtonWidget from "../buttons/history/history_back.js"; | ||||||
|  | import ForwardInHistoryButtonWidget from "../buttons/history/history_forward.js"; | ||||||
| 
 | 
 | ||||||
| export default class ShortcutContainer extends FlexContainer { | export default class ShortcutContainer extends FlexContainer { | ||||||
|     constructor() { |     constructor() { | ||||||
| @ -63,6 +65,10 @@ export default class ShortcutContainer extends FlexContainer { | |||||||
|                         this.child(new ProtectedSessionStatusWidget()); |                         this.child(new ProtectedSessionStatusWidget()); | ||||||
|                     } else if (builtinWidget === 'syncStatus') { |                     } else if (builtinWidget === 'syncStatus') { | ||||||
|                         this.child(new SyncStatusWidget()); |                         this.child(new SyncStatusWidget()); | ||||||
|  |                     } else if (builtinWidget === 'backInHistoryButton') { | ||||||
|  |                         this.child(new BackInHistoryButtonWidget()); | ||||||
|  |                     } else if (builtinWidget === 'forwardInHistoryButton') { | ||||||
|  |                         this.child(new ForwardInHistoryButtonWidget()); | ||||||
|                     } else { |                     } else { | ||||||
|                         console.log(`Unrecognized builtin widget ${builtinWidget} for shortcut ${shortcut.noteId} "${shortcut.title}"`); |                         console.log(`Unrecognized builtin widget ${builtinWidget} for shortcut ${shortcut.noteId} "${shortcut.title}"`); | ||||||
|                     } |                     } | ||||||
|  | |||||||
| @ -6,7 +6,7 @@ import libraryLoader from "../../services/library_loader.js"; | |||||||
| import openService from "../../services/open.js"; | import openService from "../../services/open.js"; | ||||||
| import protectedSessionHolder from "../../services/protected_session_holder.js"; | import protectedSessionHolder from "../../services/protected_session_holder.js"; | ||||||
| import BasicWidget from "../basic_widget.js"; | import BasicWidget from "../basic_widget.js"; | ||||||
| import dialogService from "../dialog.js"; | import dialogService from "../../services/dialog.js"; | ||||||
| 
 | 
 | ||||||
| const TPL = ` | const TPL = ` | ||||||
| <div class="note-revisions-dialog modal fade mx-auto" tabindex="-1" role="dialog"> | <div class="note-revisions-dialog modal fade mx-auto" tabindex="-1" role="dialog"> | ||||||
|  | |||||||
| @ -1,5 +1,5 @@ | |||||||
| import server from "../../../services/server.js"; | import server from "../../../services/server.js"; | ||||||
| import dialogService from "../../dialog.js"; | import dialogService from "../../../services/dialog.js"; | ||||||
| import toastService from "../../../services/toast.js"; | import toastService from "../../../services/toast.js"; | ||||||
| import OptionsTab from "./options_tab.js"; | import OptionsTab from "./options_tab.js"; | ||||||
| 
 | 
 | ||||||
|  | |||||||
| @ -1,6 +1,6 @@ | |||||||
| import server from "../../../services/server.js"; | import server from "../../../services/server.js"; | ||||||
| import utils from "../../../services/utils.js"; | import utils from "../../../services/utils.js"; | ||||||
| import dialogService from "../../dialog.js"; | import dialogService from "../../../services/dialog.js"; | ||||||
| import OptionsTab from "./options_tab.js"; | import OptionsTab from "./options_tab.js"; | ||||||
| 
 | 
 | ||||||
| const TPL = ` | const TPL = ` | ||||||
|  | |||||||
| @ -6,7 +6,7 @@ import froca from "../../services/froca.js"; | |||||||
| import appContext from "../../services/app_context.js"; | import appContext from "../../services/app_context.js"; | ||||||
| import hoistedNoteService from "../../services/hoisted_note.js"; | import hoistedNoteService from "../../services/hoisted_note.js"; | ||||||
| import BasicWidget from "../basic_widget.js"; | import BasicWidget from "../basic_widget.js"; | ||||||
| import dialogService from "../dialog.js"; | import dialogService from "../../services/dialog.js"; | ||||||
| import toastService from "../../services/toast.js"; | import toastService from "../../services/toast.js"; | ||||||
| 
 | 
 | ||||||
| const TPL = ` | const TPL = ` | ||||||
|  | |||||||
| @ -17,7 +17,7 @@ import linkService from "../services/link.js"; | |||||||
| import syncService from "../services/sync.js"; | import syncService from "../services/sync.js"; | ||||||
| import options from "../services/options.js"; | import options from "../services/options.js"; | ||||||
| import protectedSessionHolder from "../services/protected_session_holder.js"; | import protectedSessionHolder from "../services/protected_session_holder.js"; | ||||||
| import dialogService from "./dialog.js"; | import dialogService from "../services/dialog.js"; | ||||||
| 
 | 
 | ||||||
| const TPL = ` | const TPL = ` | ||||||
| <div class="tree-wrapper"> | <div class="tree-wrapper"> | ||||||
| @ -368,7 +368,7 @@ export default class NoteTreeWidget extends NoteContextAwareWidget { | |||||||
|             }, |             }, | ||||||
|             beforeActivate: (event, data) => { |             beforeActivate: (event, data) => { | ||||||
|                 // hidden subtree is hidden hackily, prevent activating it e.g. by keyboard
 |                 // hidden subtree is hidden hackily, prevent activating it e.g. by keyboard
 | ||||||
|                 return data.node.data.noteId !== 'hidden'; |                 return hoistedNoteService.getHoistedNoteId() === 'hidden' || data.node.data.noteId !== 'hidden'; | ||||||
|             }, |             }, | ||||||
|             activate: async (event, data) => { |             activate: async (event, data) => { | ||||||
|                 // click event won't propagate so let's close context menu manually
 |                 // click event won't propagate so let's close context menu manually
 | ||||||
|  | |||||||
| @ -1,7 +1,7 @@ | |||||||
| import server from '../services/server.js'; | import server from '../services/server.js'; | ||||||
| import mimeTypesService from '../services/mime_types.js'; | import mimeTypesService from '../services/mime_types.js'; | ||||||
| import NoteContextAwareWidget from "./note_context_aware_widget.js"; | import NoteContextAwareWidget from "./note_context_aware_widget.js"; | ||||||
| import dialogService from "./dialog.js"; | import dialogService from "../services/dialog.js"; | ||||||
| 
 | 
 | ||||||
| const NOTE_TYPES = [ | const NOTE_TYPES = [ | ||||||
|     { type: "file", title: "File", selectable: false }, |     { type: "file", title: "File", selectable: false }, | ||||||
| @ -9,6 +9,7 @@ const NOTE_TYPES = [ | |||||||
|     { type: "search", title: "Saved Search", selectable: false }, |     { type: "search", title: "Saved Search", selectable: false }, | ||||||
|     { type: "note-map", mime: '', title: "Note Map", selectable: false }, |     { type: "note-map", mime: '', title: "Note Map", selectable: false }, | ||||||
|     { type: "shortcut", mime: '', title: "Shortcut", selectable: false }, |     { type: "shortcut", mime: '', title: "Shortcut", selectable: false }, | ||||||
|  |     { type: "doc", mime: '', title: "Doc", selectable: false }, | ||||||
| 
 | 
 | ||||||
|     { type: "text", mime: "text/html", title: "Text", selectable: true }, |     { type: "text", mime: "text/html", title: "Text", selectable: true }, | ||||||
|     { type: "relation-map", mime: "application/json", title: "Relation Map", selectable: true }, |     { type: "relation-map", mime: "application/json", title: "Relation Map", selectable: true }, | ||||||
|  | |||||||
| @ -3,7 +3,7 @@ import branchService from "../services/branches.js"; | |||||||
| import server from "../services/server.js"; | import server from "../services/server.js"; | ||||||
| import utils from "../services/utils.js"; | import utils from "../services/utils.js"; | ||||||
| import syncService from "../services/sync.js"; | import syncService from "../services/sync.js"; | ||||||
| import dialogService from "./dialog.js"; | import dialogService from "../services/dialog.js"; | ||||||
| 
 | 
 | ||||||
| export default class SharedSwitchWidget extends SwitchWidget { | export default class SharedSwitchWidget extends SwitchWidget { | ||||||
|     isEnabled() { |     isEnabled() { | ||||||
|  | |||||||
| @ -8,7 +8,7 @@ import TypeWidget from "./type_widget.js"; | |||||||
| import appContext from "../../services/app_context.js"; | import appContext from "../../services/app_context.js"; | ||||||
| import utils from "../../services/utils.js"; | import utils from "../../services/utils.js"; | ||||||
| import froca from "../../services/froca.js"; | import froca from "../../services/froca.js"; | ||||||
| import dialogService from "../../widgets/dialog.js"; | import dialogService from "../../services/dialog.js"; | ||||||
| 
 | 
 | ||||||
| const uniDirectionalOverlays = [ | const uniDirectionalOverlays = [ | ||||||
|     [ "Arrow", { |     [ "Arrow", { | ||||||
|  | |||||||
| @ -70,6 +70,10 @@ function createShortcut(req) { | |||||||
|     return specialNotesService.createShortcut(req.params.parentNoteId, req.params.type); |     return specialNotesService.createShortcut(req.params.parentNoteId, req.params.type); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | function resetShortcut(req) { | ||||||
|  |     return specialNotesService.resetShortcut(req.params.noteId); | ||||||
|  | } | ||||||
|  | 
 | ||||||
| module.exports = { | module.exports = { | ||||||
|     getInboxNote, |     getInboxNote, | ||||||
|     getDayNote, |     getDayNote, | ||||||
| @ -81,5 +85,6 @@ module.exports = { | |||||||
|     saveSqlConsole, |     saveSqlConsole, | ||||||
|     createSearchNote, |     createSearchNote, | ||||||
|     saveSearchNote, |     saveSearchNote, | ||||||
|     createShortcut |     createShortcut, | ||||||
|  |     resetShortcut | ||||||
| }; | }; | ||||||
|  | |||||||
| @ -326,6 +326,7 @@ function register(app) { | |||||||
|     apiRoute(POST, '/api/special-notes/save-sql-console', specialNotesRoute.saveSqlConsole); |     apiRoute(POST, '/api/special-notes/save-sql-console', specialNotesRoute.saveSqlConsole); | ||||||
|     apiRoute(POST, '/api/special-notes/search-note', specialNotesRoute.createSearchNote); |     apiRoute(POST, '/api/special-notes/search-note', specialNotesRoute.createSearchNote); | ||||||
|     apiRoute(POST, '/api/special-notes/save-search-note', specialNotesRoute.saveSearchNote); |     apiRoute(POST, '/api/special-notes/save-search-note', specialNotesRoute.saveSearchNote); | ||||||
|  |     apiRoute(POST, '/api/special-notes/shortcuts/:noteId/reset', specialNotesRoute.resetShortcut); | ||||||
|     apiRoute(POST, '/api/special-notes/shortcuts/:parentNoteId/:type', specialNotesRoute.createShortcut); |     apiRoute(POST, '/api/special-notes/shortcuts/:parentNoteId/:type', specialNotesRoute.createShortcut); | ||||||
| 
 | 
 | ||||||
|     // :filename is not used by trilium, but instead used for "save as" to assign a human-readable filename
 |     // :filename is not used by trilium, but instead used for "save as" to assign a human-readable filename
 | ||||||
|  | |||||||
| @ -4,7 +4,7 @@ const build = require('./build'); | |||||||
| const packageJson = require('../../package'); | const packageJson = require('../../package'); | ||||||
| const {TRILIUM_DATA_DIR} = require('./data_dir'); | const {TRILIUM_DATA_DIR} = require('./data_dir'); | ||||||
| 
 | 
 | ||||||
| const APP_DB_VERSION = 202; | const APP_DB_VERSION = 203; | ||||||
| const SYNC_VERSION = 27; | const SYNC_VERSION = 27; | ||||||
| const CLIPPER_PROTOCOL_VERSION = "1.0"; | const CLIPPER_PROTOCOL_VERSION = "1.0"; | ||||||
| 
 | 
 | ||||||
|  | |||||||
| @ -11,5 +11,6 @@ module.exports = [ | |||||||
|     'mermaid', |     'mermaid', | ||||||
|     'canvas', |     'canvas', | ||||||
|     'web-view', |     'web-view', | ||||||
|     'shortcut' |     'shortcut', | ||||||
|  |     'doc' | ||||||
| ]; | ]; | ||||||
|  | |||||||
| @ -37,7 +37,7 @@ function getHiddenRoot() { | |||||||
|             branchId: 'hidden', |             branchId: 'hidden', | ||||||
|             noteId: 'hidden', |             noteId: 'hidden', | ||||||
|             title: 'hidden', |             title: 'hidden', | ||||||
|             type: 'text', |             type: 'doc', | ||||||
|             content: '', |             content: '', | ||||||
|             parentNoteId: 'root' |             parentNoteId: 'root' | ||||||
|         }).note; |         }).note; | ||||||
| @ -46,6 +46,11 @@ function getHiddenRoot() { | |||||||
|         // the flag is not inherited to the children
 |         // the flag is not inherited to the children
 | ||||||
|         hidden.addLabel('archived', "", false); |         hidden.addLabel('archived', "", false); | ||||||
|         hidden.addLabel('excludeFromNoteMap', "", true); |         hidden.addLabel('excludeFromNoteMap', "", true); | ||||||
|  |         hidden.addLabel('iconClass', "bx bx-chip", false); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     if (!hidden.hasOwnedLabel("docName")) { | ||||||
|  |         hidden.addLabel("docName", "hidden"); | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     return hidden; |     return hidden; | ||||||
| @ -59,7 +64,7 @@ function getSearchRoot() { | |||||||
|             branchId: 'search', |             branchId: 'search', | ||||||
|             noteId: 'search', |             noteId: 'search', | ||||||
|             title: 'search', |             title: 'search', | ||||||
|             type: 'text', |             type: 'doc', | ||||||
|             content: '', |             content: '', | ||||||
|             parentNoteId: getHiddenRoot().noteId |             parentNoteId: getHiddenRoot().noteId | ||||||
|         }).note; |         }).note; | ||||||
| @ -95,10 +100,12 @@ function getSqlConsoleRoot() { | |||||||
|             branchId: 'sqlconsole', |             branchId: 'sqlconsole', | ||||||
|             noteId: 'sqlconsole', |             noteId: 'sqlconsole', | ||||||
|             title: 'SQL Console', |             title: 'SQL Console', | ||||||
|             type: 'text', |             type: 'doc', | ||||||
|             content: '', |             content: '', | ||||||
|             parentNoteId: getHiddenRoot().noteId |             parentNoteId: getHiddenRoot().noteId | ||||||
|         }).note; |         }).note; | ||||||
|  | 
 | ||||||
|  |         sqlConsoleRoot.addLabel('iconClass', 'bx bx-data'); | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     return sqlConsoleRoot; |     return sqlConsoleRoot; | ||||||
| @ -114,6 +121,7 @@ function createSqlConsole() { | |||||||
|     }); |     }); | ||||||
| 
 | 
 | ||||||
|     note.setLabel("sqlConsole", dateUtils.localNowDate()); |     note.setLabel("sqlConsole", dateUtils.localNowDate()); | ||||||
|  |     note.setLabel('iconClass', 'bx bx-data'); | ||||||
| 
 | 
 | ||||||
|     return note; |     return note; | ||||||
| } | } | ||||||
| @ -199,12 +207,16 @@ function getShareRoot() { | |||||||
|             branchId: 'share', |             branchId: 'share', | ||||||
|             noteId: 'share', |             noteId: 'share', | ||||||
|             title: 'Shared notes', |             title: 'Shared notes', | ||||||
|             type: 'text', |             type: 'doc', | ||||||
|             content: '', |             content: '', | ||||||
|             parentNoteId: hiddenRoot.noteId |             parentNoteId: hiddenRoot.noteId | ||||||
|         }).note; |         }).note; | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|  |     if (!shareRoot.hasOwnedLabel("docName")) { | ||||||
|  |         shareRoot.addLabel("docName", "share"); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|     return shareRoot; |     return shareRoot; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| @ -233,7 +245,7 @@ function getLaunchBarRoot() { | |||||||
|             branchId: 'lb_root', |             branchId: 'lb_root', | ||||||
|             noteId: 'lb_root', |             noteId: 'lb_root', | ||||||
|             title: 'Launch bar', |             title: 'Launch bar', | ||||||
|             type: 'shortcut', |             type: 'doc', | ||||||
|             content: '', |             content: '', | ||||||
|             parentNoteId: getHiddenRoot().noteId |             parentNoteId: getHiddenRoot().noteId | ||||||
|         }).note; |         }).note; | ||||||
| @ -253,7 +265,7 @@ function getLaunchBarAvailableShortcutsRoot() { | |||||||
|             branchId: 'lb_availableshortcuts', |             branchId: 'lb_availableshortcuts', | ||||||
|             noteId: 'lb_availableshortcuts', |             noteId: 'lb_availableshortcuts', | ||||||
|             title: 'Available shortcuts', |             title: 'Available shortcuts', | ||||||
|             type: 'shortcut', |             type: 'doc', | ||||||
|             content: '', |             content: '', | ||||||
|             parentNoteId: getLaunchBarRoot().noteId |             parentNoteId: getLaunchBarRoot().noteId | ||||||
|         }).note; |         }).note; | ||||||
| @ -279,7 +291,7 @@ function getLaunchBarVisibleShortcutsRoot() { | |||||||
|             branchId: 'lb_visibleshortcuts', |             branchId: 'lb_visibleshortcuts', | ||||||
|             noteId: 'lb_visibleshortcuts', |             noteId: 'lb_visibleshortcuts', | ||||||
|             title: 'Visible shortcuts', |             title: 'Visible shortcuts', | ||||||
|             type: 'shortcut', |             type: 'doc', | ||||||
|             content: '', |             content: '', | ||||||
|             parentNoteId: getLaunchBarRoot().noteId |             parentNoteId: getLaunchBarRoot().noteId | ||||||
|         }).note; |         }).note; | ||||||
| @ -298,11 +310,11 @@ function getLaunchBarVisibleShortcutsRoot() { | |||||||
| } | } | ||||||
| 
 | 
 | ||||||
| const shortcuts = [ | const shortcuts = [ | ||||||
|  |     // visible shortcuts:
 | ||||||
|     { id: 'lb_newnote', command: 'createNoteIntoInbox', title: 'New note', icon: 'bx bx-file-blank', isVisible: true }, |     { id: 'lb_newnote', command: 'createNoteIntoInbox', title: 'New note', icon: 'bx bx-file-blank', isVisible: true }, | ||||||
|     { id: 'lb_search', command: 'searchNotes', title: 'Search notes', icon: 'bx bx-search', isVisible: true }, |     { id: 'lb_search', command: 'searchNotes', title: 'Search notes', icon: 'bx bx-search', isVisible: true }, | ||||||
|     { id: 'lb_jumpto', command: 'jumpToNote', title: 'Jump to note', icon: 'bx bx-send', isVisible: true }, |     { id: 'lb_jumpto', command: 'jumpToNote', title: 'Jump to note', icon: 'bx bx-send', isVisible: true }, | ||||||
|     { id: 'lb_notemap', targetNoteId: 'globalnotemap', title: 'Note map', icon: 'bx bx-map-alt', isVisible: true }, |     { id: 'lb_notemap', targetNoteId: 'globalnotemap', title: 'Note map', icon: 'bx bx-map-alt', isVisible: true }, | ||||||
|     { id: 'lb_recentchanges', command: 'showRecentChanges', title: 'Recent changes', icon: 'bx bx-history', isVisible: false }, |  | ||||||
|     { id: 'lb_calendar', builtinWidget: 'calendar', title: 'Calendar', icon: 'bx bx-calendar', isVisible: true }, |     { id: 'lb_calendar', builtinWidget: 'calendar', title: 'Calendar', icon: 'bx bx-calendar', isVisible: true }, | ||||||
|     { id: 'lb_spacer1', builtinWidget: 'spacer', title: 'Spacer', icon: 'bx bx-move-vertical', isVisible: true, labels: [ |     { id: 'lb_spacer1', builtinWidget: 'spacer', title: 'Spacer', icon: 'bx bx-move-vertical', isVisible: true, labels: [ | ||||||
|             { type: "number", name: "baseSize", value: "40" }, |             { type: "number", name: "baseSize", value: "40" }, | ||||||
| @ -316,6 +328,11 @@ const shortcuts = [ | |||||||
|         ] }, |         ] }, | ||||||
|     { id: 'lb_protectedsession', builtinWidget: 'protectedSession', title: 'Protected session', icon: 'bx bx bx-shield-quarter', isVisible: true }, |     { id: 'lb_protectedsession', builtinWidget: 'protectedSession', title: 'Protected session', icon: 'bx bx bx-shield-quarter', isVisible: true }, | ||||||
|     { id: 'lb_syncstatus', builtinWidget: 'syncStatus', title: 'Sync status', icon: 'bx bx-wifi', isVisible: true }, |     { id: 'lb_syncstatus', builtinWidget: 'syncStatus', title: 'Sync status', icon: 'bx bx-wifi', isVisible: true }, | ||||||
|  | 
 | ||||||
|  |     // available shortcuts:
 | ||||||
|  |     { id: 'lb_recentchanges', command: 'showRecentChanges', title: 'Recent changes', icon: 'bx bx-history', isVisible: false }, | ||||||
|  |     { id: 'lb_backinhistory', builtinWidget: 'backInHistoryButton', title: 'Back in history', icon: 'bx bxs-left-arrow-square', isVisible: false }, | ||||||
|  |     { id: 'lb_forwardinhistory', builtinWidget: 'forwardInHistoryButton', title: 'Forward in history', icon: 'bx bxs-right-arrow-square', isVisible: false }, | ||||||
| ]; | ]; | ||||||
| 
 | 
 | ||||||
| function createMissingSpecialNotes() { | function createMissingSpecialNotes() { | ||||||
| @ -324,7 +341,8 @@ function createMissingSpecialNotes() { | |||||||
|     getBulkActionNote(); |     getBulkActionNote(); | ||||||
|     getLaunchBarRoot(); |     getLaunchBarRoot(); | ||||||
|     getLaunchBarAvailableShortcutsRoot(); |     getLaunchBarAvailableShortcutsRoot(); | ||||||
|     getLaunchBarVisibleShortcutsRoot() |     getLaunchBarVisibleShortcutsRoot(); | ||||||
|  |     getShareRoot(); | ||||||
| 
 | 
 | ||||||
|     for (const shortcut of shortcuts) { |     for (const shortcut of shortcuts) { | ||||||
|         let note = becca.getNote(shortcut.id); |         let note = becca.getNote(shortcut.id); | ||||||
| @ -333,7 +351,10 @@ function createMissingSpecialNotes() { | |||||||
|             continue; |             continue; | ||||||
|         } |         } | ||||||
| 
 | 
 | ||||||
|         const parentNoteId = shortcut.isVisible ? getLaunchBarVisibleShortcutsRoot().noteId : getLaunchBarAvailableShortcutsRoot().noteId; |         const parentNoteId = shortcut.isVisible | ||||||
|  |             ? getLaunchBarVisibleShortcutsRoot().noteId | ||||||
|  |             : getLaunchBarAvailableShortcutsRoot().noteId; | ||||||
|  | 
 | ||||||
|         note = noteService.createNewNote({ |         note = noteService.createNewNote({ | ||||||
|             noteId: shortcut.id, |             noteId: shortcut.id, | ||||||
|             title: shortcut.title, |             title: shortcut.title, | ||||||
| @ -428,6 +449,29 @@ function createShortcut(parentNoteId, type) { | |||||||
|     }; |     }; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | function resetShortcut(noteId) { | ||||||
|  |     if (noteId.startsWith('lb_')) { | ||||||
|  |         const note = becca.getNote(noteId); | ||||||
|  | 
 | ||||||
|  |         if (note) { | ||||||
|  |             if (noteId === 'lb_root') { | ||||||
|  |                 // deleting hoisted notes are not allowed, so we just reset the children
 | ||||||
|  |                 for (const childNote of note.getChildNotes()) { | ||||||
|  |                     childNote.deleteNote(); | ||||||
|  |                 } | ||||||
|  |             } else { | ||||||
|  |                 note.deleteNote(); | ||||||
|  |             } | ||||||
|  |         } else { | ||||||
|  |             log.info(`Note ${noteId} has not been found and cannot be reset.`); | ||||||
|  |         } | ||||||
|  |     } else { | ||||||
|  |         log.info(`Note ${noteId} is not a resettable shortcut note.`); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     createMissingSpecialNotes(); | ||||||
|  | } | ||||||
|  | 
 | ||||||
| module.exports = { | module.exports = { | ||||||
|     getInboxNote, |     getInboxNote, | ||||||
|     createSqlConsole, |     createSqlConsole, | ||||||
| @ -438,5 +482,6 @@ module.exports = { | |||||||
|     getShareRoot, |     getShareRoot, | ||||||
|     getHiddenRoot, |     getHiddenRoot, | ||||||
|     getBulkActionNote, |     getBulkActionNote, | ||||||
|     createShortcut |     createShortcut, | ||||||
|  |     resetShortcut | ||||||
| }; | }; | ||||||
|  | |||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user
	 zadam
						zadam