autocollapse notes after period of inactivity + some other changes, #1192

This commit is contained in:
zadam 2020-08-17 20:58:34 +02:00
parent 53b39e2e82
commit f24e27dadd
13 changed files with 81 additions and 46 deletions

37
package-lock.json generated
View File

@ -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"
}
} }
} }
}, },

View File

@ -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",

View File

@ -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;

View File

@ -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) {

View File

@ -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;

View File

@ -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() {

View File

@ -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');

View File

@ -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;

View File

@ -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');

View File

@ -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;
} }

View File

@ -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());

View File

@ -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;
}

View File

@ -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>