Merge branch 'develop' into revisions_number_limit

This commit is contained in:
SiriusXT 2024-09-14 14:58:47 +08:00
commit 0a9e76abb7
14 changed files with 3554 additions and 4235 deletions

1
.npmrc Normal file
View File

@ -0,0 +1 @@
save-prefix = ''

7479
package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@ -49,36 +49,35 @@
"generate-document": "cross-env nodemon src/tools/generate_document.ts 1000"
},
"dependencies": {
"@braintree/sanitize-url": "^7.1.0",
"@braintree/sanitize-url": "7.1.0",
"@electron/remote": "2.1.2",
"@excalidraw/excalidraw": "^0.17.6",
"@types/electron-squirrel-startup": "^1.0.2",
"archiver": "^7.0.1",
"async-mutex": "^0.5.0",
"autocomplete.js": "^0.38.1",
"axios": "^1.7.7",
"better-sqlite3": "^11.3.0",
"bootstrap": "^5.3.3",
"@excalidraw/excalidraw": "0.17.6",
"archiver": "7.0.1",
"async-mutex": "0.5.0",
"autocomplete.js": "0.38.1",
"axios": "1.7.7",
"better-sqlite3": "11.3.0",
"bootstrap": "5.3.3",
"boxicons": "2.1.4",
"chokidar": "3.6.0",
"cls-hooked": "4.2.2",
"codemirror": "^5.65.17",
"codemirror": "5.65.17",
"compression": "1.7.4",
"cookie-parser": "1.4.6",
"csurf": "1.11.0",
"dayjs": "^1.11.13",
"dayjs": "1.11.13",
"dayjs-plugin-utc": "0.1.2",
"debounce": "^2.1.0",
"ejs": "^3.1.10",
"electron-debug": "^4.0.1",
"electron-dl": "^4.0.0",
"electron-squirrel-startup": "^1.0.0",
"debounce": "2.1.1",
"ejs": "3.1.10",
"electron-debug": "4.0.1",
"electron-dl": "4.0.0",
"electron-squirrel-startup": "1.0.1",
"electron-window-state": "5.0.3",
"escape-html": "1.0.3",
"eslint": "^9.10.0",
"express": "^4.21.0",
"eslint": "9.10.0",
"express": "4.21.0",
"express-partial-content": "1.0.2",
"express-rate-limit": "^7.3.1",
"express-rate-limit": "7.4.0",
"express-session": "1.18.0",
"force-graph": "1.43.5",
"fs-extra": "11.2.0",
@ -86,113 +85,114 @@
"html": "1.0.0",
"html2plaintext": "2.1.4",
"http-proxy-agent": "7.0.2",
"https-proxy-agent": "^7.0.5",
"i18next": "^23.15.1",
"i18next-fs-backend": "^2.3.2",
"i18next-http-backend": "^2.6.1",
"https-proxy-agent": "7.0.5",
"i18next": "23.15.1",
"i18next-fs-backend": "2.3.2",
"i18next-http-backend": "2.6.1",
"image-type": "4.1.0",
"ini": "^5.0.0",
"ini": "5.0.0",
"is-animated": "2.0.2",
"is-svg": "4.3.2",
"jimp": "0.22.12",
"joplin-turndown-plugin-gfm": "1.0.12",
"jquery": "3.7.1",
"jquery-hotkeys": "0.2.2",
"jquery.fancytree": "^2.38.3",
"jsdom": "^25.0.0",
"jsplumb": "^2.15.6",
"katex": "^0.16.11",
"knockout": "^3.5.1",
"mark.js": "^8.11.1",
"marked": "^14.1.2",
"mermaid": "^11.1.1",
"jquery.fancytree": "2.38.3",
"jsdom": "25.0.0",
"jsplumb": "2.15.6",
"katex": "0.16.11",
"knockout": "3.5.1",
"mark.js": "8.11.1",
"marked": "14.1.2",
"mermaid": "11.2.0",
"mime-types": "2.1.35",
"mind-elixir": "^4.0.5",
"mind-elixir": "4.1.1",
"multer": "1.4.5-lts.1",
"node-abi": "^3.65.0",
"node-abi": "3.67.0",
"normalize-strings": "1.1.1",
"normalize.css": "^8.0.1",
"normalize.css": "8.0.1",
"panzoom": "9.4.3",
"print-this": "2.0.0",
"rand-token": "1.0.1",
"react": "^18.3.1",
"react-dom": "^18.3.1",
"react": "18.3.1",
"react-dom": "18.3.1",
"request": "2.88.2",
"safe-compare": "1.1.4",
"sanitize-filename": "1.6.3",
"sanitize-html": "^2.13.0",
"sax": "^1.4.1",
"semver": "^7.6.3",
"sanitize-html": "2.13.0",
"sax": "1.4.1",
"semver": "7.6.3",
"serve-favicon": "2.5.0",
"session-file-store": "1.5.0",
"source-map-support": "^0.5.21",
"source-map-support": "0.5.21",
"split.js": "1.6.5",
"stream-throttle": "0.1.3",
"striptags": "3.2.0",
"tmp": "0.2.3",
"tree-kill": "1.2.2",
"turndown": "^7.2.0",
"turndown": "7.2.0",
"unescape": "1.0.1",
"vanilla-js-wheel-zoom": "^9.0.2",
"ws": "^8.18.0",
"vanilla-js-wheel-zoom": "9.0.2",
"ws": "8.18.0",
"xml2js": "0.6.2",
"yauzl": "^3.1.3"
"yauzl": "3.1.3"
},
"devDependencies": {
"@electron-forge/cli": "^7.4.0",
"@electron-forge/maker-deb": "^7.4.0",
"@electron-forge/maker-dmg": "^7.4.0",
"@electron-forge/maker-squirrel": "^7.4.0",
"@electron-forge/maker-zip": "^7.4.0",
"@electron-forge/plugin-auto-unpack-natives": "^7.4.0",
"@playwright/test": "^1.46.0",
"@types/archiver": "^6.0.2",
"@types/better-sqlite3": "^7.6.9",
"@types/cls-hooked": "^4.3.8",
"@types/compression": "^1.7.5",
"@types/cookie-parser": "^1.4.7",
"@types/csurf": "^1.11.5",
"@types/debounce": "^1.2.4",
"@types/ejs": "^3.1.5",
"@types/escape-html": "^1.0.4",
"@types/express": "^4.17.21",
"@types/express-session": "^1.18.0",
"@types/html": "^1.0.4",
"@types/ini": "^4.1.0",
"@types/jasmine": "^5.1.4",
"@types/jsdom": "^21.1.6",
"@types/mime-types": "^2.1.4",
"@types/multer": "^1.4.12",
"@types/node": "^22.5.2",
"@types/safe-compare": "^1.1.2",
"@types/sanitize-html": "^2.13.0",
"@types/sax": "^1.2.7",
"@types/semver": "^7.5.8",
"@types/serve-favicon": "^2.5.7",
"@types/session-file-store": "^1.2.5",
"@types/source-map-support": "^0.5.10",
"@types/stream-throttle": "^0.1.4",
"@types/tmp": "^0.2.6",
"@types/turndown": "^5.0.5",
"@types/ws": "^8.5.12",
"@types/xml2js": "^0.4.14",
"@electron-forge/cli": "7.4.0",
"@electron-forge/maker-deb": "7.4.0",
"@electron-forge/maker-dmg": "7.4.0",
"@electron-forge/maker-squirrel": "7.4.0",
"@electron-forge/maker-zip": "7.4.0",
"@electron-forge/plugin-auto-unpack-natives": "7.4.0",
"@playwright/test": "1.47.1",
"@types/archiver": "6.0.2",
"@types/better-sqlite3": "7.6.11",
"@types/cls-hooked": "4.3.8",
"@types/compression": "1.7.5",
"@types/cookie-parser": "1.4.7",
"@types/csurf": "1.11.5",
"@types/debounce": "1.2.4",
"@types/ejs": "3.1.5",
"@types/electron-squirrel-startup": "1.0.2",
"@types/escape-html": "1.0.4",
"@types/express": "4.17.21",
"@types/express-session": "1.18.0",
"@types/html": "1.0.4",
"@types/ini": "4.1.1",
"@types/jasmine": "5.1.4",
"@types/jsdom": "21.1.7",
"@types/mime-types": "2.1.4",
"@types/multer": "1.4.12",
"@types/node": "22.5.4",
"@types/safe-compare": "1.1.2",
"@types/sanitize-html": "2.13.0",
"@types/sax": "1.2.7",
"@types/semver": "7.5.8",
"@types/serve-favicon": "2.5.7",
"@types/session-file-store": "1.2.5",
"@types/source-map-support": "0.5.10",
"@types/stream-throttle": "0.1.4",
"@types/tmp": "0.2.6",
"@types/turndown": "5.0.5",
"@types/ws": "8.5.12",
"@types/xml2js": "0.4.14",
"cross-env": "7.0.3",
"electron": "^31.3.1",
"electron": "31.3.1",
"electron-packager": "17.1.2",
"electron-rebuild": "3.2.9",
"esm": "3.2.25",
"iconsur": "^1.7.0",
"jasmine": "^5.3.0",
"jsdoc": "^4.0.3",
"iconsur": "1.7.0",
"jasmine": "5.3.0",
"jsdoc": "4.0.3",
"lorem-ipsum": "2.0.8",
"nodemon": "^3.1.4",
"nodemon": "3.1.4",
"rcedit": "4.0.1",
"rimraf": "^6.0.1",
"ts-node": "^10.9.2",
"tslib": "^2.7.0",
"tsx": "^4.19.1",
"typescript": "^5.5.4",
"webpack": "^5.93.0",
"rimraf": "6.0.1",
"ts-node": "10.9.2",
"tslib": "2.7.0",
"tsx": "4.19.1",
"typescript": "5.6.2",
"webpack": "5.94.0",
"webpack-cli": "5.1.4"
}
}

View File

@ -70,6 +70,7 @@ const TPL = `
background-color: var(--button-background-color);
padding: 3px;
margin-left: 3px;
text-decoration: none;
}
.global-menu .zoom-buttons a:hover {

View File

@ -70,9 +70,9 @@ const TPL = `
<button class="btn dropdown-toggle note-icon" type="button" data-bs-toggle="dropdown" aria-haspopup="true" aria-expanded="false" title="${t("note_icon.change_note_icon")}"></button>
<div class="dropdown-menu" aria-labelledby="note-path-list-button" style="width: 610px;">
<div class="filter-row">
<span>Category:</span> <select name="icon-category" class="form-control"></select>
<span>${t("note_icon.category")}</span> <select name="icon-category" class="form-control"></select>
<span>Search:</span> <input type="text" name="icon-search" class="form-control" />
<span>${t("note_icon.search")}</span> <input type="text" name="icon-search" class="form-control" />
</div>
<div class="icon-list"></div>
@ -151,7 +151,7 @@ export default class NoteIconWidget extends NoteContextAwareWidget {
this.$iconList.append(
$(`<div style="text-align: center">`)
.append(
$('<button class="btn btn-sm">Reset to default icon</button>')
$(`<button class="btn btn-sm">${t("note_icon.reset-default")}</button>`)
.on('click', () => this.getIconLabels()
.forEach(label => attributeService.removeAttributeById(this.noteId, label.attributeId))
)

View File

@ -18,6 +18,7 @@ import options from "../services/options.js";
import protectedSessionHolder from "../services/protected_session_holder.js";
import dialogService from "../services/dialog.js";
import shortcutService from "../services/shortcuts.js";
import { t } from "../services/i18n.js";
const TPL = `
<div class="tree-wrapper">
@ -99,15 +100,15 @@ const TPL = `
<div class="tree-actions">
<button class="tree-floating-button bx bx-layer-minus collapse-tree-button"
title="Collapse note tree"
title="${t("note_tree.collapse-title")}"
data-trigger-command="collapseTree"></button>
<button class="tree-floating-button bx bx-crosshair scroll-to-active-note-button"
title="Scroll to active note"
title="${t("note_tree.scroll-active-title")}"
data-trigger-command="scrollToActiveNote"></button>
<button class="tree-floating-button bx bxs-tree tree-settings-button"
title="Tree settings"></button>
title="${t("note_tree.tree-settings-title")}"></button>
</div>
@ -116,22 +117,22 @@ const TPL = `
<label class="form-check-label">
<input class="form-check-input hide-archived-notes" type="checkbox" value="">
Hide archived notes
${t("note_tree.hide-archived-notes")}
</label>
</div>
<div class="form-check">
<label class="form-check-label">
<input class="form-check-input auto-collapse-note-tree" type="checkbox" value="">
Automatically collapse notes
${t("note_tree.automatically-collapse-notes")}
<span class="bx bx-info-circle"
title="Notes will be collapsed after period of inactivity to declutter the tree."></span>
title="${t("note_tree.automatically-collapse-notes-title")}"></span>
</label>
</div>
<br/>
<button class="btn btn-sm btn-primary save-tree-settings-button" type="submit">Save & apply changes</button>
<button class="btn btn-sm btn-primary save-tree-settings-button" type="submit">${t("note_tree.save-changes")}</button>
</div>
</div>
`;

View File

@ -5,6 +5,7 @@ import froca from "../services/froca.js";
import utils from "../services/utils.js";
import appContext from "../components/app_context.js";
import shortcutService from "../services/shortcuts.js";
import { t } from "../services/i18n.js";
const TPL = `
<div class="quick-search input-group input-group-sm">
@ -35,7 +36,7 @@ const TPL = `
</button>
<div class="dropdown-menu dropdown-menu-left"></div>
</div>
<input type="text" class="form-control form-control-sm search-string" placeholder="Quick search">
<input type="text" class="form-control form-control-sm search-string" placeholder="${t("quick-search.placeholder")}">
</div>`;
const MAX_DISPLAYED_NOTES = 15;
@ -94,7 +95,7 @@ export default class QuickSearchWidget extends BasicWidget {
}
this.$dropdownMenu.empty();
this.$dropdownMenu.append('<span class="dropdown-item disabled"><span class="bx bx-loader bx-spin"></span> Searching ...</span>');
this.$dropdownMenu.append(`<span class="dropdown-item disabled"><span class="bx bx-loader bx-spin"></span>${t("quick-search.searching")}</span>`);
const { searchResultNoteIds, error } = await server.get(`quick-search/${encodeURIComponent(searchString)}`);
@ -115,7 +116,7 @@ export default class QuickSearchWidget extends BasicWidget {
this.$dropdownMenu.empty();
if (displayedNoteIds.length === 0) {
this.$dropdownMenu.append('<span class="dropdown-item disabled">No results found</span>');
this.$dropdownMenu.append(`<span class="dropdown-item disabled">${t("quick-search.no-results")}</span>`);
}
for (const note of await froca.getNotes(displayedNoteIds)) {
@ -140,11 +141,12 @@ export default class QuickSearchWidget extends BasicWidget {
}
if (searchResultNoteIds.length > MAX_DISPLAYED_NOTES) {
this.$dropdownMenu.append(`<span class="dropdown-item disabled">... and ${searchResultNoteIds.length - MAX_DISPLAYED_NOTES} more results.</span>`);
const numRemainingResults = (searchResultNoteIds.length - MAX_DISPLAYED_NOTES);
this.$dropdownMenu.append(`<span class="dropdown-item disabled">${t("quick-search.more-results", { number: numRemainingResults })}</span>`);
}
const $showInFullButton = $('<a class="dropdown-item" tabindex="0">')
.append($('<button class="btn btn-sm">Show in full search</button>'));
.append($(`<button class="btn btn-sm">${t("quick-search.show-in-full-search")}</button>`));
this.$dropdownMenu.append($showInFullButton);

View File

@ -1,6 +1,7 @@
import BasicWidget from "./basic_widget.js";
import options from "../services/options.js";
import utils from "../services/utils.js";
import { t } from "../services/i18n.js";
const TPL = `
<div class="title-bar-buttons">
@ -41,7 +42,7 @@ const TPL = `
</style>
<!-- divs act as a hitbox for the buttons, making them clickable on corners -->
<div class="top-btn" title="Keep this window on top. "><button class="btn bx bx-pin"></button></div>
<div class="top-btn" title="${t("title_bar_buttons.window-on-top")}"><button class="btn bx bx-pin"></button></div>
<div class="minimize-btn"><button class="btn bx bx-minus"></button></div>
<div class="maximize-btn"><button class="btn bx bx-checkbox"></button></div>
<div class="close-btn"><button class="btn bx bx-x"></button></div>

View File

@ -80,8 +80,7 @@ export default class KeyboardShortcutsOptions extends OptionsWidget {
.attr("style","background-color: var(--accented-background-color); font-weight: bold;")
.text(action.separator)
)
}
else {
} else if (action.defaultShortcuts) {
$tr.append($("<td>").text(action.actionName))
.append($("<td>").append(
$(`<input type="text" class="form-control">`)

View File

@ -683,7 +683,10 @@
"error_unrecognized_command": "Unrecognized command {{command}}"
},
"note_icon": {
"change_note_icon": "Change note icon"
"change_note_icon": "Change note icon",
"category": "Category:",
"search": "Search:",
"reset-default": "Reset to default icon"
},
"basic_properties": {
"note_type": "Note type",
@ -1356,5 +1359,24 @@
},
"mermaid": {
"diagram_error": "The diagram could not be displayed. See <a href=\"https://mermaid-js.github.io/mermaid/#/flowchart?id=graph\">help and examples</a>."
},
"quick-search": {
"placeholder": "Quick search",
"searching": "Searching...",
"no-results": "No results found",
"more-results": "... and {{number}} more results.",
"show-in-full-search": "Show in full search"
},
"note_tree": {
"collapse-title": "Collapse note tree",
"scroll-active-title": "Scroll to active note",
"tree-settings-title": "Tree settings",
"hide-archived-notes": "Hide archived notes",
"automatically-collapse-notes": "Automatically collapse notes",
"automatically-collapse-notes-title": "Notes will be collapsed after period of inactivity to declutter the tree.",
"save-changes": "Save & apply changes"
},
"title_bar_buttons": {
"window-on-top": "Keep this window on top."
}
}

View File

@ -1318,5 +1318,55 @@
"toggle-off-hint": "Înlătură notița ca șablon",
"toggle-on-hint": "Marchează notița drept șablon"
},
"open-help-page": "Deschide pagina de informații"
"open-help-page": "Deschide pagina de informații",
"find": {
"match_words": "doar cuvinte întregi",
"case_sensitive": "ține cont de majuscule"
},
"highlights_list_2": {
"options": "Setări",
"title": "Listă de evidențieri"
},
"mermaid": {
"diagram_error": "Diagrama nu a putut fi afișată. Vedeți <a href=\"https://mermaid-js.github.io/mermaid/#/flowchart?id=graph\">informații și exemple pe site-ul oficial</a>."
},
"note_icon": {
"change_note_icon": "Schimbă iconița notiței",
"category": "Categorie:",
"reset-default": "Resetează la iconița implicită",
"search": "Căutare:"
},
"show_highlights_list_widget_button": {
"show_highlights_list": "Afișează lista de evidențieri"
},
"show_toc_widget_button": {
"show_toc": "Afișează cuprinsul"
},
"sync_status": {
"connected_no_changes": "<p>Conectat la server-ul de sincronizare.<br>Toate modificările au fost deja sincronizate.</p><p>Clic pentru a forța o sincronizare.</p>",
"connected_with_changes": "<p>Conectat la server-ul de sincronizare. <br>Există modificări nesincronizate.</p><p>Clic pentru a rula o sincronizare.</p>",
"disconnected_no_changes": "<p>Nu s-a putut stabili conexiunea la server-ul de sincronizare.<br>Toate modificările cunoscute au fost deja sincronizate.</p><p>Clic pentru a reîncerca sincronizarea.</p>",
"disconnected_with_changes": "<p>Nu s-a putut realiza conexiunea la server-ul de sincronizare.<br>Există modificări nesincronizate.</p><p>Clic pentru a rula o sincronizare.</p>",
"in_progress": "Sincronizare cu server-ul în curs.",
"unknown": "<p>Starea sincronizării va fi cunoscută după o încercare de sincronizare.</p><p>Clic pentru a rula sincronizarea acum.</p>"
},
"quick-search": {
"more-results": "... și încă {{number}} rezultate.",
"no-results": "Niciun rezultat găsit",
"placeholder": "Căutare rapidă",
"searching": "Se caută...",
"show-in-full-search": "Afișează în căutare completă"
},
"note_tree": {
"automatically-collapse-notes": "Minimează automat notițele",
"automatically-collapse-notes-title": "Notițele vor fi minimizate automat după o perioadă de inactivitate pentru a simplifica ierarhia notițelor.",
"collapse-title": "Minimizează ierarhia de notițe",
"hide-archived-notes": "Ascunde notițele arhivate",
"save-changes": "Salvează și aplică modificările",
"scroll-active-title": "Mergi la notița activă",
"tree-settings-title": "Setări ale ierarhiei notițelor"
},
"title_bar_buttons": {
"window-on-top": "Menține fereastra mereu vizibilă"
}
}

View File

@ -11,6 +11,7 @@ import utils from "./utils.js";
const template = `[Desktop Entry]
Type=Application
Name=TriliumNext Notes
StartupWMClass=TriliumNext Notes
Icon=#APP_ROOT_DIR#/icon.png
Exec=#EXE_PATH#
Categories=Office

View File

@ -11,8 +11,7 @@ export async function initializeTranslations() {
ns: "server",
backend: {
loadPath: "translations/{{lng}}/{{ns}}.json"
},
debug: true
}
});
}

View File

@ -1,7 +1,4 @@
{
"keyboard-actions": {
"note-navigation": "Navigarea printre notițe"
},
"keyboard_actions": {
"activate-next-tab": "Activează tab-ul din dreapta",
"activate-previous-tab": "Activează tab-ul din stânga",