Compare commits

...

10 Commits

Author SHA1 Message Date
SiriusXT
914483151a Merge branch 'main' into tree-activate-clone 2025-10-29 15:19:10 +08:00
SiriusXT
5db4c39051 Fix: activate the nearest path when opening a cloned note 2025-10-29 15:17:41 +08:00
Elian Doran
0ad95d00dc chore(ci): try to fix arm v6/v7 build 2025-10-29 08:08:16 +02:00
Elian Doran
5b7e9d4c12 Revision history: two fixes (#7544) 2025-10-28 18:30:50 +02:00
contributor
bee2fdb22f chore: remove dead translation 2025-10-28 18:26:35 +02:00
contributor
5c46a0dfa8 chore: remove dead code
https://github.com/TriliumNext/Trilium/pull/7544#issuecomment-3456187575
2025-10-28 18:26:35 +02:00
Elian Doran
69b262040a Translations update from Hosted Weblate (#7547) 2025-10-28 16:22:15 +02:00
Manfred Manni
8731fa6c31 Translated using Weblate (German)
Currently translated at 59.3% (70 of 118 strings)

Translation: Trilium Notes/README
Translate-URL: https://hosted.weblate.org/projects/trilium/readme/de/
2025-10-28 13:50:36 +00:00
contributor
c579cd3ce7 fix: no note on edited notes view if a revision made between note created/modified date 2025-10-28 12:55:34 +02:00
contributor
945e2625d3 fix: wrong dates in “Note Revisions” view 2025-10-28 12:55:13 +02:00
23 changed files with 97 additions and 72 deletions

View File

@@ -116,10 +116,10 @@ jobs:
- dockerfile: Dockerfile
platform: linux/arm64
image: ubuntu-24.04-arm
- dockerfile: Dockerfile
- dockerfile: Dockerfile.legacy
platform: linux/arm/v7
image: ubuntu-24.04-arm
- dockerfile: Dockerfile
- dockerfile: Dockerfile.legacy
platform: linux/arm/v8
image: ubuntu-24.04-arm
runs-on: ${{ matrix.image }}

View File

@@ -417,7 +417,7 @@ export default class FNote {
return notePaths;
}
getSortedNotePathRecords(hoistedNoteId = "root"): NotePathRecord[] {
getSortedNotePathRecords(hoistedNoteId = "root", activeNotePath: string | null = null): NotePathRecord[] {
const isHoistedRoot = hoistedNoteId === "root";
const notePaths: NotePathRecord[] = this.getAllNotePaths().map((path) => ({
@@ -428,7 +428,23 @@ export default class FNote {
isHidden: path.includes("_hidden")
}));
// Calculate the length of the prefix match between two arrays
const prefixMatchLength = (path: string[], target: string[]) => {
const diffIndex = path.findIndex((seg, i) => seg !== target[i]);
return diffIndex === -1 ? Math.min(path.length, target.length) : diffIndex;
};
notePaths.sort((a, b) => {
if (activeNotePath) {
const activeSegments = activeNotePath.split('/');
const aOverlap = prefixMatchLength(a.notePath, activeSegments);
const bOverlap = prefixMatchLength(b.notePath, activeSegments);
// Paths with more matching prefix segments are prioritized
// when the match count is equal, other criteria are used for sorting
if (bOverlap !== aOverlap) {
return bOverlap - aOverlap;
}
}
if (a.isInHoistedSubTree !== b.isInHoistedSubTree) {
return a.isInHoistedSubTree ? -1 : 1;
} else if (a.isArchived !== b.isArchived) {
@@ -449,10 +465,11 @@ export default class FNote {
* Returns the note path considered to be the "best"
*
* @param {string} [hoistedNoteId='root']
* @param {string|null} [activeNotePath=null]
* @return {string[]} array of noteIds constituting the particular note path
*/
getBestNotePath(hoistedNoteId = "root") {
return this.getSortedNotePathRecords(hoistedNoteId)[0]?.notePath;
getBestNotePath(hoistedNoteId = "root", activeNotePath: string | null = null) {
return this.getSortedNotePathRecords(hoistedNoteId, activeNotePath)[0]?.notePath;
}
/**

View File

@@ -26,21 +26,12 @@ async function resolveNotePathToSegments(notePath: string, hoistedNoteId = "root
}
const path = notePath.split("/").reverse();
if (!path.includes("root")) {
path.push("root");
}
const effectivePathSegments: string[] = [];
let childNoteId: string | null = null;
let i = 0;
while (true) {
if (i >= path.length) {
break;
}
const parentNoteId = path[i++];
for (let i = 0; i < path.length; i++) {
const parentNoteId = path[i];
if (childNoteId !== null) {
const child = await froca.getNote(childNoteId, !logErrors);
@@ -65,7 +56,7 @@ async function resolveNotePathToSegments(notePath: string, hoistedNoteId = "root
return null;
}
if (!parents.some((p) => p.noteId === parentNoteId)) {
if (!parents.some(p => p.noteId === parentNoteId) || (i === path.length - 1 && parentNoteId !== 'root')) {
if (logErrors) {
const parent = froca.getNoteFromCache(parentNoteId);
@@ -77,7 +68,8 @@ async function resolveNotePathToSegments(notePath: string, hoistedNoteId = "root
);
}
const bestNotePath = child.getBestNotePath(hoistedNoteId);
const activeNotePath = appContext.tabManager.getActiveContextNotePath();
const bestNotePath = child.getBestNotePath(hoistedNoteId, activeNotePath);
if (bestNotePath) {
const pathToRoot = bestNotePath.reverse().slice(1);
@@ -108,7 +100,9 @@ async function resolveNotePathToSegments(notePath: string, hoistedNoteId = "root
if (!note) {
throw new Error(`Unable to find note: ${notePath}.`);
}
const bestNotePath = note.getBestNotePath(hoistedNoteId);
const activeNotePath = appContext.tabManager.getActiveContextNotePath();
const bestNotePath = note.getBestNotePath(hoistedNoteId, activeNotePath);
if (!bestNotePath) {
throw new Error(`Did not find any path segments for '${note.toString()}', hoisted note '${hoistedNoteId}'`);

View File

@@ -259,7 +259,6 @@
"delete_all_revisions": "删除此笔记的所有修订版本",
"delete_all_button": "删除所有修订版本",
"help_title": "关于笔记修订版本的帮助",
"revision_last_edited": "此修订版本上次编辑于 {{date}}",
"confirm_delete_all": "您是否要删除此笔记的所有修订版本?",
"no_revisions": "此笔记暂无修订版本...",
"restore_button": "恢复",

View File

@@ -260,7 +260,6 @@
"delete_all_revisions": "Lösche alle Revisionen dieser Notiz",
"delete_all_button": "Alle Revisionen löschen",
"help_title": "Hilfe zu Notizrevisionen",
"revision_last_edited": "Diese Revision wurde zuletzt am {{date}} bearbeitet",
"confirm_delete_all": "Möchtest du alle Revisionen dieser Notiz löschen?",
"no_revisions": "Für diese Notiz gibt es noch keine Revisionen...",
"confirm_restore": "Möchtest du diese Revision wiederherstellen? Dadurch werden der aktuelle Titel und Inhalt der Notiz mit dieser Revision überschrieben.",

View File

@@ -261,7 +261,6 @@
"delete_all_revisions": "Delete all revisions of this note",
"delete_all_button": "Delete all revisions",
"help_title": "Help on Note Revisions",
"revision_last_edited": "This revision was last edited on {{date}}",
"confirm_delete_all": "Do you want to delete all revisions of this note?",
"no_revisions": "No revisions for this note yet...",
"restore_button": "Restore",

View File

@@ -259,7 +259,6 @@
"delete_all_revisions": "Eliminar todas las revisiones de esta nota",
"delete_all_button": "Eliminar todas las revisiones",
"help_title": "Ayuda sobre revisiones de notas",
"revision_last_edited": "Esta revisión se editó por última vez en {{date}}",
"confirm_delete_all": "¿Quiere eliminar todas las revisiones de esta nota?",
"no_revisions": "Aún no hay revisiones para esta nota...",
"restore_button": "Restaurar",

View File

@@ -260,7 +260,6 @@
"delete_all_revisions": "Supprimer toutes les versions de cette note",
"delete_all_button": "Supprimer toutes les versions",
"help_title": "Aide sur les versions de notes",
"revision_last_edited": "Cette version a été modifiée pour la dernière fois le {{date}}",
"confirm_delete_all": "Voulez-vous supprimer toutes les versions de cette note ?",
"no_revisions": "Aucune version pour cette note pour l'instant...",
"confirm_restore": "Voulez-vous restaurer cette version ? Le titre et le contenu actuels de la note seront écrasés par cette version.",

View File

@@ -867,7 +867,6 @@
"delete_all_revisions": "Elimina tutte le revisioni di questa nota",
"delete_all_button": "Elimina tutte le revisioni",
"help_title": "Aiuto sulle revisioni delle note",
"revision_last_edited": "Questa revisione è stata modificata l'ultima volta il {{date}}",
"confirm_delete_all": "Vuoi eliminare tutte le revisioni di questa nota?",
"no_revisions": "Ancora nessuna revisione per questa nota...",
"restore_button": "Ripristina",

View File

@@ -610,7 +610,6 @@
"delete_all_revisions": "このノートの変更履歴をすべて削除",
"delete_all_button": "変更履歴をすべて削除",
"help_title": "変更履歴のヘルプ",
"revision_last_edited": "この変更は{{date}}に行われました",
"confirm_delete_all": "このノートのすべての変更履歴を削除しますか?",
"no_revisions": "このノートに変更履歴はまだありません...",
"restore_button": "復元",

View File

@@ -912,7 +912,6 @@
"delete_all_revisions": "Usuń wszystkie wersje tej notatki",
"delete_all_button": "Usuń wszystkie wersje",
"help_title": "Pomoc dotycząca wersji notatki",
"revision_last_edited": "Ta wersja była ostatnio edytowana {{date}}",
"confirm_delete_all": "Czy chcesz usunąć wszystkie wersje tej notatki?",
"no_revisions": "Brak wersji dla tej notatki...",
"restore_button": "Przywróć",

View File

@@ -259,7 +259,6 @@
"delete_all_revisions": "Apagar todas as versões desta nota",
"delete_all_button": "Apagar todas as versões",
"help_title": "Ajuda sobre as versões da nota",
"revision_last_edited": "Esta versão foi editada pela última vez em {{date}}",
"confirm_delete_all": "Quer apagar todas as versões desta nota?",
"no_revisions": "Ainda não há versões para esta nota...",
"restore_button": "Recuperar",

View File

@@ -415,7 +415,6 @@
"delete_all_revisions": "Excluir todas as versões desta nota",
"delete_all_button": "Excluir todas as versões",
"help_title": "Ajuda sobre as versões da nota",
"revision_last_edited": "Esta versão foi editada pela última vez em {{date}}",
"confirm_delete_all": "Você quer excluir todas as versões desta nota?",
"no_revisions": "Ainda não há versões para esta nota...",
"restore_button": "Recuperar",

View File

@@ -1090,7 +1090,6 @@
"preview_not_available": "Nu este disponibilă o previzualizare pentru acest tip de notiță.",
"restore_button": "Restaurează",
"revision_deleted": "Revizia notiței a fost ștearsă.",
"revision_last_edited": "Revizia a fost ultima oară modificată pe {{date}}",
"revision_restored": "Revizia notiței a fost restaurată.",
"revisions_deleted": "Notița reviziei a fost ștearsă.",
"maximum_revisions": "Numărul maxim de revizii pentru notița curentă: {{number}}.",

View File

@@ -366,7 +366,6 @@
"delete_all_button": "Удалить все версии",
"help_title": "Помощь по версиям заметок",
"confirm_delete_all": "Вы хотите удалить все версии этой заметки?",
"revision_last_edited": "Эта версия последний раз редактировалась {{date}}",
"confirm_restore": "Хотите восстановить эту версию? Текущее название и содержание заметки будут перезаписаны этой версией.",
"confirm_delete": "Вы хотите удалить эту версию?",
"revisions_deleted": "Версии заметки были удалены.",

View File

@@ -256,7 +256,6 @@
"delete_all_revisions": "Obriši sve revizije ove beleške",
"delete_all_button": "Obriši sve revizije",
"help_title": "Pomoć za Revizije beleški",
"revision_last_edited": "Ova revizija je poslednji put izmenjena {{date}}",
"confirm_delete_all": "Da li želite da obrišete sve revizije ove beleške?",
"no_revisions": "Još uvek nema revizija za ovu belešku...",
"restore_button": "Vrati",

View File

@@ -260,7 +260,6 @@
"delete_all_revisions": "刪除此筆記的所有歷史版本",
"delete_all_button": "刪除所有歷史版本",
"help_title": "關於筆記歷史版本的說明",
"revision_last_edited": "此歷史版本上次於 {{date}} 編輯",
"confirm_delete_all": "您是否要刪除此筆記的所有歷史版本?",
"no_revisions": "此筆記暫無歷史版本…",
"confirm_restore": "您是否要還原此歷史版本?這將使用此歷史版本覆寫筆記的目前標題和內容。",

View File

@@ -309,7 +309,6 @@
"delete_all_revisions": "Видалити всі версії цієї нотатки",
"delete_all_button": "Видалити всі версії",
"help_title": "Довідка щодо Версій нотаток",
"revision_last_edited": "Цю версію востаннє редагували {{date}}",
"confirm_delete_all": "Ви хочете видалити всі версії цієї нотатки?",
"no_revisions": "Поки що немає версій цієї нотатки...",
"restore_button": "Відновити",

View File

@@ -140,11 +140,10 @@ function RevisionsList({ revisions, onSelect, currentRevision }: { revisions: Re
<FormList onSelect={onSelect} fullHeight>
{revisions.map((item) =>
<FormListItem
title={t("revisions.revision_last_edited", { date: item.dateLastEdited })}
value={item.revisionId}
active={currentRevision && item.revisionId === currentRevision.revisionId}
>
{item.dateLastEdited && item.dateLastEdited.substr(0, 16)} ({item.contentLength && utils.formatSize(item.contentLength)})
{item.dateCreated && item.dateCreated.substr(0, 16)} ({item.contentLength && utils.formatSize(item.contentLength)})
</FormListItem>
)}
</FormList>);

View File

@@ -0,0 +1,28 @@
FROM node:22.21.0-bullseye-slim AS builder
RUN corepack enable
# Install native dependencies since we might be building cross-platform.
WORKDIR /usr/src/app/build
COPY ./docker/package.json ./docker/pnpm-workspace.yaml /usr/src/app/
# We have to use --no-frozen-lockfile due to CKEditor patches
RUN pnpm install --no-frozen-lockfile --prod && pnpm rebuild
FROM node:24.10.0-bullseye-slim
# Install only runtime dependencies
RUN apt-get update && \
apt-get install -y --no-install-recommends \
gosu && \
rm -rf \
/var/lib/apt/lists/* \
/var/cache/apt/*
WORKDIR /usr/src/app
COPY ./dist /usr/src/app
RUN rm -rf /usr/src/app/node_modules/better-sqlite3
COPY --from=builder /usr/src/app/node_modules/better-sqlite3 /usr/src/app/node_modules/better-sqlite3
COPY ./start-docker.sh /usr/src/app
# Configure container
EXPOSE 8080
CMD [ "sh", "./start-docker.sh" ]
HEALTHCHECK --start-period=10s CMD exec gosu node node /usr/src/app/docker_healthcheck.cjs

View File

@@ -162,7 +162,7 @@ function getEditedNotesOnDate(req: Request) {
AND (noteId NOT LIKE '_%')
UNION ALL
SELECT noteId FROM revisions
WHERE revisions.dateLastEdited LIKE :date
WHERE revisions.dateCreated LIKE :date
)
ORDER BY isDeleted
LIMIT 50`,

70
docs/README-de.md vendored
View File

@@ -128,57 +128,59 @@ Unsere Dokumentation ist verfügbar in mehreren Formaten:
einfachen Speichern von Webinhalten
* Anpassbare Benutzeroberfläche (Seitenleisten-Schaltflächen, benutzerdefinierte
Widgets, ...)
* [Metriken]{1, zusammen mit einem
* [Metriken](./docs/User%20Guide/User%20Guide/Advanced%20Usage/Metrics.md),
zusammen mit einem
[Grafana-Dashboard](./docs/User%20Guide/User%20Guide/Advanced%20Usage/Metrics/grafana-dashboard.json)
Check out the following third-party resources/communities for more TriliumNext
related goodies:
Weitere Informationen zu TriliumNext findet man in den folgenden
Ressourcen/Communities von Drittanbietern:
- [awesome-trilium](https://github.com/Nriver/awesome-trilium) for 3rd party
themes, scripts, plugins and more.
- [TriliumRocks!](https://trilium.rocks/) for tutorials, guides, and much more.
- [awesome-trilium](https://github.com/Nriver/awesome-trilium) bietet von
Drittanbietern erstellte Themes, Skripte, Plugins und vieles mehr
- [TriliumRocks!](https://trilium.rocks/) für Tutorials, Anleitungen und vieles
mehr.
## ❓Why TriliumNext?
## ❓ Warum TriliumNext?
The original Trilium developer ([Zadam](https://github.com/zadam)) has
graciously given the Trilium repository to the community project which resides
at https://github.com/TriliumNext
Der ursprüngliche Entwickler von Trilium ([Zadam](https://github.com/zadam)) hat
das Trilium-Repository der Gemeinschaft übergeben, die nun unter
https://github.com/TriliumNext agiert
### Migration von Zadam/Trilium?
There are no special migration steps to migrate from a zadam/Trilium instance to
a TriliumNext/Trilium instance. Simply [install
TriliumNext/Trilium](#-installation) as usual and it will use your existing
database.
Es sind keine speziellen Migrationsschritte erforderlich, um von einer
zadam/Trilium-Instanz auf eine TriliumNext/Trilium-Instanz umzustellen. Man
[Installieret TriliumNext/Trilium](#-installation) einfach wie gewohnt, und die
vorhandene Datenbank wird verwendet.
Versions up to and including
[v0.90.4](https://github.com/TriliumNext/Trilium/releases/tag/v0.90.4) are
compatible with the latest zadam/trilium version of
[v0.63.7](https://github.com/zadam/trilium/releases/tag/v0.63.7). Any later
versions of TriliumNext/Trilium have their sync versions incremented which
prevents direct migration.
Versionen bis einschließlich
[v0.90.4](https://github.com/TriliumNext/Trilium/releases/tag/v0.90.4) sind
kompatibel mit der letzten zadam/trilium-Version
[v0.63.7](https://github.com/zadam/trilium/releases/tag/v0.63.7). Alle späteren
Versionen von TriliumNext/Trilium haben ihre Sync-Versionen erhöht, was eine
direkte Migration verhindert
## 💬 Discuss with us
## 💬 Diskussion mit uns
Feel free to join our official conversations. We would love to hear what
features, suggestions, or issues you may have!
Nehme gerne an den offiziellen Diskussionen teil. Feedback, Funktionsvorschläge
oder Problemberichte sind jederzeit willkommen!
- [Matrix](https://matrix.to/#/#triliumnext:matrix.org) (For synchronous
discussions.)
- The `General` Matrix room is also bridged to
[XMPP](xmpp:discuss@trilium.thisgreat.party?join)
- [Github Discussions](https://github.com/TriliumNext/Trilium/discussions) (For
asynchronous discussions.)
- [Github Issues](https://github.com/TriliumNext/Trilium/issues) (For bug
reports and feature requests.)
- [Matrix](https://matrix.to/#/#triliumnext:matrix.org) (für
Echtzeit-Diskussionen.)
- Der `allgemeine` Matrix-Raum ist zusätzlich mit
[XMPP](xmpp:discuss@trilium.thisgreat.party?join) verbunden
- (Github Diskussionen)(https://github.com/TriliumNext/Trilium/discussions) (r
asynchrone Diskussionen)
- [Github-Probleme](https://github.com/TriliumNext/Trilium/issues) (für
Fehlerberichte und Funktionsanfragen)
## 🏗 Installation
### Windows / MacOS
Download the binary release for your platform from the [latest release
page](https://github.com/TriliumNext/Trilium/releases/latest), unzip the package
and run the `trilium` executable.
Lade die Binärversion für deine Plattform von der Seite mit den [neuesten
Versionen](https://github.com/TriliumNext/Trilium/releases/latest) herunter,
entpacke das Paket und führe die ausführbare Datei `trilium` aus.
### Linux

View File

@@ -29,7 +29,7 @@ export interface DeleteNotesPreview {
export interface RevisionItem {
noteId: string;
revisionId?: string;
dateLastEdited?: string;
dateCreated?: string;
contentLength?: number;
type: NoteType;
title: string;