mirror of
https://github.com/zadam/trilium.git
synced 2025-06-06 18:08:33 +02:00
mobile frontend WIP, removing extra dependencies
This commit is contained in:
parent
a32645cdeb
commit
e0028ab6f1
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 treeCache from "./tree_cache.js";
|
||||||
import libraryLoader from "./library_loader.js";
|
import libraryLoader from "./library_loader.js";
|
||||||
import hoistedNoteService from './hoisted_note.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
|
// required for CKEditor image upload plugin
|
||||||
window.glob.getCurrentNode = treeService.getCurrentNode;
|
window.glob.getCurrentNode = treeService.getCurrentNode;
|
||||||
@ -144,3 +147,9 @@ entrypoints.registerEntrypoints();
|
|||||||
noteTooltipService.setupGlobalTooltip();
|
noteTooltipService.setupGlobalTooltip();
|
||||||
|
|
||||||
bundle.executeStartupBundles();
|
bundle.executeStartupBundles();
|
||||||
|
|
||||||
|
noteTypeService.init();
|
||||||
|
|
||||||
|
linkService.init();
|
||||||
|
|
||||||
|
noteAutocompleteService.init();
|
@ -88,17 +88,19 @@ function addTextToEditor(text) {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
ko.bindingHandlers.noteLink = {
|
function init() {
|
||||||
init: async function(element, valueAccessor, allBindings, viewModel, bindingContext) {
|
ko.bindingHandlers.noteLink = {
|
||||||
const noteId = ko.unwrap(valueAccessor());
|
init: async function(element, valueAccessor, allBindings, viewModel, bindingContext) {
|
||||||
|
const noteId = ko.unwrap(valueAccessor());
|
||||||
|
|
||||||
if (noteId) {
|
if (noteId) {
|
||||||
const link = await createNoteLink(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
|
// 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
|
// of opening the link in new window/tab
|
||||||
@ -124,5 +126,6 @@ export default {
|
|||||||
getNotePathFromUrl,
|
getNotePathFromUrl,
|
||||||
createNoteLink,
|
createNoteLink,
|
||||||
addLinkToEditor,
|
addLinkToEditor,
|
||||||
addTextToEditor
|
addTextToEditor,
|
||||||
|
init
|
||||||
};
|
};
|
@ -1,3 +1,43 @@
|
|||||||
import treeService from "./tree.js";
|
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;
|
return $el;
|
||||||
}
|
}
|
||||||
|
|
||||||
$.fn.getSelectedPath = function() {
|
function init() {
|
||||||
if (!$(this).val().trim()) {
|
$.fn.getSelectedPath = function () {
|
||||||
return "";
|
if (!$(this).val().trim()) {
|
||||||
}
|
return "";
|
||||||
else {
|
} else {
|
||||||
return $(this).attr(SELECTED_PATH_KEY);
|
return $(this).attr(SELECTED_PATH_KEY);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
$.fn.setSelectedPath = function(path) {
|
$.fn.setSelectedPath = function (path) {
|
||||||
path = path || "";
|
path = path || "";
|
||||||
|
|
||||||
$(this).attr(SELECTED_PATH_KEY, path);
|
$(this).attr(SELECTED_PATH_KEY, path);
|
||||||
|
|
||||||
$(this)
|
$(this)
|
||||||
.closest(".input-group")
|
.closest(".input-group")
|
||||||
.find(".go-to-selected-note-button")
|
.find(".go-to-selected-note-button")
|
||||||
.toggleClass("disabled", !path.trim())
|
.toggleClass("disabled", !path.trim())
|
||||||
.attr(SELECTED_PATH_KEY, path); // we also set attr here so tooltip can be displayed
|
.attr(SELECTED_PATH_KEY, path); // we also set attr here so tooltip can be displayed
|
||||||
};
|
};
|
||||||
|
|
||||||
ko.bindingHandlers.noteAutocomplete = {
|
ko.bindingHandlers.noteAutocomplete = {
|
||||||
init: function(element, valueAccessor, allBindings, viewModel, bindingContext) {
|
init: function (element, valueAccessor, allBindings, viewModel, bindingContext) {
|
||||||
initNoteAutocomplete($(element));
|
initNoteAutocomplete($(element));
|
||||||
|
|
||||||
$(element).setSelectedPath(bindingContext.$data.selectedPath);
|
$(element).setSelectedPath(bindingContext.$data.selectedPath);
|
||||||
|
|
||||||
$(element).on('autocomplete:selected', function(event, suggestion, dataset) {
|
$(element).on('autocomplete:selected', function (event, suggestion, dataset) {
|
||||||
bindingContext.$data.selectedPath = $(element).val().trim() ? suggestion.path : '';
|
bindingContext.$data.selectedPath = $(element).val().trim() ? suggestion.path : '';
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
}
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
initNoteAutocomplete,
|
initNoteAutocomplete,
|
||||||
showRecentNotes
|
showRecentNotes,
|
||||||
|
init
|
||||||
}
|
}
|
@ -17,6 +17,7 @@ import noteDetailRender from './note_detail_render.js';
|
|||||||
import noteDetailRelationMap from './note_detail_relation_map.js';
|
import noteDetailRelationMap from './note_detail_relation_map.js';
|
||||||
import bundleService from "./bundle.js";
|
import bundleService from "./bundle.js";
|
||||||
import attributeService from "./attributes.js";
|
import attributeService from "./attributes.js";
|
||||||
|
import utils from "./utils.js";
|
||||||
|
|
||||||
const $noteTitle = $("#note-title");
|
const $noteTitle = $("#note-title");
|
||||||
|
|
||||||
@ -89,11 +90,11 @@ async function reload() {
|
|||||||
await loadNoteDetail(getCurrentNoteId());
|
await loadNoteDetail(getCurrentNoteId());
|
||||||
}
|
}
|
||||||
|
|
||||||
async function switchToNote(noteId) {
|
async function switchToNote(noteId, mobile) {
|
||||||
if (getCurrentNoteId() !== noteId) {
|
if (getCurrentNoteId() !== noteId) {
|
||||||
await saveNoteIfChanged();
|
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
|
// only now that we're in sync with tree active node we will switch currentNote
|
||||||
currentNote = loadedNote;
|
currentNote = loadedNote;
|
||||||
|
|
||||||
// needs to happend after loading the note itself because it references current noteId
|
if (utils.isDesktop()) {
|
||||||
attributeService.refreshAttributes();
|
// needs to happen after loading the note itself because it references current noteId
|
||||||
|
attributeService.refreshAttributes();
|
||||||
|
}
|
||||||
|
|
||||||
if (isNewNoteCreated) {
|
if (isNewNoteCreated) {
|
||||||
isNewNoteCreated = false;
|
isNewNoteCreated = false;
|
||||||
@ -197,8 +200,10 @@ async function loadNoteDetail(noteId) {
|
|||||||
try {
|
try {
|
||||||
$noteTitle.val(currentNote.title);
|
$noteTitle.val(currentNote.title);
|
||||||
|
|
||||||
noteTypeService.setNoteType(currentNote.type);
|
if (utils.isDesktop()) {
|
||||||
noteTypeService.setNoteMime(currentNote.mime);
|
noteTypeService.setNoteType(currentNote.type);
|
||||||
|
noteTypeService.setNoteMime(currentNote.mime);
|
||||||
|
}
|
||||||
|
|
||||||
for (const componentType in components) {
|
for (const componentType in components) {
|
||||||
if (componentType !== currentNote.type) {
|
if (componentType !== currentNote.type) {
|
||||||
@ -225,13 +230,15 @@ async function loadNoteDetail(noteId) {
|
|||||||
// after loading new note make sure editor is scrolled to the top
|
// after loading new note make sure editor is scrolled to the top
|
||||||
getComponent(currentNote.type).scrollToTop();
|
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() {
|
async function showChildrenOverview() {
|
||||||
|
@ -44,7 +44,7 @@ const DEFAULT_MIME_TYPES = [
|
|||||||
{ mime: 'text/x-yaml', title: 'YAML' }
|
{ mime: 'text/x-yaml', title: 'YAML' }
|
||||||
];
|
];
|
||||||
|
|
||||||
const noteTypeModel = new NoteTypeModel();
|
let noteTypeModel;
|
||||||
|
|
||||||
function NoteTypeModel() {
|
function NoteTypeModel() {
|
||||||
const self = this;
|
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 {
|
export default {
|
||||||
getNoteType: () => noteTypeModel.type(),
|
getNoteType: () => noteTypeModel.type(),
|
||||||
@ -168,5 +172,6 @@ export default {
|
|||||||
|
|
||||||
getDefaultCodeMimeTypes: () => DEFAULT_MIME_TYPES.slice(),
|
getDefaultCodeMimeTypes: () => DEFAULT_MIME_TYPES.slice(),
|
||||||
getCodeMimeTypes: () => noteTypeModel.codeMimeTypes(),
|
getCodeMimeTypes: () => noteTypeModel.codeMimeTypes(),
|
||||||
setCodeMimeTypes: types => noteTypeModel.codeMimeTypes(types)
|
setCodeMimeTypes: types => noteTypeModel.codeMimeTypes(types),
|
||||||
|
init
|
||||||
};
|
};
|
@ -359,7 +359,7 @@ function initFancyTree(tree) {
|
|||||||
$tree.fancytree({
|
$tree.fancytree({
|
||||||
autoScroll: true,
|
autoScroll: true,
|
||||||
keyboard: false, // we takover keyboard handling in the hotkeys plugin
|
keyboard: false, // we takover keyboard handling in the hotkeys plugin
|
||||||
extensions: ["hotkeys", "filter", "dnd5", "clones"],
|
extensions: ["hotkeys", "dnd5", "clones"],
|
||||||
source: tree,
|
source: tree,
|
||||||
scrollParent: $tree,
|
scrollParent: $tree,
|
||||||
minExpandLevel: 2, // root can't be collapsed
|
minExpandLevel: 2, // root can't be collapsed
|
||||||
@ -397,18 +397,6 @@ function initFancyTree(tree) {
|
|||||||
hotkeys: {
|
hotkeys: {
|
||||||
keydown: treeKeyBindings
|
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,
|
dnd5: dragAndDropSetup,
|
||||||
lazyLoad: function(event, data) {
|
lazyLoad: function(event, data) {
|
||||||
const noteId = data.node.data.noteId;
|
const noteId = data.node.data.noteId;
|
||||||
@ -696,5 +684,8 @@ export default {
|
|||||||
getSelectedNodes,
|
getSelectedNodes,
|
||||||
clearSelectedNodes,
|
clearSelectedNodes,
|
||||||
sortAlphabetically,
|
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 {
|
export default {
|
||||||
reloadApp,
|
reloadApp,
|
||||||
parseDate,
|
parseDate,
|
||||||
@ -166,5 +174,7 @@ export default {
|
|||||||
download,
|
download,
|
||||||
toObject,
|
toObject,
|
||||||
randomString,
|
randomString,
|
||||||
bindShortcut
|
bindShortcut,
|
||||||
|
isMobile,
|
||||||
|
isDesktop
|
||||||
};
|
};
|
@ -205,6 +205,7 @@
|
|||||||
|
|
||||||
<script type="text/javascript">
|
<script type="text/javascript">
|
||||||
window.baseApiUrl = 'api/';
|
window.baseApiUrl = 'api/';
|
||||||
|
window.device = "desktop";
|
||||||
window.glob = {
|
window.glob = {
|
||||||
activeDialog: null,
|
activeDialog: null,
|
||||||
sourceId: '<%= sourceId %>',
|
sourceId: '<%= sourceId %>',
|
||||||
|
@ -10,6 +10,7 @@
|
|||||||
|
|
||||||
<script type="text/javascript">
|
<script type="text/javascript">
|
||||||
window.baseApiUrl = 'api/';
|
window.baseApiUrl = 'api/';
|
||||||
|
window.device = "mobile";
|
||||||
window.glob = {
|
window.glob = {
|
||||||
activeDialog: null,
|
activeDialog: null,
|
||||||
sourceId: '<%= sourceId %>',
|
sourceId: '<%= sourceId %>',
|
||||||
@ -26,11 +27,6 @@
|
|||||||
<link href="libraries/bootstrap/css/bootstrap.min.css" rel="stylesheet">
|
<link href="libraries/bootstrap/css/bootstrap.min.css" rel="stylesheet">
|
||||||
<script src="javascripts/services/mobile.js" crossorigin type="module"></script>
|
<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/style.css" rel="stylesheet">
|
||||||
<link href="stylesheets/mobile.css" rel="stylesheet">
|
<link href="stylesheets/mobile.css" rel="stylesheet">
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user