mirror of
https://github.com/zadam/trilium.git
synced 2025-01-16 20:21:43 +08:00
mobile frontend is working again
This commit is contained in:
parent
f15239c006
commit
0f4ba43463
8 changed files with 58 additions and 105 deletions
|
@ -1,99 +0,0 @@
|
|||
import treeService from "./services/tree.js";
|
||||
import treeCache from "./services/tree_cache.js";
|
||||
import treeBuilder from "./services/tree_builder.js";
|
||||
import contextMenuWidget from "./services/context_menu.js";
|
||||
import branchService from "./services/branches.js";
|
||||
import utils from "./services/utils.js";
|
||||
import appContext from "./services/app_context.js";
|
||||
import noteCreateService from "./services/note_create.js";
|
||||
import glob from "./services/glob.js";
|
||||
|
||||
const $leftPane = $("#left-pane");
|
||||
const $tree = $("#tree");
|
||||
const $detail = $("#detail");
|
||||
|
||||
function togglePanes() {
|
||||
if (!$leftPane.is(":visible") || !$detail.is(":visible")) {
|
||||
$detail.toggleClass("d-none");
|
||||
$leftPane.toggleClass("d-none");
|
||||
}
|
||||
}
|
||||
|
||||
function showDetailPane() {
|
||||
if (!$detail.is(":visible")) {
|
||||
$detail.removeClass("d-none");
|
||||
$leftPane.addClass("d-none");
|
||||
}
|
||||
}
|
||||
|
||||
$detail.on("click", ".close-detail-button",() => {
|
||||
// no page is opened
|
||||
document.location.hash = '-';
|
||||
|
||||
togglePanes();
|
||||
});
|
||||
|
||||
async function showTree() {
|
||||
const treeData = await treeBuilder.prepareTree();
|
||||
|
||||
$tree.fancytree({
|
||||
autoScroll: true,
|
||||
extensions: ["dnd5", "clones"],
|
||||
source: treeData,
|
||||
scrollParent: $tree,
|
||||
minExpandLevel: 2, // root can't be collapsed
|
||||
click: (event, data) => {
|
||||
if (data.targetType !== 'expander' && data.node.isActive()) {
|
||||
// this is important for single column mobile view, otherwise it's not possible to see again previously displayed note
|
||||
$tree.fancytree('getTree').reactivate(true);
|
||||
|
||||
return false;
|
||||
}
|
||||
},
|
||||
activate: async (event, data) => {
|
||||
const node = data.node;
|
||||
|
||||
treeService.clearSelectedNodes();
|
||||
|
||||
showDetailPane();
|
||||
|
||||
const notePath = await treeService.getNotePath(node);
|
||||
|
||||
},
|
||||
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
|
||||
},
|
||||
// this is done to automatically lazy load all expanded search notes after tree load
|
||||
loadChildren: (event, data) => {
|
||||
data.node.visit((subNode) => {
|
||||
// Load all lazy/unloaded child nodes
|
||||
// (which will trigger `loadChildren` recursively)
|
||||
if (subNode.isUndefined() && subNode.isExpanded()) {
|
||||
subNode.load();
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
treeService.setTree($.ui.fancytree.getTree("#tree"));
|
||||
}
|
||||
|
||||
$("#log-out-button").on('click', () => {
|
||||
$("#logout-form").trigger('submit');
|
||||
});
|
||||
|
||||
// this is done so that startNotePath is not used
|
||||
if (!document.location.hash) {
|
||||
document.location.hash = '-';
|
||||
}
|
||||
|
||||
showTree();
|
|
@ -10,6 +10,7 @@ import TabManager from "./tab_manager.js";
|
|||
import treeService from "./tree.js";
|
||||
import Component from "../widgets/component.js";
|
||||
import keyboardActionsService from "./keyboard_actions.js";
|
||||
import MobileScreenSwitcherExecutor from "../widgets/mobile_screen_switcher.js";
|
||||
|
||||
class AppContext extends Component {
|
||||
setLayout(layout) {
|
||||
|
@ -48,6 +49,10 @@ class AppContext extends Component {
|
|||
new Entrypoints()
|
||||
];
|
||||
|
||||
if (utils.isMobile()) {
|
||||
this.executors.push(new MobileScreenSwitcherExecutor());
|
||||
}
|
||||
|
||||
this.child(rootWidget);
|
||||
|
||||
for (const executor of this.executors) {
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
import BasicWidget from "./basic_widget.js";
|
||||
|
||||
const TPL = `
|
||||
<button type="button" class="close-detail-button action-button d-sm-none d-md-none d-lg-none d-xl-none" aria-label="Close">
|
||||
<button type="button" class="action-button d-sm-none d-md-none d-lg-none d-xl-none" aria-label="Close">
|
||||
<span aria-hidden="true">×</span>
|
||||
</button>`;
|
||||
|
||||
|
@ -9,7 +9,7 @@ class CloseDetailButtonWidget extends BasicWidget {
|
|||
doRender() {
|
||||
this.$widget = $(TPL);
|
||||
|
||||
//this.$widget.find('.close-detail-button').on('click', );
|
||||
this.$widget.on('click', () => this.triggerCommand('setActiveScreen', {screen:'tree'}));
|
||||
|
||||
return this.$widget;
|
||||
}
|
||||
|
|
|
@ -9,6 +9,7 @@ const WIDGET_TPL = `
|
|||
justify-content: space-around;
|
||||
padding: 3px 0 3px 0;
|
||||
margin: 0 10px 0 16px;
|
||||
font-size: larger;
|
||||
}
|
||||
</style>
|
||||
|
||||
|
|
|
@ -5,6 +5,7 @@ import NoteTreeWidget from "./note_tree.js";
|
|||
import MobileGlobalButtonsWidget from "./mobile_global_buttons.js";
|
||||
import CloseDetailButtonWidget from "./close_detail_button.js";
|
||||
import MobileDetailMenuWidget from "./mobile_detail_menu.js";
|
||||
import ScreenContainer from "./screen_container.js";
|
||||
|
||||
export default class MobileLayout {
|
||||
getRootWidget(appContext) {
|
||||
|
@ -12,12 +13,12 @@ export default class MobileLayout {
|
|||
.setParent(appContext)
|
||||
.id('root-widget')
|
||||
.css('height', '100vh')
|
||||
.child(new FlexContainer('column')
|
||||
.child(new ScreenContainer("tree", 'column')
|
||||
.class("d-sm-flex d-md-flex d-lg-flex d-xl-flex col-12 col-sm-5 col-md-4 col-lg-4 col-xl-4")
|
||||
.child(new MobileGlobalButtonsWidget())
|
||||
.child(new NoteTreeWidget()))
|
||||
.child(new FlexContainer('column')
|
||||
.class("d-none d-sm-flex d-md-flex d-lg-flex d-xl-flex col-12 col-sm-7 col-md-8 col-lg-8")
|
||||
.child(new ScreenContainer("detail", "column")
|
||||
.class("d-sm-flex d-md-flex d-lg-flex d-xl-flex col-12 col-sm-7 col-md-8 col-lg-8")
|
||||
.child(new FlexContainer('row')
|
||||
.child(new MobileDetailMenuWidget())
|
||||
.child(new NoteTitleWidget())
|
||||
|
|
15
src/public/javascripts/widgets/mobile_screen_switcher.js
Normal file
15
src/public/javascripts/widgets/mobile_screen_switcher.js
Normal file
|
@ -0,0 +1,15 @@
|
|||
import Component from "./component.js";
|
||||
|
||||
export default class MobileScreenSwitcherExecutor extends Component {
|
||||
setActiveScreenCommand({screen}) {
|
||||
if (screen !== this.activeScreen) {
|
||||
this.activeScreen = screen;
|
||||
|
||||
this.triggerEvent('activeScreenChanged', {activeScreen: screen});
|
||||
}
|
||||
}
|
||||
|
||||
initialRenderCompleteEvent() {
|
||||
this.setActiveScreenCommand({screen: 'tree'});
|
||||
}
|
||||
}
|
|
@ -66,7 +66,7 @@ export default class NoteTreeWidget extends TabAwareWidget {
|
|||
this.$widget.fancytree({
|
||||
autoScroll: true,
|
||||
keyboard: false, // we takover keyboard handling in the hotkeys plugin
|
||||
extensions: utils.isMobile() ? ["clones"] : ["hotkeys", "dnd5", "clones"],
|
||||
extensions: utils.isMobile() ? ["dnd5", "clones"] : ["hotkeys", "dnd5", "clones"],
|
||||
source: treeData,
|
||||
scrollParent: this.$widget,
|
||||
minExpandLevel: 2, // root can't be collapsed
|
||||
|
@ -83,6 +83,10 @@ export default class NoteTreeWidget extends TabAwareWidget {
|
|||
const notePath = treeService.getNotePath(node);
|
||||
appContext.tabManager.openTabWithNote(notePath);
|
||||
}
|
||||
else if (data.node.isActive()) {
|
||||
// this is important for single column mobile view, otherwise it's not possible to see again previously displayed note
|
||||
this.tree.reactivate(true);
|
||||
}
|
||||
else {
|
||||
node.setActive();
|
||||
|
||||
|
@ -100,6 +104,10 @@ export default class NoteTreeWidget extends TabAwareWidget {
|
|||
|
||||
const activeTabContext = appContext.tabManager.getActiveTabContext();
|
||||
await activeTabContext.setNote(notePath);
|
||||
|
||||
if (utils.isMobile()) {
|
||||
this.triggerCommand('setActiveScreen', {screen:'detail'});
|
||||
}
|
||||
},
|
||||
expand: (event, data) => this.setExpandedToServer(data.node.data.branchId, true),
|
||||
collapse: (event, data) => this.setExpandedToServer(data.node.data.branchId, false),
|
||||
|
@ -810,4 +818,8 @@ export default class NoteTreeWidget extends TabAwareWidget {
|
|||
|
||||
noteCreateService.duplicateNote(noteId, branch.parentNoteId);
|
||||
}
|
||||
|
||||
activeScreenChangedEvent({activeScreen}) {
|
||||
this.toggle(activeScreen === 'tree');
|
||||
}
|
||||
}
|
18
src/public/javascripts/widgets/screen_container.js
Normal file
18
src/public/javascripts/widgets/screen_container.js
Normal file
|
@ -0,0 +1,18 @@
|
|||
import FlexContainer from "./flex_container.js";
|
||||
|
||||
export default class ScreenContainer extends FlexContainer {
|
||||
constructor(screenName, direction) {
|
||||
super(direction);
|
||||
|
||||
this.screenName = screenName;
|
||||
}
|
||||
|
||||
activeScreenChangedEvent({activeScreen}) {console.log("Active screen", activeScreen);
|
||||
if (activeScreen === this.screenName) {
|
||||
this.$widget.removeClass('d-none');
|
||||
}
|
||||
else {
|
||||
this.$widget.addClass('d-none');
|
||||
}
|
||||
}
|
||||
}
|
Loading…
Reference in a new issue