diff --git a/package-lock.json b/package-lock.json
index 9da7d3d6c..3ea3c36e5 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -5,7 +5,6 @@
"requires": true,
"packages": {
"": {
- "name": "trilium",
"version": "0.57.3",
"hasInstallScript": true,
"license": "AGPL-3.0-only",
diff --git a/src/becca/entities/attribute.js b/src/becca/entities/attribute.js
index 8a188e0c7..834631add 100644
--- a/src/becca/entities/attribute.js
+++ b/src/becca/entities/attribute.js
@@ -63,6 +63,8 @@ class Attribute extends AbstractEntity {
}
init() {
+ this.validate();
+
if (this.attributeId) {
this.becca.attributes[this.attributeId] = this;
}
@@ -85,6 +87,16 @@ class Attribute extends AbstractEntity {
}
}
+ validate() {
+ if (!["label", "relation"].includes(this.type)) {
+ throw new Error(`Invalid attribute type '${this.type}' in attribute '${this.attributeId}'`);
+ }
+
+ if (!this.name?.trim()) {
+ throw new Error(`Invalid empty name in attribute '${this.attributeId}'`);
+ }
+ }
+
get isAffectingSubtree() {
return this.isInheritable
|| (this.type === 'relation' && this.name === 'template');
@@ -162,6 +174,8 @@ class Attribute extends AbstractEntity {
}
beforeSaving() {
+ this.validate();
+
if (this.type === 'relation') {
if (!(this.value in this.becca.notes)) {
throw new Error(`Cannot save relation '${this.name}' since it target not existing note '${this.value}'.`);
diff --git a/src/public/app/components/mobile_screen_switcher.js b/src/public/app/components/mobile_screen_switcher.js
index 22808a620..3db8ec8f3 100644
--- a/src/public/app/components/mobile_screen_switcher.js
+++ b/src/public/app/components/mobile_screen_switcher.js
@@ -5,11 +5,11 @@ export default class MobileScreenSwitcherExecutor extends Component {
if (screen !== this.activeScreen) {
this.activeScreen = screen;
+ if (screen === 'tree') {
+ document.location.hash = '';
+ }
+
this.triggerEvent('activeScreenChanged', {activeScreen: screen});
}
}
-
- initialRenderCompleteEvent() {
- this.setActiveScreenCommand({screen: 'tree'});
- }
}
diff --git a/src/public/app/components/note_context.js b/src/public/app/components/note_context.js
index 0f042681e..60d9a675b 100644
--- a/src/public/app/components/note_context.js
+++ b/src/public/app/components/note_context.js
@@ -83,6 +83,8 @@ class NoteContext extends Component {
if (utils.isDesktop()) {
// close dangling autocompletes after closing the tab
$(".aa-input").autocomplete("close");
+ } else if (utils.isMobile()) {
+ this.triggerCommand('setActiveScreen', {screen: 'detail'});
}
}
diff --git a/src/public/app/layouts/mobile_layout.js b/src/public/app/layouts/mobile_layout.js
index c86a0bff7..76ee76c1a 100644
--- a/src/public/app/layouts/mobile_layout.js
+++ b/src/public/app/layouts/mobile_layout.js
@@ -117,7 +117,7 @@ export default class MobileLayout {
.child(new FlexContainer("row")
.filling()
.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")
+ .class("d-sm-flex d-md-flex d-lg-flex d-xl-flex col-12 col-sm-5 col-md-4 col-lg-3 col-xl-3")
.css("max-height", "100%")
.css('padding-left', 0)
.css('contain', 'content')
@@ -125,7 +125,7 @@ export default class MobileLayout {
.child(new NoteTreeWidget()
.cssBlock(FANCYTREE_CSS)))
.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")
+ .class("d-sm-flex d-md-flex d-lg-flex d-xl-flex col-12 col-sm-7 col-md-8 col-lg-9")
.css('max-height', '100%')
.child(new FlexContainer('row').contentSized()
.css('font-size', 'larger')
diff --git a/src/public/app/widgets/buttons/global_menu.js b/src/public/app/widgets/buttons/global_menu.js
index fec1eb44b..64582f1b2 100644
--- a/src/public/app/widgets/buttons/global_menu.js
+++ b/src/public/app/widgets/buttons/global_menu.js
@@ -95,10 +95,15 @@ const TPL = `
@@ -218,7 +223,8 @@ export default class GlobalMenuWidget extends BasicWidget {
this.$widget.find(".logout-button").toggle(!isElectron);
this.$widget.find(".open-dev-tools-button").toggle(isElectron);
- this.$widget.find(".switch-to-mobile-version-button").toggle(!isElectron);
+ this.$widget.find(".switch-to-mobile-version-button").toggle(!isElectron && utils.isDesktop());
+ this.$widget.find(".switch-to-desktop-version-button").toggle(!isElectron && utils.isMobile());
this.$widget.on('click', '.dropdown-item', e => {
if ($(e.target).parent(".zoom-buttons")) {
diff --git a/src/public/app/widgets/containers/launcher.js b/src/public/app/widgets/containers/launcher.js
index 4b3a5147c..693540942 100644
--- a/src/public/app/widgets/containers/launcher.js
+++ b/src/public/app/widgets/containers/launcher.js
@@ -9,6 +9,7 @@ import BasicWidget from "../basic_widget.js";
import NoteLauncher from "../buttons/launcher/note_launcher.js";
import ScriptLauncher from "../buttons/launcher/script_launcher.js";
import CommandButtonWidget from "../buttons/command_button.js";
+import utils from "../../services/utils.js";
export default class LauncherWidget extends BasicWidget {
constructor() {
@@ -30,6 +31,10 @@ export default class LauncherWidget extends BasicWidget {
throw new Error(`Note '${note.noteId}' '${note.title}' is not a launcher even though it's in the launcher subtree`);
}
+ if (!utils.isDesktop() && note.hasLabel('desktopOnly')) {
+ return false;
+ }
+
const launcherType = note.getLabelValue("launcherType");
if (launcherType === 'command') {
@@ -54,6 +59,8 @@ export default class LauncherWidget extends BasicWidget {
}
this.child(this.innerWidget);
+
+ return true;
}
initCommandLauncherWidget(note) {
diff --git a/src/public/app/widgets/containers/launcher_container.js b/src/public/app/widgets/containers/launcher_container.js
index 8a5cf8fa2..78f049d6c 100644
--- a/src/public/app/widgets/containers/launcher_container.js
+++ b/src/public/app/widgets/containers/launcher_container.js
@@ -32,8 +32,11 @@ export default class LauncherContainer extends FlexContainer {
.map(async launcherNote => {
try {
const launcherWidget = new LauncherWidget();
- await launcherWidget.initLauncher(launcherNote);
- this.child(launcherWidget);
+ const success = await launcherWidget.initLauncher(launcherNote);
+
+ if (success) {
+ this.child(launcherWidget);
+ }
}
catch (e) {
console.error(e);
diff --git a/src/public/app/widgets/note_tree.js b/src/public/app/widgets/note_tree.js
index 444f979ba..80396a84c 100644
--- a/src/public/app/widgets/note_tree.js
+++ b/src/public/app/widgets/note_tree.js
@@ -383,10 +383,6 @@ export default class NoteTreeWidget extends NoteContextAwareWidget {
const activeNoteContext = appContext.tabManager.getActiveContext();
await activeNoteContext.setNote(notePath);
-
- if (utils.isMobile()) {
- this.triggerCommand('setActiveScreen', {screen: 'detail'});
- }
},
expand: (event, data) => this.setExpanded(data.node.data.branchId, true),
collapse: (event, data) => this.setExpanded(data.node.data.branchId, false),
diff --git a/src/services/hidden_subtree.js b/src/services/hidden_subtree.js
index 64800471c..d550d79d2 100644
--- a/src/services/hidden_subtree.js
+++ b/src/services/hidden_subtree.js
@@ -171,11 +171,17 @@ const HIDDEN_SUBTREE_DEFINITION = {
attributes: [ { type: 'label', name: 'docName', value: 'launchbar_intro' } ],
children: [
{ id: 'lbNewNote', title: 'New Note', type: 'launcher', command: 'createNoteIntoInbox', icon: 'bx bx-file-blank' },
- { id: 'lbSearch', title: 'Search Notes', type: 'launcher', command: 'searchNotes', icon: 'bx bx-search' },
- { id: 'lbJumpTo', title: 'Jump to Note', type: 'launcher', command: 'jumpToNote', icon: 'bx bx-send' },
+ { id: 'lbSearch', title: 'Search Notes', type: 'launcher', command: 'searchNotes', icon: 'bx bx-search', attributes: [
+ { type: 'label', name: 'desktopOnly' }
+ ] },
+ { id: 'lbJumpTo', title: 'Jump to Note', type: 'launcher', command: 'jumpToNote', icon: 'bx bx-send', attributes: [
+ { type: 'label', name: 'desktopOnly' }
+ ] },
{ id: 'lbNoteMap', title: 'Note Map', type: 'launcher', targetNoteId: 'globalNoteMap', icon: 'bx bx-map-alt' },
{ id: 'lbCalendar', title: 'Calendar', type: 'launcher', builtinWidget: 'calendar', icon: 'bx bx-calendar' },
- { id: 'lbRecentChanges', title: 'Recent Changes', type: 'launcher', command: 'showRecentChanges', icon: 'bx bx-history' },
+ { id: 'lbRecentChanges', title: 'Recent Changes', type: 'launcher', command: 'showRecentChanges', icon: 'bx bx-history', attributes: [
+ { type: 'label', name: 'desktopOnly' }
+ ] },
{ id: 'lbSpacer1', title: 'Spacer', type: 'launcher', builtinWidget: 'spacer', baseSize: "50", growthFactor: "0" },
{ id: 'lbBookmarks', title: 'Bookmarks', type: 'launcher', builtinWidget: 'bookmarks', icon: 'bx bx-bookmark' },
{ id: 'lbSpacer2', title: 'Spacer', type: 'launcher', builtinWidget: 'spacer', baseSize: "0", growthFactor: "1" },