diff --git a/_regroup/package.json b/_regroup/package.json index 1937327e0..721fe4390 100644 --- a/_regroup/package.json +++ b/_regroup/package.json @@ -37,7 +37,7 @@ "devDependencies": { "@playwright/test": "1.56.1", "@stylistic/eslint-plugin": "5.5.0", - "@types/express": "5.0.4", + "@types/express": "5.0.5", "@types/node": "22.18.12", "@types/yargs": "17.0.34", "@vitest/coverage-v8": "3.2.4", diff --git a/apps/client/package.json b/apps/client/package.json index 61738b8bb..6bc7f10f2 100644 --- a/apps/client/package.json +++ b/apps/client/package.json @@ -54,12 +54,12 @@ "leaflet-gpx": "2.2.0", "mark.js": "8.11.1", "marked": "16.4.1", - "mermaid": "11.12.0", + "mermaid": "11.12.1", "mind-elixir": "5.3.4", "normalize.css": "8.0.1", "panzoom": "9.4.3", "preact": "10.27.2", - "react-i18next": "16.2.0", + "react-i18next": "16.2.1", "reveal.js": "5.2.1", "svg-pan-zoom": "3.6.2", "tabulator-tables": "6.3.1", diff --git a/apps/client/src/print.tsx b/apps/client/src/print.tsx index de11d581a..3dbdf1de0 100644 --- a/apps/client/src/print.tsx +++ b/apps/client/src/print.tsx @@ -56,7 +56,20 @@ function SingleNoteRenderer({ note, onReady }: RendererProps) { await import("@triliumnext/ckeditor5/src/theme/ck-content.css"); } const { $renderedContent } = await content_renderer.getRenderedContent(note, { noChildrenList: true }); - containerRef.current?.replaceChildren(...$renderedContent); + const container = containerRef.current!; + container.replaceChildren(...$renderedContent); + + // Wait for all images to load. + const images = Array.from(container.querySelectorAll("img")); + await Promise.all( + images.map(img => { + if (img.complete) return Promise.resolve(); + return new Promise(resolve => { + img.addEventListener("load", () => resolve(), { once: true }); + img.addEventListener("error", () => resolve(), { once: true }); + }); + }) + ); } load().then(() => requestAnimationFrame(onReady)) diff --git a/apps/client/src/translations/de/translation.json b/apps/client/src/translations/de/translation.json index e5037b780..b3f4c9a46 100644 --- a/apps/client/src/translations/de/translation.json +++ b/apps/client/src/translations/de/translation.json @@ -648,7 +648,8 @@ "logout": "Abmelden", "show-cheatsheet": "Cheatsheet anzeigen", "toggle-zen-mode": "Zen Modus", - "new-version-available": "Neues Update verfügbar" + "new-version-available": "Neues Update verfügbar", + "download-update": "Version {{latestVersion}} herunterladen" }, "sync_status": { "unknown": "

Der Synchronisations-Status wird bekannt, sobald der nächste Synchronisierungsversuch gestartet wird.

Klicke, um eine Synchronisierung jetzt auszulösen.

", @@ -1657,7 +1658,7 @@ "add-term-to-dictionary": "Begriff \"{{term}}\" zum Wörterbuch hinzufügen", "cut": "Ausschneiden", "copy": "Kopieren", - "copy-link": "Link opieren", + "copy-link": "Link kopieren", "paste": "Einfügen", "paste-as-plain-text": "Als unformatierten Text einfügen", "search_online": "Suche nach \"{{term}}\" mit {{searchEngine}} starten" @@ -2082,6 +2083,7 @@ }, "presentation_view": { "edit-slide": "Folie bearbeiten", - "start-presentation": "Präsentation starten" + "start-presentation": "Präsentation starten", + "slide-overview": "Übersicht der Folien ein-/ausblenden" } } diff --git a/apps/client/src/translations/nl/translation.json b/apps/client/src/translations/nl/translation.json index d07df69e5..de5cfb6c7 100644 --- a/apps/client/src/translations/nl/translation.json +++ b/apps/client/src/translations/nl/translation.json @@ -13,6 +13,13 @@ "critical-error": { "title": "Kritische Error", "message": "Een kritieke fout heeft plaatsgevonden waardoor de cliënt zich aanmeldt vanaf het begin:\n\n84X\n\nDit is waarschijnlijk veroorzaakt door een script dat op een onverwachte manier faalt. Probeer de sollicitatie in veilige modus te starten en de kwestie aan te spreken." + }, + "widget-error": { + "title": "Starten widget mislukt", + "message-unknown": "Onbekende widget kan niet gestart worden omdat:\n\n{{message}}" + }, + "bundle-error": { + "title": "Custom script laden mislukt" } }, "add_link": { diff --git a/apps/client/src/translations/ru/translation.json b/apps/client/src/translations/ru/translation.json index 2dc068850..eeee4b28f 100644 --- a/apps/client/src/translations/ru/translation.json +++ b/apps/client/src/translations/ru/translation.json @@ -320,7 +320,8 @@ "explodeArchivesTooltip": "Если этот флажок установлен, Trilium будет читать файлы .zip, .enex и .opml и создавать заметки из файлов внутри этих архивов. Если флажок не установлен, Trilium будет прикреплять сами архивы к заметке.", "explodeArchives": "Прочитать содержимое архивов .zip, .enex и .opml.", "shrinkImagesTooltip": "

Если этот параметр включен, Trilium попытается уменьшить размер импортируемых изображений путём масштабирования и оптимизации, что может повлиять на воспринимаемое качество изображения. Если этот параметр не установлен, изображения будут импортированы без изменений.

Это не относится к импорту файлов .zip с метаданными, поскольку предполагается, что эти файлы уже оптимизированы.

", - "codeImportedAsCode": "Импортировать распознанные файлы кода (например, .json) в виде заметок типа \"код\", если это неясно из метаданных" + "codeImportedAsCode": "Импортировать распознанные файлы кода (например, .json) в виде заметок типа \"код\", если это неясно из метаданных", + "importZipRecommendation": "При импорте ZIP файла иерархия заметок будет отражена в структуре папок внутри архива." }, "markdown_import": { "dialog_title": "Импорт Markdown", @@ -980,7 +981,8 @@ "open_sql_console_history": "Открыть историю консоли SQL", "show_shared_notes_subtree": "Поддерево общедоступных заметок", "switch_to_mobile_version": "Перейти на мобильную версию", - "switch_to_desktop_version": "Переключиться на версию для ПК" + "switch_to_desktop_version": "Переключиться на версию для ПК", + "new-version-available": "Доступно обновление" }, "zpetne_odkazy": { "backlink": "{{count}} ссылки", diff --git a/apps/client/src/widgets/dialogs/popup_editor.ts b/apps/client/src/widgets/dialogs/popup_editor.ts index a1697c5f5..a823740cd 100644 --- a/apps/client/src/widgets/dialogs/popup_editor.ts +++ b/apps/client/src/widgets/dialogs/popup_editor.ts @@ -174,6 +174,11 @@ export default class PopupEditorDialog extends Container { return Promise.resolve(); } + // Avoid not showing recent notes when creating a new empty tab. + if ("noteContext" in data && data.noteContext.ntxId !== "_popup-editor") { + return Promise.resolve(); + } + return super.handleEventInChildren(name, data); } diff --git a/apps/client/src/widgets/icon_list.ts b/apps/client/src/widgets/icon_list.ts index a152e9a34..cef6eaf34 100644 --- a/apps/client/src/widgets/icon_list.ts +++ b/apps/client/src/widgets/icon_list.ts @@ -147,6 +147,12 @@ const categories: Category[] = [ ]; const icons: Icon[] = [ + { + name: "empty", + slug: "empty", + category_id: 113, + type_of_icon: "REGULAR" + }, { name: "child", slug: "child-regular", diff --git a/apps/client/src/widgets/note_icon.css b/apps/client/src/widgets/note_icon.css index a05be824d..a3be50dc6 100644 --- a/apps/client/src/widgets/note_icon.css +++ b/apps/client/src/widgets/note_icon.css @@ -56,4 +56,16 @@ .note-icon-widget .icon-list span:hover { border: 1px solid var(--main-border-color); +} + +.note-icon-widget .icon-list span.bx-empty { + width: unset; +} + +.note-icon-widget .icon-list span.bx-empty::before { + display: inline-block; + content: ""; + border: 1px dashed var(--muted-text-color); + width: 1em; + height: 1em; } \ No newline at end of file diff --git a/apps/desktop/electron-forge/trilium-no-cert-check.bat b/apps/desktop/electron-forge/trilium-no-cert-check.bat index cfc345c42..d3405b497 100644 --- a/apps/desktop/electron-forge/trilium-no-cert-check.bat +++ b/apps/desktop/electron-forge/trilium-no-cert-check.bat @@ -6,7 +6,7 @@ WHERE powershell.exe > NUL 2>&1 IF %ERRORLEVEL% NEQ 0 GOTO BATCH ELSE GOTO POWERSHELL :POWERSHELL -powershell -ExecutionPolicy Bypass -NonInteractive -NoLogo "Set-Item -Path Env:NODE_TLS_REJECT_UNAUTHORIZED -Value 0; ./trilium.exe" +powershell -ExecutionPolicy Bypass -NonInteractive -NoLogo -Command "Set-Item -Path Env:NODE_TLS_REJECT_UNAUTHORIZED -Value 0; ./trilium.exe" GOTO END :BATCH diff --git a/apps/desktop/electron-forge/trilium-portable.bat b/apps/desktop/electron-forge/trilium-portable.bat index b6eeb853f..5b71c9cf2 100644 --- a/apps/desktop/electron-forge/trilium-portable.bat +++ b/apps/desktop/electron-forge/trilium-portable.bat @@ -6,7 +6,7 @@ WHERE powershell.exe > NUL 2>&1 IF %ERRORLEVEL% NEQ 0 GOTO BATCH ELSE GOTO POWERSHELL :POWERSHELL -powershell -ExecutionPolicy Bypass -NonInteractive -NoLogo "Set-Item -Path Env:TRILIUM_DATA_DIR -Value './trilium-data'; ./trilium.exe" +powershell -ExecutionPolicy Bypass -NonInteractive -NoLogo -Command "Set-Item -Path Env:TRILIUM_DATA_DIR -Value './trilium-data'; ./trilium.exe" GOTO END :BATCH diff --git a/apps/desktop/electron-forge/trilium-safe-mode.bat b/apps/desktop/electron-forge/trilium-safe-mode.bat index 7e0fafa99..e112896f7 100644 --- a/apps/desktop/electron-forge/trilium-safe-mode.bat +++ b/apps/desktop/electron-forge/trilium-safe-mode.bat @@ -6,7 +6,7 @@ WHERE powershell.exe > NUL 2>&1 IF %ERRORLEVEL% NEQ 0 GOTO BATCH ELSE GOTO POWERSHELL :POWERSHELL -powershell -ExecutionPolicy Bypass -NonInteractive -NoLogo "Set-Item -Path Env:TRILIUM_SAFE_MODE -Value 1; ./trilium.exe --disable-gpu" +powershell -ExecutionPolicy Bypass -NonInteractive -NoLogo -Command "Set-Item -Path Env:TRILIUM_SAFE_MODE -Value 1; ./trilium.exe --disable-gpu" GOTO END :BATCH diff --git a/apps/server/package.json b/apps/server/package.json index cf021cb6e..93bf2819f 100644 --- a/apps/server/package.json +++ b/apps/server/package.json @@ -36,7 +36,7 @@ "@triliumnext/commons": "workspace:*", "@triliumnext/express-partial-content": "workspace:*", "@triliumnext/turndown-plugin-gfm": "workspace:*", - "@types/archiver": "6.0.4", + "@types/archiver": "7.0.0", "@types/better-sqlite3": "7.6.13", "@types/cls-hooked": "4.3.9", "@types/compression": "1.8.1", @@ -56,17 +56,17 @@ "@types/sanitize-html": "2.16.0", "@types/sax": "1.2.7", "@types/serve-favicon": "2.5.7", - "@types/serve-static": "1.15.10", + "@types/serve-static": "2.2.0", "@types/stream-throttle": "0.1.4", "@types/supertest": "6.0.3", "@types/swagger-ui-express": "4.1.8", "@types/tmp": "0.2.6", - "@types/turndown": "5.0.5", + "@types/turndown": "5.0.6", "@types/ws": "8.18.1", "@types/xml2js": "0.4.14", "archiver": "7.0.1", "async-mutex": "0.5.0", - "axios": "1.12.2", + "axios": "1.13.0", "bindings": "1.5.0", "bootstrap": "5.3.8", "chardet": "2.1.0", diff --git a/apps/website/index.html b/apps/website/index.html index 798ca14f9..55cb4fa6a 100644 --- a/apps/website/index.html +++ b/apps/website/index.html @@ -1,5 +1,5 @@ - + diff --git a/apps/website/package.json b/apps/website/package.json index 14cb094d1..cf27abca5 100644 --- a/apps/website/package.json +++ b/apps/website/package.json @@ -5,6 +5,7 @@ "scripts": { "dev": "vite", "build": "vite build", + "test": "vitest", "preview": "pnpm build && vite preview" }, "dependencies": { @@ -13,7 +14,7 @@ "preact": "10.27.2", "preact-iso": "2.11.0", "preact-render-to-string": "6.6.3", - "react-i18next": "16.2.0" + "react-i18next": "16.2.1" }, "devDependencies": { "@preact/preset-vite": "2.10.2", diff --git a/apps/website/public/collection_presentation.webp b/apps/website/public/collection_presentation.webp new file mode 100644 index 000000000..f7ae75cc3 Binary files /dev/null and b/apps/website/public/collection_presentation.webp differ diff --git a/apps/website/public/translations/de/translation.json b/apps/website/public/translations/de/translation.json deleted file mode 100644 index b696dc66d..000000000 --- a/apps/website/public/translations/de/translation.json +++ /dev/null @@ -1,8 +0,0 @@ -{ - "get-started": { - "title": "Loslegen", - "desktop_title": "Die Desktop-App herunterladen (v{{version}})", - "architecture": "Architektur:", - "older_releases": "Ältere Releases anzeigen" - } -} diff --git a/apps/website/public/translations/tr/translation.json b/apps/website/public/translations/tr/translation.json deleted file mode 100644 index 0967ef424..000000000 --- a/apps/website/public/translations/tr/translation.json +++ /dev/null @@ -1 +0,0 @@ -{} diff --git a/apps/website/src/assets/boxicons/bx-slideshow.svg b/apps/website/src/assets/boxicons/bx-slideshow.svg new file mode 100644 index 000000000..45dbd8251 --- /dev/null +++ b/apps/website/src/assets/boxicons/bx-slideshow.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/apps/website/src/components/Card.tsx b/apps/website/src/components/Card.tsx index 593a9025b..721cf4241 100644 --- a/apps/website/src/components/Card.tsx +++ b/apps/website/src/components/Card.tsx @@ -1,7 +1,7 @@ import { ComponentChildren, HTMLAttributes } from "preact"; import { Link } from "./Button.js"; import Icon from "./Icon.js"; -import { t } from "../i18n.js"; +import { useTranslation } from "react-i18next"; interface CardProps extends Omit, "title"> { title: ComponentChildren; @@ -13,6 +13,8 @@ interface CardProps extends Omit, "title"> { } export default function Card({ title, children, imageUrl, iconSvg, className, moreInfoUrl, ...restProps }: CardProps) { + const { t } = useTranslation(); + return (
{imageUrl && } diff --git a/apps/website/src/components/DownloadButton.tsx b/apps/website/src/components/DownloadButton.tsx index 75fbeff18..883adcdd1 100644 --- a/apps/website/src/components/DownloadButton.tsx +++ b/apps/website/src/components/DownloadButton.tsx @@ -3,18 +3,21 @@ import "./DownloadButton.css"; import Button from "./Button.js"; import downloadIcon from "../assets/boxicons/bx-arrow-in-down-square-half.svg?raw"; import packageJson from "../../../../package.json" with { type: "json" }; -import { useEffect, useState } from "preact/hooks"; -import { t } from "../i18n.js"; +import { useContext, useEffect, useState } from "preact/hooks"; +import { useTranslation } from "react-i18next"; +import { LocaleContext } from "../index.js"; interface DownloadButtonProps { big?: boolean; } export default function DownloadButton({ big }: DownloadButtonProps) { + const locale = useContext(LocaleContext); + const { t } = useTranslation(); const [ recommendedDownload, setRecommendedDownload ] = useState(); useEffect(() => { - getRecommendedDownload()?.then(setRecommendedDownload); - }, []); + getRecommendedDownload(t)?.then(setRecommendedDownload); + }, [ t ]); return (recommendedDownload && <> @@ -35,7 +38,7 @@ export default function DownloadButton({ big }: DownloadButtonProps) { ) : (