mirror of
https://github.com/zadam/trilium.git
synced 2025-06-06 18:08:33 +02:00
autocollapse notes after period of inactivity + some other changes, #1192
This commit is contained in:
parent
53b39e2e82
commit
f24e27dadd
37
package-lock.json
generated
37
package-lock.json
generated
@ -3057,9 +3057,9 @@
|
|||||||
"integrity": "sha1-WQxhFWsK4vTwJVcyoViyZrxWsh0="
|
"integrity": "sha1-WQxhFWsK4vTwJVcyoViyZrxWsh0="
|
||||||
},
|
},
|
||||||
"ejs": {
|
"ejs": {
|
||||||
"version": "3.1.3",
|
"version": "3.1.5",
|
||||||
"resolved": "https://registry.npmjs.org/ejs/-/ejs-3.1.3.tgz",
|
"resolved": "https://registry.npmjs.org/ejs/-/ejs-3.1.5.tgz",
|
||||||
"integrity": "sha512-wmtrUGyfSC23GC/B1SMv2ogAUgbQEtDmTIhfqielrG5ExIM9TP4UoYdi90jLF1aTcsWCJNEO0UrgKzP0y3nTSg==",
|
"integrity": "sha512-dldq3ZfFtgVTJMLjOe+/3sROTzALlL9E34V4/sDtUd/KlBSS0s6U1/+WPE1B4sj9CXHJpL1M6rhNJnc9Wbal9w==",
|
||||||
"requires": {
|
"requires": {
|
||||||
"jake": "^10.6.1"
|
"jake": "^10.6.1"
|
||||||
}
|
}
|
||||||
@ -5268,41 +5268,10 @@
|
|||||||
"minimatch": "^3.0.4"
|
"minimatch": "^3.0.4"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"ansi-styles": {
|
|
||||||
"version": "3.2.1",
|
|
||||||
"resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz",
|
|
||||||
"integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==",
|
|
||||||
"requires": {
|
|
||||||
"color-convert": "^1.9.0"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"async": {
|
"async": {
|
||||||
"version": "0.9.2",
|
"version": "0.9.2",
|
||||||
"resolved": "https://registry.npmjs.org/async/-/async-0.9.2.tgz",
|
"resolved": "https://registry.npmjs.org/async/-/async-0.9.2.tgz",
|
||||||
"integrity": "sha1-rqdNXmHB+JlhO/ZL2mbUx48v0X0="
|
"integrity": "sha1-rqdNXmHB+JlhO/ZL2mbUx48v0X0="
|
||||||
},
|
|
||||||
"chalk": {
|
|
||||||
"version": "2.4.2",
|
|
||||||
"resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz",
|
|
||||||
"integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==",
|
|
||||||
"requires": {
|
|
||||||
"ansi-styles": "^3.2.1",
|
|
||||||
"escape-string-regexp": "^1.0.5",
|
|
||||||
"supports-color": "^5.3.0"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"has-flag": {
|
|
||||||
"version": "3.0.0",
|
|
||||||
"resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz",
|
|
||||||
"integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0="
|
|
||||||
},
|
|
||||||
"supports-color": {
|
|
||||||
"version": "5.5.0",
|
|
||||||
"resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz",
|
|
||||||
"integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==",
|
|
||||||
"requires": {
|
|
||||||
"has-flag": "^3.0.0"
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
@ -34,7 +34,7 @@
|
|||||||
"csurf": "1.11.0",
|
"csurf": "1.11.0",
|
||||||
"dayjs": "1.8.33",
|
"dayjs": "1.8.33",
|
||||||
"debug": "4.1.1",
|
"debug": "4.1.1",
|
||||||
"ejs": "3.1.3",
|
"ejs": "3.1.5",
|
||||||
"electron-debug": "3.1.0",
|
"electron-debug": "3.1.0",
|
||||||
"electron-dl": "3.0.2",
|
"electron-dl": "3.0.2",
|
||||||
"electron-find": "1.0.6",
|
"electron-find": "1.0.6",
|
||||||
|
@ -26,6 +26,8 @@ class NoteComplement {
|
|||||||
/** @param {string} */
|
/** @param {string} */
|
||||||
this.utcDateModified = row.utcDateModified;
|
this.utcDateModified = row.utcDateModified;
|
||||||
|
|
||||||
|
// "combined" date modified give larger out of note's and note_content's dateModified
|
||||||
|
|
||||||
/** @param {string} */
|
/** @param {string} */
|
||||||
this.combinedDateModified = row.combinedDateModified;
|
this.combinedDateModified = row.combinedDateModified;
|
||||||
|
|
||||||
|
@ -85,6 +85,11 @@ class TabContext extends Component {
|
|||||||
return treeCache.notes[this.noteId];
|
return treeCache.notes[this.noteId];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** @property {string[]} */
|
||||||
|
get notePathArray() {
|
||||||
|
return this.notePath ? this.notePath.split('/') : [];
|
||||||
|
}
|
||||||
|
|
||||||
/** @return {NoteComplement} */
|
/** @return {NoteComplement} */
|
||||||
async getNoteComplement() {
|
async getNoteComplement() {
|
||||||
if (!this.noteId) {
|
if (!this.noteId) {
|
||||||
|
@ -16,7 +16,7 @@ class TreeContextMenu {
|
|||||||
this.treeWidget = treeWidget;
|
this.treeWidget = treeWidget;
|
||||||
this.node = node;
|
this.node = node;
|
||||||
}
|
}
|
||||||
|
|
||||||
async show(e) {
|
async show(e) {
|
||||||
contextMenu.show({
|
contextMenu.show({
|
||||||
x: e.pageX,
|
x: e.pageX,
|
||||||
@ -111,7 +111,14 @@ class TreeContextMenu {
|
|||||||
const notePath = treeService.getNotePath(this.node);
|
const notePath = treeService.getNotePath(this.node);
|
||||||
|
|
||||||
if (command === 'openInTab') {
|
if (command === 'openInTab') {
|
||||||
appContext.tabManager.openTabWithNote(notePath);
|
|
||||||
|
const start = Date.now();
|
||||||
|
|
||||||
|
await this.node.load(true);
|
||||||
|
|
||||||
|
console.log("Reload took", Date.now() - start, "ms");
|
||||||
|
|
||||||
|
// appContext.tabManager.openTabWithNote(notePath);
|
||||||
}
|
}
|
||||||
else if (command === "insertNoteAfter") {
|
else if (command === "insertNoteAfter") {
|
||||||
const parentNoteId = this.node.data.parentNoteId;
|
const parentNoteId = this.node.data.parentNoteId;
|
||||||
@ -136,4 +143,4 @@ class TreeContextMenu {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export default TreeContextMenu;
|
export default TreeContextMenu;
|
||||||
|
@ -63,7 +63,7 @@ const TPL = `
|
|||||||
<div class="attr-is-owned-by"></div>
|
<div class="attr-is-owned-by"></div>
|
||||||
|
|
||||||
<table class="attr-edit-table">
|
<table class="attr-edit-table">
|
||||||
<tr>
|
<tr title="Attribute name can be composed of alphanumeric characters, colon and underscore only">
|
||||||
<th>Name:</th>
|
<th>Name:</th>
|
||||||
<td><input type="text" class="attr-input-name form-control" /></td>
|
<td><input type="text" class="attr-input-name form-control" /></td>
|
||||||
</tr>
|
</tr>
|
||||||
@ -159,15 +159,15 @@ const ATTR_TITLES = {
|
|||||||
};
|
};
|
||||||
|
|
||||||
export default class AttributeDetailWidget extends TabAwareWidget {
|
export default class AttributeDetailWidget extends TabAwareWidget {
|
||||||
isEnabled() {
|
async refresh() {
|
||||||
// this widget is not activated in a standard way
|
// this widget is not activated in a standard way
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
doRender() {
|
doRender() {
|
||||||
this.relatedNotesSpacedUpdate = new SpacedUpdate(async () => this.updateRelatedNotes(), 1000);
|
this.relatedNotesSpacedUpdate = new SpacedUpdate(async () => this.updateRelatedNotes(), 1000);
|
||||||
|
|
||||||
this.$widget = $(TPL);
|
this.$widget = $(TPL);
|
||||||
|
this.contentSized();
|
||||||
|
|
||||||
this.$title = this.$widget.find('.attr-detail-title');
|
this.$title = this.$widget.find('.attr-detail-title');
|
||||||
|
|
||||||
@ -280,7 +280,7 @@ export default class AttributeDetailWidget extends TabAwareWidget {
|
|||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
console.log("RENDERING");
|
||||||
this.attrType = this.getAttrType(attribute);
|
this.attrType = this.getAttrType(attribute);
|
||||||
|
|
||||||
const attrName =
|
const attrName =
|
||||||
@ -373,6 +373,8 @@ export default class AttributeDetailWidget extends TabAwareWidget {
|
|||||||
this.$widget.outerHeight() + y > $(window).height() - 50
|
this.$widget.outerHeight() + y > $(window).height() - 50
|
||||||
? $(window).height() - y - 50
|
? $(window).height() - y - 50
|
||||||
: 10000);
|
: 10000);
|
||||||
|
|
||||||
|
console.log("RENDERING DONE");
|
||||||
}
|
}
|
||||||
|
|
||||||
async updateRelatedNotes() {
|
async updateRelatedNotes() {
|
||||||
|
@ -116,7 +116,7 @@ export default class AttributeListWidget extends TabAwareWidget {
|
|||||||
|
|
||||||
doRender() {
|
doRender() {
|
||||||
this.$widget = $(TPL);
|
this.$widget = $(TPL);
|
||||||
this.contentSized();
|
this.overflowing();
|
||||||
|
|
||||||
this.$promotedExpander = this.$widget.find('.attr-promoted-expander');
|
this.$promotedExpander = this.$widget.find('.attr-promoted-expander');
|
||||||
this.$allAttrWrapper = this.$widget.find('.all-attr-wrapper');
|
this.$allAttrWrapper = this.$widget.find('.all-attr-wrapper');
|
||||||
|
@ -30,6 +30,11 @@ class BasicWidget extends Component {
|
|||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
overflowing() {
|
||||||
|
this.css('contain', 'none');
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
collapsible() {
|
collapsible() {
|
||||||
this.css('min-height', '0');
|
this.css('min-height', '0');
|
||||||
return this;
|
return this;
|
||||||
|
@ -93,7 +93,7 @@ const TPL = `
|
|||||||
export default class NoteActionsWidget extends TabAwareWidget {
|
export default class NoteActionsWidget extends TabAwareWidget {
|
||||||
doRender() {
|
doRender() {
|
||||||
this.$widget = $(TPL);
|
this.$widget = $(TPL);
|
||||||
this.contentSized();
|
this.overflowing();
|
||||||
|
|
||||||
this.$showSourceButton = this.$widget.find('.show-source-button');
|
this.$showSourceButton = this.$widget.find('.show-source-button');
|
||||||
|
|
||||||
|
@ -312,6 +312,8 @@ export default class NoteTreeWidget extends TabAwareWidget {
|
|||||||
scrollParent: this.$tree,
|
scrollParent: this.$tree,
|
||||||
minExpandLevel: 2, // root can't be collapsed
|
minExpandLevel: 2, // root can't be collapsed
|
||||||
click: (event, data) => {
|
click: (event, data) => {
|
||||||
|
this.activityDetected();
|
||||||
|
|
||||||
const targetType = data.targetType;
|
const targetType = data.targetType;
|
||||||
const node = data.node;
|
const node = data.node;
|
||||||
|
|
||||||
@ -911,6 +913,8 @@ export default class NoteTreeWidget extends TabAwareWidget {
|
|||||||
async refresh() {
|
async refresh() {
|
||||||
this.toggleInt(this.isEnabled());
|
this.toggleInt(this.isEnabled());
|
||||||
|
|
||||||
|
this.activityDetected();
|
||||||
|
|
||||||
const oldActiveNode = this.getActiveNode();
|
const oldActiveNode = this.getActiveNode();
|
||||||
let oldActiveNodeFocused = false;
|
let oldActiveNodeFocused = false;
|
||||||
|
|
||||||
@ -956,7 +960,44 @@ export default class NoteTreeWidget extends TabAwareWidget {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
activityDetected() {
|
||||||
|
if (this.autoCollapseTimeoutId) {
|
||||||
|
clearTimeout(this.autoCollapseTimeoutId);
|
||||||
|
}
|
||||||
|
|
||||||
|
this.autoCollapseTimeoutId = setTimeout(() => {
|
||||||
|
/*
|
||||||
|
* We're collapsing notes after period of inactivity to "cleanup" the tree - users rarely
|
||||||
|
* collapse the notes and the tree becomes unusuably large.
|
||||||
|
* Some context: https://github.com/zadam/trilium/issues/1192
|
||||||
|
*/
|
||||||
|
|
||||||
|
const noteIdsToKeepExpanded = new Set(
|
||||||
|
appContext.tabManager.getTabContexts()
|
||||||
|
.map(tc => tc.notePathArray)
|
||||||
|
.flat()
|
||||||
|
);
|
||||||
|
|
||||||
|
let noneCollapsedYet = true;
|
||||||
|
|
||||||
|
this.tree.getRootNode().visit(node => {
|
||||||
|
if (node.isExpanded() && !noteIdsToKeepExpanded.has(node.data.noteId)) {
|
||||||
|
node.setExpanded(false);
|
||||||
|
|
||||||
|
if (noneCollapsedYet) {
|
||||||
|
toastService.showMessage("Auto collapsing notes after inactivity...");
|
||||||
|
noneCollapsedYet = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
console.log("Auto collapsed", node.data.noteId);
|
||||||
|
}
|
||||||
|
}, false);
|
||||||
|
}, 600 * 1000);
|
||||||
|
}
|
||||||
|
|
||||||
async entitiesReloadedEvent({loadResults}) {
|
async entitiesReloadedEvent({loadResults}) {
|
||||||
|
this.activityDetected();
|
||||||
|
|
||||||
if (loadResults.isEmptyForTree()) {
|
if (loadResults.isEmptyForTree()) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -34,7 +34,7 @@ const TPL = `
|
|||||||
export default class NoteTypeWidget extends TabAwareWidget {
|
export default class NoteTypeWidget extends TabAwareWidget {
|
||||||
doRender() {
|
doRender() {
|
||||||
this.$widget = $(TPL);
|
this.$widget = $(TPL);
|
||||||
this.contentSized();
|
this.overflowing();
|
||||||
|
|
||||||
this.$widget.on('show.bs.dropdown', () => this.renderDropdown());
|
this.$widget.on('show.bs.dropdown', () => this.renderDropdown());
|
||||||
|
|
||||||
|
@ -825,3 +825,7 @@ body {
|
|||||||
.ck.ck-mentions > .ck-list__item {
|
.ck.ck-mentions > .ck-list__item {
|
||||||
max-width: 600px;
|
max-width: 600px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ul.fancytree-container li {
|
||||||
|
contain: layout paint;
|
||||||
|
}
|
||||||
|
@ -66,7 +66,7 @@
|
|||||||
<link href="libraries/ckeditor/ckeditor-content.css" rel="stylesheet">
|
<link href="libraries/ckeditor/ckeditor-content.css" rel="stylesheet">
|
||||||
|
|
||||||
<!-- Include Fancytree skin and library -->
|
<!-- Include Fancytree skin and library -->
|
||||||
<link href="libraries/fancytree/skin-win8/ui.fancytree.min.css" rel="stylesheet">
|
<link href="libraries/fancytree/skin-win8/ui.fancytree.css" rel="stylesheet">
|
||||||
<script src="libraries/fancytree/jquery.fancytree-all-deps.min.js"></script>
|
<script src="libraries/fancytree/jquery.fancytree-all-deps.min.js"></script>
|
||||||
|
|
||||||
<script src="libraries/jquery.hotkeys.js"></script>
|
<script src="libraries/jquery.hotkeys.js"></script>
|
||||||
|
Loading…
x
Reference in New Issue
Block a user