mirror of
				https://github.com/zadam/trilium.git
				synced 2025-10-31 10:26:08 +01:00 
			
		
		
		
	mobile frontend WIP, removing extra dependencies
This commit is contained in:
		
							
								
								
									
										9
									
								
								src/public/javascripts/services/bootstrap.js
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										9
									
								
								src/public/javascripts/services/bootstrap.js
									
									
									
									
										vendored
									
									
								
							| @@ -33,6 +33,9 @@ import bundle from "./bundle.js"; | ||||
| import treeCache from "./tree_cache.js"; | ||||
| import libraryLoader from "./library_loader.js"; | ||||
| import hoistedNoteService from './hoisted_note.js'; | ||||
| import noteTypeService from './note_type.js'; | ||||
| import linkService from './link.js'; | ||||
| import noteAutocompleteService from './note_autocomplete.js'; | ||||
|  | ||||
| // required for CKEditor image upload plugin | ||||
| window.glob.getCurrentNode = treeService.getCurrentNode; | ||||
| @@ -144,3 +147,9 @@ entrypoints.registerEntrypoints(); | ||||
| noteTooltipService.setupGlobalTooltip(); | ||||
|  | ||||
| bundle.executeStartupBundles(); | ||||
|  | ||||
| noteTypeService.init(); | ||||
|  | ||||
| linkService.init(); | ||||
|  | ||||
| noteAutocompleteService.init(); | ||||
| @@ -88,17 +88,19 @@ function addTextToEditor(text) { | ||||
|     }); | ||||
| } | ||||
|  | ||||
| ko.bindingHandlers.noteLink = { | ||||
|     init: async function(element, valueAccessor, allBindings, viewModel, bindingContext) { | ||||
|         const noteId = ko.unwrap(valueAccessor()); | ||||
| function init() { | ||||
|     ko.bindingHandlers.noteLink = { | ||||
|         init: async function(element, valueAccessor, allBindings, viewModel, bindingContext) { | ||||
|             const noteId = ko.unwrap(valueAccessor()); | ||||
|  | ||||
|         if (noteId) { | ||||
|             const link = await createNoteLink(noteId); | ||||
|             if (noteId) { | ||||
|                 const link = await createNoteLink(noteId); | ||||
|  | ||||
|             $(element).append(link); | ||||
|                 $(element).append(link); | ||||
|             } | ||||
|         } | ||||
|     } | ||||
| }; | ||||
|     }; | ||||
| } | ||||
|  | ||||
| // when click on link popup, in case of internal link, just go the the referenced note instead of default behavior | ||||
| // of opening the link in new window/tab | ||||
| @@ -124,5 +126,6 @@ export default { | ||||
|     getNotePathFromUrl, | ||||
|     createNoteLink, | ||||
|     addLinkToEditor, | ||||
|     addTextToEditor | ||||
|     addTextToEditor, | ||||
|     init | ||||
| }; | ||||
| @@ -1,3 +1,43 @@ | ||||
| import treeService from "./tree.js"; | ||||
| import noteDetailService from "./note_detail.js"; | ||||
| import dragAndDropSetup from "./drag_and_drop.js"; | ||||
| import treeCache from "./tree_cache.js"; | ||||
| import treeBuilder from "./tree_builder.js"; | ||||
|  | ||||
| treeService.showTree(); | ||||
| const $tree = $("#tree"); | ||||
|  | ||||
| async function showTree() { | ||||
|     const tree = await treeService.loadTree(); | ||||
|  | ||||
|     $tree.fancytree({ | ||||
|         autoScroll: true, | ||||
|         keyboard: false, // we takover keyboard handling in the hotkeys plugin | ||||
|         extensions: ["dnd5", "clones"], | ||||
|         source: tree, | ||||
|         scrollParent: $tree, | ||||
|         minExpandLevel: 2, // root can't be collapsed | ||||
|         activate: (event, data) => { | ||||
|             const node = data.node; | ||||
|             const noteId = node.data.noteId; | ||||
|  | ||||
|             treeService.setCurrentNotePathToHash(node); | ||||
|  | ||||
|             noteDetailService.switchToNote(noteId, true); | ||||
|         }, | ||||
|         expand: (event, data) => treeService.setExpandedToServer(data.node.data.branchId, true), | ||||
|         collapse: (event, data) => treeService.setExpandedToServer(data.node.data.branchId, false), | ||||
|         init: (event, data) => treeService.treeInitialized(), // don't collapse to short form | ||||
|         dnd5: dragAndDropSetup, | ||||
|         lazyLoad: function(event, data) { | ||||
|             const noteId = data.node.data.noteId; | ||||
|  | ||||
|             data.result = treeCache.getNote(noteId).then(note => treeBuilder.prepareBranch(note)); | ||||
|         }, | ||||
|         clones: { | ||||
|             highlightActiveClones: true | ||||
|         } | ||||
|     }); | ||||
|  | ||||
| } | ||||
|  | ||||
| showTree(); | ||||
| @@ -101,40 +101,42 @@ function initNoteAutocomplete($el, options) { | ||||
|     return $el; | ||||
| } | ||||
|  | ||||
| $.fn.getSelectedPath = function() { | ||||
|     if (!$(this).val().trim()) { | ||||
|         return ""; | ||||
|     } | ||||
|     else { | ||||
|         return $(this).attr(SELECTED_PATH_KEY); | ||||
|     } | ||||
| }; | ||||
| function init() { | ||||
|     $.fn.getSelectedPath = function () { | ||||
|         if (!$(this).val().trim()) { | ||||
|             return ""; | ||||
|         } else { | ||||
|             return $(this).attr(SELECTED_PATH_KEY); | ||||
|         } | ||||
|     }; | ||||
|  | ||||
| $.fn.setSelectedPath = function(path) { | ||||
|     path = path || ""; | ||||
|     $.fn.setSelectedPath = function (path) { | ||||
|         path = path || ""; | ||||
|  | ||||
|     $(this).attr(SELECTED_PATH_KEY, path); | ||||
|         $(this).attr(SELECTED_PATH_KEY, path); | ||||
|  | ||||
|     $(this) | ||||
|         .closest(".input-group") | ||||
|         .find(".go-to-selected-note-button") | ||||
|         .toggleClass("disabled", !path.trim()) | ||||
|         .attr(SELECTED_PATH_KEY, path); // we also set attr here so tooltip can be displayed | ||||
| }; | ||||
|         $(this) | ||||
|             .closest(".input-group") | ||||
|             .find(".go-to-selected-note-button") | ||||
|             .toggleClass("disabled", !path.trim()) | ||||
|             .attr(SELECTED_PATH_KEY, path); // we also set attr here so tooltip can be displayed | ||||
|     }; | ||||
|  | ||||
| ko.bindingHandlers.noteAutocomplete = { | ||||
|     init: function(element, valueAccessor, allBindings, viewModel, bindingContext) { | ||||
|         initNoteAutocomplete($(element)); | ||||
|     ko.bindingHandlers.noteAutocomplete = { | ||||
|         init: function (element, valueAccessor, allBindings, viewModel, bindingContext) { | ||||
|             initNoteAutocomplete($(element)); | ||||
|  | ||||
|         $(element).setSelectedPath(bindingContext.$data.selectedPath); | ||||
|             $(element).setSelectedPath(bindingContext.$data.selectedPath); | ||||
|  | ||||
|         $(element).on('autocomplete:selected', function(event, suggestion, dataset) { | ||||
|             bindingContext.$data.selectedPath = $(element).val().trim() ? suggestion.path : ''; | ||||
|         }); | ||||
|     } | ||||
| }; | ||||
|             $(element).on('autocomplete:selected', function (event, suggestion, dataset) { | ||||
|                 bindingContext.$data.selectedPath = $(element).val().trim() ? suggestion.path : ''; | ||||
|             }); | ||||
|         } | ||||
|     }; | ||||
| } | ||||
|  | ||||
| export default { | ||||
|     initNoteAutocomplete, | ||||
|     showRecentNotes | ||||
|     showRecentNotes, | ||||
|     init | ||||
| } | ||||
| @@ -17,6 +17,7 @@ import noteDetailRender from './note_detail_render.js'; | ||||
| import noteDetailRelationMap from './note_detail_relation_map.js'; | ||||
| import bundleService from "./bundle.js"; | ||||
| import attributeService from "./attributes.js"; | ||||
| import utils from "./utils.js"; | ||||
|  | ||||
| const $noteTitle = $("#note-title"); | ||||
|  | ||||
| @@ -89,11 +90,11 @@ async function reload() { | ||||
|     await loadNoteDetail(getCurrentNoteId()); | ||||
| } | ||||
|  | ||||
| async function switchToNote(noteId) { | ||||
| async function switchToNote(noteId, mobile) { | ||||
|     if (getCurrentNoteId() !== noteId) { | ||||
|         await saveNoteIfChanged(); | ||||
|  | ||||
|         await loadNoteDetail(noteId); | ||||
|         await loadNoteDetail(noteId, mobile); | ||||
|     } | ||||
| } | ||||
|  | ||||
| @@ -177,8 +178,10 @@ async function loadNoteDetail(noteId) { | ||||
|     // only now that we're in sync with tree active node we will switch currentNote | ||||
|     currentNote = loadedNote; | ||||
|  | ||||
|     // needs to happend after loading the note itself because it references current noteId | ||||
|     attributeService.refreshAttributes(); | ||||
|     if (utils.isDesktop()) { | ||||
|         // needs to happen after loading the note itself because it references current noteId | ||||
|         attributeService.refreshAttributes(); | ||||
|     } | ||||
|  | ||||
|     if (isNewNoteCreated) { | ||||
|         isNewNoteCreated = false; | ||||
| @@ -197,8 +200,10 @@ async function loadNoteDetail(noteId) { | ||||
|     try { | ||||
|         $noteTitle.val(currentNote.title); | ||||
|  | ||||
|         noteTypeService.setNoteType(currentNote.type); | ||||
|         noteTypeService.setNoteMime(currentNote.mime); | ||||
|         if (utils.isDesktop()) { | ||||
|             noteTypeService.setNoteType(currentNote.type); | ||||
|             noteTypeService.setNoteMime(currentNote.mime); | ||||
|         } | ||||
|  | ||||
|         for (const componentType in components) { | ||||
|             if (componentType !== currentNote.type) { | ||||
| @@ -225,13 +230,15 @@ async function loadNoteDetail(noteId) { | ||||
|     // after loading new note make sure editor is scrolled to the top | ||||
|     getComponent(currentNote.type).scrollToTop(); | ||||
|  | ||||
|     $scriptArea.empty(); | ||||
|     if (utils.isDesktop()) { | ||||
|         $scriptArea.empty(); | ||||
|  | ||||
|     await bundleService.executeRelationBundles(getCurrentNote(), 'runOnNoteView'); | ||||
|         await bundleService.executeRelationBundles(getCurrentNote(), 'runOnNoteView'); | ||||
|  | ||||
|     await attributeService.showAttributes(); | ||||
|         await attributeService.showAttributes(); | ||||
|  | ||||
|     await showChildrenOverview(); | ||||
|         await showChildrenOverview(); | ||||
|     } | ||||
| } | ||||
|  | ||||
| async function showChildrenOverview() { | ||||
|   | ||||
| @@ -44,7 +44,7 @@ const DEFAULT_MIME_TYPES = [ | ||||
|     { mime: 'text/x-yaml', title: 'YAML' } | ||||
| ]; | ||||
|  | ||||
| const noteTypeModel = new NoteTypeModel(); | ||||
| let noteTypeModel; | ||||
|  | ||||
| function NoteTypeModel() { | ||||
|     const self = this; | ||||
| @@ -153,7 +153,11 @@ function NoteTypeModel() { | ||||
|     } | ||||
| } | ||||
|  | ||||
| ko.applyBindings(noteTypeModel, document.getElementById('note-type-wrapper')); | ||||
| function init() { | ||||
|     noteTypeModel = new NoteTypeModel(); | ||||
|  | ||||
|     ko.applyBindings(noteTypeModel, document.getElementById('note-type-wrapper')); | ||||
| } | ||||
|  | ||||
| export default { | ||||
|     getNoteType: () => noteTypeModel.type(), | ||||
| @@ -168,5 +172,6 @@ export default { | ||||
|  | ||||
|     getDefaultCodeMimeTypes: () => DEFAULT_MIME_TYPES.slice(), | ||||
|     getCodeMimeTypes: () => noteTypeModel.codeMimeTypes(), | ||||
|     setCodeMimeTypes: types => noteTypeModel.codeMimeTypes(types) | ||||
|     setCodeMimeTypes: types => noteTypeModel.codeMimeTypes(types), | ||||
|     init | ||||
| }; | ||||
| @@ -359,7 +359,7 @@ function initFancyTree(tree) { | ||||
|     $tree.fancytree({ | ||||
|         autoScroll: true, | ||||
|         keyboard: false, // we takover keyboard handling in the hotkeys plugin | ||||
|         extensions: ["hotkeys", "filter", "dnd5", "clones"], | ||||
|         extensions: ["hotkeys", "dnd5", "clones"], | ||||
|         source: tree, | ||||
|         scrollParent: $tree, | ||||
|         minExpandLevel: 2, // root can't be collapsed | ||||
| @@ -397,18 +397,6 @@ function initFancyTree(tree) { | ||||
|         hotkeys: { | ||||
|             keydown: treeKeyBindings | ||||
|         }, | ||||
|         filter: { | ||||
|             autoApply: true,   // Re-apply last filter if lazy data is loaded | ||||
|             autoExpand: true, // Expand all branches that contain matches while filtered | ||||
|             counter: false,     // Show a badge with number of matching child nodes near parent icons | ||||
|             fuzzy: false,      // Match single characters in order, e.g. 'fb' will match 'FooBar' | ||||
|             hideExpandedCounter: true,  // Hide counter badge if parent is expanded | ||||
|             hideExpanders: false,       // Hide expanders if all child nodes are hidden by filter | ||||
|             highlight: true,   // Highlight matches by wrapping inside <mark> tags | ||||
|             leavesOnly: false, // Match end nodes only | ||||
|             nodata: true,      // Display a 'no data' status node if result is empty | ||||
|             mode: "hide"       // Grayout unmatched nodes (pass "hide" to remove unmatched node instead) | ||||
|         }, | ||||
|         dnd5: dragAndDropSetup, | ||||
|         lazyLoad: function(event, data) { | ||||
|             const noteId = data.node.data.noteId; | ||||
| @@ -696,5 +684,8 @@ export default { | ||||
|     getSelectedNodes, | ||||
|     clearSelectedNodes, | ||||
|     sortAlphabetically, | ||||
|     showTree | ||||
|     showTree, | ||||
|     loadTree, | ||||
|     treeInitialized, | ||||
|     setExpandedToServer | ||||
| }; | ||||
| @@ -143,6 +143,14 @@ function bindShortcut(keyboardShortcut, handler) { | ||||
|     }); | ||||
| } | ||||
|  | ||||
| function isMobile() { | ||||
|     return window.device === "mobile"; | ||||
| } | ||||
|  | ||||
| function isDesktop() { | ||||
|     return window.device === "desktop"; | ||||
| } | ||||
|  | ||||
| export default { | ||||
|     reloadApp, | ||||
|     parseDate, | ||||
| @@ -166,5 +174,7 @@ export default { | ||||
|     download, | ||||
|     toObject, | ||||
|     randomString, | ||||
|     bindShortcut | ||||
|     bindShortcut, | ||||
|     isMobile, | ||||
|     isDesktop | ||||
| }; | ||||
| @@ -205,6 +205,7 @@ | ||||
|  | ||||
| <script type="text/javascript"> | ||||
|     window.baseApiUrl = 'api/'; | ||||
|     window.device = "desktop"; | ||||
|     window.glob = { | ||||
|         activeDialog: null, | ||||
|         sourceId: '<%= sourceId %>', | ||||
|   | ||||
| @@ -10,6 +10,7 @@ | ||||
|  | ||||
| <script type="text/javascript"> | ||||
|     window.baseApiUrl = 'api/'; | ||||
|     window.device = "mobile"; | ||||
|     window.glob = { | ||||
|         activeDialog: null, | ||||
|         sourceId: '<%= sourceId %>', | ||||
| @@ -26,11 +27,6 @@ | ||||
| <link href="libraries/bootstrap/css/bootstrap.min.css" rel="stylesheet"> | ||||
| <script src="javascripts/services/mobile.js" crossorigin type="module"></script> | ||||
|  | ||||
| <script src="libraries/jquery.hotkeys.js"></script> | ||||
| <script src="libraries/jquery.fancytree.hotkeys.js"></script> | ||||
|  | ||||
| <script src="libraries/knockout.min.js"></script> | ||||
|  | ||||
| <link href="stylesheets/style.css" rel="stylesheet"> | ||||
| <link href="stylesheets/mobile.css" rel="stylesheet"> | ||||
|  | ||||
|   | ||||
		Reference in New Issue
	
	Block a user