diff --git a/.envrc b/.envrc new file mode 100644 index 0000000000..6deccfe3a5 --- /dev/null +++ b/.envrc @@ -0,0 +1,3 @@ +if has nix; then + use flake +fi diff --git a/.github/workflows/main-docker.yml b/.github/workflows/main-docker.yml index e85239bccd..32e4d8ba5c 100644 --- a/.github/workflows/main-docker.yml +++ b/.github/workflows/main-docker.yml @@ -86,12 +86,12 @@ jobs: - name: Upload Playwright trace if: failure() - uses: actions/upload-artifact@v5 + uses: actions/upload-artifact@v6 with: name: Playwright trace (${{ matrix.dockerfile }}) path: test-output/playwright/output - - uses: actions/upload-artifact@v5 + - uses: actions/upload-artifact@v6 if: ${{ !cancelled() }} with: name: Playwright report (${{ matrix.dockerfile }}) @@ -213,7 +213,7 @@ jobs: touch "/tmp/digests/${digest#sha256:}" - name: Upload digest - uses: actions/upload-artifact@v5 + uses: actions/upload-artifact@v6 with: name: digests-${{ env.PLATFORM_PAIR }}-${{ matrix.dockerfile }} path: /tmp/digests/* @@ -227,7 +227,7 @@ jobs: - build steps: - name: Download digests - uses: actions/download-artifact@v6 + uses: actions/download-artifact@v7 with: path: /tmp/digests pattern: digests-* diff --git a/.github/workflows/nightly.yml b/.github/workflows/nightly.yml index bde9a606b3..ac287dc91b 100644 --- a/.github/workflows/nightly.yml +++ b/.github/workflows/nightly.yml @@ -102,7 +102,7 @@ jobs: name: Nightly Build - name: Publish artifacts - uses: actions/upload-artifact@v5 + uses: actions/upload-artifact@v6 if: ${{ github.event_name == 'pull_request' }} with: name: TriliumNotes ${{ matrix.os.name }} ${{ matrix.arch }} diff --git a/.github/workflows/playwright.yml b/.github/workflows/playwright.yml index 5739700977..d529d42587 100644 --- a/.github/workflows/playwright.yml +++ b/.github/workflows/playwright.yml @@ -77,7 +77,7 @@ jobs: - name: Upload test report if: failure() - uses: actions/upload-artifact@v5 + uses: actions/upload-artifact@v6 with: name: e2e report ${{ matrix.arch }} path: apps/server-e2e/test-output diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index eab78541e8..28d45245d0 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -73,7 +73,7 @@ jobs: GPG_SIGNING_KEY: ${{ secrets.GPG_SIGN_KEY }} - name: Upload the artifact - uses: actions/upload-artifact@v5 + uses: actions/upload-artifact@v6 with: name: release-desktop-${{ matrix.os.name }}-${{ matrix.arch }} path: apps/desktop/upload/*.* @@ -100,7 +100,7 @@ jobs: arch: ${{ matrix.arch }} - name: Upload the artifact - uses: actions/upload-artifact@v5 + uses: actions/upload-artifact@v6 with: name: release-server-linux-${{ matrix.arch }} path: upload/*.* @@ -120,7 +120,7 @@ jobs: docs/Release Notes - name: Download all artifacts - uses: actions/download-artifact@v6 + uses: actions/download-artifact@v7 with: merge-multiple: true pattern: release-* diff --git a/.gitignore b/.gitignore index d10c0ec0d7..1d82de1efe 100644 --- a/.gitignore +++ b/.gitignore @@ -44,9 +44,10 @@ upload .rollup.cache *.tsbuildinfo +/.direnv /result .svelte-kit # docs site/ -apps/*/coverage \ No newline at end of file +apps/*/coverage diff --git a/.nvmrc b/.nvmrc index f677377056..1e4f3920b5 100644 --- a/.nvmrc +++ b/.nvmrc @@ -1 +1 @@ -24.11.1 \ No newline at end of file +24.12.0 \ No newline at end of file diff --git a/.vscode/settings.json b/.vscode/settings.json index 2eaee6a3bb..57d22dcb8e 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -37,6 +37,9 @@ "apps/server/src/assets/doc_notes/**": true, "apps/edit-docs/demo/**": true }, + "editor.codeActionsOnSave": { + "source.fixAll.eslint": "explicit" + }, "eslint.rules.customizations": [ { "rule": "*", "severity": "warn" } ] diff --git a/apps/build-docs/package.json b/apps/build-docs/package.json index 8e3329b73e..5a78698437 100644 --- a/apps/build-docs/package.json +++ b/apps/build-docs/package.json @@ -9,13 +9,13 @@ "keywords": [], "author": "Elian Doran ", "license": "AGPL-3.0-only", - "packageManager": "pnpm@10.24.0", + "packageManager": "pnpm@10.26.2", "devDependencies": { - "@redocly/cli": "2.12.3", + "@redocly/cli": "2.14.1", "archiver": "7.0.1", - "fs-extra": "11.3.2", - "react": "19.2.1", - "react-dom": "19.2.1", + "fs-extra": "11.3.3", + "react": "19.2.3", + "react-dom": "19.2.3", "typedoc": "0.28.15", "typedoc-plugin-missing-exports": "4.1.2" } diff --git a/apps/client/package.json b/apps/client/package.json index d055c67c46..91fe674a3c 100644 --- a/apps/client/package.json +++ b/apps/client/package.json @@ -17,12 +17,12 @@ }, "dependencies": { "@excalidraw/excalidraw": "0.18.0", - "@fullcalendar/core": "6.1.19", - "@fullcalendar/daygrid": "6.1.19", - "@fullcalendar/interaction": "6.1.19", - "@fullcalendar/list": "6.1.19", - "@fullcalendar/multimonth": "6.1.19", - "@fullcalendar/timegrid": "6.1.19", + "@fullcalendar/core": "6.1.20", + "@fullcalendar/daygrid": "6.1.20", + "@fullcalendar/interaction": "6.1.20", + "@fullcalendar/list": "6.1.20", + "@fullcalendar/multimonth": "6.1.20", + "@fullcalendar/timegrid": "6.1.20", "@maplibre/maplibre-gl-leaflet": "0.1.3", "@mermaid-js/layout-elk": "0.2.0", "@mind-elixir/node-menu": "5.0.1", @@ -44,7 +44,7 @@ "draggabilly": "3.0.0", "force-graph": "1.51.0", "globals": "16.5.0", - "i18next": "25.7.1", + "i18next": "25.7.3", "i18next-http-backend": "3.0.2", "jquery": "3.7.1", "jquery.fancytree": "2.38.5", @@ -56,11 +56,11 @@ "mark.js": "8.11.1", "marked": "17.0.1", "mermaid": "11.12.2", - "mind-elixir": "5.3.7", + "mind-elixir": "5.3.8", "normalize.css": "8.0.1", "panzoom": "9.4.3", - "preact": "10.28.0", - "react-i18next": "16.4.0", + "preact": "10.28.1", + "react-i18next": "16.5.0", "reveal.js": "5.2.1", "svg-pan-zoom": "3.6.2", "tabulator-tables": "6.3.1", @@ -75,7 +75,7 @@ "@types/leaflet-gpx": "1.3.8", "@types/mark.js": "8.11.12", "@types/reveal.js": "5.2.2", - "@types/tabulator-tables": "6.3.0", + "@types/tabulator-tables": "6.3.1", "copy-webpack-plugin": "13.0.1", "happy-dom": "20.0.11", "script-loader": "0.7.2", diff --git a/apps/client/src/components/app_context.ts b/apps/client/src/components/app_context.ts index 5cd4eecbe0..e0b8c651b6 100644 --- a/apps/client/src/components/app_context.ts +++ b/apps/client/src/components/app_context.ts @@ -1,40 +1,41 @@ -import froca from "../services/froca.js"; -import RootCommandExecutor from "./root_command_executor.js"; -import Entrypoints from "./entrypoints.js"; -import options from "../services/options.js"; -import utils, { hasTouchBar } from "../services/utils.js"; -import zoomComponent from "./zoom.js"; -import TabManager from "./tab_manager.js"; -import Component from "./component.js"; -import keyboardActionsService from "../services/keyboard_actions.js"; -import linkService, { type ViewScope } from "../services/link.js"; -import MobileScreenSwitcherExecutor, { type Screen } from "./mobile_screen_switcher.js"; -import MainTreeExecutors from "./main_tree_executors.js"; -import toast from "../services/toast.js"; -import ShortcutComponent from "./shortcut_component.js"; -import { t, initLocale } from "../services/i18n.js"; -import type { ResolveOptions } from "../widgets/dialogs/delete_notes.js"; -import type { PromptDialogOptions } from "../widgets/dialogs/prompt.js"; -import type { ConfirmWithMessageOptions, ConfirmWithTitleOptions } from "../widgets/dialogs/confirm.js"; -import type LoadResults from "../services/load_results.js"; -import type { Attribute } from "../services/attribute_parser.js"; -import type NoteTreeWidget from "../widgets/note_tree.js"; -import type { default as NoteContext, GetTextEditorCallback } from "./note_context.js"; -import type { NativeImage, TouchBar } from "electron"; -import TouchBarComponent from "./touch_bar.js"; import type { CKTextEditor } from "@triliumnext/ckeditor5"; import type CodeMirror from "@triliumnext/codemirror"; -import { StartupChecks } from "./startup_checks.js"; -import type { CreateNoteOpts } from "../services/note_create.js"; -import { ColumnComponent } from "tabulator-tables"; -import { ChooseNoteTypeCallback } from "../widgets/dialogs/note_type_chooser.jsx"; -import type RootContainer from "../widgets/containers/root_container.js"; import { SqlExecuteResults } from "@triliumnext/commons"; -import { AddLinkOpts } from "../widgets/dialogs/add_link.jsx"; -import { IncludeNoteOpts } from "../widgets/dialogs/include_note.jsx"; +import type { NativeImage, TouchBar } from "electron"; +import { ColumnComponent } from "tabulator-tables"; + +import type { Attribute } from "../services/attribute_parser.js"; +import froca from "../services/froca.js"; +import { initLocale,t } from "../services/i18n.js"; +import keyboardActionsService from "../services/keyboard_actions.js"; +import linkService, { type ViewScope } from "../services/link.js"; +import type LoadResults from "../services/load_results.js"; +import type { CreateNoteOpts } from "../services/note_create.js"; +import options from "../services/options.js"; +import toast from "../services/toast.js"; +import utils, { hasTouchBar } from "../services/utils.js"; import { ReactWrappedWidget } from "../widgets/basic_widget.js"; -import type { MarkdownImportOpts } from "../widgets/dialogs/markdown_import.jsx"; +import type RootContainer from "../widgets/containers/root_container.js"; +import { AddLinkOpts } from "../widgets/dialogs/add_link.jsx"; +import type { ConfirmWithMessageOptions, ConfirmWithTitleOptions } from "../widgets/dialogs/confirm.js"; +import type { ResolveOptions } from "../widgets/dialogs/delete_notes.js"; +import { IncludeNoteOpts } from "../widgets/dialogs/include_note.jsx"; import type { InfoProps } from "../widgets/dialogs/info.jsx"; +import type { MarkdownImportOpts } from "../widgets/dialogs/markdown_import.jsx"; +import { ChooseNoteTypeCallback } from "../widgets/dialogs/note_type_chooser.jsx"; +import type { PromptDialogOptions } from "../widgets/dialogs/prompt.js"; +import type NoteTreeWidget from "../widgets/note_tree.js"; +import Component from "./component.js"; +import Entrypoints from "./entrypoints.js"; +import MainTreeExecutors from "./main_tree_executors.js"; +import MobileScreenSwitcherExecutor, { type Screen } from "./mobile_screen_switcher.js"; +import type { default as NoteContext, GetTextEditorCallback } from "./note_context.js"; +import RootCommandExecutor from "./root_command_executor.js"; +import ShortcutComponent from "./shortcut_component.js"; +import { StartupChecks } from "./startup_checks.js"; +import TabManager from "./tab_manager.js"; +import TouchBarComponent from "./touch_bar.js"; +import zoomComponent from "./zoom.js"; interface Layout { getRootWidget: (appContext: AppContext) => RootContainer; @@ -265,7 +266,7 @@ export type CommandMappings = { reEvaluateRightPaneVisibility: CommandData; runActiveNote: CommandData; - scrollContainerToCommand: CommandData & { + scrollContainerTo: CommandData & { position: number; }; scrollToEnd: CommandData; @@ -447,6 +448,7 @@ type EventMappings = { }; searchRefreshed: { ntxId?: string | null }; textEditorRefreshed: { ntxId?: string | null, editor: CKTextEditor }; + contentElRefreshed: { ntxId?: string | null, contentEl: HTMLElement }; hoistedNoteChanged: { noteId: string; ntxId: string | null; @@ -695,10 +697,8 @@ $(window).on("beforeunload", () => { console.log(`Component ${component.componentId} is not finished saving its state.`); allSaved = false; } - } else { - if (!listener()) { - allSaved = false; - } + } else if (!listener()) { + allSaved = false; } } @@ -708,7 +708,7 @@ $(window).on("beforeunload", () => { } }); -$(window).on("hashchange", function () { +$(window).on("hashchange", () => { const { notePath, ntxId, viewScope, searchString } = linkService.parseNavigationStateFromUrl(window.location.href); if (notePath || ntxId) { diff --git a/apps/client/src/components/component.ts b/apps/client/src/components/component.ts index 9a59b96be6..56c9e7b798 100644 --- a/apps/client/src/components/component.ts +++ b/apps/client/src/components/component.ts @@ -65,8 +65,8 @@ export class TypedComponent> { // don't create promises if not needed (optimization) return callMethodPromise && childrenPromise ? Promise.all([callMethodPromise, childrenPromise]) : callMethodPromise || childrenPromise; - } catch (e: any) { - console.error(`Handling of event '${name}' failed in ${this.constructor.name} with error ${e.message} ${e.stack}`); + } catch (e: unknown) { + console.error(`Handling of event '${name}' failed in ${this.constructor.name} with error`, e); return null; } diff --git a/apps/client/src/components/note_context.ts b/apps/client/src/components/note_context.ts index b360c6fce1..5295007a7d 100644 --- a/apps/client/src/components/note_context.ts +++ b/apps/client/src/components/note_context.ts @@ -1,18 +1,19 @@ -import protectedSessionHolder from "../services/protected_session_holder.js"; -import server from "../services/server.js"; -import utils from "../services/utils.js"; -import appContext, { type EventData, type EventListener } from "./app_context.js"; -import treeService from "../services/tree.js"; -import Component from "./component.js"; -import froca from "../services/froca.js"; -import hoistedNoteService from "../services/hoisted_note.js"; -import options from "../services/options.js"; -import type { ViewScope } from "../services/link.js"; -import type FNote from "../entities/fnote.js"; import type { CKTextEditor } from "@triliumnext/ckeditor5"; import type CodeMirror from "@triliumnext/codemirror"; + +import type FNote from "../entities/fnote.js"; import { closeActiveDialog } from "../services/dialog.js"; +import froca from "../services/froca.js"; +import hoistedNoteService from "../services/hoisted_note.js"; +import type { ViewScope } from "../services/link.js"; +import options from "../services/options.js"; +import protectedSessionHolder from "../services/protected_session_holder.js"; +import server from "../services/server.js"; +import treeService from "../services/tree.js"; +import utils from "../services/utils.js"; import { ReactWrappedWidget } from "../widgets/basic_widget.js"; +import appContext, { type EventData, type EventListener } from "./app_context.js"; +import Component from "./component.js"; export interface SetNoteOpts { triggerSwitchEvent?: unknown; @@ -389,7 +390,7 @@ class NoteContext extends Component implements EventListener<"entitiesReloaded"> * If no content could be determined `null` is returned instead. */ async getContentElement() { - return this.timeout>( + return this.timeout | null>( new Promise((resolve) => appContext.triggerCommand("executeWithContentElement", { resolve, diff --git a/apps/client/src/components/root_command_executor.ts b/apps/client/src/components/root_command_executor.ts index 4a1c987f76..048aa4bd09 100644 --- a/apps/client/src/components/root_command_executor.ts +++ b/apps/client/src/components/root_command_executor.ts @@ -1,14 +1,14 @@ -import Component from "./component.js"; -import appContext, { type CommandData, type CommandListenerData } from "./app_context.js"; import dateNoteService from "../services/date_notes.js"; -import treeService from "../services/tree.js"; -import openService from "../services/open.js"; -import protectedSessionService from "../services/protected_session.js"; -import options from "../services/options.js"; import froca from "../services/froca.js"; -import utils from "../services/utils.js"; -import toastService from "../services/toast.js"; import noteCreateService from "../services/note_create.js"; +import openService from "../services/open.js"; +import options from "../services/options.js"; +import protectedSessionService from "../services/protected_session.js"; +import toastService from "../services/toast.js"; +import treeService from "../services/tree.js"; +import utils, { openInReusableSplit } from "../services/utils.js"; +import appContext, { type CommandListenerData } from "./app_context.js"; +import Component from "./component.js"; export default class RootCommandExecutor extends Component { editReadOnlyNoteCommand() { @@ -193,6 +193,19 @@ export default class RootCommandExecutor extends Component { appContext.triggerEvent("zenModeChanged", { isEnabled }); } + async toggleRibbonTabNoteMapCommand(data: CommandListenerData<"toggleRibbonTabNoteMap">) { + const { isExperimentalFeatureEnabled } = await import("../services/experimental_features.js"); + const isNewLayout = isExperimentalFeatureEnabled("new-layout"); + if (!isNewLayout) { + this.triggerEvent("toggleRibbonTabNoteMap", data); + return; + } + + const activeContext = appContext.tabManager.getActiveContext(); + if (!activeContext?.notePath) return; + openInReusableSplit(activeContext.notePath, "note-map"); + } + firstTabCommand() { this.#goToTab(1); } @@ -262,7 +275,7 @@ export default class RootCommandExecutor extends Component { } catch (e) { console.error("Error creating AI Chat note:", e); - toastService.showError("Failed to create AI Chat note: " + (e as Error).message); + toastService.showError(`Failed to create AI Chat note: ${(e as Error).message}`); } } } diff --git a/apps/client/src/desktop.ts b/apps/client/src/desktop.ts index e77ba845b7..b88eb8d4a9 100644 --- a/apps/client/src/desktop.ts +++ b/apps/client/src/desktop.ts @@ -64,6 +64,9 @@ function initOnElectron() { if (options.get("nativeTitleBarVisible") !== "true") { initTitleBarButtons(style, currentWindow); } + + // Clear navigation history on frontend refresh. + currentWindow.webContents.navigationHistory.clear(); } function initTitleBarButtons(style: CSSStyleDeclaration, currentWindow: Electron.BrowserWindow) { diff --git a/apps/client/src/entities/fnote.ts b/apps/client/src/entities/fnote.ts index 0f6df098a5..f826231b83 100644 --- a/apps/client/src/entities/fnote.ts +++ b/apps/client/src/entities/fnote.ts @@ -1,17 +1,19 @@ -import server from "../services/server.js"; -import noteAttributeCache from "../services/note_attribute_cache.js"; -import protectedSessionHolder from "../services/protected_session_holder.js"; +import { MIME_TYPES_DICT } from "@triliumnext/commons"; + import cssClassManager from "../services/css_class_manager.js"; import type { Froca } from "../services/froca-interface.js"; -import type FAttachment from "./fattachment.js"; -import type { default as FAttribute, AttributeType } from "./fattribute.js"; -import utils from "../services/utils.js"; +import noteAttributeCache from "../services/note_attribute_cache.js"; +import protectedSessionHolder from "../services/protected_session_holder.js"; import search from "../services/search.js"; +import server from "../services/server.js"; +import utils from "../services/utils.js"; +import type FAttachment from "./fattachment.js"; +import type { AttributeType,default as FAttribute } from "./fattribute.js"; const LABEL = "label"; const RELATION = "relation"; -const NOTE_TYPE_ICONS = { +export const NOTE_TYPE_ICONS = { file: "bx bx-file", image: "bx bx-image", code: "bx bx-code", @@ -268,13 +270,12 @@ export default class FNote { } } return results; - } else { - return this.children; } + return this.children; } async getSubtreeNoteIds(includeArchived = false) { - let noteIds: (string | string[])[] = []; + const noteIds: (string | string[])[] = []; for (const child of await this.getChildNotes()) { if (child.isArchived && !includeArchived) continue; @@ -471,9 +472,8 @@ export default class FNote { return a.isHidden ? 1 : -1; } else if (a.isSearch !== b.isSearch) { return a.isSearch ? 1 : -1; - } else { - return a.notePath.length - b.notePath.length; } + return a.notePath.length - b.notePath.length; }); return notePaths; @@ -597,14 +597,13 @@ export default class FNote { } else if (this.type === "text") { if (this.isFolder()) { return "bx bx-folder"; - } else { - return "bx bx-note"; } - } else if (this.type === "code" && this.mime.startsWith("text/x-sql")) { - return "bx bx-data"; - } else { - return NOTE_TYPE_ICONS[this.type]; + return "bx bx-note"; + } else if (this.type === "code") { + const correspondingMimeType = MIME_TYPES_DICT.find(m => m.mime === this.mime); + return correspondingMimeType?.icon ?? NOTE_TYPE_ICONS.code; } + return NOTE_TYPE_ICONS[this.type]; } getColorClass() { @@ -617,7 +616,7 @@ export default class FNote { } getFilteredChildBranches() { - let childBranches = this.getChildBranches(); + const childBranches = this.getChildBranches(); if (!childBranches) { console.error(`No children for '${this.noteId}'. This shouldn't happen.`); @@ -811,9 +810,9 @@ export default class FNote { return this.getLabelValue(nameWithPrefix.substring(1)); } else if (nameWithPrefix.startsWith("~")) { return this.getRelationValue(nameWithPrefix.substring(1)); - } else { - return this.getLabelValue(nameWithPrefix); } + return this.getLabelValue(nameWithPrefix); + } /** @@ -878,10 +877,10 @@ export default class FNote { promotedAttrs.sort((a, b) => { if (a.noteId === b.noteId) { return a.position < b.position ? -1 : 1; - } else { - // inherited promoted attributes should stay grouped: https://github.com/zadam/trilium/issues/3761 - return a.noteId < b.noteId ? -1 : 1; } + // inherited promoted attributes should stay grouped: https://github.com/zadam/trilium/issues/3761 + return a.noteId < b.noteId ? -1 : 1; + }); return promotedAttrs; @@ -993,6 +992,10 @@ export default class FNote { ); } + isJsx() { + return (this.type === "code" && this.mime === "text/jsx"); + } + /** @returns true if this note is HTML */ isHtml() { return (this.type === "code" || this.type === "file" || this.type === "render") && this.mime === "text/html"; @@ -1000,7 +1003,7 @@ export default class FNote { /** @returns JS script environment - either "frontend" or "backend" */ getScriptEnv() { - if (this.isHtml() || (this.isJavaScript() && this.mime.endsWith("env=frontend"))) { + if (this.isHtml() || (this.isJavaScript() && this.mime.endsWith("env=frontend")) || this.isJsx()) { return "frontend"; } @@ -1022,7 +1025,7 @@ export default class FNote { * @returns a promise that resolves when the script has been run. Additionally, for front-end notes, the promise will contain the value that is returned by the script. */ async executeScript() { - if (!this.isJavaScript()) { + if (!(this.isJavaScript() || this.isJsx())) { throw new Error(`Note ${this.noteId} is of type ${this.type} and mime ${this.mime} and thus cannot be executed`); } diff --git a/apps/client/src/layouts/desktop_layout.tsx b/apps/client/src/layouts/desktop_layout.tsx index 50dc05d99e..21760b9a9d 100644 --- a/apps/client/src/layouts/desktop_layout.tsx +++ b/apps/client/src/layouts/desktop_layout.tsx @@ -1,49 +1,59 @@ -import { applyModals } from "./layout_commons.js"; -import { DESKTOP_FLOATING_BUTTONS } from "../widgets/FloatingButtonsDefinitions.jsx"; +import type { AppContext } from "../components/app_context.js"; +import type { WidgetsByParent } from "../services/bundle.js"; +import { isExperimentalFeatureEnabled } from "../services/experimental_features.js"; +import options from "../services/options.js"; +import utils from "../services/utils.js"; import ApiLog from "../widgets/api_log.jsx"; import ClosePaneButton from "../widgets/buttons/close_pane_button.js"; -import CloseZenModeButton from "../widgets/close_zen_button.jsx"; -import ContentHeader from "../widgets/containers/content_header.js"; import CreatePaneButton from "../widgets/buttons/create_pane_button.js"; -import FindWidget from "../widgets/find.js"; -import FlexContainer from "../widgets/containers/flex_container.js"; -import FloatingButtons from "../widgets/FloatingButtons.jsx"; import GlobalMenu from "../widgets/buttons/global_menu.jsx"; -import HighlightsListWidget from "../widgets/highlights_list.js"; -import LeftPaneContainer from "../widgets/containers/left_pane_container.js"; import LeftPaneToggle from "../widgets/buttons/left_pane_toggle.js"; import MovePaneButton from "../widgets/buttons/move_pane_button.js"; -import NoteIconWidget from "../widgets/note_icon.jsx"; +import RightPaneToggle from "../widgets/buttons/right_pane_toggle.jsx"; +import CloseZenModeButton from "../widgets/close_zen_button.jsx"; import NoteList from "../widgets/collections/NoteList.jsx"; -import NoteTitleWidget from "../widgets/note_title.jsx"; -import NoteTreeWidget from "../widgets/note_tree.js"; -import NoteWrapperWidget from "../widgets/note_wrapper.js"; -import options from "../services/options.js"; -import PasswordNoteSetDialog from "../widgets/dialogs/password_not_set.js"; -import QuickSearchWidget from "../widgets/quick_search.js"; -import ReadOnlyNoteInfoBar from "../widgets/ReadOnlyNoteInfoBar.jsx"; -import Ribbon from "../widgets/ribbon/Ribbon.jsx"; +import ContentHeader from "../widgets/containers/content_header.js"; +import FlexContainer from "../widgets/containers/flex_container.js"; +import LeftPaneContainer from "../widgets/containers/left_pane_container.js"; import RightPaneContainer from "../widgets/containers/right_pane_container.js"; import RootContainer from "../widgets/containers/root_container.js"; import ScrollingContainer from "../widgets/containers/scrolling_container.js"; +import SplitNoteContainer from "../widgets/containers/split_note_container.js"; +import PasswordNoteSetDialog from "../widgets/dialogs/password_not_set.js"; +import UploadAttachmentsDialog from "../widgets/dialogs/upload_attachments.js"; +import FindWidget from "../widgets/find.js"; +import FloatingButtons from "../widgets/FloatingButtons.jsx"; +import { DESKTOP_FLOATING_BUTTONS } from "../widgets/FloatingButtonsDefinitions.jsx"; +import HighlightsListWidget from "../widgets/highlights_list.js"; +import LauncherContainer from "../widgets/launch_bar/LauncherContainer.jsx"; +import SpacerWidget from "../widgets/launch_bar/SpacerWidget.jsx"; +import InlineTitle from "../widgets/layout/InlineTitle.jsx"; +import NoteBadges from "../widgets/layout/NoteBadges.jsx"; +import NoteTitleActions from "../widgets/layout/NoteTitleActions.jsx"; +import StatusBar from "../widgets/layout/StatusBar.jsx"; +import NoteIconWidget from "../widgets/note_icon.jsx"; +import NoteTitleWidget from "../widgets/note_title.jsx"; +import NoteTreeWidget from "../widgets/note_tree.js"; +import NoteWrapperWidget from "../widgets/note_wrapper.js"; +import NoteDetail from "../widgets/NoteDetail.jsx"; +import PromotedAttributes from "../widgets/PromotedAttributes.jsx"; +import QuickSearchWidget from "../widgets/quick_search.js"; +import ReadOnlyNoteInfoBar from "../widgets/ReadOnlyNoteInfoBar.jsx"; +import { FixedFormattingToolbar } from "../widgets/ribbon/FormattingToolbar.jsx"; +import NoteActions from "../widgets/ribbon/NoteActions.jsx"; +import Ribbon from "../widgets/ribbon/Ribbon.jsx"; import ScrollPadding from "../widgets/scroll_padding.js"; import SearchResult from "../widgets/search_result.jsx"; import SharedInfo from "../widgets/shared_info.jsx"; -import SplitNoteContainer from "../widgets/containers/split_note_container.js"; +import RightPanelContainer from "../widgets/sidebar/RightPanelContainer.jsx"; import SqlResults from "../widgets/sql_result.js"; import SqlTableSchemas from "../widgets/sql_table_schemas.js"; import TabRowWidget from "../widgets/tab_row.js"; +import TabHistoryNavigationButtons from "../widgets/TabHistoryNavigationButtons.jsx"; import TitleBarButtons from "../widgets/title_bar_buttons.jsx"; import TocWidget from "../widgets/toc.js"; -import type { AppContext } from "../components/app_context.js"; -import type { WidgetsByParent } from "../services/bundle.js"; -import UploadAttachmentsDialog from "../widgets/dialogs/upload_attachments.js"; -import utils from "../services/utils.js"; import WatchedFileUpdateStatusWidget from "../widgets/watched_file_update_status.js"; -import NoteDetail from "../widgets/NoteDetail.jsx"; -import PromotedAttributes from "../widgets/PromotedAttributes.jsx"; -import SpacerWidget from "../widgets/launch_bar/SpacerWidget.jsx"; -import LauncherContainer from "../widgets/launch_bar/LauncherContainer.jsx"; +import { applyModals } from "./layout_commons.js"; export default class DesktopLayout { @@ -69,17 +79,20 @@ export default class DesktopLayout { */ const fullWidthTabBar = launcherPaneIsHorizontal || (isElectron && !hasNativeTitleBar && isMac); const customTitleBarButtons = !hasNativeTitleBar && !isMac && !isWindows; + const isNewLayout = isExperimentalFeatureEnabled("new-layout"); const rootContainer = new RootContainer(true) .setParent(appContext) - .class((launcherPaneIsHorizontal ? "horizontal" : "vertical") + "-layout") + .class(`${launcherPaneIsHorizontal ? "horizontal" : "vertical" }-layout`) .optChild( fullWidthTabBar, new FlexContainer("row") .class("tab-row-container") .child(new FlexContainer("row").id("tab-row-left-spacer")) .optChild(launcherPaneIsHorizontal, ) + .child() .child(new TabRowWidget().class("full-width")) + .optChild(launcherPaneIsHorizontal && isNewLayout, ) .optChild(customTitleBarButtons, ) .css("height", "40px") .css("background-color", "var(--launcher-pane-background-color)") @@ -101,7 +114,17 @@ export default class DesktopLayout { new FlexContainer("column") .id("rest-pane") .css("flex-grow", "1") - .optChild(!fullWidthTabBar, new FlexContainer("row").child(new TabRowWidget()).optChild(customTitleBarButtons, ).css("height", "40px")) + .optChild(!fullWidthTabBar, + new FlexContainer("row") + .class("tab-row-container") + .child() + .child(new TabRowWidget()) + .optChild(isNewLayout, ) + .optChild(customTitleBarButtons, ) + .css("height", "40px") + .css("align-items", "center") + ) + .optChild(isNewLayout, ) .child( new FlexContainer("row") .filling() @@ -115,32 +138,31 @@ export default class DesktopLayout { .child( new SplitNoteContainer(() => new NoteWrapperWidget() - .child( - new FlexContainer("row") - .class("title-row") - .css("height", "50px") - .css("min-height", "50px") - .css("align-items", "center") - .cssBlock(".title-row > * { margin: 5px; }") - .child() - .child() - .child() - .child() - .child() - .child() - .child() - ) - .child() + .child(new FlexContainer("row") + .class("title-row note-split-title") + .cssBlock(".title-row > * { margin: 5px; }") + .child() + .child() + .optChild(isNewLayout, ) + .child() + .optChild(!isNewLayout, ) + .optChild(!isNewLayout, ) + .optChild(!isNewLayout, ) + .optChild(!isNewLayout, ) + .optChild(isNewLayout, )) + .optChild(!isNewLayout, ) .child(new WatchedFileUpdateStatusWidget()) - .child() + .optChild(!isNewLayout, ) .child( new ScrollingContainer() .filling() - .child(new ContentHeader() + .optChild(isNewLayout, ) + .optChild(isNewLayout, ) + .optChild(!isNewLayout, new ContentHeader() .child() .child() ) - .child() + .optChild(!isNewLayout, ) .child() .child() .child() @@ -150,23 +172,24 @@ export default class DesktopLayout { ) .child() .child(new FindWidget()) - .child( - ...this.customWidgets.get("node-detail-pane"), // typo, let's keep it for a while as BC - ...this.customWidgets.get("note-detail-pane") - ) + .child(...this.customWidgets.get("note-detail-pane")) ) ) .child(...this.customWidgets.get("center-pane")) + ) - .child( + .optChild(!isNewLayout, new RightPaneContainer() .child(new TocWidget()) .child(new HighlightsListWidget()) .child(...this.customWidgets.get("right-pane")) ) + .optChild(isNewLayout, ) ) + .optChild(!launcherPaneIsHorizontal && isNewLayout, ) ) ) + .optChild(launcherPaneIsHorizontal && isNewLayout, ) .child() // Desktop-specific dialogs. diff --git a/apps/client/src/layouts/layout_commons.tsx b/apps/client/src/layouts/layout_commons.tsx index 3620d495de..50550ea4b5 100644 --- a/apps/client/src/layouts/layout_commons.tsx +++ b/apps/client/src/layouts/layout_commons.tsx @@ -52,5 +52,5 @@ export function applyModals(rootContainer: RootContainer) { .child() .child() .child() - .child() + .child(); } diff --git a/apps/client/src/menus/link_context_menu.ts b/apps/client/src/menus/link_context_menu.ts index 0799a58aba..607ff6c56a 100644 --- a/apps/client/src/menus/link_context_menu.ts +++ b/apps/client/src/menus/link_context_menu.ts @@ -1,10 +1,11 @@ -import { t } from "../services/i18n.js"; -import contextMenu, { type ContextMenuEvent, type MenuItem } from "./context_menu.js"; +import type { LeafletMouseEvent } from "leaflet"; + import appContext, { type CommandNames } from "../components/app_context.js"; +import { t } from "../services/i18n.js"; import type { ViewScope } from "../services/link.js"; import utils, { isMobile } from "../services/utils.js"; import { getClosestNtxId } from "../widgets/widget_utils.js"; -import type { LeafletMouseEvent } from "leaflet"; +import contextMenu, { type ContextMenuEvent, type MenuItem } from "./context_menu.js"; function openContextMenu(notePath: string, e: ContextMenuEvent, viewScope: ViewScope = {}, hoistedNoteId: string | null = null) { contextMenu.show({ @@ -34,15 +35,21 @@ function handleLinkContextMenuItem(command: string | undefined, e: ContextMenuEv if (command === "openNoteInNewTab") { appContext.tabManager.openContextWithNote(notePath, { hoistedNoteId, viewScope }); + return true; } else if (command === "openNoteInNewSplit") { const ntxId = getNtxId(e); - if (!ntxId) return; + if (!ntxId) return false; appContext.triggerCommand("openNewNoteSplit", { ntxId, notePath, hoistedNoteId, viewScope }); + return true; } else if (command === "openNoteInNewWindow") { appContext.triggerCommand("openInWindow", { notePath, hoistedNoteId, viewScope }); + return true; } else if (command === "openNoteInPopup") { - appContext.triggerCommand("openInPopup", { noteIdOrPath: notePath }) + appContext.triggerCommand("openInPopup", { noteIdOrPath: notePath }); + return true; } + + return false; } function getNtxId(e: ContextMenuEvent | LeafletMouseEvent) { @@ -52,9 +59,9 @@ function getNtxId(e: ContextMenuEvent | LeafletMouseEvent) { return subContexts[subContexts.length - 1].ntxId; } else if (e.target instanceof HTMLElement) { return getClosestNtxId(e.target); - } else { - return null; } + return null; + } export default { diff --git a/apps/client/src/services/bundle.ts b/apps/client/src/services/bundle.ts index e925253ce2..d33ba76a0a 100644 --- a/apps/client/src/services/bundle.ts +++ b/apps/client/src/services/bundle.ts @@ -1,10 +1,15 @@ +import { h, VNode } from "preact"; + +import BasicWidget, { ReactWrappedWidget } from "../widgets/basic_widget.js"; +import RightPanelWidget from "../widgets/right_panel_widget.js"; +import froca from "./froca.js"; +import type { Entity } from "./frontend_script_api.js"; +import { WidgetDefinitionWithType } from "./frontend_script_api_preact.js"; +import { t } from "./i18n.js"; import ScriptContext from "./script_context.js"; import server from "./server.js"; -import toastService, { showError } from "./toast.js"; -import froca from "./froca.js"; -import utils from "./utils.js"; -import { t } from "./i18n.js"; -import type { Entity } from "./frontend_script_api.js"; +import toastService, { showErrorForScriptNote } from "./toast.js"; +import utils, { getErrorMessage } from "./utils.js"; // TODO: Deduplicate with server. export interface Bundle { @@ -14,9 +19,13 @@ export interface Bundle { allNoteIds: string[]; } -interface Widget { +type LegacyWidget = (BasicWidget | RightPanelWidget) & { parentWidget?: string; -} +}; +type WithNoteId = T & { + _noteId: string; +}; +export type Widget = WithNoteId<(LegacyWidget | WidgetDefinitionWithType)>; async function getAndExecuteBundle(noteId: string, originEntity = null, script = null, params = null) { const bundle = await server.post(`script/bundle/${noteId}`, { @@ -27,6 +36,8 @@ async function getAndExecuteBundle(noteId: string, originEntity = null, script = return await executeBundle(bundle, originEntity); } +export type ParentName = "left-pane" | "center-pane" | "note-detail-pane" | "right-pane"; + export async function executeBundle(bundle: Bundle, originEntity?: Entity | null, $container?: JQuery) { const apiContext = await ScriptContext(bundle.noteId, bundle.allNoteIds, originEntity, $container); @@ -35,24 +46,14 @@ export async function executeBundle(bundle: Bundle, originEntity?: Entity | null return eval(`const apiContext = this; (async function() { ${bundle.script}\r\n})()`); }.call(apiContext); } catch (e: any) { - const note = await froca.getNote(bundle.noteId); - toastService.showPersistent({ - id: `custom-script-failure-${note?.noteId}`, - title: t("toast.bundle-error.title"), - icon: "bx bx-error-circle", - message: t("toast.bundle-error.message", { - id: note?.noteId, - title: note?.title, - message: e.message - }) - }); + showErrorForScriptNote(bundle.noteId, t("toast.bundle-error.message", { message: e.message })); logError("Widget initialization failed: ", e); } } async function executeStartupBundles() { const isMobile = utils.isMobile(); - const scriptBundles = await server.get("script/startup" + (isMobile ? "?mobile=true" : "")); + const scriptBundles = await server.get(`script/startup${ isMobile ? "?mobile=true" : ""}`); for (const bundle of scriptBundles) { await executeBundle(bundle); @@ -60,68 +61,99 @@ async function executeStartupBundles() { } export class WidgetsByParent { - private byParent: Record; + private legacyWidgets: Record[]>; + private preactWidgets: Record[]>; constructor() { - this.byParent = {}; + this.legacyWidgets = {}; + this.preactWidgets = {}; } add(widget: Widget) { - if (!widget.parentWidget) { - console.log(`Custom widget does not have mandatory 'parentWidget' property defined`); - return; + let hasParentWidget = false; + let isPreact = false; + if ("type" in widget && widget.type === "preact-widget") { + // React-based script. + const reactWidget = widget as WithNoteId; + this.preactWidgets[reactWidget.parent] = this.preactWidgets[reactWidget.parent] || []; + this.preactWidgets[reactWidget.parent].push(reactWidget); + isPreact = true; + hasParentWidget = !!reactWidget.parent; + } else if ("parentWidget" in widget && widget.parentWidget) { + this.legacyWidgets[widget.parentWidget] = this.legacyWidgets[widget.parentWidget] || []; + this.legacyWidgets[widget.parentWidget].push(widget); + hasParentWidget = !!widget.parentWidget; } - this.byParent[widget.parentWidget] = this.byParent[widget.parentWidget] || []; - this.byParent[widget.parentWidget].push(widget); + if (!hasParentWidget) { + showErrorForScriptNote(widget._noteId, t("toast.widget-missing-parent", { + property: isPreact ? "parent" : "parentWidget" + })); + } } - get(parentName: string) { - if (!this.byParent[parentName]) { - return []; + get(parentName: ParentName) { + const widgets: (BasicWidget | VNode)[] = this.getLegacyWidgets(parentName); + for (const preactWidget of this.getPreactWidgets(parentName)) { + const el = h(preactWidget.render, {}); + const widget = new ReactWrappedWidget(el); + widget.contentSized(); + if (preactWidget.position) { + widget.position = preactWidget.position; + } + widgets.push(widget); } + return widgets; + } + + getLegacyWidgets(parentName: ParentName): (BasicWidget | RightPanelWidget)[] { + if (!this.legacyWidgets[parentName]) return []; + return ( - this.byParent[parentName] + this.legacyWidgets[parentName] // previously, custom widgets were provided as a single instance, but that has the disadvantage // for splits where we actually need multiple instaces and thus having a class to instantiate is better // https://github.com/zadam/trilium/issues/4274 .map((w: any) => (w.prototype ? new w() : w)) ); } + + getPreactWidgets(parentName: ParentName) { + return this.preactWidgets[parentName] ?? []; + } } async function getWidgetBundlesByParent() { - const scriptBundles = await server.get("script/widgets"); - const widgetsByParent = new WidgetsByParent(); - for (const bundle of scriptBundles) { - let widget; + try { + const scriptBundles = await server.get("script/widgets"); - try { - widget = await executeBundle(bundle); - if (widget) { - widget._noteId = bundle.noteId; - widgetsByParent.add(widget); + for (const bundle of scriptBundles) { + let widget; + + try { + widget = await executeBundle(bundle); + if (widget) { + widget._noteId = bundle.noteId; + widgetsByParent.add(widget); + } + } catch (e: any) { + const noteId = bundle.noteId; + showErrorForScriptNote(noteId, t("toast.bundle-error.message", { message: e.message })); + + logError("Widget initialization failed: ", e); + continue; } - } catch (e: any) { - const noteId = bundle.noteId; - const note = await froca.getNote(noteId); - toastService.showPersistent({ - id: `custom-script-failure-${noteId}`, - title: t("toast.bundle-error.title"), - icon: "bx bx-error-circle", - message: t("toast.bundle-error.message", { - id: noteId, - title: note?.title, - message: e.message - }) - }); - - logError("Widget initialization failed: ", e); - continue; } + } catch (e) { + toastService.showPersistent({ + id: `custom-widget-list-failure`, + title: t("toast.widget-list-error.title"), + message: getErrorMessage(e), + icon: "bx bx-error-circle" + }); } return widgetsByParent; diff --git a/apps/client/src/services/experimental_features.ts b/apps/client/src/services/experimental_features.ts new file mode 100644 index 0000000000..d252e2a776 --- /dev/null +++ b/apps/client/src/services/experimental_features.ts @@ -0,0 +1,59 @@ +import { t } from "./i18n"; +import options from "./options"; + +export interface ExperimentalFeature { + id: string; + name: string; + description: string; +} + +export const experimentalFeatures = [ + { + id: "new-layout", + name: t("experimental_features.new_layout_name"), + description: t("experimental_features.new_layout_description"), + } +] as const satisfies ExperimentalFeature[]; + +export type ExperimentalFeatureId = typeof experimentalFeatures[number]["id"]; + +let enabledFeatures: Set | null = null; + +export function isExperimentalFeatureEnabled(featureId: ExperimentalFeatureId): boolean { + if (featureId === "new-layout") { + return options.is("newLayout"); + } + + return getEnabledFeatures().has(featureId); +} + +export function getEnabledExperimentalFeatureIds() { + const values = [ ...getEnabledFeatures().values() ]; + if (options.is("newLayout")) { + values.push("new-layout"); + } + return values; +} + +export async function toggleExperimentalFeature(featureId: ExperimentalFeatureId, enable: boolean) { + const features = new Set(getEnabledFeatures()); + if (enable) { + features.add(featureId); + } else { + features.delete(featureId); + } + await options.save("experimentalFeatures", JSON.stringify(Array.from(features))); +} + +function getEnabledFeatures() { + if (!enabledFeatures) { + let features: ExperimentalFeatureId[] = []; + try { + features = JSON.parse(options.get("experimentalFeatures")) as ExperimentalFeatureId[]; + } catch (e) { + console.warn("Failed to parse experimental features from options:", e); + } + enabledFeatures = new Set(features); + } + return enabledFeatures; +} diff --git a/apps/client/src/services/frontend_script_api.ts b/apps/client/src/services/frontend_script_api.ts index e16670d38d..a76a09d557 100644 --- a/apps/client/src/services/frontend_script_api.ts +++ b/apps/client/src/services/frontend_script_api.ts @@ -1,26 +1,27 @@ -import server from "./server.js"; -import utils from "./utils.js"; -import toastService from "./toast.js"; -import linkService from "./link.js"; +import { dayjs, formatLogMessage } from "@triliumnext/commons"; + +import appContext from "../components/app_context.js"; +import type Component from "../components/component.js"; +import type NoteContext from "../components/note_context.js"; +import type FNote from "../entities/fnote.js"; +import BasicWidget, { ReactWrappedWidget } from "../widgets/basic_widget.js"; +import NoteContextAwareWidget from "../widgets/note_context_aware_widget.js"; +import RightPanelWidget from "../widgets/right_panel_widget.js"; +import dateNotesService from "./date_notes.js"; +import dialogService from "./dialog.js"; import froca from "./froca.js"; +import { preactAPI } from "./frontend_script_api_preact.js"; +import { t } from "./i18n.js"; +import linkService from "./link.js"; import noteTooltipService from "./note_tooltip.js"; import protectedSessionService from "./protected_session.js"; -import dateNotesService from "./date_notes.js"; import searchService from "./search.js"; -import RightPanelWidget from "../widgets/right_panel_widget.js"; -import ws from "./ws.js"; -import appContext from "../components/app_context.js"; -import NoteContextAwareWidget from "../widgets/note_context_aware_widget.js"; -import BasicWidget, { ReactWrappedWidget } from "../widgets/basic_widget.js"; -import SpacedUpdate from "./spaced_update.js"; +import server from "./server.js"; import shortcutService from "./shortcuts.js"; -import dialogService from "./dialog.js"; -import type FNote from "../entities/fnote.js"; -import { t } from "./i18n.js"; -import { dayjs } from "@triliumnext/commons"; -import type NoteContext from "../components/note_context.js"; -import type Component from "../components/component.js"; -import { formatLogMessage } from "@triliumnext/commons"; +import SpacedUpdate from "./spaced_update.js"; +import toastService from "./toast.js"; +import utils from "./utils.js"; +import ws from "./ws.js"; /** * A whole number @@ -464,6 +465,8 @@ export interface Api { * Log given message to the log pane in UI */ log(message: string | object): void; + + preact: typeof preactAPI; } /** @@ -533,9 +536,8 @@ function FrontendScriptApi(this: Api, startNote: FNote, currentNote: FNote, orig return params.map((p) => { if (typeof p === "function") { return `!@#Function: ${p.toString()}`; - } else { - return p; } + return p; }); } @@ -562,9 +564,8 @@ function FrontendScriptApi(this: Api, startNote: FNote, currentNote: FNote, orig await ws.waitForMaxKnownEntityChangeId(); return ret.executionResult; - } else { - throw new Error(`server error: ${ret.error}`); } + throw new Error(`server error: ${ret.error}`); }; this.runOnBackend = async (func, params = []) => { @@ -721,6 +722,8 @@ function FrontendScriptApi(this: Api, startNote: FNote, currentNote: FNote, orig this.logMessages[noteId].push(message); this.logSpacedUpdates[noteId].scheduleUpdate(); }; + + this.preact = preactAPI; } export default FrontendScriptApi as any as { diff --git a/apps/client/src/services/frontend_script_api_preact.ts b/apps/client/src/services/frontend_script_api_preact.ts new file mode 100644 index 0000000000..2829ca101e --- /dev/null +++ b/apps/client/src/services/frontend_script_api_preact.ts @@ -0,0 +1,101 @@ +import { Fragment, h, VNode } from "preact"; +import * as hooks from "preact/hooks"; + +import ActionButton from "../widgets/react/ActionButton"; +import Admonition from "../widgets/react/Admonition"; +import Button from "../widgets/react/Button"; +import CKEditor from "../widgets/react/CKEditor"; +import Collapsible from "../widgets/react/Collapsible"; +import Dropdown from "../widgets/react/Dropdown"; +import FormCheckbox from "../widgets/react/FormCheckbox"; +import FormDropdownList from "../widgets/react/FormDropdownList"; +import { FormFileUploadActionButton, FormFileUploadButton } from "../widgets/react/FormFileUpload"; +import FormGroup from "../widgets/react/FormGroup"; +import { FormDropdownDivider, FormDropdownSubmenu, FormListItem } from "../widgets/react/FormList"; +import FormRadioGroup from "../widgets/react/FormRadioGroup"; +import FormText from "../widgets/react/FormText"; +import FormTextArea from "../widgets/react/FormTextArea"; +import FormTextBox from "../widgets/react/FormTextBox"; +import FormToggle from "../widgets/react/FormToggle"; +import * as triliumHooks from "../widgets/react/hooks"; +import Icon from "../widgets/react/Icon"; +import LinkButton from "../widgets/react/LinkButton"; +import LoadingSpinner from "../widgets/react/LoadingSpinner"; +import Modal from "../widgets/react/Modal"; +import NoteAutocomplete from "../widgets/react/NoteAutocomplete"; +import NoteLink from "../widgets/react/NoteLink"; +import RawHtml from "../widgets/react/RawHtml"; +import Slider from "../widgets/react/Slider"; +import RightPanelWidget from "../widgets/sidebar/RightPanelWidget"; + +export interface WidgetDefinition { + parent: "right-pane", + render: () => VNode, + position?: number, +} + +export interface WidgetDefinitionWithType extends WidgetDefinition { + type: "preact-widget" +} + +export interface LauncherWidgetDefinitionWithType { + type: "preact-launcher-widget" + render: () => VNode +} + +export const preactAPI = Object.freeze({ + // Core + h, + Fragment, + + /** + * Method that must be run for widget scripts that run on Preact, using JSX. The method just returns the same definition, reserved for future typechecking and perhaps validation purposes. + * + * @param definition the widget definition. + */ + defineWidget(definition: WidgetDefinition) { + return { + type: "preact-widget", + ...definition + }; + }, + + defineLauncherWidget(definition: Omit) { + return { + type: "preact-launcher-widget", + ...definition + }; + }, + + // Basic widgets + ActionButton, + Admonition, + Button, + CKEditor, + Collapsible, + Dropdown, + FormCheckbox, + FormDropdownList, + FormFileUploadButton, FormFileUploadActionButton, + FormGroup, + FormListItem, FormDropdownDivider, FormDropdownSubmenu, + FormRadioGroup, + FormText, + FormTextArea, + FormTextBox, + FormToggle, + Icon, + LinkButton, + LoadingSpinner, + Modal, + NoteAutocomplete, + NoteLink, + RawHtml, + Slider, + + // Specialized widgets + RightPanelWidget, + + ...hooks, + ...triliumHooks +}); diff --git a/apps/client/src/services/link.ts b/apps/client/src/services/link.ts index a596e71366..b74dd5f7b1 100644 --- a/apps/client/src/services/link.ts +++ b/apps/client/src/services/link.ts @@ -1,10 +1,11 @@ -import treeService from "./tree.js"; -import linkContextMenuService from "../menus/link_context_menu.js"; -import appContext, { type NoteCommandData } from "../components/app_context.js"; -import froca from "./froca.js"; -import utils from "./utils.js"; import { ALLOWED_PROTOCOLS } from "@triliumnext/commons"; + +import appContext, { type NoteCommandData } from "../components/app_context.js"; import { openInCurrentNoteContext } from "../components/note_context.js"; +import linkContextMenuService from "../menus/link_context_menu.js"; +import froca from "./froca.js"; +import treeService from "./tree.js"; +import utils from "./utils.js"; function getNotePathFromUrl(url: string) { const notePathMatch = /#(root[A-Za-z0-9_/]*)$/.exec(url); @@ -27,7 +28,7 @@ async function getLinkIcon(noteId: string, viewMode: ViewMode | undefined) { return icon; } -export type ViewMode = "default" | "source" | "attachments" | "contextual-help"; +export type ViewMode = "default" | "source" | "attachments" | "contextual-help" | "note-map"; export interface ViewScope { /** @@ -99,7 +100,7 @@ async function createLink(notePath: string | undefined, options: CreateLinkOptio const viewMode = viewScope.viewMode || "default"; let linkTitle = options.title; - if (!linkTitle) { + if (linkTitle === undefined) { if (viewMode === "attachments" && viewScope.attachmentId) { const attachment = await froca.getAttachment(viewScope.attachmentId); @@ -122,7 +123,7 @@ async function createLink(notePath: string | undefined, options: CreateLinkOptio const $container = $(""); if (showNoteIcon) { - let icon = await getLinkIcon(noteId, viewMode); + const icon = await getLinkIcon(noteId, viewMode); if (icon) { $container.append($("").addClass(`bx ${icon}`)).append(" "); @@ -131,7 +132,7 @@ async function createLink(notePath: string | undefined, options: CreateLinkOptio const hash = calculateHash({ notePath, - viewScope: viewScope + viewScope }); const $noteLink = $("", { @@ -171,11 +172,11 @@ async function createLink(notePath: string | undefined, options: CreateLinkOptio return $container; } -function calculateHash({ notePath, ntxId, hoistedNoteId, viewScope = {} }: NoteCommandData) { +export function calculateHash({ notePath, ntxId, hoistedNoteId, viewScope = {} }: NoteCommandData) { notePath = notePath || ""; const params = [ - ntxId ? { ntxId: ntxId } : null, - hoistedNoteId && hoistedNoteId !== "root" ? { hoistedNoteId: hoistedNoteId } : null, + ntxId ? { ntxId } : null, + hoistedNoteId && hoistedNoteId !== "root" ? { hoistedNoteId } : null, viewScope.viewMode && viewScope.viewMode !== "default" ? { viewMode: viewScope.viewMode } : null, viewScope.attachmentId ? { attachmentId: viewScope.attachmentId } : null ].filter((p) => !!p); @@ -219,7 +220,7 @@ export function parseNavigationStateFromUrl(url: string | undefined) { } const hash = url.substr(hashIdx + 1); // strip also the initial '#' - let [notePath, paramString] = hash.split("?"); + const [notePath, paramString] = hash.split("?"); const viewScope: ViewScope = { viewMode: "default" @@ -252,7 +253,7 @@ export function parseNavigationStateFromUrl(url: string | undefined) { } if (searchString) { - return { searchString } + return { searchString }; } if (!notePath.match(/^[_a-z0-9]{4,}(\/[_a-z0-9]{4,})*$/i)) { @@ -334,7 +335,7 @@ export function goToLinkExt(evt: MouseEvent | JQuery.ClickEvent | JQuery.MouseDo window.open(hrefLink, "_blank"); } else { // Enable protocols supported by CKEditor 5 to be clickable. - if (ALLOWED_PROTOCOLS.some((protocol) => hrefLink.toLowerCase().startsWith(protocol + ":"))) { + if (ALLOWED_PROTOCOLS.some((protocol) => hrefLink.toLowerCase().startsWith(`${protocol}:`))) { if ( utils.isElectron()) { const electron = utils.dynamicRequire("electron"); electron.shell.openExternal(hrefLink); @@ -395,7 +396,7 @@ async function loadReferenceLinkTitle($el: JQuery, href: string | n href = href || $link.attr("href"); if (!href) { - console.warn("Empty URL for parsing: " + $el[0].outerHTML); + console.warn(`Empty URL for parsing: ${$el[0].outerHTML}`); return; } @@ -438,9 +439,9 @@ async function getReferenceLinkTitle(href: string) { const attachment = await note.getAttachmentById(viewScope.attachmentId); return attachment ? attachment.title : "[missing attachment]"; - } else { - return note.title; } + return note.title; + } function getReferenceLinkTitleSync(href: string) { @@ -462,9 +463,9 @@ function getReferenceLinkTitleSync(href: string) { const attachment = note.attachments.find((att) => att.attachmentId === viewScope.attachmentId); return attachment ? attachment.title : "[missing attachment]"; - } else { - return note.title; } + return note.title; + } if (glob.device !== "print") { diff --git a/apps/client/src/services/render.ts b/apps/client/src/services/render.ts index bec5cb5148..adfd8a4949 100644 --- a/apps/client/src/services/render.ts +++ b/apps/client/src/services/render.ts @@ -1,6 +1,10 @@ -import server from "./server.js"; -import bundleService, { type Bundle } from "./bundle.js"; +import { h, VNode } from "preact"; + import type FNote from "../entities/fnote.js"; +import { renderReactWidgetAtElement } from "../widgets/react/react_utils.jsx"; +import bundleService, { type Bundle } from "./bundle.js"; +import froca from "./froca.js"; +import server from "./server.js"; async function render(note: FNote, $el: JQuery) { const relations = note.getRelations("renderNote"); @@ -17,12 +21,34 @@ async function render(note: FNote, $el: JQuery) { $scriptContainer.append(bundle.html); // async so that scripts cannot block trilium execution - bundleService.executeBundle(bundle, note, $scriptContainer); + bundleService.executeBundle(bundle, note, $scriptContainer).then(result => { + // Render JSX + if (bundle.html === "") { + renderIfJsx(bundle, result, $el); + } + }); } return renderNoteIds.length > 0; } +async function renderIfJsx(bundle: Bundle, result: unknown, $el: JQuery) { + // Ensure the root script note is actually a JSX. + const rootScriptNoteId = await froca.getNote(bundle.noteId); + if (rootScriptNoteId?.mime !== "text/jsx") return; + + // Ensure the output is a valid el. + if (typeof result !== "function") return; + + // Obtain the parent component. + const closestComponent = glob.getComponentByEl($el.closest(".component")[0]); + if (!closestComponent) return; + + // Render the element. + const el = h(result as () => VNode, {}); + renderReactWidgetAtElement(closestComponent, el, $el[0]); +} + export default { render }; diff --git a/apps/client/src/services/server.ts b/apps/client/src/services/server.ts index 978aa91ab9..b13653cf3e 100644 --- a/apps/client/src/services/server.ts +++ b/apps/client/src/services/server.ts @@ -133,11 +133,11 @@ async function call(method: string, url: string, componentId?: string, option }; ipc.send("server-request", { - requestId: requestId, - headers: headers, - method: method, + requestId, + headers, + method, url: `/${window.glob.baseApiUrl}${url}`, - data: data + data }); })) as any; } else { @@ -161,7 +161,7 @@ function ajax(url: string, method: string, data: unknown, headers: Headers, sile const options: JQueryAjaxSettings = { url: window.glob.baseApiUrl + url, type: method, - headers: headers, + headers, timeout: 60000, success: (body, textStatus, jqXhr) => { const respHeaders: Headers = {}; @@ -288,8 +288,8 @@ async function reportError(method: string, url: string, statusCode: number, resp t("server.unknown_http_error_content", { statusCode, method, url, message: messageStr }), 15_000); } - const { throwError } = await import("./ws.js"); - throwError(`${statusCode} ${method} ${url} - ${message}`); + const { logError } = await import("./ws.js"); + logError(`${statusCode} ${method} ${url} - ${message}`); } } diff --git a/apps/client/src/services/toast.ts b/apps/client/src/services/toast.ts index 3e81bf6e1b..f31e242cdd 100644 --- a/apps/client/src/services/toast.ts +++ b/apps/client/src/services/toast.ts @@ -1,5 +1,8 @@ import { signal } from "@preact/signals"; +import appContext from "../components/app_context.js"; +import froca from "./froca.js"; +import { t } from "./i18n.js"; import utils from "./utils.js"; export interface ToastOptions { @@ -61,6 +64,24 @@ function showErrorTitleAndMessage(title: string, message: string, timeout = 1000 }); } +export async function showErrorForScriptNote(noteId: string, message: string) { + const note = await froca.getNote(noteId, true); + + showPersistent({ + id: `custom-widget-failure-${noteId}`, + title: t("toast.scripting-error", { title: note?.title ?? "" }), + icon: note?.getIcon() ?? "bx bx-error-circle", + message, + timeout: 15_000, + buttons: [ + { + text: t("toast.open-script-note"), + onClick: () => appContext.tabManager.openInNewTab(noteId, null, true) + } + ] + }); +} + //#region Toast store export const toasts = signal([]); @@ -74,7 +95,7 @@ function addToast(opts: ToastOptions) { function updateToast(id: string, partial: Partial) { toasts.value = toasts.value.map(toast => { if (toast.id === id) { - return { ...toast, ...partial } + return { ...toast, ...partial }; } return toast; }); diff --git a/apps/client/src/services/tree.ts b/apps/client/src/services/tree.ts index cfa210600b..00e88cf6d6 100644 --- a/apps/client/src/services/tree.ts +++ b/apps/client/src/services/tree.ts @@ -4,6 +4,8 @@ import froca from "./froca.js"; import hoistedNoteService from "./hoisted_note.js"; import appContext from "../components/app_context.js"; +export const NOTE_PATH_TITLE_SEPARATOR = " › "; + async function resolveNotePath(notePath: string, hoistedNoteId = "root") { const runPath = await resolveNotePathToSegments(notePath, hoistedNoteId); @@ -254,7 +256,7 @@ async function getNotePathTitle(notePath: string) { const titlePath = await getNotePathTitleComponents(notePath); - return titlePath.join(" / "); + return titlePath.join(NOTE_PATH_TITLE_SEPARATOR); } async function getNoteTitleWithPathAsSuffix(notePath: string) { diff --git a/apps/client/src/services/utils.ts b/apps/client/src/services/utils.ts index 2c999690d4..8c2a12c6ac 100644 --- a/apps/client/src/services/utils.ts +++ b/apps/client/src/services/utils.ts @@ -1,5 +1,5 @@ import { dayjs } from "@triliumnext/commons"; -import type { ViewScope } from "./link.js"; +import type { ViewMode, ViewScope } from "./link.js"; import FNote from "../entities/fnote"; import { snapdom } from "@zumer/snapdom"; @@ -439,7 +439,20 @@ async function openInAppHelp($button: JQuery) { * @param inAppHelpPage the ID of the help note (excluding the `_help_` prefix). * @returns a promise that resolves once the help has been opened. */ -export async function openInAppHelpFromUrl(inAppHelpPage: string) { +export function openInAppHelpFromUrl(inAppHelpPage: string) { + return openInReusableSplit(`_help_${inAppHelpPage}`, "contextual-help"); +} + +/** + * Similar to opening a new note in a split, but re-uses an existing split if there is already one open with the same view mode. + * + * @param targetNoteId the note ID to open in the split. + * @param targetViewMode the view mode of the split to open the note in. + * @param openOpts additional options for opening the note. + */ +export async function openInReusableSplit(targetNoteId: string, targetViewMode: ViewMode, openOpts: { + hoistedNoteId?: string; +} = {}) { // Dynamic import to avoid import issues in tests. const appContext = (await import("../components/app_context.js")).default; const activeContext = appContext.tabManager.getActiveContext(); @@ -447,23 +460,20 @@ export async function openInAppHelpFromUrl(inAppHelpPage: string) { return; } const subContexts = activeContext.getSubContexts(); - const targetNote = `_help_${inAppHelpPage}`; - const helpSubcontext = subContexts.find((s) => s.viewScope?.viewMode === "contextual-help"); - const viewScope: ViewScope = { - viewMode: "contextual-help", - }; - if (!helpSubcontext) { - // The help is not already open, open a new split with it. + const existingSubcontext = subContexts.find((s) => s.viewScope?.viewMode === targetViewMode); + const viewScope: ViewScope = { viewMode: targetViewMode }; + if (!existingSubcontext) { + // The target split is not already open, open a new split with it. const { ntxId } = subContexts[subContexts.length - 1]; appContext.triggerCommand("openNewNoteSplit", { ntxId, - notePath: targetNote, - hoistedNoteId: "_help", + notePath: targetNoteId, + hoistedNoteId: openOpts.hoistedNoteId, viewScope - }) + }); } else { - // There is already a help window open, make sure it opens on the right note. - helpSubcontext.setNote(targetNote, { viewScope }); + // There is already a target split open, make sure it opens on the right note. + existingSubcontext.setNote(targetNoteId, { viewScope }); } } diff --git a/apps/client/src/stylesheets/style.css b/apps/client/src/stylesheets/style.css index f2f5546296..d3a4deeda0 100644 --- a/apps/client/src/stylesheets/style.css +++ b/apps/client/src/stylesheets/style.css @@ -24,8 +24,8 @@ --bs-body-font-family: var(--main-font-family) !important; --bs-body-font-weight: var(--main-font-weight) !important; --bs-body-color: var(--main-text-color) !important; - --bs-body-bg: var(--main-background-color) !important; - --ck-mention-list-max-height: 500px; + --bs-body-bg: var(--main-background-color) !important; + --ck-mention-list-max-height: 500px; --tn-modal-max-height: 90vh; --tree-item-light-theme-max-color-lightness: 50; @@ -423,16 +423,16 @@ body.desktop .tabulator-popup-container, pointer-events: none; } -.dropdown-menu .disabled .disabled-tooltip { +.dropdown-menu .disabled .contextual-help { pointer-events: all; margin-inline-start: 8px; font-size: 0.75rem; - color: var(--disabled-tooltip-icon-color); + color: var(--contextual-help-icon-color); cursor: help; opacity: 0.75; } -.dropdown-menu .disabled .disabled-tooltip:hover { +.dropdown-menu .disabled .contextual-help:hover { opacity: 1; } @@ -458,6 +458,7 @@ body.desktop .tabulator-popup-container, } body.desktop .dropdown-menu:not(#context-menu-container) .dropdown-item, +body.desktop .dropdown-menu .dropdown-toggle, body #context-menu-container .dropdown-item > span, body.mobile .dropdown .dropdown-submenu > span { display: flex; @@ -471,7 +472,7 @@ body.mobile .dropdown .dropdown-submenu > span { padding-inline-start: 12px; } -.dropdown-menu kbd { +.dropdown-menu kbd { color: var(--muted-text-color); border: none; background-color: transparent; @@ -487,7 +488,7 @@ body.mobile .dropdown .dropdown-submenu > span { border: 1px solid transparent !important; } -/* This is a workaround for Firefox not supporting break-before / break-after: avoid on columns. +/* This is a workaround for Firefox not supporting break-before / break-after: avoid on columns. * It usually wraps a menu item followed by a separator / header and another menu item. */ .dropdown-no-break { break-inside: avoid; @@ -521,9 +522,7 @@ body.mobile .dropdown .dropdown-submenu > span { .cm-editor { height: 100%; outline: none !important; - border-radius: 6px; overflow: hidden; - margin: 4px; font-size: var(--monospace-font-size); } @@ -629,6 +628,11 @@ pre:not(.hljs) { padding: var(--padding-size); } +pre:has(> .cm-editor) { + padding: 0; + margin: 0; +} + pre > button.copy-button { position: absolute; top: var(--copy-button-margin-size); @@ -720,6 +724,10 @@ table.promoted-attributes-in-tooltip th { z-index: 32767 !important; } +.pre-wrap-text { + white-space: pre-wrap; +} + .bs-tooltip-bottom .tooltip-arrow::before { border-bottom-color: var(--main-border-color) !important; } @@ -1315,12 +1323,21 @@ body.desktop li.dropdown-submenu:hover > ul.dropdown-menu { top: 0; inset-inline-start: calc(100% - 2px); /* -2px, otherwise there's a small gap between menu and submenu where the hover can disappear */ margin-top: -10px; - min-width: 15rem; /* to make submenu scrollable https://github.com/zadam/trilium/issues/3136 */ max-height: 600px; overflow: auto; } +body.desktop .dropdown-submenu > .dropdown-menu { + min-width: max-content; + max-width: 300px; +} + +.dropdown-submenu.dropstart > .dropdown-menu { + inset-inline-start: auto; + inset-inline-end: calc(100% - 2px); +} + body:not(.mobile) #launcher-pane.horizontal .dropdown-submenu > .dropdown-menu { inset-inline-start: calc(-100% + 10px); } @@ -1367,6 +1384,10 @@ body:not(.mobile) #launcher-pane.horizontal .dropdown-submenu > .dropdown-menu { background-color: var(--scrollbar-background-color); } +::-webkit-scrollbar-button { + display: none; +} + ::-webkit-scrollbar-corner { background-color: inherit; } @@ -1591,7 +1612,7 @@ body:not(.mobile) #launcher-pane.horizontal .dropdown-submenu > .dropdown-menu { inset-inline-start: 0; inset-inline-end: 0; margin: 0 !important; - max-height: 85vh; + max-height: 85vh; display: flex; } @@ -1940,7 +1961,7 @@ body.electron.platform-darwin:not(.native-titlebar):not(.full-screen) #tab-row-l width: 80px; } -.tab-row-widget { +.tab-row-container { padding-inline-end: calc(100vw - env(titlebar-area-width, 100vw)); } @@ -1991,8 +2012,10 @@ body.zen .shared-info-widget, body.zen .ribbon-container:not(:has(.classic-toolbar-widget)), body.zen .ribbon-container:has(.classic-toolbar-widget) .ribbon-top-row, body.zen .ribbon-container .ribbon-body:not(:has(.classic-toolbar-widget)), -body.zen .note-icon-widget, body.zen .title-row .icon-action, +body.zen .note-badges > *:not(.read-only-badge), +body.zen .ribbon-button-container, +body.zen .inline-title, body.zen .promoted-attributes-widget, body.zen .floating-buttons-children > *:not(.bx-edit-alt), body.zen .action-button, @@ -2015,11 +2038,11 @@ body.zen #launcher-pane { } body.zen .title-row { - display: block !important; height: unset !important; -webkit-app-region: drag; padding-inline-start: env(titlebar-area-x); padding-inline-end: calc(100vw - env(titlebar-area-width, 100vw) + 2.5em); + border-bottom: none !important; } body.zen .floating-buttons { @@ -2039,8 +2062,6 @@ body.zen .floating-buttons-children .button-widget { body.zen .note-title-widget, body.zen .note-title-widget input { font-size: 1rem !important; - background: transparent !important; - pointer-events: none; } body.zen #detail-container { @@ -2093,65 +2114,114 @@ body.zen .note-split.type-text .scrolling-container { body.zen:not(.backdrop-effects-disabled) .note-split.type-text .scrolling-container { --padding-top: 50px; /* Should be enough to cover the title row */ - + padding-top: var(--padding-top); scroll-padding-top: var(--padding-top); } /* Fixed formatting toolbar */ -body.zen .note-split .ribbon-container { - position: fixed; - left: 0; - bottom: 20px; - width: 100%; - z-index: 1000; - opacity: 0; /* Hidden unless the current note split is focused */ - pointer-events: none; - transition: opacity 100ms linear; -} - -body.zen .note-split:focus-within .ribbon-container { - opacity: 1; /* Show when the note split is focused */ -} - -body.zen .note-split .ribbon-container .ribbon-body { - border: 0; -} - -body.zen .note-split .ribbon-container .classic-toolbar-widget { - margin: auto; - width: fit-content; - box-shadow: 0px 10px 20px rgba(0, 0, 0, .1); - border-radius: 8px; - border: 1px solid var(--main-border-color); - padding: 4px; - background: var(--menu-background-color); -} - -body.zen .note-split .ribbon-container .classic-toolbar-widget:not(:has(> .ck-toolbar)) { - /* Hide the toolbar wrapper if the toolbar is missing */ - display: none; -} - -body.zen .note-split:focus-within .ribbon-container .classic-toolbar-widget { - pointer-events: all; -} - -@media (max-width: 1300px) { - body.zen .note-split .ribbon-container .classic-toolbar-widget { - /* Set the toolbar to full with */ +body.zen:not(.experimental-feature-new-layout) { + .note-split .ribbon-container { + position: fixed; + left: 0; + bottom: 20px; width: 100%; + z-index: 1000; + opacity: 0; /* Hidden unless the current note split is focused */ + pointer-events: none; + transition: opacity 100ms linear; } - body.zen .classic-toolbar-widget .ck.ck-dropdown .ck-dropdown__panel.ck-dropdown__panel_se, - body.zen .classic-toolbar-widget .ck.ck-dropdown .ck-dropdown__panel.ck-dropdown__panel_sw, - body.zen .classic-toolbar-widget .ck.ck-dropdown .ck-dropdown__panel.ck-dropdown__panel_smw, - body.zen .classic-toolbar-widget .ck.ck-dropdown .ck-dropdown__panel.ck-dropdown__panel_sme, - body.zen .classic-toolbar-widget .ck.ck-dropdown .ck-dropdown__panel.ck-dropdown__panel_s { - /* Force toolbar items overflow dropdowns open upwards */ - top: auto; - bottom: 100%; + .note-split:focus-within .ribbon-container { + opacity: 1; /* Show when the note split is focused */ + } + + .note-split .ribbon-container .ribbon-body { + border: 0; + } + + .note-split .ribbon-container .classic-toolbar-widget { + margin: auto; + width: fit-content; + box-shadow: 0px 10px 20px rgba(0, 0, 0, .1); + border-radius: 8px; + border: 1px solid var(--main-border-color); + padding: 4px; + background: var(--menu-background-color); + } + + .note-split .ribbon-container .classic-toolbar-widget:not(:has(> .ck-toolbar)) { + /* Hide the toolbar wrapper if the toolbar is missing */ + display: none; + } + + .note-split:focus-within .ribbon-container .classic-toolbar-widget { + pointer-events: all; + } + + @media (max-width: 1300px) { + .note-split .ribbon-container .classic-toolbar-widget { + /* Set the toolbar to full with */ + width: 100%; + } + + .classic-toolbar-widget .ck.ck-dropdown .ck-dropdown__panel.ck-dropdown__panel_se, + .classic-toolbar-widget .ck.ck-dropdown .ck-dropdown__panel.ck-dropdown__panel_sw, + .classic-toolbar-widget .ck.ck-dropdown .ck-dropdown__panel.ck-dropdown__panel_smw, + .classic-toolbar-widget .ck.ck-dropdown .ck-dropdown__panel.ck-dropdown__panel_sme, + .classic-toolbar-widget .ck.ck-dropdown .ck-dropdown__panel.ck-dropdown__panel_s { + /* Force toolbar items overflow dropdowns open upwards */ + top: auto; + bottom: 100%; + } + } +} + +body.zen.experimental-feature-new-layout { + .status-bar { + display: none; + } + + .classic-toolbar-widget { + position: fixed; + left: 50%; + bottom: 20px; + z-index: 1000; + opacity: 0; /* Hidden unless the current note split is focused */ + pointer-events: none; + transition: opacity 100ms linear; + width: fit-content; + box-shadow: 0px 10px 20px rgba(0, 0, 0, .1); + border-radius: 8px; + border: 1px solid var(--main-border-color); + padding: 4px; + background: var(--menu-background-color) !important; + transform: translateX(-50%); + backdrop-filter: blur(6px); + } + + #root-widget:has(.note-split.type-text:focus-within) .classic-toolbar-widget, + .classic-toolbar-widget:focus-within { + opacity: 1; /* Show when the note split is focused */ + pointer-events: all; + } + + @media (max-width: 1300px) { + .classic-toolbar-widget { + /* Set the toolbar to full with */ + width: 100%; + } + + .classic-toolbar-widget .ck.ck-dropdown .ck-dropdown__panel.ck-dropdown__panel_se, + .classic-toolbar-widget .ck.ck-dropdown .ck-dropdown__panel.ck-dropdown__panel_sw, + .classic-toolbar-widget .ck.ck-dropdown .ck-dropdown__panel.ck-dropdown__panel_smw, + .classic-toolbar-widget .ck.ck-dropdown .ck-dropdown__panel.ck-dropdown__panel_sme, + .classic-toolbar-widget .ck.ck-dropdown .ck-dropdown__panel.ck-dropdown__panel_s { + /* Force toolbar items overflow dropdowns open upwards */ + top: auto; + bottom: 100%; + } } } @@ -2365,7 +2435,7 @@ footer.webview-footer button { margin-bottom: 0; } -.admonition::before { +.admonition::before { color: var(--accent-color); font-family: boxicons !important; position: absolute; @@ -2391,7 +2461,7 @@ footer.webview-footer button { .ck-content ul.todo-list li:has(> span.todo-list__label input[type="checkbox"]:checked) > span.todo-list__label span.todo-list__label__description { text-decoration: line-through; - opacity: 0.6; + opacity: 0.6; } .chat-options-container { @@ -2458,6 +2528,11 @@ footer.webview-footer button { inset-inline-start: 10px; } +.content-floating-buttons.top-right { + top: 10px; + inset-inline-end: 10px; +} + .content-floating-buttons.bottom-left { bottom: 10px; inset-inline-start: 10px; @@ -2524,6 +2599,7 @@ iframe.print-iframe { position: relative; flex-grow: 1; width: 100%; + overflow: hidden; } /* Calendar collection */ @@ -2538,7 +2614,7 @@ iframe.print-iframe { body.mobile { .split-note-container-widget { flex-direction: column !important; - + .note-split { width: 100%; } @@ -2553,4 +2629,10 @@ iframe.print-iframe { opacity: 0.4; } } -} \ No newline at end of file +} + +body.desktop .title-row { + height: 50px; + min-height: 50px; + align-items: center; +} diff --git a/apps/client/src/stylesheets/theme-dark.css b/apps/client/src/stylesheets/theme-dark.css index 6912533fa6..84fc30db6b 100644 --- a/apps/client/src/stylesheets/theme-dark.css +++ b/apps/client/src/stylesheets/theme-dark.css @@ -19,7 +19,7 @@ --dropdown-border-color: #555; --dropdown-shadow-opacity: 0.4; --dropdown-item-icon-destructive-color: #de6e5b; - --disabled-tooltip-icon-color: #7fd2ef; + --contextual-help-icon-color: #7fd2ef; --accented-background-color: #555; --more-accented-background-color: #777; diff --git a/apps/client/src/stylesheets/theme-light.css b/apps/client/src/stylesheets/theme-light.css index 97bb386fa8..34c4e8b4b5 100644 --- a/apps/client/src/stylesheets/theme-light.css +++ b/apps/client/src/stylesheets/theme-light.css @@ -23,7 +23,7 @@ html { --dropdown-border-color: #ccc; --dropdown-shadow-opacity: 0.2; --dropdown-item-icon-destructive-color: #ec5138; - --disabled-tooltip-icon-color: #004382; + --contextual-help-icon-color: #004382; --accented-background-color: #f5f5f5; --more-accented-background-color: #ddd; @@ -89,17 +89,20 @@ html { --custom-color: var(--light-theme-custom-color); } -:root .reference-link, -:root .reference-link:hover, -.ck-content a.reference-link > span, -.board-note { +:root .reference-link.use-note-color, +:root .reference-link.use-note-color:hover, +.ck-content a.reference-link.use-note-color > span, +.board-note.use-note-color { color: var(--light-theme-custom-color, inherit); } .use-note-color { --custom-color: var(--light-theme-custom-color); } +<<<<<<< HEAD span.fancytree-active { color: var(--custom-color, var(--active-item-text-color)); } +======= +>>>>>>> a47ea0d653757e0336f693072bc1cd7df6772f9f diff --git a/apps/client/src/stylesheets/theme-next-dark.css b/apps/client/src/stylesheets/theme-next-dark.css index 8358de09bf..d7865d757b 100644 --- a/apps/client/src/stylesheets/theme-next-dark.css +++ b/apps/client/src/stylesheets/theme-next-dark.css @@ -6,7 +6,7 @@ */ :root { - /* + /* * ⚠️ NOTICE: This theme is currently in the beta stage of development. * The names and purposes of these CSS variables are subject to frequent changes. */ @@ -21,8 +21,8 @@ --subtle-border-color: #313131; --dropdown-border-color: #404040; --dropdown-shadow-opacity: 0.6; - --dropdown-item-icon-destructive-color: #de6e5b; - --disabled-tooltip-icon-color: #7fd2ef; + --dropdown-item-icon-destructive-color: #d58477; + --contextual-help-icon-color: #7fd2ef; --accented-background-color: #555; @@ -74,11 +74,13 @@ --select-arrow-svg: url("data:image/svg+xml,"); --select-group-heading-text-color: gray; - --link-hover-background: #ffffff26; - --link-hover-color: white; + --link-color: #95c3d9; + --link-hover-background: #75c2e324; + --link-hover-color: var(--link-color); + --link-selection-outline-color: #75c2e385; --hover-item-text-color: #efefef; - --hover-item-background-color: #ffffff24; + --hover-item-background-color: #ffffff16; --hover-item-border-color: transparent; --active-item-text-color: var(--left-pane-text-color); @@ -170,6 +172,9 @@ --protected-session-active-icon-color: #8edd8e; --sync-status-error-pulse-color: #f47871; + --classic-toolbar-vert-layout-background-color: #ffffff0d; + --classic-toolbar-horiz-layout-background-color: var(--main-background-color); + --center-pane-vert-layout-background-color-bgfx: #0c0c0c69; --center-pane-horiz-layout-background-color-bgfx: #1e1e1ec7; @@ -182,7 +187,7 @@ --tab-close-button-hover-background: #a45353; --tab-close-button-hover-color: white; - + --active-tab-background-color: #ffffff1c; --active-tab-hover-background-color: var(--active-tab-background-color); --active-tab-icon-color: #a9a9a9; @@ -199,9 +204,19 @@ --badge-background-color: #ffffff1a; --badge-text-color: var(--muted-text-color); + --badge-temporaraily-editable-background-color: #297331; + --badge-read-only-background-color: #af4340; + --badge-share-background-color: #4d4d4d; + --badge-clipped-note-background-color: #295773; + --badge-execute-background-color: #604180; + + --note-icon-background-color: #444444; + --note-icon-color: #d4d4d4; + --note-icon-hover-background-color: #555555; + --promoted-attribute-card-background-color: #ffffff21; --promoted-attribute-card-shadow: none; - + --floating-button-shadow-color: #00000080; --floating-button-background-color: #494949d2; --floating-button-color: var(--button-text-color); @@ -220,14 +235,17 @@ --right-pane-item-hover-background: #ffffff26; --right-pane-item-hover-color: white; + --bottom-panel-background-color: #11111180; + --bottom-panel-title-bar-background-color: #3F3F3F80; + + --status-bar-border-color: var(--main-border-color); + --scrollbar-thumb-color: #fdfdfd5c; --scrollbar-thumb-hover-color: #ffffff7d; --scrollbar-background-color: transparent; --scrollbar-border-color: unset; /* Deprecated */ --selection-background-color: #3399FF70; - - --link-color: lightskyblue; --mermaid-theme: dark; @@ -293,10 +311,10 @@ --custom-bg-color: hsl(var(--custom-color-hue), 20%, 33%, 0.4); } -:root .reference-link, -:root .reference-link:hover, -.ck-content a.reference-link > span, -.board-note { +:root .reference-link.use-note-color, +:root .reference-link.use-note-color:hover, +.ck-content a.reference-link.use-note-color > span, +.board-note.use-note-color { color: var(--dark-theme-custom-color, inherit); } @@ -320,4 +338,16 @@ body .todo-list input[type="checkbox"]:not(:checked):before { .use-note-color { --custom-color: var(--dark-theme-custom-color); +} + +.note-split.with-hue, +.quick-edit-dialog-wrapper.with-hue { + --note-icon-custom-background-color: hsl(var(--custom-color-hue), 15.8%, 30.9%); + --note-icon-custom-color: hsl(var(--custom-color-hue), 100%, 76.5%); + --note-icon-hover-custom-background-color: hsl(var(--custom-color-hue), 28.3%, 36.7%); +} + +.note-split.with-hue *::selection, +.quick-edit-dialog-wrapper.with-hue *::selection { + background: hsl(var(--custom-color-hue), 49.2%, 35%); } \ No newline at end of file diff --git a/apps/client/src/stylesheets/theme-next-light.css b/apps/client/src/stylesheets/theme-next-light.css index 60e7d55b2b..fb39917611 100644 --- a/apps/client/src/stylesheets/theme-next-light.css +++ b/apps/client/src/stylesheets/theme-next-light.css @@ -6,7 +6,7 @@ */ :root { - /* + /* * ⚠️ NOTICE: This theme is currently in the beta stage of development. * The names and purposes of these CSS variables are subject to frequent changes. */ @@ -21,8 +21,8 @@ --subtle-border-color: rgba(0, 0, 0, 0.1); --dropdown-border-color: #ccc; --dropdown-shadow-opacity: 0.2; - --dropdown-item-icon-destructive-color: #ec5138; - --disabled-tooltip-icon-color: #004382; + --dropdown-item-icon-destructive-color: #de4027; + --contextual-help-icon-color: #004382; --accented-background-color: #f5f5f5; @@ -74,8 +74,10 @@ --select-arrow-svg: url("data:image/svg+xml,"); --select-group-heading-text-color: gray; - --link-hover-background: #00000012; - --link-hover-color: black; + --link-color: #0076af; + --link-hover-background: #3c7fa017; + --link-hover-color: var(--link-color); + --link-selection-outline-color: #95c3d9db; --hover-item-text-color: black; --hover-item-background-color: #0000001a; @@ -138,7 +140,7 @@ /* Deprecated: now local variables in #launcher, with the values dependent on the current layout. */ --launcher-pane-background-color: unset; --launcher-pane-text-color: unset; - + --launcher-pane-vert-background-color: #e8e8e8; --launcher-pane-vert-text-color: #000000bd; --launcher-pane-vert-button-hover-color: black; @@ -162,6 +164,9 @@ --protected-session-active-icon-color: #16b516; --sync-status-error-pulse-color: #ff5528; + --classic-toolbar-vert-layout-background-color: #ffffffa1; + --classic-toolbar-horiz-layout-background-color: var(--main-background-color); + --center-pane-vert-layout-background-color-bgfx: #ffffff75; --center-pane-horiz-layout-background-color-bgfx: #ffffffd6; @@ -174,7 +179,7 @@ --tab-close-button-hover-background: #c95a5a; --tab-close-button-hover-color: white; - + --active-tab-background-color: white; --active-tab-hover-background-color: var(--active-tab-background-color); --active-tab-icon-color: gray; @@ -191,6 +196,16 @@ --badge-background-color: #00000011; --badge-text-color: var(--muted-text-color); + --badge-temporaraily-editable-background-color: #35a64c; + --badge-read-only-background-color: #c8302c; + --badge-share-background-color: #6b6b6b; + --badge-clipped-note-background-color: #2284c0; + --badge-execute-background-color: #7b47af; + + --note-icon-background-color: #4f4f4f; + --note-icon-color: white; + --note-icon-hover-background-color: #737373; + --promoted-attribute-card-background-color: #00000014; --promoted-attribute-card-shadow: none; @@ -218,6 +233,11 @@ --right-pane-item-hover-background: #00000013; --right-pane-item-hover-color: inherit; + --bottom-panel-background-color: #ffffff8c; + --bottom-panel-title-bar-background-color: #94949414; + + --status-bar-border-color: #0000003a; + --scrollbar-thumb-color: #0000005c; --scrollbar-thumb-hover-color: #00000066; --scrollbar-background-color: transparent; @@ -225,8 +245,6 @@ --selection-background-color: #3399FF70; - --link-color: blue; - --mermaid-theme: default; --code-block-box-shadow: 4px 4px 8px rgba(0, 0, 0, 0.1), 0px 0px 2px rgba(0, 0, 0, 0.2); @@ -291,4 +309,16 @@ --modal-background-color: hsl(var(--custom-color-hue), 56%, 96%); --modal-border-color: hsl(var(--custom-color-hue), 33%, 41%); --promoted-attribute-card-background-color: hsl(var(--custom-color-hue), 40%, 88%); +} + +.note-split.with-hue, +.quick-edit-dialog-wrapper.with-hue { + --note-icon-custom-background-color: hsl(var(--custom-color-hue), 44.5%, 43.1%); + --note-icon-custom-color: hsl(var(--custom-color-hue), 91.3%, 91%); + --note-icon-hover-custom-background-color: hsl(var(--custom-color-hue), 55.1%, 50.2%); +} + +.note-split.with-hue *::selection, +.quick-edit-dialog-wrapper.with-hue *::selection { + background: hsl(var(--custom-color-hue), 60%, 90%); } \ No newline at end of file diff --git a/apps/client/src/stylesheets/theme-next/base.css b/apps/client/src/stylesheets/theme-next/base.css index 2f207ed440..b75cdb3389 100644 --- a/apps/client/src/stylesheets/theme-next/base.css +++ b/apps/client/src/stylesheets/theme-next/base.css @@ -50,7 +50,7 @@ --tab-bar-height: 50px; --tab-height: 36px; - --tab-first-item-horiz-offset: 1px; + --tab-first-item-horiz-offset: 0; --new-tab-button-size: 24px; --center-pane-border-radius: 10px; @@ -89,13 +89,13 @@ * the color is adjusted based on the current color scheme (light or dark). The lightness * component of the color represented in the CIELAB color space, will be * constrained to a certain percentage defined below. - * + * * Note: the tree background may vary when background effects are enabled, so it is recommended * to maintain a higher contrast margin than on the usual note tree solid background. */ /* The maximum perceptual lightness for the custom color in the light theme (%): */ --tree-item-light-theme-max-color-lightness: 60; - + /* The minimum perceptual lightness for the custom color in the dark theme (%): */ --tree-item-dark-theme-min-color-lightness: 65; } @@ -128,6 +128,22 @@ body.backdrop-effects-disabled { font-size: 0.9rem !important; } +/* Use this class for non-legacy menus */ +.dropdown-menu.tn-dropdown-menu { + --menu-item-icon-vert-offset: 0; + white-space-collapse: discard; +} + +.dropdown-menu.tn-dropdown-menu .bx { + margin-inline-end: 6px; +} + +.dropdown-menu.tn-dropdown-menu-scrollable { + /* Note: scrollable dropdowns does not support submenus */ + max-height: 90vh; + overflow-y: auto; +} + body.desktop .dropdown-menu::before, :root .ck.ck-dropdown__panel::before, :root .excalidraw .popover::before, @@ -147,14 +163,14 @@ body.desktop .dropdown-menu.tn-dropdown-list { backdrop-filter: var(--dropdown-backdrop-filter); } -body.desktop .dropdown-menu.tn-dropdown-list::before { - display: none; -} - body.desktop .dropdown-submenu .dropdown-menu::before { content: unset; } +body.desktop .dropdown-menu.tn-dropdown-list::before { + display: none; +} + body.desktop .dropdown-submenu .dropdown-menu { backdrop-filter: var(--dropdown-backdrop-filter); background: transparent; @@ -165,17 +181,35 @@ body.desktop .dropdown-submenu .dropdown-menu { --menu-item-start-padding: 8px; --menu-item-end-padding: 22px; --menu-item-vertical-padding: 2px; - - padding-top: var(--menu-item-vertical-padding) !important; - padding-bottom: var(--menu-item-vertical-padding) !important; - padding-inline-start: var(--menu-item-start-padding) !important; - padding-inline-end: var(--menu-item-end-padding) !important; /* Note: the right padding should also accommodate the submenu arrow. */ border-radius: 6px; cursor: default !important; } +.dropdown-item:not(.dropdown-submenu), +body.desktop .dropdown-item.dropdown-submenu .dropdown-toggle, +.excalidraw .context-menu .context-menu-item { + padding-top: var(--menu-item-vertical-padding) !important; + padding-bottom: var(--menu-item-vertical-padding) !important; + padding-inline-start: var(--menu-item-start-padding) !important; + padding-inline-end: var(--menu-item-end-padding) !important; +} + +.dropdown-item.dropdown-submenu { + padding: 0 !important; + + .dropdown-toggle { + flex-grow: 1; + } +} + +body.desktop .dropdown-menu:has(> .dropdown-submenu.dropstart) > .dropdown-item:not(.dropdown-submenu), +body.desktop .dropdown-menu:has(> .dropdown-submenu.dropstart) > .dropdown-item.dropdown-submenu .dropdown-toggle { + padding-inline-end: var(--menu-item-start-padding) !important; + padding-inline-start: var(--menu-item-end-padding) !important; +} + :root .dropdown-item:focus-visible { outline: 2px solid var(--input-focus-outline-color) !important; background-color: transparent; @@ -200,6 +234,10 @@ html body .dropdown-item[disabled] { opacity: var(--menu-item-disabled-opacity); } +.dropdown-item:not(.disabled) .destructive-action-icon, +.dropdown-item:not(.disabled) .bx-trash { + --menu-item-icon-color: var(--dropdown-item-icon-destructive-color); +} /* Badges */ :root .badge { --bs-badge-color: var(--badge-text-color); @@ -249,7 +287,8 @@ html body .dropdown-item[disabled] { } /* Menu item arrow */ -.dropdown-menu .dropdown-toggle::after { +body.mobile .dropdown-submenu .dropdown-toggle::after, +body.desktop .dropdown-submenu:not(.dropstart) .dropdown-toggle::after { content: "\ed3b" !important; position: absolute; display: flex !important; @@ -265,6 +304,26 @@ html body .dropdown-item[disabled] { color: var(--menu-item-arrow-color) !important; } +body.mobile .dropdown-submenu.dropstart .dropdown-toggle::before { + content: unset; +} + +body.desktop .dropdown-submenu.dropstart .dropdown-toggle::before { + content: "\ea4d" !important; + position: absolute; + display: flex !important; + align-items: center; + justify-content: center; + top: 0; + inset-inline-start: 0; + margin: unset !important; + border: unset !important; + padding: 0 4px; + font-family: boxicons; + font-size: 1.2em; + color: var(--menu-item-arrow-color) !important; +} + body[dir=rtl] .dropdown-menu:not([data-popper-placement="bottom-start"]) .dropdown-toggle::after { content: "\ea4d" !important; } @@ -339,7 +398,7 @@ body.mobile .dropdown-menu { font-size: 1em !important; backdrop-filter: var(--dropdown-backdrop-filter); position: relative; - + .dropdown-toggle::after { top: 0.5em; right: var(--dropdown-menu-padding-horizontal); @@ -356,7 +415,7 @@ body.mobile .dropdown-menu { padding: var(--dropdown-menu-padding-vertical) var(--dropdown-menu-padding-horizontal) !important; background: var(--card-background-color); border-bottom: 1px solid var(--menu-item-delimiter-color) !important; - border-radius: 0; + border-radius: 0; } .dropdown-item:first-of-type, @@ -367,9 +426,9 @@ body.mobile .dropdown-menu { border-top-right-radius: 6px; } - .dropdown-item:last-of-type, + .dropdown-item:last-of-type, .dropdown-item:has(+ .dropdown-divider), - .dropdown-custom-item:last-of-type, + .dropdown-custom-item:last-of-type, .dropdown-custom-item:has(+ .dropdown-divider) { border-bottom-left-radius: 6px; border-bottom-right-radius: 6px; @@ -392,10 +451,10 @@ body.mobile .dropdown-menu { --menu-background-color: --menu-submenu-mobile-background-color; --bs-dropdown-divider-margin-y: 0.25rem; border-radius: 0; - max-height: 0; + max-height: 0; transition: max-height 100ms ease-in; - display: block !important; - + display: block !important; + &.show { max-height: 1000px; padding: 0.5rem 0.75rem !important; @@ -405,7 +464,7 @@ body.mobile .dropdown-menu { &.submenu-open { .dropdown-toggle { padding-bottom: var(--dropdown-menu-padding-vertical); - } + } } } @@ -743,4 +802,4 @@ li.dropdown-item a.dropdown-item-button:focus-visible { .note-detail-empty .aa-suggestions div.aa-cursor { background: var(--hover-item-background-color); color: var(--hover-item-text-color); -} \ No newline at end of file +} diff --git a/apps/client/src/stylesheets/theme-next/forms.css b/apps/client/src/stylesheets/theme-next/forms.css index fb53f167d4..6de90a963b 100644 --- a/apps/client/src/stylesheets/theme-next/forms.css +++ b/apps/client/src/stylesheets/theme-next/forms.css @@ -56,7 +56,8 @@ button.btn.btn-primary:focus-visible, button.btn.btn-secondary:focus-visible, button.btn.btn-sm:not(.select-button):focus-visible, button.btn.btn-success:focus-visible, -button.ck.ck-button:is(.ck-button-action, .ck-button-save, .ck-button-cancel, .ck-button-replaceall, .ck-button-replace).ck-button_with-text:not(.ck-disabled):focus-visible { +button.ck.ck-button:is(.ck-button-action, .ck-button-save, .ck-button-cancel, .ck-button-replaceall, .ck-button-replace).ck-button_with-text:not(.ck-disabled):focus-visible, +.tn-focusable-button:focus-visible { outline: 2px solid var(--input-focus-outline-color); } @@ -154,7 +155,7 @@ button.btn.btn-success kbd { color: var(--button-group-active-button-text-color); } -/* +/* * Input boxes */ @@ -352,6 +353,11 @@ label.input-group.tn-number-unit-pair input { padding-inline-end: 0; } +:root .input-group > pre[aria-hidden="true"] { + margin: 0; + padding: 0; +} + /* Combo box-like dropdown buttons */ .select-button.dropdown-toggle::after { @@ -399,7 +405,8 @@ button.select-button.dropdown-toggle.btn:active { select:focus, select.form-select:focus, select.form-control:focus, -.select-button.dropdown-toggle.btn:focus { +.select-button.dropdown-toggle.btn:focus, +.select-button.focus-outline:focus { box-shadow: unset; outline: 3px solid var(--input-focus-outline-color); outline-offset: 0; @@ -422,7 +429,7 @@ optgroup { line-height: 40px; } -/* +/* * File input * * こちらをご覧ください。Google経由でOpenIDサービスを設定するには、こちらの手順に従ってください。", + "oauth_description": "OpenIDは、Googleなどの他のサービスのアカウントを使用して web サイトにログインし、本人確認を行うための標準化された方法です。デフォルトの発行者はGoogleですが、他のOpenIDプロバイダに変更できます。詳しくはこちらをご覧ください。Google経由でOpenIDサービスを設定するには、こちらの手順に従ってください。", "oauth_description_warning": "OAuth/OpenIDを有効にするには、config.iniファイルにOAuth/OpenIDのベースURL、クライアントID、クライアントシークレットを設定し、アプリケーションを再起動する必要があります。環境変数から設定する場合は、TRILIUM_OAUTH_BASE_URL, TRILIUM_OAUTH_CLIENT_ID and TRILIUM_OAUTH_CLIENT_SECRET を設定してください。", "oauth_missing_vars": "設定がありません: {{-variables}}", "oauth_user_account": "ユーザーアカウント: ", @@ -2116,5 +2155,64 @@ "unknown_http_error_title": "サーバーとの通信エラー", "unknown_http_error_content": "ステータスコード: {{statusCode}}\nURL: {{method}} {{url}}\nメッセージ: {{message}}", "traefik_blocks_requests": "Traefik リバース プロキシを使用している場合、サーバーとの通信に影響する重大な変更が導入されました。" + }, + "tab_history_navigation_buttons": { + "go-back": "前のノートに戻る", + "go-forward": "次のノートに進む" + }, + "experimental_features": { + "title": "実験オプション", + "disclaimer": "これらのオプションは試験的なもので、動作が不安定になる可能性があります。注意してご使用ください。", + "new_layout_name": "新しいレイアウト", + "new_layout_description": "よりモダンな外観と使いやすさが向上した新しいレイアウトをお試しください。今後のリリースで大幅な変更が加えられる可能性があります。" + }, + "breadcrumb_badges": { + "read_only_explicit": "読み取り専用", + "read_only_auto": "自動的に読み取り専用", + "shared_publicly": "公開で共有", + "shared_locally": "ローカルで共有", + "read_only_explicit_description": "このノートは手動で読み取り専用に設定されています。\nクリックすると一時的に編集できます。", + "read_only_temporarily_disabled": "一時的に編集可能", + "read_only_auto_description": "このノートはパフォーマンス上の理由により、自動的に読み取り専用モードに設定されました。この自動制限は設定から調整できます。\n\n一時的に編集するにはクリックしてください。", + "read_only_temporarily_disabled_description": "このノートは現在編集可能ですが、通常は読み取り専用です。別のノートに移動すると読み取り専用に戻ります。\n\nクリックすると読み取り専用モードが再度有効になります。", + "clipped_note": "Web クリップ", + "clipped_note_description": "このノートは {{url}} から取得されました。\n\nクリックすると元の web ページに移動します。", + "execute_script": "スクリプトを実行", + "execute_script_description": "このノートはスクリプトノートです。クリックするとスクリプトが実行されます。", + "execute_sql": "SQL を実行", + "execute_sql_description": "このノートは SQL ノートです。クリックすると SQL クエリが実行されます。", + "shared_copy_to_clipboard": "リンクをクリップボードにコピー", + "shared_open_in_browser": "ブラウザでリンクを開く", + "shared_unshare": "共有を削除" + }, + "status_bar": { + "language_title": "コンテンツの言語を変更", + "note_info_title": "ノート情報を表示(例: 日付、ノートのサイズなど)", + "backlinks_title_other": "バックリンクを表示", + "attachments_title_other": "添付ファイルを新しいタブで表示", + "attributes_other": "{{count}} 個の属性", + "attributes_title": "所有属性と継承属性", + "note_paths_title": "ノートパス", + "code_note_switcher": "言語モードを変更", + "backlinks_other": "{{count}} バックリンク", + "attachments_other": "{{count}} 件の添付ファイル", + "note_paths_other": "{{count}} 個のパス" + }, + "breadcrumb": { + "hoisted_badge": "ホイスト", + "hoisted_badge_title": "ホイスト解除", + "workspace_badge": "ワークスペース", + "scroll_to_top_title": "ノートの先頭にジャンプ", + "create_new_note": "新しい子ノートを作成", + "empty_hide_archived_notes": "アーカイブされたノートを非表示" + }, + "right_pane": { + "empty_message": "このノートには何も表示されません", + "empty_button": "パネルを非表示", + "toggle": "右パネルを切り替え", + "custom_widget_go_to_source": "ソースコードへ移動" + }, + "attributes_panel": { + "title": "ノート属性" } } diff --git a/apps/client/src/translations/pl/translation.json b/apps/client/src/translations/pl/translation.json index 6f3ed86c0c..40cdd80fc2 100644 --- a/apps/client/src/translations/pl/translation.json +++ b/apps/client/src/translations/pl/translation.json @@ -1,164 +1,177 @@ { "about": { "title": "O Trilium Notes", - "homepage": "Strona główna:", + "homepage": "Strona domowa:", "app_version": "Wersja aplikacji:", "db_version": "Wersja bazy danych:", "sync_version": "Wersja synchronizacji:", "build_date": "Data kompilacji:", - "build_revision": "Wersja:", - "data_directory": "Katalog z danymi:" + "build_revision": "Rewizja:", + "data_directory": "Katalog danych:" }, "toast": { "critical-error": { "title": "Błąd krytyczny", - "message": "Wystąpił krytyczny błąd uniemożliwiający uruchomienie aplikacji:\n\n{{message}}\n\nJest to spowodowane najprawdopodobniej niespodziewanym błędem skryptu. Spróbuj uruchomić aplikację ponownie w trybie bezpiecznym i zaadresuj problem." + "message": "Wystąpił błąd krytyczny, który uniemożliwia uruchomienie aplikacji klienckiej:\n\n{{message}}\n\nNajprawdopodobniej jest to spowodowane nieoczekiwanym błędem skryptu. Spróbuj uruchomić aplikację w trybie bezpiecznym (safe mode) i rozwiązać problem." }, "widget-error": { "title": "Nie udało się zainicjować widżetu", - "message-custom": "Niestandardowy widżet z notatki o identyfikatorze \"{{id}}\", i tytule \"{{title}}\" nie mógł zostać zainicjowany z powodu:\n\n{{message}}", - "message-unknown": "Nieznany widżet nie mógł być zainicjowany z powodu:\n\n{{message}}" + "message-custom": "Niestandardowy widżet z notatki o ID \"{{id}}\", zatytułowany \"{{title}}\", nie mógł zostać zainicjowany z powodu:\n\n{{message}}", + "message-unknown": "Nieznany widżet nie mógł zostać zainicjowany z powodu:\n\n{{message}}" }, "bundle-error": { "title": "Nie udało się załadować niestandardowego skryptu", - "message": "Skrypt z notatki o identyfikatorze \"{{id}}\", tytule \"{{title}}: nie został uruchomiony z powodu:\n\n{{message}}" - } + "message": "Skrypt z notatki o ID \"{{id}}\", zatytułowany \"{{title}}\", nie mógł zostać wykonany z powodu:\n\n{{message}}" + }, + "widget-list-error": { + "title": "Nie udało się pobrać listy widżetów z serwera" + }, + "widget-render-error": { + "title": "Nie udało się wyrenderować niestandardowego widżetu React" + }, + "widget-missing-parent": "Niestandardowy widżet nie ma zdefiniowanej obowiązkowej właściwości „{{property}}”.", + "open-script-note": "Otwórz notatkę ze skryptem" }, "add_link": { "add_link": "Dodaj link", "note": "Notatka", - "search_note": "Wyszukaj notatkę po nazwie", - "link_title_arbitrary": "Tytuł linku można dowolnie zmieniać", + "search_note": "wyszukaj notatkę po nazwie", + "link_title_arbitrary": "tytuł linku można dowolnie zmieniać", "link_title": "Tytuł linku", "button_add_link": "Dodaj link", "help_on_links": "Pomoc dotycząca linków", - "link_title_mirrors": "tytuł linku odzwierciedla tytuł obecnej notatki" + "link_title_mirrors": "Tytuł linku odzwierciedla obecną nazwę notatki" }, "branch_prefix": { "save": "Zapisz", "edit_branch_prefix": "Edytuj prefiks gałęzi", "prefix": "Prefiks: ", - "branch_prefix_saved": "Zapisano prefiks gałęzi.", - "help_on_tree_prefix": "Pomoc dotycząca prefiksu drzewa" + "branch_prefix_saved": "Prefiks gałęzi został zapisany.", + "help_on_tree_prefix": "Pomoc dotycząca prefiksu drzewa", + "edit_branch_prefix_multiple": "Edytuj prefiks gałęzi dla {{count}} gałęzi", + "branch_prefix_saved_multiple": "Prefiks gałęzi został zapisany dla {{count}} gałęzi.", + "affected_branches": "Dotyczy gałęzi ({{count}}):" }, "bulk_actions": { "labels": "Etykiety", "notes": "Notatki", "other": "Inne", - "relations": "Powiązania", - "bulk_actions": "Działania zbiorcze", - "include_descendants": "Uwzględnia rozwinięcia wybranych notatek", - "available_actions": "Dostępne działania", - "chosen_actions": "Wybrane działania", - "execute_bulk_actions": "Wykonaj zbiór działań", - "bulk_actions_executed": "Zbiór działań został wykonany prawidłowo.", - "none_yet": "Brak zaznaczonych działań... dodaj działanie poprzez kliknięcie jednej z dostępnych opcji powyżej.", + "relations": "Relacje", + "bulk_actions": "Akcje masowe", + "include_descendants": "Uwzględnij elementy podrzędne wybranych notatek", + "available_actions": "Dostępne akcje", + "chosen_actions": "Wybrane akcje", + "execute_bulk_actions": "Wykonaj akcje masowe", + "bulk_actions_executed": "Akcje masowe zostały wykonane pomyślnie.", + "none_yet": "Jeszcze nic... dodaj akcję, klikając jedną z dostępnych powyżej.", "affected_notes": "Dotyczy notatek" }, "confirm": { "ok": "OK", "cancel": "Anuluj", "confirmation": "Potwierdzenie", - "are_you_sure_remove_note": "Czy napewno chcesz usunąć notatkę \"{{title}}\" z mapy powiązań? ", - "if_you_dont_check": "Jeśli nie zaznaczysz tej opcji, notatka zostanie usunięta jedynie z mapy powiązań.", - "also_delete_note": "Usuń dodatkowo notatkę" + "are_you_sure_remove_note": "Czy na pewno chcesz usunąć notatkę \"{{title}}\" z mapy relacji? ", + "if_you_dont_check": "Jeśli tego nie zaznaczysz, notatka zostanie usunięta tylko z mapy relacji.", + "also_delete_note": "Usuń również notatkę" }, "delete_notes": { "cancel": "Anuluj", "close": "Zamknij", - "delete_notes_preview": "Usuń podgląd notatek", - "delete_all_clones_description": "Usuń również wszystkie sklonowania (działanie może zostać cofnięte w ostatnich zmianach)", - "erase_notes_description": "Normalne (miękkie) usuwanie zaznacza jedynie notatki jako usunięte i można je przywrócić (w oknie dialogowym ostatnich zmian) przez wyznaczony okres czasu. Zaznaczenie tej opcji spowoduje natychmiastowe usunięcie notatek, bez możliwości ich przywrócenia.", - "erase_notes_warning": "Usuń notatki permanentnie (bez opcji ich przywrócenia), włączając wszystkie kopie. Działanie to wymaga ponownego uruchomienia aplikacji.", + "delete_notes_preview": "Podgląd usuwania notatek", + "delete_all_clones_description": "Usuń również wszystkie klony (można cofnąć w oknie Ostatnie zmiany)", + "erase_notes_description": "Normalne (miękkie) usuwanie jedynie oznacza notatki jako usunięte i można je przywrócić (w oknie Ostatnie zmiany) przez pewien czas. Zaznaczenie tej opcji spowoduje natychmiastowe wymazanie notatek i nie będzie możliwe ich przywrócenie.", + "erase_notes_warning": "Wymaż notatki trwale (nie można cofnąć), w tym wszystkie klony. Wymusi to przeładowanie aplikacji.", "notes_to_be_deleted": "Następujące notatki zostaną usunięte ({{notesCount}})", - "no_note_to_delete": "Żadne notatki nie zostaną usunięte (jedynie kopie).", - "broken_relations_to_be_deleted": "Następujące powiązania zostaną uszkodzone i usunięte ({{ relationCount}})", + "no_note_to_delete": "Żadna notatka nie zostanie usunięta (tylko klony).", + "broken_relations_to_be_deleted": "Następujące relacje zostaną zerwane i usunięte ({{ relationCount}})", "ok": "OK", - "deleted_relation_text": "Notatka {{- note}} (do usunięcia) jest powiązana przez relację {{- relation}} pochodzącą z {{- source}}." + "deleted_relation_text": "Notatka {{- note}} (do usunięcia) jest powiązana relacją {{- relation}} pochodzącą z {{- source}}." }, "export": { "close": "Zamknij", "export_note_title": "Eksportuj notatkę", - "export_type_subtree": "Ta notatka oraz wszystkie podrzędne", - "format_html": "HTML - rekomendowany jako zachowujący całość formatowania", - "format_html_zip": "HTML w archiwum ZIP - rekomendowany jako zachowujący całość formatowania.", + "export_type_subtree": "Ta notatka i wszystkie jej elementy podrzędne", + "format_html": "HTML - zalecane, ponieważ zachowuje pełne formatowanie", + "format_html_zip": "HTML w archiwum ZIP - zalecane, ponieważ zachowuje pełne formatowanie.", "format_markdown": "Markdown - zachowuje większość formatowania.", - "format_opml": "OPML - format wymiany danych dla outlinerów zawierający tylko tekst. Formatowanie, obrazy i pliki nie są uwzględnione.", + "format_opml": "OPML - format wymiany konspektów (tylko tekst). Formatowanie, obrazy i pliki nie są dołączane.", "opml_version_1": "OPML v1.0 - tylko zwykły tekst", - "opml_version_2": "OPML v2.0 - umożliwia również HTML", - "export_type_single": "Tylko ta notatka, bez elementów podrzędnych", + "opml_version_2": "OPML v2.0 - dopuszcza również HTML", + "export_type_single": "Tylko ta notatka (bez elementów podrzędnych)", "export": "Eksportuj", - "choose_export_type": "Wybierz najpierw rodzaj pliku do eksportu", + "choose_export_type": "Proszę najpierw wybrać typ eksportu", "export_status": "Status eksportu", - "export_in_progress": "Postęp eksportowania: {{progressCount}}", - "export_finished_successfully": "Eksportowanie zakończone.", - "format_pdf": "PDF - w celu drukowania lub udostępniania." + "export_in_progress": "Eksport w toku: {{progressCount}}", + "export_finished_successfully": "Eksport zakończony pomyślnie.", + "format_pdf": "PDF - do druku lub udostępniania.", + "share-format": "HTML do publikacji w sieci - używa tego samego motywu co udostępnione notatki, ale może być opublikowany jako statyczna strona." }, "clone_to": { "clone_notes_to": "Sklonuj notatki do...", "notes_to_clone": "Notatki do sklonowania", - "search_for_note_by_its_name": "Wyszukaj notatkę po jej nazwie", - "cloned_note_prefix_title": "Sklonowana notatka zostanie wyświetlona w drzewie notatki z podanym prefiksem", - "prefix_optional": "Prefiks (opcjonalne)", + "search_for_note_by_its_name": "wyszukaj notatkę po nazwie", + "cloned_note_prefix_title": "Sklonowana notatka będzie wyświetlana w drzewie z podanym prefiksem", + "prefix_optional": "Prefiks (opcjonalnie)", "clone_to_selected_note": "Sklonuj do wybranej notatki", "no_path_to_clone_to": "Brak ścieżki do sklonowania.", "note_cloned": "Notatka \"{{clonedTitle}}\" została sklonowana do \"{{targetTitle}}\"", "help_on_links": "Pomoc dotycząca linków", - "target_parent_note": "Docelowa główna notatka" + "target_parent_note": "Docelowa notatka nadrzędna" }, "help": { "title": "Ściągawka", "noteNavigation": "Nawigacja po notatkach", - "goUpDown": "przewijanie w górę/w dół w liście notatek", - "collapseExpand": "zwiń/rozwiń zbiór", - "notSet": "niezdefiniowany", - "goBackForwards": "przewijaj do tyłu/do przodu w historii", - "showJumpToNoteDialog": "pokaż \"przejdź do dialogu", + "goUpDown": "idź w górę/dół listy notatek", + "collapseExpand": "zwiń/rozwiń węzeł", + "notSet": "nie ustawiono", + "goBackForwards": "idź wstecz / do przodu w historii", + "showJumpToNoteDialog": "pokaż okno \"Przejdź do\"", "scrollToActiveNote": "przewiń do aktywnej notatki", - "jumpToParentNote": "przejdź do głównej notatki", - "collapseWholeTree": "zwiń całe drzewko notatki", - "collapseSubTree": "zwiń gałąź notatki", - "tabShortcuts": "Skóry kart", - "newTabNoteLink": "link notatki otwiera notatkę w nowej karcie", - "newTabWithActivationNoteLink": "link notatki otwiera i aktywuje notatkę w nowej karcie", - "onlyInDesktop": "Tylko na komputerze stacjonarnym (wersja Electron)", - "openEmptyTab": "Otwórz pustą kartę", + "jumpToParentNote": "przejdź do notatki nadrzędnej", + "collapseWholeTree": "zwiń całe drzewo notatek", + "collapseSubTree": "zwiń poddrzewo", + "tabShortcuts": "Skróty kart", + "newTabNoteLink": "na linku notatki otwiera notatkę w nowej karcie", + "newTabWithActivationNoteLink": "na linku notatki otwiera i aktywuje notatkę w nowej karcie", + "onlyInDesktop": "Tylko w wersji desktopowej (Electron)", + "openEmptyTab": "otwórz pustą kartę", "closeActiveTab": "zamknij aktywną kartę", "activateNextTab": "aktywuj następną kartę", "activatePreviousTab": "aktywuj poprzednią kartę", "creatingNotes": "Tworzenie notatek", - "createNoteAfter": "Utwórz nową notatkę obok obecnie aktywnej", - "createNoteInto": "Utwórz nową podnotatkę w obecnie otwartej", - "editBranchPrefix": "edytuj prefiks aktywnej kopii notatki", - "movingCloningNotes": "Przenoszenie / kopiowanie notatek", - "moveNoteUpDown": "Przenieś notatkę w górę/w dół na liście notatek", - "moveNoteUpHierarchy": "Przenieś notatkę w górę w hierarchii", - "multiSelectNote": "Zaznacz wiele notatek powyżej/poniżej", - "selectAllNotes": "Wybierz wszystkie notatki na obecnym poziomie", - "selectNote": "Wybierz notatkę", - "copyNotes": "skopiuj obecną notatkę (lub obecną sekcję) do schowka (zastosowanie dlaklonowania)", - "cutNotes": "przytnij obecną notatkę (lub obecną sekcję) do schowka (zastosowanie dla przenoszenia notatek)", - "pasteNotes": "wklej notatkę jako podnotatka w obecnej notatce (rozumiane jako przenieś lub skopiuj, w zależności czy notatka była skopiowana czy wycięta)", - "deleteNotes": "usuń notatkę / gałąź", - "editingNotes": "Edytowanie notatek", + "createNoteAfter": "utwórz nową notatkę po aktywnej notatce", + "createNoteInto": "Utwórz nową podnotatkę w aktywnej notatce", + "editBranchPrefix": "edytuj prefiks klona aktywnej notatki", + "movingCloningNotes": "Przenoszenie / klonowanie notatek", + "moveNoteUpDown": "przesuń notatkę w górę/dół na liście", + "moveNoteUpHierarchy": "przesuń notatkę w górę w hierarchii", + "multiSelectNote": "wybierz wiele notatek powyżej/poniżej", + "selectAllNotes": "zaznacz wszystkie notatki na bieżącym poziomie", + "selectNote": "wybierz notatkę", + "copyNotes": "kopiuj aktywną notatkę (lub zaznaczenie) do schowka (używane do klonowania)", + "cutNotes": "wytnij bieżącą notatkę (lub zaznaczenie) do schowka (używane do przenoszenia)", + "pasteNotes": "wklej notatkę(-i) jako pod-notatkę do aktywnej notatki (jest to przeniesienie lub klonowanie w zależności od tego, czy użyto kopiuj czy wytnij)", + "deleteNotes": "usuń notatkę / poddrzewo", + "editingNotes": "Edycja notatek", "other": "Inne", - "editNoteTitle": "W panelu drzewa nastąpi przejście z panelu drzewa do tytułu notatki. Naciśnięcie klawisza Enter w tytule notatki spowoduje przejście do edytora tekstu. Ctrl+. spowoduje powrót z edytora do panelu drzewa.", - "createEditLink": "stwórz / edytuj zewnętrzny link", - "createInternalLink": "stwórz wewnętrzny link", - "followLink": "kliknij link pod kursorem", - "insertDateTime": "wstaw aktualną datę i godzinę w pozycji kursora", + "editNoteTitle": "w panelu drzewa przełącza z drzewa na tytuł notatki. Enter na tytule notatki przenosi fokus do edytora tekstu. Ctrl+. przełącza z powrotem z edytora do panelu drzewa.", + "createEditLink": "utwórz / edytuj link zewnętrzny", + "createInternalLink": "utwórz link wewnętrzny", + "followLink": "podążaj za linkiem pod kursorem", + "insertDateTime": "wstaw bieżącą datę i godzinę w pozycji karetki", "markdownAutoformat": "Autoformatowanie w stylu Markdown", - "headings": "##, ###, #### itd., po których następuje miejsce na nagłówki", - "bulletList": "* lub -, a następnie spacja, aby utworzyć listę", - "jumpToTreePane": "przejdź do panelu drzewa i przewiń do aktywnej notatki", - "numberedList": "1. or 1) po którym następuje miejsce na listę numerowaną", - "blockQuote": "zacznij linijkę od aby po kliknięciu spacji dodać blok cytatu", - "troubleshooting": "Rozwiązywanie błędów", - "reloadFrontend": "Załaduj ponownie Frontend Trilium", + "headings": "##, ###, #### itd. a następnie spacja dla nagłówków", + "bulletList": "* lub - a następnie spacja dla listy punktowanej", + "jumpToTreePane": "przeskocz do panelu drzewa i przewiń do aktywnej notatki", + "numberedList": "1. lub 1) a następnie spacja dla listy numerowanej", + "blockQuote": "rozpocznij linię znakiem > a następnie spacją dla cytatu blokowego", + "troubleshooting": "Rozwiązywanie problemów", + "reloadFrontend": "przeładuj frontend Trilium", "showDevTools": "pokaż narzędzia deweloperskie", "showSQLConsole": "pokaż konsolę SQL", - "quickSearch": "skup się na szybkim wyszukiwaniu", - "inPageSearch": "wyszukiwanie wewnątrz strony" + "quickSearch": "skupienie na szybkim wyszukiwaniu", + "inPageSearch": "wyszukiwanie na stronie", + "editShortcuts": "Edytuj skróty klawiszowe" }, "book_properties": { "list": "Lista", @@ -171,85 +184,96 @@ "invalid_view_type": "Nieprawidłowy typ widoku '{{type}}'", "calendar": "Kalendarz", "table": "Tabela", - "geo-map": "Mapa geograficzna", + "geo-map": "Mapa Geo", "board": "Tablica", "presentation": "Prezentacja", - "include_archived_notes": "Pokaż zarchiwizowane notatki" + "include_archived_notes": "Pokaż zarchiwizowane notatki", + "expand_tooltip": "Rozwija bezpośrednie elementy podrzędne tej kolekcji (o jeden poziom). Aby uzyskać więcej opcji, naciśnij strzałkę po prawej.", + "expand_first_level": "Rozwiń bezpośrednie elementy podrzędne", + "expand_nth_level": "Rozwiń {{depth}} poziomów", + "expand_all_levels": "Rozwiń wszystkie poziomy" }, "board_view": { "move-to": "Przenieś do", - "insert-above": "Umieść nad", - "insert-below": "Umieść pod", + "insert-above": "Wstaw powyżej", + "insert-below": "Wstaw poniżej", "delete-column": "Usuń kolumnę", - "delete-column-confirmation": "Czy na pewno chcesz usunąć tę kolumnę? Odpowiedni atrybut zostanie również usunięty w notatkach pod tą kolumną.", + "delete-column-confirmation": "Czy na pewno chcesz usunąć tę kolumnę? Odpowiedni atrybut zostanie usunięty również z notatek pod tą kolumną.", "new-item": "Nowy element", - "new-item-placeholder": "Wpisz tytuł notatki...", + "new-item-placeholder": "Wprowadź tytuł notatki...", "add-column": "Dodaj kolumnę", - "add-column-placeholder": "Wpisz tytuł kolumny...", - "edit-note-title": "Naciśnij aby edytować tytuł notatki", - "edit-column-title": "Naciśnij aby edytować tytuł kolumny", + "add-column-placeholder": "Wprowadź nazwę kolumny...", + "edit-note-title": "Kliknij, aby edytować tytuł notatki", + "edit-column-title": "Kliknij, aby edytować tytuł kolumny", "delete-note": "Usuń notatkę...", "remove-from-board": "Usuń z tablicy", - "archive-note": "Archiwalna notatka", - "unarchive-note": "Usuń notatkę z archiwum" + "archive-note": "Archiwizuj notatkę", + "unarchive-note": "Przywróć notatkę z archiwum", + "column-already-exists": "Ta kolumna już istnieje na tablicy." }, "command_palette": { "tree-action-name": "Drzewo: {{name}}", - "export_note_title": "Wyeksportuj notatkę", - "export_note_description": "Wyeksportuj aktualną notatkę", + "export_note_title": "Eksportuj notatkę", + "export_note_description": "Eksportuj bieżącą notatkę", "show_attachments_title": "Pokaż załączniki", - "show_attachments_description": "Zobacz załączniki notatki", + "show_attachments_description": "Wyświetl załączniki notatki", "search_notes_title": "Szukaj notatek", "search_notes_description": "Otwórz zaawansowane wyszukiwanie", - "search_subtree_title": "Poszukaj w poddrzewie", - "search_subtree_description": "poszukaj wewnątrz poddrzewa", + "search_subtree_title": "Szukaj w poddrzewie", + "search_subtree_description": "Szukaj w bieżącym poddrzewie", "search_history_title": "Pokaż historię wyszukiwania", - "search_history_description": "Pokaż poprzednie wyszukiwania", - "configure_launch_bar_title": "Ustaw Launch Bar", - "configure_launch_bar_description": "Otwórz konfigurację Launch Bar, aby dodać lub usunąć elementy." + "search_history_description": "Wyświetl poprzednie wyszukiwania", + "configure_launch_bar_title": "Konfiguruj pasek szybkiego dostępu", + "configure_launch_bar_description": "Otwórz konfigurację paska szybkiego dostępu, aby dodać lub usunąć elementy." }, "content_renderer": { "open_externally": "Otwórz zewnętrznie" }, "modal": { "close": "Zamknij", - "help_title": "Pokaż więcej informacji na temat tego ekranu" + "help_title": "Wyświetl więcej informacji o tym ekranie" }, "call_to_action": { - "next_theme_title": "Spróbuj nowy motyw Trilium", - "next_theme_message": "Obecnie używasz starszego motywu. Czy chcesz wypróbować nowy motyw?", - "next_theme_button": "Spróbuj nowego motywu", - "background_effects_title": "Efekty w tle są już stabilne", + "next_theme_title": "Wypróbuj nowy motyw Trilium", + "next_theme_message": "Obecnie używasz starszego motywu (legacy), czy chciałbyś wypróbować nowy motyw?", + "next_theme_button": "Wypróbuj nowy motyw", + "background_effects_title": "Efekty tła są teraz stabilne", "dismiss": "Odrzuć", - "background_effects_button": "Włącz efekty w tle", - "background_effects_message": "Na urządzeniach z systemem Windows efekty tła są teraz w pełni stabilne. Efekty tła dodają odrobinę koloru do interfejsu użytkownika, rozmywając tło za nim. Ta technika jest również stosowana w innych aplikacjach, takich jak Eksplorator Windows." + "background_effects_button": "Włącz efekty tła", + "background_effects_message": "Na urządzeniach z systemem Windows efekty tła są teraz w pełni stabilne. Efekty tła dodają odrobinę koloru do interfejsu użytkownika poprzez rozmycie tła za nim. Ta technika jest również stosowana w innych aplikacjach, takich jak Eksplorator Windows.", + "new_layout_title": "Nowy układ", + "new_layout_message": "Wprowadziliśmy zmodernizowany układ interfejsu dla Trilium. Wstążka została usunięta i płynnie zintegrowana z głównym interfejsem, a jej kluczowe funkcje przejęły nowy pasek stanu i rozwijane sekcje (takie jak promowane atrybuty).\n\nNowy układ jest domyślnie włączony i można go tymczasowo wyłączyć w Ustawienia → Wygląd.", + "new_layout_button": "Szczegóły" }, "settings": { "related_settings": "Powiązane ustawienia" }, "settings_appearance": { "related_code_blocks": "Schemat kolorów dla bloków kodu w notatkach tekstowych", - "related_code_notes": "Schemat kolorów dla kodu" + "related_code_notes": "Schemat kolorów dla notatek kodu", + "ui": "Interfejs użytkownika", + "ui_old_layout": "Stary układ", + "ui_new_layout": "Nowy układ" }, "units": { "percentage": "%" }, "pagination": { - "page_title": "Strony:{{startIndex}}-{{endIndex}}", - "total_notes": "{{count}}notatek" + "page_title": "Strona {{startIndex}} - {{endIndex}}", + "total_notes": "{{count}} notatek" }, "collections": { - "rendering_error": "Błąd - Nie można pokazać treści." + "rendering_error": "Nie można wyświetlić zawartości z powodu błędu." }, "add_label": { "add_label": "Dodaj etykietę", - "label_name_placeholder": "Nazwa etykiety", + "label_name_placeholder": "nazwa etykiety", "label_name_title": "Dozwolone są znaki alfanumeryczne, podkreślenie i dwukropek.", - "to_value": "do wartości", + "to_value": "na wartość", "new_value_placeholder": "nowa wartość", - "help_text": "We wszystkich dopasowanych notatkach:", - "help_text_item2": "albo zmień wartość istniejącej etykiety", - "help_text_item1": "utwórz daną etykietę, jeśli notatka jeszcze jej nie ma", + "help_text": "Na wszystkich dopasowanych notatkach:", + "help_text_item2": "lub zmień wartość istniejącej etykiety", + "help_text_item1": "utwórz podaną etykietę, jeśli notatka jeszcze jej nie ma", "help_text_note": "Możesz również wywołać tę metodę bez wartości, w takim przypadku etykieta zostanie przypisana do notatki bez wartości." }, "attribute_detail": { @@ -258,26 +282,26 @@ "more_notes": "Więcej notatek", "label": "Szczegóły etykiety", "label_definition": "Szczegóły definicji etykiety", - "relation": "Szczegóły powiązania", - "relation_definition": "Szczegóły definicji powiązania", - "disable_versioning": "Wyłącza automatyczne wersjonowanie. Przydatne np. w przypadku dużych, ale nieistotnych notatek – np. dużych bibliotek JS używanych do skryptów", - "precision": "Prezycja", - "digits": "znaki", - "inverse_relation_title": "Opcjonalne ustawienie definiujące, do której relacji jest ta relacja przeciwna. Przykład: Główna - podnotatka są relacjami odwrotnymi do siebie.", - "inverse_relation": "Odwrócone powiązanie", + "relation": "Szczegóły relacji", + "relation_definition": "Szczegóły definicji relacji", + "disable_versioning": "wyłącza automatyczne wersjonowanie. Przydatne np. dla dużych, ale mało ważnych notatek - np. dużych bibliotek JS używanych do skryptów", + "precision": "Precyzja", + "digits": "cyfry", + "inverse_relation_title": "Opcjonalne ustawienie określające, do której relacji ta jest odwrotna. Przykład: Ojciec - Syn to relacje odwrotne.", + "inverse_relation": "Relacja odwrotna", "attr_detail_title": "Tytuł szczegółów atrybutu", "close_button_title": "Anuluj zmiany i zamknij", - "attr_is_owned_by": "Atrybut jest własnością", - "attr_name_title": "Nazwa atrybutu może składać się tylko ze znaków alfanumerycznych, dwukropka i podkreślenia", + "attr_is_owned_by": "Atrybut należy do", + "attr_name_title": "Nazwa atrybutu może składać się wyłącznie ze znaków alfanumerycznych, dwukropka i podkreślenia", "name": "Nazwa", "value": "Wartość", "target_note_title": "Relacja to nazwane połączenie między notatką źródłową a docelową.", "target_note": "Notatka docelowa", - "promoted_title": "Promowany atrybut jest wyraźnie wyświetlany w notatce.", - "promoted": "Promowany", - "promoted_alias_title": "Nazwa, która ma być wyświetlana w interfejsie promowanych atrybutów.", + "promoted_title": "Wyróżniony atrybut jest wyświetlany w widocznym miejscu notatki.", + "promoted": "Wyróżniony", + "promoted_alias_title": "Nazwa wyświetlana w interfejsie wyróżnionych atrybutów.", "promoted_alias": "Alias", - "multiplicity_title": "Krotność definiuje, ile atrybutów o tej samej nazwie można utworzyć - maksymalnie 1 lub więcej niż 1.", + "multiplicity_title": "Krotność określa, ile atrybutów o tej samej nazwie można utworzyć - maksymalnie 1 lub więcej niż 1.", "multiplicity": "Krotność", "single_value": "Pojedyncza wartość", "multi_value": "Wiele wartości", @@ -287,121 +311,122 @@ "number": "Liczba", "boolean": "Wartość logiczna", "date": "Data", - "date_time": "Data i czas", - "time": "Czas", + "date_time": "Data i godzina", + "time": "Godzina", "url": "URL", - "precision_title": "Jaka liczba cyfr po przecinku powinna być dostępna w interfejsie ustawiania wartości.", - "inheritable_title": "Dziedziczny atrybut będzie dziedziczony przez wszystkich potomków w tym drzewie.", - "inheritable": "Dziedziczny", + "precision_title": "Ile cyfr po przecinku powinno być dostępnych w interfejsie ustawiania wartości.", + "inheritable_title": "Atrybut dziedziczony będzie dziedziczony przez wszystkie elementy podrzędne w tym drzewie.", + "inheritable": "Dziedziczony", "save_and_close": "Zapisz i zamknij Ctrl+Enter", "calendar_root": "oznacza notatkę, która powinna być używana jako korzeń dla notatek dziennych. Tylko jedna powinna być tak oznaczona.", - "archived": "notatki z tą etykietą nie będą domyślnie widoczne w wynikach wyszukiwania (również w dialogach Przejdź do, Dodaj link itp.).", - "exclude_from_export": "notatki (wraz z ich poddrzewem) nie będą uwzględniane w żadnym eksporcie notatek", - "run": "definiuje, przy jakich zdarzeniach skrypt powinien być uruchamiany. Możliwe wartości to:\n
    \n
  • frontendStartup - gdy frontend Trilium się uruchamia (lub jest odświeżany), ale nie na urządzeniach mobilnych.
  • \n
  • mobileStartup - gdy frontend Trilium się uruchamia (lub jest odświeżany), na urządzeniach mobilnych.
  • \n
  • backendStartup - gdy backend Trilium się uruchamia
  • \n
  • hourly - uruchamiaj raz na godzinę. Możesz użyć dodatkowej etykiety runAtHour, aby określić, o której godzinie.
  • \n
  • daily - uruchamiaj raz dziennie
  • \n
", - "run_on_instance": "Zdefiniuj, która instancja Trilium ma to uruchomić. Domyślnie wszystkie instancje.", - "run_at_hour": "O której godzinie ma to być uruchomione. Powinno być używane razem z #run=hourly. Można zdefiniować wielokrotnie dla większej liczby uruchomień w ciągu dnia.", - "disable_inclusion": "skrypty z tą etykietą nie będą uwzględniane w wykonaniu skryptu nadrzędnego.", + "archived": "notatki z tą etykietą domyślnie nie będą widoczne w wynikach wyszukiwania (również w oknach Przejdź do, Dodaj link itp.).", + "exclude_from_export": "notatki (wraz z ich poddrzewem) nie zostaną uwzględnione w żadnym eksporcie notatek", + "run": "określa, przy jakich zdarzeniach skrypt powinien zostać uruchomiony. Możliwe wartości:\n
    \n
  • frontendStartup - gdy frontend Trilium uruchamia się (lub jest odświeżany), ale nie na urządzeniach mobilnych.
  • \n
  • mobileStartup - gdy frontend Trilium uruchamia się (lub jest odświeżany) na urządzeniach mobilnych.
  • \n
  • backendStartup - gdy backend Trilium uruchamia się
  • \n
  • hourly - uruchamiaj raz na godzinę. Możesz użyć dodatkowej etykiety runAtHour, aby określić godzinę.
  • \n
  • daily - uruchamiaj raz dziennie
  • \n
", + "run_on_instance": "Zdefiniuj, która instancja Trilium powinna to uruchomić. Domyślnie wszystkie instancje.", + "run_at_hour": "O której godzinie powinno to zostać uruchomione. Należy używać razem z #run=hourly. Można zdefiniować wielokrotnie dla większej liczby uruchomień w ciągu dnia.", + "disable_inclusion": "skrypty z tą etykietą nie zostaną uwzględnione w wykonaniu skryptu nadrzędnego.", "sorted": "utrzymuje notatki podrzędne posortowane alfabetycznie według tytułu", "sort_direction": "ASC (domyślnie) lub DESC", - "sort_folders_first": "Foldery (notatki z dziećmi) powinny być sortowane na górze", - "top": "utrzymuj daną notatkę na górze w jej rodzicu (dotyczy tylko posortowanych rodziców)", - "hide_promoted_attributes": "Ukryj promowane atrybuty w tej notatce", + "sort_folders_first": "Foldery (notatki z elementami podrzędnymi) powinny być sortowane na górze", + "top": "utrzymaj daną notatkę na górze w jej rodzicu (dotyczy tylko posortowanych rodziców)", + "hide_promoted_attributes": "Ukryj wyróżnione atrybuty w tej notatce", "read_only": "edytor jest w trybie tylko do odczytu. Działa tylko dla notatek tekstowych i kodowych.", - "auto_read_only_disabled": "notatki tekstowe/kodowe mogą być automatycznie ustawiane w tryb tylko do odczytu, gdy są zbyt duże. Możesz wyłączyć to zachowanie dla poszczególnych notatek, dodając tę etykietę do notatki", - "app_css": "oznacza notatki CSS, które są ładowane do aplikacji Trilium i mogą być używane do modyfikacji wyglądu Trilium.", + "auto_read_only_disabled": "notatki tekstowe/kodowe mogą być automatycznie ustawiane w tryb odczytu, gdy są zbyt duże. Możesz wyłączyć to zachowanie dla poszczególnych notatek, dodając tę etykietę", + "app_css": "oznacza notatki CSS, które są ładowane do aplikacji Trilium i mogą być używane do modyfikowania wyglądu Trilium.", "app_theme": "oznacza notatki CSS, które są pełnymi motywami Trilium i są dostępne w opcjach Trilium.", - "app_theme_base": "ustaw na \"next\", \"next-light\" lub \"next-dark\", aby użyć odpowiedniego motywu TriliumNext (auto, jasny lub ciemny) jako podstawy dla niestandardowego motywu, zamiast starszego.", - "css_class": "wartość tej etykiety jest dodawana jako klasa CSS do węzła reprezentującego daną notatkę w drzewie. Może to być przydatne do zaawansowanego motywowania. Może być używane w notatkach-szablonach.", - "icon_class": "wartość tej etykiety jest dodawana jako klasa CSS do ikony w drzewie, co może pomóc wizualnie odróżnić notatki w drzewie. Przykładem może być bx bx-home - ikony pochodzą z boxicons. Może być używane w notatkach-szablonach.", - "page_size": "liczba elementów na stronie w liście notatek", - "custom_request_handler": "zobacz Niestandardowy obsługujący żądania", - "custom_resource_provider": "zobacz Niestandardowy obsługujący żądania", + "app_theme_base": "ustaw na \"next\", \"next-light\" lub \"next-dark\", aby użyć odpowiedniego motywu TriliumNext (auto, jasny lub ciemny) jako bazy dla własnego motywu, zamiast starszego (legacy).", + "css_class": "wartość tej etykiety jest dodawana jako klasa CSS do węzła reprezentującego daną notatkę w drzewie. Może to być przydatne do zaawansowanego stylowania. Można używać w notatkach szablonów.", + "icon_class": "wartość tej etykiety jest dodawana jako klasa CSS do ikony w drzewie, co może pomóc wizualnie odróżnić notatki. Przykładem może być bx bx-home - ikony pochodzą z boxicons. Można używać w notatkach szablonów.", + "page_size": "liczba elementów na stronę w liście notatek", + "custom_request_handler": "zobacz Niestandardowa obsługa żądań", + "custom_resource_provider": "zobacz Niestandardowa obsługa żądań", "widget": "oznacza tę notatkę jako niestandardowy widżet, który zostanie dodany do drzewa komponentów Trilium", - "workspace": "oznacza tę notatkę jako obszar roboczy, co pozwala na łatwe podnoszenie", - "workspace_icon_class": "definiuje klasę CSS ikony box, która będzie używana w karcie po podniesieniu do tej notatki", - "workspace_tab_background_color": "Kolor CSS używany w karcie notatki po podniesieniu do tej notatki", + "workspace": "oznacza tę notatkę jako obszar roboczy, który umożliwia łatwe zawężanie widoku (hoisting)", + "workspace_icon_class": "definiuje klasę CSS box icon, która będzie używana w karcie po zawężeniu widoku do tej notatki", + "workspace_tab_background_color": "kolor CSS używany w karcie notatki po zawężeniu widoku do tej notatki", "workspace_calendar_root": "Definiuje korzeń kalendarza dla obszaru roboczego", - "workspace_template": "Ta notatka pojawi się w wyborze dostępnych szablonów podczas tworzenia nowej notatki, ale tylko po podniesieniu do obszaru roboczego zawierającego ten szablon", + "workspace_template": "Ta notatka pojawi się w wyborze dostępnych szablonów podczas tworzenia nowej notatki, ale tylko po zawężeniu widoku do obszaru roboczego zawierającego ten szablon", "search_home": "nowe notatki wyszukiwania będą tworzone jako dzieci tej notatki", - "workspace_search_home": "nowe notatki wyszukiwania będą tworzone jako dzieci tej notatki po podniesieniu do jakiegoś przodka tej notatki obszaru roboczego", - "inbox": "domyślna lokalizacja skrzynki odbiorczej dla nowych notatek - gdy tworzysz notatkę za pomocą przycisku \"nowa notatka\" na pasku bocznym, notatki będą tworzone jako notatki podrzędne w notatce oznaczonej etykietą #inbox.", - "workspace_inbox": "domyślna lokalizacja skrzynki odbiorczej dla nowych notatek po podniesieniu do jakiegoś przodka tej notatki obszaru roboczego", + "workspace_search_home": "nowe notatki wyszukiwania będą tworzone jako dzieci tej notatki, gdy widok zostanie zawężony do przodka tej notatki obszaru roboczego", + "inbox": "domyślna lokalizacja skrzynki odbiorczej dla nowych notatek - gdy tworzysz notatkę przy użyciu przycisku \"nowa notatka\" na pasku bocznym, notatki zostaną utworzone jako podrzędne w notatce oznaczonej etykietą #inbox.", + "workspace_inbox": "domyślna lokalizacja skrzynki odbiorczej dla nowych notatek, gdy widok jest zawężony do przodka tej notatki obszaru roboczego", "sql_console_home": "domyślna lokalizacja notatek konsoli SQL", "bookmark_folder": "notatka z tą etykietą pojawi się w zakładkach jako folder (umożliwiając dostęp do jej dzieci)", - "share_hidden_from_tree": "ta notatka jest ukryta w lewym drzewie nawigacyjnym, ale nadal dostępna pod swoim adresem URL", + "share_hidden_from_tree": "ta notatka jest ukryta w lewym drzewie nawigacyjnym, ale nadal dostępna przez jej adres URL", "share_external_link": "notatka będzie działać jako link do zewnętrznej strony internetowej w drzewie udostępniania", - "share_alias": "zdefiniuj alias, za pomocą którego notatka będzie dostępna pod adresem https://your_trilium_host/share/[your_alias]", - "share_omit_default_css": "domyślny CSS strony udostępniania zostanie pominięty. Użyj, gdy wprowadzasz obszerne zmiany w stylizacji.", - "share_root": "oznacza notatkę, która jest serwowana w katalogu głównym /share.", - "share_description": "zdefiniuj tekst, który ma być dodany do metatagu HTML dla opisu", - "share_raw": "notatka będzie serwowana w surowym formacie, bez opakowania HTML", - "share_disallow_robot_indexing": "zabroni robotom indeksowania tej notatki za pomocą nagłówka X-Robots-Tag: noindex", - "share_credentials": "wymagaj poświadczeń, aby uzyskać dostęp do tej udostępnionej notatki. Oczekuje się, że wartość będzie w formacie 'nazwa_użytkownika:hasło'. Nie zapomnij uczynić tego dziedzicznym, aby zastosować do notatek podrzędnych/obrazów.", - "share_index": "notatka z tą etykietą będzie zawierać listę wszystkich korzeni udostępnionych notatek", - "display_relations": "rozdzielone przecinkami nazwy relacji, które powinny być wyświetlane. Wszystkie inne będą ukryte.", - "hide_relations": "rozdzielone przecinkami nazwy relacji, które powinny być ukryte. Wszystkie inne będą wyświetlane.", - "title_template": "domyślny tytuł notatek tworzonych jako dzieci tej notatki. Wartość jest oceniana jako ciąg znaków JavaScript\n i dlatego może być wzbogacona o dynamiczną treść za pomocą wstrzykniętych zmiennych now i parentNote. Przykłady:\n \n
    \n
  • ${parentNote.getLabelValue('authorName')}'s literary works
  • \n
  • Log for ${now.format('YYYY-MM-DD HH:mm:ss')}
  • \n
\n \n Zobacz wiki ze szczegółami, dokumentację API dla parentNote i now, aby uzyskać szczegółowe informacje.", + "share_alias": "zdefiniuj alias, za pomocą którego notatka będzie dostępna pod adresem https://twoj_host_trilium/share/[twoj_alias]", + "share_omit_default_css": "domyślny CSS strony udostępniania zostanie pominięty. Użyj, gdy wprowadzasz obszerne zmiany w stylu.", + "share_root": "oznacza notatkę, która jest serwowana pod adresem /share root.", + "share_description": "zdefiniuj tekst, który ma zostać dodany do tagu meta HTML description", + "share_raw": "notatka będzie serwowana w formacie surowym, bez otoczki HTML", + "share_disallow_robot_indexing": "zakaże indeksowania tej notatki przez roboty za pomocą nagłówka X-Robots-Tag: noindex", + "share_credentials": "wymagaj poświadczeń, aby uzyskać dostęp do tej udostępnionej notatki. Wartość powinna być w formacie 'użytkownik:hasło'. Nie zapomnij uczynić tego dziedziczonym, aby zastosować do notatek podrzędnych/obrazów.", + "share_index": "notatka z tą etykietą wylistuje wszystkie korzenie udostępnionych notatek", + "display_relations": "oddzielone przecinkami nazwy relacji, które powinny być wyświetlane. Wszystkie inne zostaną ukryte.", + "hide_relations": "oddzielone przecinkami nazwy relacji, które powinny być ukryte. Wszystkie inne zostaną wyświetlone.", + "title_template": "domyślny tytuł notatek utworzonych jako dzieci tej notatki. Wartość jest ewaluowana jako ciąg JavaScript \n i dzięki temu może być wzbogacona o dynamiczną zawartość za pomocą wstrzykniętych zmiennych now i parentNote. Przykłady:\n \n
    \n
  • Dzieła literackie ${parentNote.getLabelValue('authorName')}
  • \n
  • Log z ${now.format('YYYY-MM-DD HH:mm:ss')}
  • \n
\n \n Zobacz wiki ze szczegółami, dokumentację API dla parentNote oraz now po więcej szczegółów.", "template": "Ta notatka pojawi się w wyborze dostępnych szablonów podczas tworzenia nowej notatki", - "toc": "#toc lub #toc=show wymusi wyświetlenie spisu treści, #toc=hide wymusi jego ukrycie. Jeśli etykieta nie istnieje, obserwowane jest ustawienie globalne", - "color": "definiuje kolor notatki w drzewie notatek, linkach itp. Użyj dowolnej prawidłowej wartości koloru CSS, np. 'red' lub #a13d5f", - "keyboard_shortcut": "Definiuje skrót klawiaturowy, który natychmiast przejdzie do tej notatki. Przykład: 'ctrl+alt+e'. Wymaga ponownego załadowania frontendu, aby zmiana zaczęła obowiązywać.", - "keep_current_hoisting": "Otwarcie tego linku nie zmieni podniesienia, nawet jeśli notatka nie jest wyświetlana w bieżącym podniesionym poddrzewie.", + "toc": "#toc lub #toc=show wymusi pokazanie spisu treści, #toc=hide wymusi jego ukrycie. Jeśli etykieta nie istnieje, przestrzegane jest ustawienie globalne", + "color": "definiuje kolor notatki w drzewie notatek, linkach itp. Użyj dowolnej poprawnej wartości koloru CSS, np. 'red' lub #a13d5f", + "keyboard_shortcut": "Definiuje skrót klawiszowy, który natychmiast przeskoczy do tej notatki. Przykład: 'ctrl+alt+e'. Wymaga przeładowania frontendu, aby zmiana weszła w życie.", + "keep_current_hoisting": "Otwarcie tego linku nie zmieni zawężenia widoku (hoisting), nawet jeśli notatka nie jest widoczna w obecnie zawężonym poddrzewie.", "execute_button": "Tytuł przycisku, który wykona bieżącą notatkę kodu", "execute_description": "Dłuższy opis bieżącej notatki kodu wyświetlany razem z przyciskiem wykonania", - "exclude_from_note_map": "Notatki z tą etykietą będą ukryte na Mapie Notatek", + "exclude_from_note_map": "Notatki z tą etykietą będą ukryte na Mapie notatek", "new_notes_on_top": "Nowe notatki będą tworzone na górze notatki nadrzędnej, a nie na dole.", "hide_highlight_widget": "Ukryj widżet listy wyróżnień", - "run_on_note_creation": "wykonuje się, gdy notatka jest tworzona na backendzie. Użyj tej relacji, jeśli chcesz uruchomić skrypt dla wszystkich notatek utworzonych w określonym poddrzewie. W takim przypadku utwórz ją w korzeniu poddrzewa i uczyń dziedziczną. Nowa notatka utworzona w poddrzewie (na dowolnej głębokości) uruchomi skrypt.", - "run_on_child_note_creation": "wykonuje się, gdy nowa notatka jest tworzona pod notatką, w której zdefiniowano tę relację", - "run_on_note_title_change": "wykonuje się, gdy tytuł notatki jest zmieniany (obejmuje również tworzenie notatki)", - "run_on_note_content_change": "wykonuje się, gdy zawartość notatki jest zmieniana (obejmuje również tworzenie notatki).", - "run_on_note_change": "wykonuje się, gdy notatka jest zmieniana (obejmuje również tworzenie notatki). Nie obejmuje zmian w zawartości", + "run_on_note_creation": "wykonuje się, gdy notatka jest tworzona na backendzie. Użyj tej relacji, jeśli chcesz uruchomić skrypt dla wszystkich notatek utworzonych w określonym poddrzewie. W takim przypadku utwórz go w notatce korzenia poddrzewa i uczyń go dziedziczonym. Nowa notatka utworzona w poddrzewie (na dowolnej głębokości) wyzwoli skrypt.", + "run_on_child_note_creation": "wykonuje się, gdy nowa notatka jest tworzona pod notatką, w której zdefiniowana jest ta relacja", + "run_on_note_title_change": "wykonuje się, gdy tytuł notatki zostanie zmieniony (obejmuje również utworzenie notatki)", + "run_on_note_content_change": "wykonuje się, gdy treść notatki zostanie zmieniona (obejmuje również utworzenie notatki).", + "run_on_note_change": "wykonuje się, gdy notatka zostanie zmieniona (obejmuje również utworzenie notatki). Nie obejmuje zmian treści", "run_on_note_deletion": "wykonuje się, gdy notatka jest usuwana", - "run_on_branch_creation": "wykonuje się, gdy tworzona jest gałąź. Gałąź to połączenie między notatką nadrzędną a podrzędną i jest tworzona np. podczas klonowania lub przenoszenia notatki.", + "run_on_branch_creation": "wykonuje się, gdy tworzona jest gałąź. Gałąź to połączenie między notatką nadrzędną a podrzędną, tworzone np. podczas klonowania lub przenoszenia notatki.", "run_on_branch_change": "wykonuje się, gdy gałąź jest aktualizowana.", - "run_on_branch_deletion": "wykonuje się, gdy gałąź jest usuwana. Gałąź to połączenie między notatką nadrzędną a podrzędną i jest usuwana np. podczas przenoszenia notatki (stara gałąź/link jest usuwana).", + "run_on_branch_deletion": "wykonuje się, gdy gałąź jest usuwana. Gałąź to połączenie między notatką nadrzędną a podrzędną, usuwane np. podczas przenoszenia notatki (stara gałąź/link jest usuwana).", "run_on_attribute_creation": "wykonuje się, gdy tworzony jest nowy atrybut dla notatki, która definiuje tę relację", - "run_on_attribute_change": " wykonuje się, gdy atrybut jest zmieniany w notatce, która definiuje tę relację. Jest to również wyzwalane, gdy atrybut jest usuwany", - "relation_template": "atrybuty notatki będą dziedziczone nawet bez relacji rodzic-dziecko, zawartość i poddrzewo notatki zostaną dodane do notatek instancji, jeśli są puste. Zobacz dokumentację, aby uzyskać szczegółowe informacje.", - "inherit": "atrybuty notatki będą dziedziczone nawet bez relacji rodzic-dziecko. Zobacz relację szablonu dla podobnego konceptu. Zobacz dziedziczenie atrybutów w dokumentacji.", - "render_note": "notatki typu \"renderuj notatkę HTML\" będą renderowane za pomocą notatki kodu (HTML lub skrypt) i konieczne jest wskazanie za pomocą tej relacji, która notatka ma być renderowana", + "run_on_attribute_change": " wykonuje się, gdy zmieniany jest atrybut notatki, która definiuje tę relację. Jest to wyzwalane również, gdy atrybut jest usuwany", + "relation_template": "atrybuty notatki będą dziedziczone nawet bez relacji rodzic-dziecko, treść notatki i poddrzewo zostaną dodane do notatek instancji, jeśli są puste. Zobacz dokumentację, aby uzyskać szczegóły.", + "inherit": "atrybuty notatki będą dziedziczone nawet bez relacji rodzic-dziecko. Zobacz relację szablonu dla podobnej koncepcji. Zobacz dziedziczenie atrybutów w dokumentacji.", + "render_note": "notatki typu \"render HTML note\" będą renderowane przy użyciu notatki kodu (HTML lub skrypt) i konieczne jest wskazanie za pomocą tej relacji, która notatka powinna zostać wyrenderowana", "widget_relation": "cel tej relacji zostanie wykonany i wyrenderowany jako widżet na pasku bocznym", - "share_css": "Notatka CSS, która zostanie wstrzyknięta na stronę udostępniania. Notatka CSS musi również znajdować się w udostępnionym poddrzewie. Rozważ również użycie 'share_hidden_from_tree' i 'share_omit_default_css'.", - "share_js": "Notatka JavaScript, która zostanie wstrzyknięta na stronę udostępniania. Notatka JS musi również znajdować się w udostępnionym poddrzewie. Rozważ użycie 'share_hidden_from_tree'.", - "share_template": "Wbudowana notatka JavaScript, która będzie używana jako szablon do wyświetlania udostępnionej notatki. W razie niepowodzenia używany jest domyślny szablon. Rozważ użycie 'share_hidden_from_tree'.", - "share_favicon": "Notatka favicon do ustawienia na udostępnionej stronie. Zazwyczaj chcesz ustawić ją w katalogu głównym udostępniania i uczynić ją dziedziczną. Notatka favicon musi również znajdować się w udostępnionym poddrzewie. Rozważ użycie 'share_hidden_from_tree'.", + "share_css": "Notatka CSS, która zostanie wstrzyknięta na stronę udostępniania. Notatka CSS musi znajdować się również w udostępnionym poddrzewie. Rozważ użycie również 'share_hidden_from_tree' i 'share_omit_default_css'.", + "share_js": "Notatka JavaScript, która zostanie wstrzyknięta na stronę udostępniania. Notatka JS musi znajdować się również w udostępnionym poddrzewie. Rozważ użycie 'share_hidden_from_tree'.", + "share_template": "Osadzona notatka JavaScript, która zostanie użyta jako szablon do wyświetlania udostępnionej notatki. W przypadku braku używany jest szablon domyślny. Rozważ użycie 'share_hidden_from_tree'.", + "share_favicon": "Notatka Favicon do ustawienia na udostępnionej stronie. Zazwyczaj chcesz ustawić ją w korzeniu udostępniania i uczynić dziedziczoną. Notatka Favicon musi znajdować się również w udostępnionym poddrzewie. Rozważ użycie 'share_hidden_from_tree'.", "is_owned_by_note": "jest własnością notatki", - "other_notes_with_name": "Inne notatki z nazwą {{attributeType}} \"{{attributeName}}\"", + "other_notes_with_name": "Inne notatki z {{attributeType}} nazwa \"{{attributeName}}\"", "and_more": "... i {{count}} więcej.", - "print_landscape": "Podczas eksportowania do formatu PDF zmienia orientację strony na poziomą zamiast pionowej.", - "print_page_size": "Podczas eksportowania do formatu PDF zmienia rozmiar strony. Obsługiwane wartości: A0, A1, A2, A3, A4, A5, A6, Legal, Letter, Tabloid, Ledger.", + "print_landscape": "Podczas eksportowania do PDF zmienia orientację strony na poziomą zamiast pionowej.", + "print_page_size": "Podczas eksportowania do PDF zmienia rozmiar strony. Obsługiwane wartości: A0, A1, A2, A3, A4, A5, A6, Legal, Letter, Tabloid, Ledger.", "color_type": "Kolor" }, "import": { "importIntoNote": "Importuj do notatki", - "chooseImportFile": "Wybierz plik do zaimportowania", - "importDescription": "Zawartość wybranego pliku(ów) zostanie zaimportowana jako notatka(i) podrzędna(e) do", + "chooseImportFile": "Wybierz plik importu", + "importDescription": "Zawartość wybranego pliku/plików zostanie zaimportowana jako notatka/notatki podrzędne do", "options": "Opcje", "shrinkImages": "Zmniejsz obrazy", "safeImport": "Bezpieczny import", "import-status": "Status importu", - "in-progress": "Import w trakcie: {{progress}}", - "successful": "Importowanie zakończone sukcesem.", - "safeImportTooltip": "Pliki eksportu Trilium .zip mogą zawierać skrypty wykonywalne, które mogą powodować szkodliwe zachowania. Bezpieczny import dezaktywuje automatyczne wykonywanie wszystkich importowanych skryptów. Odznacz opcję „Bezpieczny import” tylko wtedy, gdy importowane archiwum ma zawierać skrypty wykonywalne i masz pełne zaufanie do zawartości importowanego pliku.", - "import": "Import", - "failed": "Błąd importu: {{message}}.", + "in-progress": "Import w toku: {{progress}}", + "successful": "Import zakończony pomyślnie.", + "safeImportTooltip": "Pliki eksportu .zip Trilium mogą zawierać skrypty wykonywalne, które mogą mieć szkodliwe działanie. Bezpieczny import dezaktywuje automatyczne wykonywanie wszystkich zaimportowanych skryptów. Odznacz \"Bezpieczny import\" tylko wtedy, gdy importowane archiwum ma zawierać skrypty i całkowicie ufasz zawartości pliku importu.", + "import": "Importuj", + "failed": "Import nie powiódł się: {{message}}.", "html_import_tags": { "title": "Tagi importu HTML", - "description": "Skonfiguruj, które tagi HTML mają zostać zachowane podczas importowania notatek. Tagi spoza tej listy zostaną usunięte podczas importu. Niektóre tagi (np. „script”) są zawsze usuwane ze względów bezpieczeństwa.", - "placeholder": "Wpisz tagi HTML, jedna na linijkę", - "reset_button": "Zresetuj do domyślnej listy" + "description": "Skonfiguruj, które tagi HTML powinny zostać zachowane podczas importowania notatek. Tagi spoza tej listy zostaną usunięte podczas importu. Niektóre tagi (jak 'script') są zawsze usuwane ze względów bezpieczeństwa.", + "placeholder": "Wprowadź tagi HTML, jeden w wierszu", + "reset_button": "Przywróć listę domyślną" }, - "explodeArchivesTooltip": "Jeśli ta opcja jest zaznaczona, Trilium odczyta pliki .zip, .enex i .opml i utworzy notatki z plików wewnątrz tych archiwów. Jeśli opcja nie jest zaznaczona, Trilium dołączy same archiwa do notatki.", + "explodeArchivesTooltip": "Jeśli zaznaczone, Trilium odczyta pliki .zip, .enex i .opml i utworzy notatki z plików wewnątrz tych archiwów. Jeśli odznaczone, Trilium dołączy same archiwa do notatki.", "explodeArchives": "Czytaj zawartość archiwów .zip, .enex i .opml.", - "shrinkImagesTooltip": "

Jeśli zaznaczysz tę opcję, Trilium spróbuje zmniejszyć importowane obrazy poprzez skalowanie i optymalizację, co może wpłynąć na postrzeganą jakość obrazu. Jeśli opcja nie jest zaznaczona, obrazy zostaną zaimportowane bez zmian.

Nie dotyczy to importów .zip z metadanymi, ponieważ zakłada się, że te pliki są już zoptymalizowane.

", - "textImportedAsText": "Importuj HTML, Markdown i TXT jako notatki tekstowe, jeśli nie jest to jasne z metadanych", - "codeImportedAsCode": "Importuj rozpoznane pliki kodu (np. .json) jako notatki kodu, jeśli nie jest to jasne z metadanych", - "replaceUnderscoresWithSpaces": "Zastąp podkreślenia spacjami w nazwach importowanych notatek" + "shrinkImagesTooltip": "

Jeśli zaznaczysz tę opcję, Trilium spróbuje zmniejszyć importowane obrazy poprzez skalowanie i optymalizację, co może wpłynąć na postrzeganą jakość obrazu. Jeśli odznaczone, obrazy zostaną zaimportowane bez zmian.

Nie dotyczy to importu .zip z metadanymi, ponieważ zakłada się, że te pliki są już zoptymalizowane.

", + "textImportedAsText": "Importuj HTML, Markdown i TXT jako notatki tekstowe, jeśli metadane nie wskazują inaczej", + "codeImportedAsCode": "Importuj rozpoznane pliki kodu (np. .json) jako notatki kodu, jeśli metadane nie wskazują inaczej", + "replaceUnderscoresWithSpaces": "Zamień znaki podkreślenia na spacje w nazwach importowanych notatek", + "importZipRecommendation": "Podczas importowania pliku ZIP hierarchia notatek będzie odzwierciedlać strukturę podkatalogów w archiwum." }, "image_properties": { "title": "Obraz", @@ -411,58 +436,61 @@ "download": "Pobierz", "open": "Otwórz", "copy_reference_to_clipboard": "Kopiuj odniesienie do schowka", - "upload_new_revision": "Wgraj nową wersję", - "upload_success": "Nowa wersja obrazu została wysłana.", - "upload_failed": "Wysyłanie nowej wersji obrazu nie powiodło się: {{message}}" + "upload_new_revision": "Prześlij nową wersję", + "upload_success": "Nowa wersja obrazu została przesłana.", + "upload_failed": "Przesłanie nowej wersji obrazu nie powiodło się: {{message}}" }, "inherited_attribute_list": { - "title": "Odziedziczone atrybuty", - "no_inherited_attributes": "Brak odziedziczonych atrybutów." + "title": "Dziedziczone atrybuty", + "no_inherited_attributes": "Brak dziedziczonych atrybutów.", + "none": "brak" }, "note_info_widget": { "note_id": "ID notatki", - "created": "Stworzona", + "created": "Utworzono", "modified": "Zmodyfikowano", "type": "Typ", "note_size": "Rozmiar notatki", - "note_size_info": "Rozmiar notatki pozwala oszacować przybliżoną ilość miejsca potrzebnego na przechowanie jej. Uwzględnia ona jej treść oraz treść jej poprawek.", + "note_size_info": "Rozmiar notatki zapewnia przybliżone oszacowanie wymagań pamięciowych dla tej notatki. Bierze pod uwagę treść notatki i zawartość jej wersji.", "calculate": "oblicz", "subtree_size": "(rozmiar poddrzewa: {{size}} w {{count}} notatkach)", - "title": "Informacje o notatce" + "title": "Info o notatce", + "show_similar_notes": "Pokaż podobne notatki", + "mime": "Typ MIME" }, "note_map": { - "open_full": "Pełne rozszerzenie", - "collapse": "Zmniejsz do normalnego rozmiaru", - "title": "Mapa notatki", - "fix-nodes": "Napraw węzły", - "link-distance": "Odległość linku" + "open_full": "Rozwiń do pełnego", + "collapse": "Zwiń do normalnego rozmiaru", + "title": "Mapa notatek", + "fix-nodes": "Zablokuj węzły", + "link-distance": "Dystans łączy" }, "note_paths": { "title": "Ścieżki notatki", "clone_button": "Sklonuj notatkę do nowej lokalizacji...", - "intro_placed": "Ta notatka jest umieszczona w następujących lokalizacjach:", - "intro_not_placed": "Ta notatka nie została jeszcze umieszczona w drzewie.", - "outside_hoisted": "Ta ścieżka znajduje się poza podniesioną notatką i trzeba ją odwiesić.", - "archived": "Zarchiwizowane", + "intro_placed": "Ta notatka jest umieszczona w następujących ścieżkach:", + "intro_not_placed": "Ta notatka nie jest jeszcze umieszczona w drzewie notatek.", + "outside_hoisted": "Ta ścieżka znajduje się poza zawężonym widokiem (hoisted note) i musisz cofnąć zawężenie.", + "archived": "Zarchiwizowana", "search": "Szukaj" }, "note_properties": { - "this_note_was_originally_taken_from": "Ta notatka oryginalnie została wzięta z:", + "this_note_was_originally_taken_from": "Ta notatka została pierwotnie pobrana z:", "info": "Info" }, "owned_attribute_list": { "owned_attributes": "Posiadane atrybuty" }, "promoted_attributes": { - "promoted_attributes": "Promowane atrybuty", - "unset-field-placeholder": "nie ustawione", + "promoted_attributes": "Wyróżnione atrybuty", + "unset-field-placeholder": "nie ustawiono", "url_placeholder": "http://strona...", "open_external_link": "Otwórz link zewnętrzny", - "unknown_label_type": "Nieznany typ etykiety \"{{type}}\"", - "unknown_attribute_type": "Nieznany typ atrybutu \"{{type}}\"", + "unknown_label_type": "Nieznany typ etykiety '{{type}}'", + "unknown_attribute_type": "Nieznany typ atrybutu '{{type}}'", "add_new_attribute": "Dodaj nowy atrybut", "remove_this_attribute": "Usuń ten atrybut", - "remove_color": "Usuń ten kolor etykiety" + "remove_color": "Usuń etykietę koloru" }, "script_executor": { "query": "Zapytanie", @@ -471,61 +499,62 @@ "execute_script": "Wykonaj skrypt" }, "search_definition": { - "add_search_option": "Dodaj opcje wyszukiwania:", + "add_search_option": "Dodaj opcję wyszukiwania:", "search_string": "ciąg wyszukiwania", "search_script": "skrypt wyszukiwania", "ancestor": "przodek", "fast_search": "szybkie wyszukiwanie", - "fast_search_description": "Opcja szybkiego wyszukiwania wyłącza pełno tekstowe przeszukiwanie zawartości notatek, co może przyspieszyć przeszukiwanie dużych baz danych.", - "include_archived": "dodaj zarchiwizowane", - "include_archived_notes_description": "Domyślnie zarchiwizowane notatki są wyłączone z wyszukiwania, z tą opcją zostaną dodane do wyszukiwania.", - "order_by": "sortuj", - "limit": "limituj", - "limit_description": "Limituj liczbę wyników", + "fast_search_description": "Opcja szybkiego wyszukiwania wyłącza pełnotekstowe przeszukiwanie treści notatek, co może przyspieszyć wyszukiwanie w dużych bazach danych.", + "include_archived": "uwzględnij zarchiwizowane", + "include_archived_notes_description": "Zarchiwizowane notatki są domyślnie wykluczone z wyników wyszukiwania, ta opcja spowoduje ich uwzględnienie.", + "order_by": "sortuj według", + "limit": "limit", + "limit_description": "Ogranicz liczbę wyników", "save_to_note": "Zapisz do notatki", "search_parameters": "Parametry wyszukiwania", "unknown_search_option": "Nieznana opcja wyszukiwania {{searchOptionName}}", - "search_note_saved": "Wyszukiwana notatka została zapisana do {{- notePathTitle}}", - "actions_executed": "Akcja została wykonana.", - "debug": "debugowanie", - "debug_description": "Debugowanie wydrukuje dodatkowe informacje debugowania w konsoli, aby pomóc w debugowaniu złożonych zapytań", + "search_note_saved": "Notatka wyszukiwania została zapisana w {{- notePathTitle}}", + "actions_executed": "Akcje zostały wykonane.", + "debug": "debug", + "debug_description": "Debugowanie wypisze dodatkowe informacje debugowania w konsoli, aby pomóc w debugowaniu złożonych zapytań", "action": "akcja", "search_button": "Szukaj", - "search_execute": "Szukaj i wykonaj akcje" + "search_execute": "Szukaj i wykonaj akcje", + "view_options": "Ustawienia widoku:" }, "similar_notes": { "title": "Podobne notatki", "no_similar_notes_found": "Nie znaleziono podobnych notatek." }, "abstract_search_option": { - "remove_this_search_option": "Usuń tą opcję wyszukiwania", - "failed_rendering": "Nieudana opcja wyszukiwania: {{dto}} z błędem: {{error}} {{stack}}" + "remove_this_search_option": "Usuń tę opcję wyszukiwania", + "failed_rendering": "Nie udało się wyrenderować opcji wyszukiwania: {{dto}} z błędem: {{error}} {{stack}}" }, "ancestor": { "label": "Przodek", - "placeholder": "szukaj notatki po jej nazwie", - "depth_label": "glębokość", - "depth_doesnt_matter": "nie ważne", - "depth_eq": "jest dokładnie {{count}}", - "direct_children": "bezpośrednie podnotatki", - "depth_gt": "jest więcej niż {{count}}", - "depth_lt": "jest mniej niż {{count}}" + "placeholder": "wyszukaj notatkę po nazwie", + "depth_label": "głębokość", + "depth_doesnt_matter": "nie ma znaczenia", + "depth_eq": "wynosi dokładnie {{count}}", + "direct_children": "bezpośrednie elementy podrzędne", + "depth_gt": "jest większa niż {{count}}", + "depth_lt": "jest mniejsza niż {{count}}" }, "debug": { - "debug": "Debuguj", - "debug_info": "Debugowanie wyświetli dodatkowe informacje debugowania w konsoli, aby ułatwić debugowanie złożonych zapytań.", - "access_info": "Aby uzyskać dostęp do informacji debugowania, wykonaj zapytanie i kliknij \"Pokaż logi backendu\" w lewym górnym rogu." + "debug": "Debug", + "debug_info": "Debugowanie wypisze dodatkowe informacje debugowania w konsoli, aby pomóc w debugowaniu złożonych zapytań.", + "access_info": "Aby uzyskać dostęp do informacji debugowania, wykonaj zapytanie i kliknij \"Pokaż log backendu\" w lewym górnym rogu." }, "fast_search": { "fast_search": "Szybkie wyszukiwanie", - "description": "Opcja szybkiego wyszukiwania wyłącza pełnotekstowe przeszukiwanie zawartości notatek, co może przyspieszyć wyszukiwanie w dużych bazach danych." + "description": "Opcja szybkiego wyszukiwania wyłącza pełnotekstowe przeszukiwanie treści notatek, co może przyspieszyć wyszukiwanie w dużych bazach danych." }, "file_properties": { "download": "Pobierz", - "open": "Otwórz", - "upload_new_revision": "Wgraj nową wersję", - "upload_success": "Nowa wersja pliku nie została wysłana.", - "upload_failed": "Wysyłanie nowej wersji pliku się nie udało.", + "open": "Otwórz zewnętrznie", + "upload_new_revision": "Prześlij nową wersję", + "upload_success": "Nowa wersja pliku została przesłana.", + "upload_failed": "Przesłanie nowej wersji pliku nie powiodło się.", "title": "Plik", "note_id": "ID notatki", "original_file_name": "Oryginalna nazwa pliku", @@ -534,28 +563,29 @@ }, "include_note": { "label_note": "Notatka", - "placeholder_search": "szukaj notatki po jej nazwie", + "placeholder_search": "wyszukaj notatkę po nazwie", "dialog_title": "Dołącz notatkę", "button_include": "Dołącz notatkę", - "box_size_prompt": "Rozmiar okna dołączonej notatki:", + "box_size_prompt": "Rozmiar pola dołączonej notatki:", "box_size_small": "mały (~ 10 linii)", "box_size_medium": "średni (~ 30 linii)", - "box_size_full": "pełny (okno pokazuje cały tekst)" + "box_size_full": "pełny (pole pokazuje cały tekst)" }, "info": { "closeButton": "Zamknij", "okButton": "OK", - "modalTitle": "Wiadomość" + "modalTitle": "Informacja", + "copy_to_clipboard": "Kopiuj do schowka" }, "jump_to_note": { - "search_placeholder": "Szukaj notatki po jej nazwie albo typie > komendy...", - "search_button": "Wyszukiwanie pełno tekstowe" + "search_placeholder": "Szukaj notatki po nazwie lub wpisz > dla poleceń...", + "search_button": "Szukaj w pełnym tekście" }, "markdown_import": { - "dialog_title": "Zaimportuj Markdown", - "import_button": "Import", + "dialog_title": "Import Markdown", + "import_button": "Importuj", "import_success": "Treść Markdown została zaimportowana do dokumentu.", - "modal_body_text": "Ze względu na środowisko przeglądarki nie jest możliwe bezpośrednie odczytanie schowka z JavaScript. Wklej Markdown do importu do poniższego pola tekstowego i kliknij przycisk Importuj" + "modal_body_text": "Ze względu na ograniczenia przeglądarki (sandbox) nie można bezpośrednio odczytać schowka z poziomu JavaScript. Proszę wkleić treść Markdown do zaimportowania w poniższe pole tekstowe i kliknąć przycisk Importuj" }, "limit": { "limit": "Limit", @@ -564,16 +594,17 @@ "link_context_menu": { "open_note_in_popup": "Szybka edycja", "open_note_in_new_tab": "Otwórz notatkę w nowej karcie", - "open_note_in_new_split": "Otwórz notatkę w nowym podziale ekranu", - "open_note_in_new_window": "Otwórz notatkę w nowym oknie" + "open_note_in_new_split": "Otwórz notatkę w nowym podziale", + "open_note_in_new_window": "Otwórz notatkę w nowym oknie", + "open_note_in_other_split": "Otwórz notatkę w drugim podziale" }, "electron_integration": { "desktop-application": "Aplikacja desktopowa", "native-title-bar": "Natywny pasek tytułu", - "native-title-bar-description": "Dla systemów Windows i macOS wyłączenie natywnego paska tytułu sprawia, że aplikacja wygląda bardziej kompaktowo. W systemie Linux włączenie natywnego paska tytułu lepiej integruje się z resztą systemu.", + "native-title-bar-description": "Dla Windows i macOS, wyłączenie natywnego paska tytułu sprawia, że aplikacja wygląda bardziej kompaktowo. Na Linuxie, włączenie natywnego paska tytułu lepiej integruje się z resztą systemu.", "background-effects": "Włącz efekty tła (tylko Windows 11)", "background-effects-description": "Efekt Mica dodaje rozmyte, stylowe tło do okien aplikacji, tworząc głębię i nowoczesny wygląd. \"Natywny pasek tytułu\" musi być wyłączony.", - "restart-app-button": "Uruchom ponownie aplikację, aby zobaczyć zmiany", + "restart-app-button": "Zrestartuj aplikację, aby zobaczyć zmiany", "zoom-factor": "Współczynnik powiększenia" }, "electron_context_menu": { @@ -581,20 +612,21 @@ "copy": "Kopiuj", "copy-link": "Kopiuj link", "paste": "Wklej", - "paste-as-plain-text": "Wklej jako plain text", - "search_online": "Szukaj \"{{term}}\" za pomocą {{searchEngine}}", - "add-term-to-dictionary": "Dodaj \"{{term}}\" do słownika" + "paste-as-plain-text": "Wklej jako zwykły tekst", + "search_online": "Szukaj \"{{term}}\" w {{searchEngine}}", + "add-term-to-dictionary": "Dodaj \"{{term}}\" do słownika", + "search_in_trilium": "Szukaj \"{{term}}\" w Trilium" }, "image_context_menu": { - "copy_reference_to_clipboard": "Skopiuj odnośnik do schowka", - "copy_image_to_clipboard": "Skopiuj obraz do schowka" + "copy_reference_to_clipboard": "Kopiuj odniesienie do schowka", + "copy_image_to_clipboard": "Kopiuj obraz do schowka" }, "note_autocomplete": { "clear-text-field": "Wyczyść pole tekstowe", "show-recent-notes": "Pokaż ostatnie notatki", "full-text-search": "Wyszukiwanie pełnotekstowe", "search-for": "Szukaj \"{{term}}\"", - "create-note": "Utwórz i połącz notatkę podrzędną \"{{term}}\"", + "create-note": "Utwórz i podlinkuj notatkę podrzędną \"{{term}}\"", "insert-external-link": "Wstaw link zewnętrzny do \"{{term}}\"" }, "note_tooltip": { @@ -602,17 +634,17 @@ "quick-edit": "Szybka edycja" }, "duration": { - "seconds": "sekundy", - "minutes": "minuty", - "hours": "godziny", - "days": "dni" + "seconds": "Sekundy", + "minutes": "Minuty", + "hours": "Godziny", + "days": "Dni" }, "share": { "title": "Ustawienia udostępniania", - "redirect_bare_domain": "Przekieruj gołą domenę na stronę udostępniania", - "redirect_bare_domain_description": "Przekieruj anonimowych użytkowników na stronę udostępniania zamiast pokazywać stronę logowania", - "show_login_link": "Pokaż link logowania w motywie udostępniania", - "show_login_link_description": "Dodaj link logowania do stopki strony udostępniania", + "redirect_bare_domain": "Przekieruj domenę główną na stronę Udostępniania", + "redirect_bare_domain_description": "Przekieruj anonimowych użytkowników na stronę Udostępniania zamiast pokazywać Logowanie", + "show_login_link": "Pokaż link Logowania w motywie Udostępniania", + "show_login_link_description": "Dodaj link logowania w stopce strony Udostępniania", "check_share_root": "Sprawdź status korzenia udostępniania", "share_root_found": "Notatka korzenia udostępniania '{{noteTitle}}' jest gotowa", "share_root_not_found": "Nie znaleziono notatki z etykietą #shareRoot", @@ -620,35 +652,37 @@ }, "tasks": { "due": { - "today": "Dziś", + "today": "Dzisiaj", "tomorrow": "Jutro", "yesterday": "Wczoraj" } }, "content_widget": { - "unknown_widget": "Nieznany widget dla \"{{id}}\"." + "unknown_widget": "Nieznany widżet dla \"{{id}}\"." }, "note_language": { - "not_set": "Nie ustawione", - "configure-languages": "Konfiguracja języków..." + "not_set": "Nie ustawiono języka", + "configure-languages": "Konfiguruj języki...", + "help-on-languages": "Pomoc dotycząca języków treści..." }, "content_language": { - "title": "Język treści", - "description": "Wybierz jeden lub więcej języków, które mają być wyświetlane w sekcji Właściwości Podstawowe Notatki Tekstowej tylko do odczytu lub edytowalnej. Umożliwi to korzystanie z takich funkcji, jak sprawdzanie pisowni czy obsługa pisania od prawej do lewej." + "title": "Języki treści", + "description": "Wybierz jeden lub więcej języków, które powinny pojawić się w wyborze języka w sekcji Właściwości podstawowe notatki tekstowej (tylko do odczytu lub edytowalnej). Umożliwi to funkcje takie jak sprawdzanie pisowni lub obsługa zapisu od prawej do lewej." }, "switch_layout_button": { - "title_vertical": "Przesuń panel edycji na dół", - "title_horizontal": "Przesuń panel edycji do lewej" + "title_vertical": "Przenieś panel edycji na dół", + "title_horizontal": "Przenieś panel edycji na lewo" }, "toggle_read_only_button": { "unlock-editing": "Odblokuj edycję", "lock-editing": "Zablokuj edycję" }, "png_export_button": { - "button_title": "Wyeksportuj diagram jako PNG" + "button_title": "Eksportuj diagram jako PNG" }, "svg": { - "export_to_png": "Diagram nie może zostać wyeksportowany jako PNG." + "export_to_png": "Diagram nie mógł zostać wyeksportowany do PNG.", + "export_to_svg": "Diagram nie mógł zostać wyeksportowany do SVG." }, "code_theme": { "title": "Wygląd", @@ -656,51 +690,51 @@ "color-scheme": "Schemat kolorów" }, "cpu_arch_warning": { - "title": "Proszę o pobranie wersji ARM64", - "message_macos": "TriliumNext działa obecnie w oparciu o technologię Rosetta 2, co oznacza, że używasz wersji Intel (x64) na komputerze Mac z procesorem Apple Silicon. Będzie to miało znaczący wpływ na wydajność i czas pracy baterii.", - "message_windows": "TriliumNext działa obecnie w trybie emulacji, co oznacza, że używasz wersji Intel (x64) na urządzeniu z systemem Windows na procesorze ARM. Będzie to miało znaczący wpływ na wydajność i czas pracy baterii.", - "recommendation": "Aby uzyskać najlepsze wrażenia, pobierz natywną wersję ARM64 aplikacji TriliumNext ze strony poświęconej wydaniom.", + "title": "Proszę pobrać wersję ARM64", + "message_macos": "TriliumNext działa obecnie w ramach translacji Rosetta 2, co oznacza, że używasz wersji Intel (x64) na komputerze Mac z procesorem Apple Silicon. Wpłynie to znacząco na wydajność i żywotność baterii.", + "message_windows": "TriliumNext działa obecnie w trybie emulacji, co oznacza, że używasz wersji Intel (x64) na urządzeniu Windows on ARM. Wpłynie to znacząco na wydajność i żywotność baterii.", + "recommendation": "Aby uzyskać najlepsze wrażenia, pobierz natywną wersję ARM64 TriliumNext z naszej strony wydań.", "download_link": "Pobierz wersję natywną", - "continue_anyway": "Kontynuuj mimo wszystko", - "dont_show_again": "Nie pokazuj więcej tego ostrzeżenia" + "continue_anyway": "Kontynuuj mimo to", + "dont_show_again": "Nie pokazuj tego ostrzeżenia ponownie" }, "editorfeatures": { - "title": "Cechy", + "title": "Funkcje", "emoji_completion_enabled": "Włącz autouzupełnianie Emoji", - "note_completion_enabled": "Włącz autouzupełnianie notatki", + "note_completion_enabled": "Włącz autouzupełnianie notatek", "emoji_completion_description": "Jeśli włączone, emoji można łatwo wstawiać do tekstu, wpisując `:`, a następnie nazwę emoji.", "note_completion_description": "Jeśli włączone, linki do notatek można tworzyć, wpisując `@`, a następnie tytuł notatki.", - "slash_commands_enabled": "Włącz polecenia z ukośnikiem", - "slash_commands_description": "Jeśli włączone, polecenia edycji, takie jak wstawianie podziałów wierszy lub nagłówków, można przełączać, wpisując `/`." + "slash_commands_enabled": "Włącz polecenia slash (/)", + "slash_commands_description": "Jeśli włączone, polecenia edycji, takie jak wstawianie podziałów wiersza lub nagłówków, można przełączać, wpisując `/`." }, "table_view": { "new-row": "Nowy wiersz", "new-column": "Nowa kolumna", - "sort-column-by": "Sotuj po \"{{title}}\"", + "sort-column-by": "Sortuj według \"{{title}}\"", "sort-column-ascending": "Rosnąco", "sort-column-descending": "Malejąco", "sort-column-clear": "Wyczyść sortowanie", "hide-column": "Ukryj kolumnę \"{{title}}\"", "show-hide-columns": "Pokaż/ukryj kolumny", - "row-insert-above": "Wstaw wiersz nad", - "row-insert-below": "Wstaw wiersz pod", - "row-insert-child": "Wstaw podnotatkę", + "row-insert-above": "Wstaw wiersz powyżej", + "row-insert-below": "Wstaw wiersz poniżej", + "row-insert-child": "Wstaw notatkę podrzędną", "add-column-to-the-left": "Dodaj kolumnę po lewej", "add-column-to-the-right": "Dodaj kolumnę po prawej", "edit-column": "Edytuj kolumnę", "delete_column_confirmation": "Czy na pewno chcesz usunąć tę kolumnę? Odpowiedni atrybut zostanie usunięty ze wszystkich notatek.", "delete-column": "Usuń kolumnę", "new-column-label": "Etykieta", - "new-column-relation": "Relacje" + "new-column-relation": "Relacja" }, "book_properties_config": { "hide-weekends": "Ukryj weekendy", - "display-week-numbers": "Pokaż numery tygodni", - "map-style": "Styl mapy:", - "max-nesting-depth": "Maksymalna głębokość zagnieżdżenia:", + "display-week-numbers": "Wyświetlaj numery tygodni", + "map-style": "Styl mapy", + "max-nesting-depth": "Maks. głębokość zagnieżdżenia:", "raster": "Raster", - "vector_light": "Wektor (jasny)", - "vector_dark": "Wektor (ciemny)", + "vector_light": "Wektor (Jasny)", + "vector_dark": "Wektor (Ciemny)", "show-scale": "Pokaż skalę" }, "table_context_menu": { @@ -710,54 +744,54 @@ "dialog_title": "Przenieś notatki do ...", "notes_to_move": "Notatki do przeniesienia", "target_parent_note": "Docelowa notatka nadrzędna", - "search_placeholder": "szukaj notatki po jej nazwie", + "search_placeholder": "wyszukaj notatkę po nazwie", "move_button": "Przenieś do wybranej notatki", "error_no_path": "Brak ścieżki do przeniesienia.", "move_success_message": "Wybrane notatki zostały przeniesione do " }, "note_type_chooser": { "modal_title": "Wybierz typ notatki", - "modal_body": "Wybierz typ / szablon notatki dla nowej notatki:", + "modal_body": "Wybierz typ notatki / szablon nowej notatki:", "templates": "Szablony", "builtin_templates": "Wbudowane szablony", - "change_path_prompt": "Zmień ścieżkę, gdzie utworzyć nową notatkę:", - "search_placeholder": "wyszukaj ścieżkę po nazwie (domyślna, jeśli pusta)" + "change_path_prompt": "Zmień miejsce utworzenia nowej notatki:", + "search_placeholder": "szukaj ścieżki po nazwie (domyślna, jeśli puste)" }, "password_not_set": { - "title": "Hasło nie zostało ustawione", - "body1": "Chronione notatki są szyfrowane hasłem użytkownika, ale hasło nie zostało jeszcze ustawione.", - "body2": "Aby móc chronić notatki, kliknij poniższy przycisk, aby otworzyć okno dialogowe Opcje i ustawić hasło.", + "title": "Hasło nie jest ustawione", + "body1": "Chronione notatki są szyfrowane przy użyciu hasła użytkownika, ale hasło nie zostało jeszcze ustawione.", + "body2": "Aby móc chronić notatki, kliknij przycisk poniżej, aby otworzyć okno Opcji i ustawić hasło.", "go_to_password_options": "Przejdź do opcji hasła" }, "add_relation": { - "add_relation": "Dodaj powiązanie", - "relation_name": "nazwa powiązania", + "add_relation": "Dodaj relację", + "relation_name": "nazwa relacji", "allowed_characters": "Dozwolone są znaki alfanumeryczne, podkreślenie i dwukropek.", "to": "do", - "target_note": "docelowa notatka", - "create_relation_on_all_matched_notes": "We wszystkich dopasowanych notatkach utwórz daną relację." + "target_note": "notatka docelowa", + "create_relation_on_all_matched_notes": "Na wszystkich dopasowanych notatkach utwórz podaną relację." }, "ai_llm": { "actions": "Akcje", - "retry": "Spróbuj ponownie", - "partial": "{{ percentage }}% wykonania", - "retry_queued": "notatka dodana do kolejki", - "retry_failed": "Nieudana próba dodania notatki do kolejki", - "max_notes_per_llm_query": "Maksymalna ilość notatek w zapytaniu", - "index_all_notes": "Zindeksuj wszystkie notatki", - "index_status": "Status indeksowania", - "indexed_notes": "Zindeksowane notatki", + "retry": "Ponów", + "partial": "{{ percentage }}% ukończono", + "retry_queued": "Notatka zakolejkowana do ponowienia", + "retry_failed": "Nie udało się zakolejkować notatki do ponowienia", + "max_notes_per_llm_query": "Maks. notatek na zapytanie", + "index_all_notes": "Indeksuj wszystkie notatki", + "index_status": "Status indeksu", + "indexed_notes": "Zaindeksowane notatki", "indexing_stopped": "Indeksowanie zatrzymane", - "indexing_in_progress": "Indeksowanie w trakcie...", - "last_indexed": "Ostatnio zindeksowane", + "indexing_in_progress": "Indeksowanie w toku...", + "last_indexed": "Ostatnio zaindeksowane", "note_chat": "Czat notatki", "note_title": "Tytuł notatki", "error": "Błąd", "last_attempt": "Ostatnia próba", - "queued_notes": "Zakolejkowane notatki", - "failed_notes": "Nieudane notatki", - "last_processed": "Ostatnio procesowane", - "refresh_stats": "Odśwież Statystyki", + "queued_notes": "Notatki w kolejce", + "failed_notes": "Notatki nieudane", + "last_processed": "Ostatnio przetworzone", + "refresh_stats": "Odśwież statystyki", "enable_ai_features": "Włącz funkcje AI/LLM", "enable_ai_description": "Włącz funkcje AI, takie jak podsumowywanie notatek, generowanie treści i inne możliwości LLM", "openai_tab": "OpenAI", @@ -767,44 +801,44 @@ "enable_ai": "Włącz funkcje AI/LLM", "enable_ai_desc": "Włącz funkcje AI, takie jak podsumowywanie notatek, generowanie treści i inne możliwości LLM", "provider_configuration": "Konfiguracja dostawcy AI", - "provider_precedence": "Pierwszeństwo dostawcy", - "provider_precedence_description": "Lista dostawców przedzielonych przecinkami w kolejności (np. „openai,anthropic,ollama”)", + "provider_precedence": "Kolejność dostawców", + "provider_precedence_description": "Lista dostawców oddzielona przecinkami w kolejności pierwszeństwa (np. 'openai,anthropic,ollama')", "temperature": "Temperatura", - "temperature_description": "Kontroluje losowość odpowiedzi (0 = deterministyczna, 2 = maksymalna losowość)", - "system_prompt": "Monit systemowy", - "system_prompt_description": "Domyślny monit systemowy używany do wszystkich interakcji ze sztuczną inteligencją", + "temperature_description": "Kontroluje losowość w odpowiedziach (0 = deterministyczne, 2 = maksymalna losowość)", + "system_prompt": "Prompt systemowy", + "system_prompt_description": "Domyślny prompt systemowy używany dla wszystkich interakcji AI", "openai_configuration": "Konfiguracja OpenAI", "openai_settings": "Ustawienia OpenAI", "api_key": "Klucz API", "url": "Bazowy URL", "model": "Model", - "openai_api_key_description": "Klucz API OpenAI umożliwiający dostęp do usług AI", - "anthropic_api_key_description": "Klucz API Anthropic umożliwiający dostęp do usług AI", - "default_model": "Domyślny Model", + "openai_api_key_description": "Twój klucz API OpenAI do dostępu do ich usług AI", + "anthropic_api_key_description": "Twój klucz API Anthropic do dostępu do modeli Claude", + "default_model": "Domyślny model", "openai_model_description": "Przykłady: gpt-4o, gpt-4-turbo, gpt-3.5-turbo", "base_url": "Bazowy URL", - "openai_url_description": "Domyślny: https://api.openai.com/v1", + "openai_url_description": "Domyślnie: https://api.openai.com/v1", "anthropic_settings": "Ustawienia Anthropic", - "anthropic_url_description": "Bazowy URL dla Anthropic API (domyślny: https://api.anthropic.com)", - "anthropic_model_description": "Modele Anthropic Claude'a do uzupełniania czatów", + "anthropic_url_description": "Bazowy URL dla API Anthropic (domyślnie: https://api.anthropic.com)", + "anthropic_model_description": "Modele Anthropic Claude do czatu", "voyage_settings": "Ustawienia Voyage AI", "ollama_settings": "Ustawienia Ollama", - "ollama_url_description": "URL dla Ollama API (domyślny: http://localhost:11434)", - "ollama_model_description": "Model Ollama używany do uzupełniania czatów", + "ollama_url_description": "URL dla API Ollama (domyślnie: http://localhost:11434)", + "ollama_model_description": "Model Ollama do użycia w czacie", "anthropic_configuration": "Konfiguracja Anthropic", "voyage_configuration": "Konfiguracja Voyage AI", - "voyage_url_description": "Domyślny: https://api.voyageai.com/v1", + "voyage_url_description": "Domyślnie: https://api.voyageai.com/v1", "ollama_configuration": "Konfiguracja Ollama", "enable_ollama": "Włącz Ollama", - "enable_ollama_description": "Włącz Ollama dla lokalnego modelu AI", - "ollama_url": "Ollama URL", + "enable_ollama_description": "Włącz Ollama do lokalnego użycia modeli AI", + "ollama_url": "URL Ollama", "ollama_model": "Model Ollama", "refresh_models": "Odśwież modele", "refreshing_models": "Odświeżanie...", "enable_automatic_indexing": "Włącz automatyczne indeksowanie", - "rebuild_index": "Odbuduj indeks", - "rebuild_index_error": "Błąd uruchomienia odbudowy indeksu. Sprawdź logi.", - "max_notes_per_llm_query_description": "Maksymalna liczba podobnych notatek do uwzględnienia w kontekście sztucznej inteligencji", + "rebuild_index": "Przebuduj indeks", + "rebuild_index_error": "Błąd podczas rozpoczynania przebudowy indeksu. Sprawdź logi po szczegóły.", + "max_notes_per_llm_query_description": "Maksymalna liczba podobnych notatek do uwzględnienia w kontekście AI", "active_providers": "Aktywni dostawcy", "disabled_providers": "Wyłączeni dostawcy", "remove_provider": "Usuń dostawcę z wyszukiwania", @@ -813,38 +847,38 @@ "not_started": "Nie rozpoczęto", "title": "Ustawienia AI", "processed_notes": "Przetworzone notatki", - "total_notes": "Wszystkie notatki", + "total_notes": "Łącznie notatek", "progress": "Postęp", "similarity_threshold_description": "Minimalny wynik podobieństwa (0-1) dla notatek, które mają być uwzględnione w kontekście zapytań LLM", - "reprocess_index": "Odbuduj indeks wyszukiwania", - "reprocessing_index": "Odbudowywanie...", + "reprocess_index": "Przebuduj indeks wyszukiwania", + "reprocessing_index": "Przebudowywanie...", "reprocess_index_started": "Optymalizacja indeksu wyszukiwania rozpoczęta w tle", - "reprocess_index_error": "Błąd odbudowywania indeksu wyszukiwania", - "index_rebuild_progress": "Postęp odbudowy indeksu", - "index_rebuilding": "Optymalizowanie indeksu ({{percentage}}%)", + "reprocess_index_error": "Błąd podczas przebudowy indeksu wyszukiwania", + "index_rebuild_progress": "Postęp przebudowy indeksu", + "index_rebuilding": "Optymalizacja indeksu ({{percentage}}%)", "index_rebuild_complete": "Optymalizacja indeksu zakończona", - "index_rebuild_status_error": "Błąd sprawdzania statusu odbudowy indeksu", + "index_rebuild_status_error": "Błąd podczas sprawdzania statusu przebudowy indeksu", "never": "Nigdy", "processing": "Przetwarzanie ({{percentage}}%)", "incomplete": "Niekompletne ({{percentage}}%)", - "complete": "Ukończono (100%)", + "complete": "Zakończone (100%)", "refreshing": "Odświeżanie...", "auto_refresh_notice": "Automatyczne odświeżanie co {{seconds}} sekund", - "note_queued_for_retry": "Notatka zakolejkowana do ponownej próby", - "failed_to_retry_note": "Nie udało się ponowić próby dla notatki", - "all_notes_queued_for_retry": "Wszystkie nieudane notatki zakolejkowane do ponownej próby", - "failed_to_retry_all": "Nie udało się ponowić próby dla notatek", + "note_queued_for_retry": "Notatka zakolejkowana do ponowienia", + "failed_to_retry_note": "Nie udało się ponowić notatki", + "all_notes_queued_for_retry": "Wszystkie nieudane notatki zakolejkowane do ponowienia", + "failed_to_retry_all": "Nie udało się ponowić notatek", "ai_settings": "Ustawienia AI", - "api_key_tooltip": "Klucz API do uzyskiwania dostępu do usługi", + "api_key_tooltip": "Klucz API do dostępu do usługi", "empty_key_warning": { - "anthropic": "Klucz API Anthropic jest pusty. Wprowadź prawidłowy klucz API.", - "openai": "Klucz API OpenAI jest pusty. Wprowadź prawidłowy klucz API.", - "voyage": "Klucz API Voyage jest pusty. Wprowadź prawidłowy klucz API.", - "ollama": "Klucz API Ollama jest pusty. Wprowadź prawidłowy klucz API." + "anthropic": "Klucz API Anthropic jest pusty. Proszę wprowadzić poprawny klucz API.", + "openai": "Klucz API OpenAI jest pusty. Proszę wprowadzić poprawny klucz API.", + "voyage": "Klucz API Voyage jest pusty. Proszę wprowadzić poprawny klucz API.", + "ollama": "Klucz API Ollama jest pusty. Proszę wprowadzić poprawny klucz API." }, "agent": { "processing": "Przetwarzanie...", - "thinking": "Myślenie...", + "thinking": "Myślę...", "loading": "Ładowanie...", "generating": "Generowanie..." }, @@ -852,23 +886,23 @@ "openai": "OpenAI", "use_enhanced_context": "Użyj rozszerzonego kontekstu", "enhanced_context_description": "Dostarcza AI więcej kontekstu z notatki i jej powiązanych notatek dla lepszych odpowiedzi", - "show_thinking": "Pokaż proces myślowy", - "show_thinking_description": "Pokaż proces myślowy AI", + "show_thinking": "Pokaż proces myślenia", + "show_thinking_description": "Pokaż ciąg myślowy AI", "enter_message": "Wpisz swoją wiadomość...", - "error_contacting_provider": "Błąd kontaktu z dostawcą AI. Sprawdź ustawienia i połączenie internetowe.", + "error_contacting_provider": "Błąd połączenia z dostawcą AI. Sprawdź swoje ustawienia i połączenie internetowe.", "error_generating_response": "Błąd generowania odpowiedzi AI", "sources": "Źródła", "start_indexing": "Rozpocznij indeksowanie", "use_advanced_context": "Użyj zaawansowanego kontekstu", - "ollama_no_url": "Ollama nie jest skonfigurowana. Wprowadź prawidłowy URL.", + "ollama_no_url": "Ollama nie jest skonfigurowana. Proszę wprowadzić poprawny URL.", "chat": { "root_note_title": "Czaty AI", - "root_note_content": "Ta notatka zawiera zapisane rozmowy na czacie AI.", + "root_note_content": "Ta notatka zawiera twoje zapisane rozmowy czatu AI.", "new_chat_title": "Nowy czat", "create_new_ai_chat": "Utwórz nowy czat AI" }, "create_new_ai_chat": "Utwórz nowy czat AI", - "configuration_warnings": "Występują problemy z konfiguracją AI. Sprawdź ustawienia.", + "configuration_warnings": "Istnieją pewne problemy z twoją konfiguracją AI. Proszę sprawdzić ustawienia.", "experimental_warning": "Funkcja LLM jest obecnie eksperymentalna - zostałeś ostrzeżony.", "selected_provider": "Wybrany dostawca", "selected_provider_description": "Wybierz dostawcę AI dla funkcji czatu i uzupełniania", @@ -876,8 +910,8 @@ "select_provider": "Wybierz dostawcę...", "ai_enabled": "Funkcje AI włączone", "ai_disabled": "Funkcje AI wyłączone", - "no_models_found_online": "Nie znaleziono modeli. Sprawdź swój klucz API i ustawienia.", - "no_models_found_ollama": "Nie znaleziono modeli Ollama. Sprawdź, czy Ollama jest uruchomiona.", + "no_models_found_online": "Nie znaleziono modeli. Proszę sprawdzić klucz API i ustawienia.", + "no_models_found_ollama": "Nie znaleziono modeli Ollama. Proszę sprawdzić, czy Ollama jest uruchomiona.", "error_fetching": "Błąd pobierania modeli: {{error}}" }, "prompt": { @@ -887,18 +921,18 @@ }, "protected_session_password": { "modal_title": "Sesja chroniona", - "help_title": "Pomoc dotycząca notatek chronionych", + "help_title": "Pomoc dotycząca chronionych notatek", "close_label": "Zamknij", "form_label": "Aby kontynuować żądaną akcję, musisz rozpocząć sesję chronioną, wprowadzając hasło:", "start_button": "Rozpocznij sesję chronioną" }, "recent_changes": { "title": "Ostatnie zmiany", - "erase_notes_button": "Wymaż teraz usunięte notatki", + "erase_notes_button": "Wymaż usunięte notatki teraz", "deleted_notes_message": "Usunięte notatki zostały wymazane.", "no_changes_message": "Brak zmian...", "undelete_link": "przywróć", - "confirm_undelete": "Czy chcesz przywrócić tę notatkę i jej podnotatki?" + "confirm_undelete": "Czy chcesz przywrócić tę notatkę i jej pod-notatki?" }, "revisions": { "note_revisions": "Wersje notatki", @@ -909,18 +943,18 @@ "no_revisions": "Brak wersji dla tej notatki...", "restore_button": "Przywróć", "diff_on": "Pokaż różnice", - "diff_off": "Pokaż zawartość", + "diff_off": "Pokaż treść", "diff_on_hint": "Kliknij, aby pokazać różnice w źródle notatki", - "diff_off_hint": "Kliknij, aby pokazać zawartość notatki", + "diff_off_hint": "Kliknij, aby pokazać treść notatki", "diff_not_available": "Różnice nie są dostępne.", - "confirm_restore": "Czy chcesz przywrócić tę wersję? Spowoduje to nadpisanie bieżącego tytułu i zawartości notatki tą wersją.", + "confirm_restore": "Czy chcesz przywrócić tę wersję? Spowoduje to nadpisanie obecnego tytułu i treści notatki tą wersją.", "delete_button": "Usuń", "confirm_delete": "Czy chcesz usunąć tę wersję?", "revisions_deleted": "Wersje notatki zostały usunięte.", "revision_restored": "Wersja notatki została przywrócona.", "revision_deleted": "Wersja notatki została usunięta.", - "snapshot_interval": "Interwał migawki wersji notatki: {{seconds}}s.", - "maximum_revisions": "Limit migawek wersji notatki: {{number}}.", + "snapshot_interval": "Interwał zrzutu wersji notatki: {{seconds}}s.", + "maximum_revisions": "Limit zrzutów wersji notatki: {{number}}.", "settings": "Ustawienia wersji notatki", "download_button": "Pobierz", "mime": "MIME: ", @@ -939,10 +973,10 @@ "descending": "malejąco", "folders": "Foldery", "sort_folders_at_top": "sortuj foldery na górze", - "natural_sort": "Sortowanie naturalne", - "sort_with_respect_to_different_character_sorting": "sortuj z uwzględnieniem różnych zasad sortowania znaków i zestawień w różnych językach lub regionach.", - "natural_sort_language": "Język sortowania naturalnego", - "the_language_code_for_natural_sort": "Kod języka dla sortowania naturalnego, np. \"zh-CN\" dla chińskiego.", + "natural_sort": "Naturalne sortowanie", + "sort_with_respect_to_different_character_sorting": "sortuj z uwzględnieniem różnych zasad sortowania znaków w różnych językach lub regionach.", + "natural_sort_language": "Język naturalnego sortowania", + "the_language_code_for_natural_sort": "Kod języka dla naturalnego sortowania, np. \"pl-PL\" dla polskiego.", "sort": "Sortuj" }, "upload_attachments": { @@ -952,10 +986,10 @@ "options": "Opcje", "shrink_images": "Zmniejsz obrazy", "upload": "Prześlij", - "tooltip": "Jeśli zaznaczysz tę opcję, Trilium spróbuje zmniejszyć przesyłane obrazy poprzez skalowanie i optymalizację, co może wpłynąć na postrzeganą jakość obrazu. Jeśli opcja nie jest zaznaczona, obrazy zostaną przesłane bez zmian." + "tooltip": "Jeśli zaznaczysz tę opcję, Trilium spróbuje zmniejszyć przesłane obrazy poprzez skalowanie i optymalizację, co może wpłynąć na postrzeganą jakość obrazu. Jeśli odznaczone, obrazy zostaną przesłane bez zmian." }, "attribute_editor": { - "help_text_body1": "Aby dodać etykietę, po prostu wpisz np. #rock lub jeśli chcesz dodać również wartość, to np. #year = 2020", + "help_text_body1": "Aby dodać etykietę, po prostu wpisz np. #rock lub jeśli chcesz dodać również wartość, np. #year = 2020", "help_text_body2": "Dla relacji wpisz ~author = @, co powinno wywołać autouzupełnianie, w którym możesz wyszukać żądaną notatkę.", "help_text_body3": "Alternatywnie możesz dodać etykietę i relację za pomocą przycisku + po prawej stronie.", "save_attributes": "Zapisz atrybuty ", @@ -972,7 +1006,7 @@ "execute_script": { "execute_script": "Wykonaj skrypt", "help_text": "Możesz wykonywać proste skrypty na dopasowanych notatkach.", - "example_1": "Na przykład, aby dołączyć ciąg znaków do tytułu notatki, użyj tego małego skryptu:", + "example_1": "Na przykład, aby dodać ciąg znaków do tytułu notatki, użyj tego małego skryptu:", "example_2": "Bardziej złożonym przykładem byłoby usunięcie wszystkich atrybutów dopasowanej notatki:" }, "delete_label": { @@ -992,41 +1026,41 @@ "update_label_value": "Zaktualizuj wartość etykiety", "label_name_placeholder": "nazwa etykiety", "label_name_title": "Dozwolone są znaki alfanumeryczne, podkreślenie i dwukropek.", - "to_value": "do wartości", + "to_value": "na wartość", "new_value_placeholder": "nowa wartość", - "help_text": "We wszystkich dopasowanych notatkach zmień wartość istniejącej etykiety.", + "help_text": "Na wszystkich dopasowanych notatkach zmień wartość istniejącej etykiety.", "help_text_note": "Możesz również wywołać tę metodę bez wartości, w takim przypadku etykieta zostanie przypisana do notatki bez wartości." }, "delete_note": { "delete_note": "Usuń notatkę", "delete_matched_notes": "Usuń dopasowane notatki", - "delete_matched_notes_description": "Spowoduje to usunięcie dopasowanych notatek.", - "undelete_notes_instruction": "Po usunięciu można je przywrócić z okna dialogowego Ostatnie zmiany.", - "erase_notes_instruction": "Aby trwale usunąć notatki, możesz po usunięciu przejść do Opcje -> Inne i kliknąć przycisk \"Wymaż teraz usunięte notatki\"." + "delete_matched_notes_description": "To spowoduje usunięcie dopasowanych notatek.", + "undelete_notes_instruction": "Po usunięciu możliwe jest ich przywrócenie w oknie Ostatnie zmiany.", + "erase_notes_instruction": "Aby trwale wymazać notatki, możesz po usunięciu przejść do Opcje -> Inne i kliknąć przycisk \"Wymaż usunięte notatki teraz\"." }, "delete_revisions": { - "delete_note_revisions": "Usuń wersje notatek", + "delete_note_revisions": "Usuń wersje notatki", "all_past_note_revisions": "Wszystkie przeszłe wersje dopasowanych notatek zostaną usunięte. Sama notatka zostanie w pełni zachowana. Innymi słowy, historia notatki zostanie usunięta." }, "move_note": { "move_note": "Przenieś notatkę", "to": "do", "target_parent_note": "docelowa notatka nadrzędna", - "on_all_matched_notes": "We wszystkich dopasowanych notatkach", + "on_all_matched_notes": "Na wszystkich dopasowanych notatkach", "move_note_new_parent": "przenieś notatkę do nowego rodzica, jeśli notatka ma tylko jednego rodzica (tj. stara gałąź jest usuwana, a nowa gałąź do nowego rodzica jest tworzona)", "clone_note_new_parent": "sklonuj notatkę do nowego rodzica, jeśli notatka ma wiele klonów/gałęzi (nie jest jasne, która gałąź powinna zostać usunięta)", - "nothing_will_happen": "nic się nie stanie, jeśli notatka nie może być przeniesiona do notatki docelowej (tj. spowodowałoby to cykl w drzewie)" + "nothing_will_happen": "nic się nie stanie, jeśli notatki nie można przenieść do notatki docelowej (tj. utworzyłoby to cykl w drzewie)" }, "rename_note": { "rename_note": "Zmień nazwę notatki", "rename_note_title_to": "Zmień tytuł notatki na", "new_note_title": "nowy tytuł notatki", "click_help_icon": "Kliknij ikonę pomocy po prawej stronie, aby zobaczyć wszystkie opcje", - "evaluated_as_js_string": "Podana wartość jest oceniana jako ciąg znaków JavaScript i dlatego może być wzbogacona o dynamiczną treść za pomocą wstrzykniętej zmiennej note (notatka, której nazwa jest zmieniana). Przykłady:", - "example_note": "Notatka - wszystkie dopasowane notatki mają zmienioną nazwę na 'Notatka'", - "example_new_title": "NOWY: ${note.title} - tytuły dopasowanych notatek są poprzedzone prefiksem 'NOWY: '", - "example_date_prefix": "${note.dateCreatedObj.format('MM-DD:')}: ${note.title} - dopasowane notatki są poprzedzone prefiksem miesiąc-dzień utworzenia notatki", - "api_docs": "Zobacz dokumentację API dla note i jej właściwości dateCreatedObj / utcDateCreatedObj, aby uzyskać szczegółowe informacje." + "evaluated_as_js_string": "Podana wartość jest ewaluowana jako ciąg JavaScript i dzięki temu może być wzbogacona o dynamiczną zawartość za pomocą wstrzykniętej zmiennej note (zmieniana notatka). Przykłady:", + "example_note": "Notatka - wszystkie dopasowane notatki zmieniają nazwę na 'Notatka'", + "example_new_title": "NOWA: ${note.title} - tytuły dopasowanych notatek są poprzedzone prefiksem 'NOWA: '", + "example_date_prefix": "${note.dateCreatedObj.format('MM-DD:')}: ${note.title} - dopasowane notatki są poprzedzone miesiącem i dniem utworzenia notatki", + "api_docs": "Zobacz dokumentację API dla notatki i jej właściwości dateCreatedObj / utcDateCreatedObj po szczegóły." }, "delete_relation": { "delete_relation": "Usuń relację", @@ -1047,15 +1081,15 @@ "allowed_characters": "Dozwolone są znaki alfanumeryczne, podkreślenie i dwukropek.", "to": "do", "target_note": "notatka docelowa", - "on_all_matched_notes": "We wszystkich dopasowanych notatkach", + "on_all_matched_notes": "Na wszystkich dopasowanych notatkach", "change_target_note": "zmień notatkę docelową istniejącej relacji", "update_relation_target": "Zaktualizuj cel relacji" }, "attachments_actions": { "open_externally": "Otwórz zewnętrznie", - "open_externally_title": "Plik zostanie otwarty w zewnętrznej aplikacji i będzie obserwowany pod kątem zmian. Następnie będziesz mógł przesłać zmodyfikowaną wersję z powrotem do Trilium.", + "open_externally_title": "Plik zostanie otwarty w zewnętrznej aplikacji i będzie monitorowany pod kątem zmian. Następnie będzie można przesłać zmodyfikowaną wersję z powrotem do Trilium.", "open_custom": "Otwórz niestandardowo", - "open_custom_title": "Plik zostanie otwarty w zewnętrznej aplikacji i będzie obserwowany pod kątem zmian. Następnie będziesz mógł przesłać zmodyfikowaną wersję z powrotem do Trilium.", + "open_custom_title": "Plik zostanie otwarty w zewnętrznej aplikacji i będzie monitorowany pod kątem zmian. Następnie będzie można przesłać zmodyfikowaną wersję z powrotem do Trilium.", "download": "Pobierz", "rename_attachment": "Zmień nazwę załącznika", "upload_new_revision": "Prześlij nową wersję", @@ -1063,14 +1097,14 @@ "convert_attachment_into_note": "Konwertuj załącznik na notatkę", "delete_attachment": "Usuń załącznik", "upload_success": "Nowa wersja załącznika została przesłana.", - "upload_failed": "Przesyłanie nowej wersji załącznika nie powiodło się.", - "open_externally_detail_page": "Otwieranie załącznika zewnętrznie jest dostępne tylko ze strony szczegółów, najpierw kliknij szczegóły załącznika i powtórz akcję.", - "open_custom_client_only": "Niestandardowe otwieranie załączników można wykonać tylko z klienta stacjonarnego.", + "upload_failed": "Przesłanie nowej wersji załącznika nie powiodło się.", + "open_externally_detail_page": "Otwieranie załącznika zewnętrznie jest dostępne tylko ze strony szczegółów, proszę najpierw kliknąć na szczegóły załącznika i powtórzyć akcję.", + "open_custom_client_only": "Niestandardowe otwieranie załączników można wykonać tylko w kliencie desktopowym.", "delete_confirm": "Czy na pewno chcesz usunąć załącznik '{{title}}'?", "delete_success": "Załącznik '{{title}}' został usunięty.", - "convert_confirm": "Czy na pewno chcesz przekonwertować załącznik '{{title}}' na osobną notatkę?", + "convert_confirm": "Czy na pewno chcesz przekonwertować załącznik '{{title}}' na oddzielną notatkę?", "convert_success": "Załącznik '{{title}}' został przekonwertowany na notatkę.", - "enter_new_name": "Wprowadź nową nazwę załącznika" + "enter_new_name": "Proszę wprowadzić nową nazwę załącznika" }, "calendar": { "mon": "Pon", @@ -1079,7 +1113,7 @@ "thu": "Czw", "fri": "Pt", "sat": "Sob", - "sun": "Niedz", + "sun": "Ndz", "cannot_find_day_note": "Nie można znaleźć notatki dziennej", "cannot_find_week_note": "Nie można znaleźć notatki tygodniowej", "january": "Styczeń", @@ -1116,35 +1150,35 @@ "edit_this_note": "Edytuj tę notatkę" }, "show_toc_widget_button": { - "show_toc": "Pokaż spis treści" + "show_toc": "Pokaż Spis Treści" }, "show_highlights_list_widget_button": { - "show_highlights_list": "Pokaż listę wyróżnień" + "show_highlights_list": "Pokaż Listę Wyróżnień" }, "global_menu": { "menu": "Menu", "options": "Opcje", "open_new_window": "Otwórz nowe okno", "switch_to_mobile_version": "Przełącz na wersję mobilną", - "switch_to_desktop_version": "Przełącz na wersję stacjonarną", + "switch_to_desktop_version": "Przełącz na wersję desktopową", "zoom": "Powiększenie", "toggle_fullscreen": "Przełącz pełny ekran", "zoom_out": "Pomniejsz", "reset_zoom_level": "Zresetuj poziom powiększenia", "zoom_in": "Powiększ", - "configure_launchbar": "Skonfiguruj pasek uruchamiania", + "configure_launchbar": "Konfiguruj pasek szybkiego dostępu", "show_shared_notes_subtree": "Pokaż poddrzewo udostępnionych notatek", "advanced": "Zaawansowane", "open_dev_tools": "Otwórz narzędzia deweloperskie", "open_sql_console": "Otwórz konsolę SQL", "open_sql_console_history": "Otwórz historię konsoli SQL", "open_search_history": "Otwórz historię wyszukiwania", - "show_backend_log": "Pokaż logi backendu", - "reload_hint": "Przeładowanie może pomóc w niektórych problemach wizualnych bez ponownego uruchamiania całej aplikacji.", + "show_backend_log": "Pokaż log backendu", + "reload_hint": "Przeładowanie może pomóc w przypadku niektórych błędów wizualnych bez ponownego uruchamiania całej aplikacji.", "reload_frontend": "Przeładuj frontend", "show_hidden_subtree": "Pokaż ukryte poddrzewo", "show_help": "Pokaż pomoc", - "about": "O notatkach Trilium", + "about": "O Trilium Notes", "logout": "Wyloguj", "show-cheatsheet": "Pokaż ściągawkę", "toggle-zen-mode": "Tryb Zen", @@ -1156,11 +1190,11 @@ }, "sync_status": { "unknown": "

Status synchronizacji będzie znany po rozpoczęciu następnej próby synchronizacji.

Kliknij, aby wywołać synchronizację teraz.

", - "connected_with_changes": "

Połączono z serwerem synchronizacji.
Istnieją pewne oczekujące zmiany, które należy zsynchronizować.

Kliknij, aby wywołać synchronizację.

", + "connected_with_changes": "

Połączono z serwerem synchronizacji.
Istnieją pewne oczekujące zmiany do zsynchronizowania.

Kliknij, aby wywołać synchronizację.

", "connected_no_changes": "

Połączono z serwerem synchronizacji.
Wszystkie zmiany zostały już zsynchronizowane.

Kliknij, aby wywołać synchronizację.

", - "disconnected_with_changes": "

Nawiązanie połączenia z serwerem synchronizacji nie powiodło się.
Istnieją pewne oczekujące zmiany, które należy zsynchronizować.

Kliknij, aby wywołać synchronizację.

", + "disconnected_with_changes": "

Nawiązanie połączenia z serwerem synchronizacji nie powiodło się.
Istnieją pewne oczekujące zmiany do zsynchronizowania.

Kliknij, aby wywołać synchronizację.

", "disconnected_no_changes": "

Nawiązanie połączenia z serwerem synchronizacji nie powiodło się.
Wszystkie znane zmiany zostały zsynchronizowane.

Kliknij, aby wywołać synchronizację.

", - "in_progress": "Synchronizacja z serwerem jest w toku." + "in_progress": "Trwa synchronizacja z serwerem." }, "left_pane_toggle": { "show_panel": "Pokaż panel", @@ -1172,12 +1206,12 @@ }, "note_actions": { "convert_into_attachment": "Konwertuj na załącznik", - "re_render_note": "Wyrenderuj ponownie notatkę", + "re_render_note": "Wyrenderuj notatkę ponownie", "search_in_note": "Szukaj w notatce", "note_source": "Źródło notatki", "note_attachments": "Załączniki notatki", "open_note_externally": "Otwórz notatkę zewnętrznie", - "open_note_externally_title": "Plik zostanie otwarty w zewnętrznej aplikacji i będzie obserwowany pod kątem zmian. Następnie będziesz mógł przesłać zmodyfikowaną wersję z powrotem do Trilium.", + "open_note_externally_title": "Plik zostanie otwarty w zewnętrznej aplikacji i będzie monitorowany pod kątem zmian. Następnie będzie można przesłać zmodyfikowaną wersję z powrotem do Trilium.", "open_note_custom": "Otwórz notatkę niestandardowo", "import_files": "Importuj pliki", "export_note": "Eksportuj notatkę", @@ -1187,10 +1221,17 @@ "convert_into_attachment_failed": "Konwersja notatki '{{title}}' nie powiodła się.", "convert_into_attachment_successful": "Notatka '{{title}}' została przekonwertowana na załącznik.", "convert_into_attachment_prompt": "Czy na pewno chcesz przekonwertować notatkę '{{title}}' na załącznik notatki nadrzędnej?", - "print_pdf": "Eksportuj jako PDF..." + "print_pdf": "Eksportuj jako PDF...", + "open_note_on_server": "Otwórz notatkę na serwerze", + "view_revisions": "Wersje notatki...", + "note_map": "Mapa notatek", + "advanced": "Zaawansowane", + "export_as_image": "Eksportuj jako obraz", + "export_as_image_png": "PNG (grafika rastrowa)", + "export_as_image_svg": "SVG (wektorowy)" }, "onclick_button": { - "no_click_handler": "Widżet przycisku '{{componentId}}' nie ma zdefiniowanego obsługi kliknięcia" + "no_click_handler": "Widżet przycisku '{{componentId}}' nie ma zdefiniowanej obsługi kliknięcia" }, "protected_session_status": { "active": "Sesja chroniona jest aktywna. Kliknij, aby opuścić sesję chronioną.", @@ -1203,7 +1244,7 @@ "update_available": "Dostępna aktualizacja" }, "note_launcher": { - "this_launcher_doesnt_define_target_note": "Ten program uruchamiający nie definiuje notatki docelowej." + "this_launcher_doesnt_define_target_note": "Ten skrót nie definiuje notatki docelowej." }, "code_buttons": { "execute_button_title": "Wykonaj skrypt", @@ -1213,7 +1254,7 @@ "sql_console_saved_message": "Notatka konsoli SQL została zapisana w {{note_path}}" }, "copy_image_reference_button": { - "button_title": "Kopiuj odniesienie do obrazu do schowka, można je wkleić do notatki tekstowej." + "button_title": "Skopiuj odniesienie do obrazu do schowka, można je wkleić w notatce tekstowej." }, "hide_floating_buttons_button": { "button_title": "Ukryj przyciski" @@ -1226,40 +1267,40 @@ }, "relation_map_buttons": { "create_child_note_title": "Utwórz nową notatkę podrzędną i dodaj ją do tej mapy relacji", - "reset_pan_zoom_title": "Zresetuj przesuwanie i powiększanie do początkowych współrzędnych i powiększenia", + "reset_pan_zoom_title": "Zresetuj przesunięcie i powiększenie do początkowych współrzędnych i powiększenia", "zoom_in_title": "Powiększ", "zoom_out_title": "Pomniejsz" }, "zpetne_odkazy": { "relation": "relacja", - "backlink_one": "{{count}} Backlink", - "backlink_few": "", - "backlink_many": "{{count}} Backlinków" + "backlink_one": "{{count}} Link zwrotny", + "backlink_few": "{{count}} Linki zwrotne", + "backlink_many": "{{count}} Linki zwrotne" }, "mobile_detail_menu": { "insert_child_note": "Wstaw notatkę podrzędną", "delete_this_note": "Usuń tę notatkę", "note_revisions": "Wersje notatki", - "error_cannot_get_branch_id": "Nie można uzyskać branchId dla notePath '{{notePath}}'", + "error_cannot_get_branch_id": "Nie można pobrać branchId dla ścieżki notatki '{{notePath}}'", "error_unrecognized_command": "Nierozpoznane polecenie {{command}}" }, "note_icon": { "change_note_icon": "Zmień ikonę notatki", "category": "Kategoria:", "search": "Szukaj:", - "reset-default": "Zresetuj do domyślnej ikony" + "reset-default": "Przywróć domyślną ikonę" }, "basic_properties": { "note_type": "Typ notatki", - "editable": "Edytowalny", - "basic_properties": "Podstawowe właściwości", + "editable": "Edytowalna", + "basic_properties": "Właściwości podstawowe", "language": "Język", - "configure_code_notes": "Skonfiguruj notatki kodowe..." + "configure_code_notes": "Konfiguruj notatki kodu..." }, "edited_notes": { - "no_edited_notes_found": "Brak edytowanych notatek tego dnia...", + "no_edited_notes_found": "Brak edytowanych notatek w tym dniu...", "title": "Edytowane notatki", - "deleted": "(usunięto)" + "deleted": "(usunięta)" }, "include_archived_notes": { "include_archived_notes": "Uwzględnij zarchiwizowane notatki" @@ -1270,9 +1311,9 @@ "title": "Tytuł", "date_created": "Data utworzenia", "date_modified": "Data ostatniej modyfikacji", - "content_size": "Rozmiar zawartości notatki", - "content_and_attachments_size": "Rozmiar zawartości notatki wraz z załącznikami", - "content_and_attachments_and_revisions_size": "Rozmiar zawartości notatki wraz z załącznikami i wersjami", + "content_size": "Rozmiar treści notatki", + "content_and_attachments_size": "Rozmiar treści notatki wraz z załącznikami", + "content_and_attachments_and_revisions_size": "Rozmiar treści notatki wraz z załącznikami i wersjami", "revision_count": "Liczba wersji", "children_count": "Liczba notatek podrzędnych", "parent_count": "Liczba klonów", @@ -1285,25 +1326,25 @@ }, "search_script": { "title": "Skrypt wyszukiwania:", - "placeholder": "szukaj notatki po jej nazwie", - "description1": "Skrypt wyszukiwania pozwala zdefiniować wyniki wyszukiwania poprzez uruchomienie skryptu. Zapewnia to maksymalną elastyczność, gdy standardowe wyszukiwanie nie wystarcza.", - "description2": "Skrypt wyszukiwania musi być typu \"kod\" i podtypu \"JavaScript backend\". Skrypt musi zwrócić tablicę noteIds lub notatek.", + "placeholder": "wyszukaj notatkę po nazwie", + "description1": "Skrypt wyszukiwania pozwala definiować wyniki wyszukiwania poprzez uruchomienie skryptu. Zapewnia to maksymalną elastyczność, gdy standardowe wyszukiwanie nie wystarcza.", + "description2": "Skrypt wyszukiwania musi być typu \"code\" i podtypu \"JavaScript backend\". Skrypt musi zwracać tablicę identyfikatorów notatek (noteIds) lub notatek.", "example_title": "Zobacz ten przykład:", - "example_code": "// 1. wstępne filtrowanie za pomocą standardowego wyszukiwania\nconst candidateNotes = api.searchForNotes(\"#journal\"); \n\n// 2. zastosowanie niestandardowych kryteriów wyszukiwania\nconst matchedNotes = candidateNotes\n .filter(note => note.title.match(/[0-9]{1,2}\\. ?[0-9]{1,2}\\. ?[0-9]{4}/));\n\nreturn matchedNotes;", - "note": "Pamiętaj, że skrypt wyszukiwania i ciąg wyszukiwania nie mogą być łączone ze sobą." + "example_code": "// 1. filtrowanie wstępne przy użyciu standardowego wyszukiwania\nconst candidateNotes = api.searchForNotes(\"#journal\"); \n\n// 2. stosowanie niestandardowych kryteriów wyszukiwania\nconst matchedNotes = candidateNotes\n .filter(note => note.title.match(/[0-9]{1,2}\\. ?[0-9]{1,2}\\. ?[0-9]{4}/));\n\nreturn matchedNotes;", + "note": "Zauważ, że skryptu wyszukiwania i ciągu wyszukiwania nie można ze sobą łączyć." }, "search_string": { "title_column": "Ciąg wyszukiwania:", - "placeholder": "słowa kluczowe pełnotekstowe, #tag = wartość...", + "placeholder": "słowa kluczowe, #tag = wartość...", "search_syntax": "Składnia wyszukiwania", - "also_see": "zobacz również", - "complete_help": "pełna pomoc dotycząca składni wyszukiwania", - "full_text_search": "Wpisz dowolny tekst do wyszukiwania pełnotekstowego", + "also_see": "zobacz także", + "complete_help": "kompletna pomoc dotycząca składni wyszukiwania", + "full_text_search": "Wpisz dowolny tekst, aby przeszukać pełną treść", "label_abc": "zwraca notatki z etykietą abc", - "label_year": "dopasowuje notatki z etykietą rok o wartości 2019", - "label_rock_pop": "dopasowuje notatki, które mają zarówno etykiety rock, jak i pop", - "label_rock_or_pop": "musi być obecna tylko jedna z etykiet", - "label_year_comparison": "porównanie numeryczne (również >, >=, <).", + "label_year": "dopasowuje notatki z etykietą year o wartości 2019", + "label_rock_pop": "dopasowuje notatki, które mają obie etykiety rock i pop", + "label_rock_or_pop": "tylko jedna z etykiet musi być obecna", + "label_year_comparison": "porównanie liczbowe (także >, >=, <).", "label_date_created": "notatki utworzone w ostatnim miesiącu", "error": "Błąd wyszukiwania: {{error}}", "search_prefix": "Szukaj:" @@ -1311,7 +1352,7 @@ "attachment_detail": { "open_help_page": "Otwórz stronę pomocy dotyczącą załączników", "owning_note": "Notatka nadrzędna: ", - "you_can_also_open": ", możesz również otworzyć ", + "you_can_also_open": ", możesz także otworzyć ", "list_of_all_attachments": "Listę wszystkich załączników", "attachment_deleted": "Ten załącznik został usunięty." }, @@ -1322,37 +1363,43 @@ "no_attachments": "Ta notatka nie ma załączników." }, "book": { - "no_children_help": "Ta kolekcja nie ma żadnych notatek podrzędnych, więc nie ma nic do wyświetlenia. Zobacz wiki, aby uzyskać szczegółowe informacje.", - "drag_locked_title": "Zablokowano do edycji", + "no_children_help": "Ta kolekcja nie posiada żadnych notatek podrzędnych, więc nie ma nic do wyświetlenia. Zobacz wiki po szczegóły.", + "drag_locked_title": "Zablokowane do edycji", "drag_locked_message": "Przeciąganie niedozwolone, ponieważ kolekcja jest zablokowana do edycji." }, "editable_code": { - "placeholder": "Wpisz tutaj treść swojej notatki kodowej..." + "placeholder": "Wpisz treść swojej notatki kodu tutaj..." }, "editable_text": { - "placeholder": "Wpisz tutaj treść swojej notatki...", - "auto-detect-language": "Wykryto automatycznie" + "placeholder": "Wpisz treść swojej notatki tutaj...", + "auto-detect-language": "Wykryto automatycznie", + "editor_crashed_title": "Edytor tekstu uległ awarii", + "editor_crashed_content": "Twoja treść została pomyślnie odzyskana, ale kilka z twoich ostatnich zmian mogło nie zostać zapisanych.", + "editor_crashed_details_button": "Zobacz więcej szczegółów...", + "editor_crashed_details_intro": "Jeśli napotkasz ten błąd wielokrotnie, rozważ zgłoszenie go na GitHub, wklejając poniższe informacje.", + "editor_crashed_details_title": "Informacje techniczne", + "keeps-crashing": "Komponent edycji ciągle ulega awarii. Proszę spróbować zrestartować Trilium. Jeśli problem będzie się powtarzał, rozważ utworzenie zgłoszenia błędu." }, "empty": { - "open_note_instruction": "Otwórz notatkę, wpisując jej tytuł w poniższe pole lub wybierz notatkę z drzewa.", - "search_placeholder": "szukaj notatki po jej nazwie", + "open_note_instruction": "Otwórz notatkę, wpisując tytuł notatki w polu poniżej lub wybierz notatkę w drzewie.", + "search_placeholder": "wyszukaj notatkę po nazwie", "enter_workspace": "Wejdź do obszaru roboczego {{title}}" }, "file": { - "file_preview_not_available": "Podgląd pliku nie jest dostępny dla tego formatu.", + "file_preview_not_available": "Podgląd pliku nie jest dostępny dla tego formatu pliku.", "too_big": "Podgląd pokazuje tylko pierwsze {{maxNumChars}} znaków pliku ze względów wydajnościowych. Pobierz plik i otwórz go zewnętrznie, aby zobaczyć całą zawartość." }, "protected_session": { - "enter_password_instruction": "Wyświetlenie chronionej notatki wymaga wprowadzenia hasła:", - "start_session_button": "Rozpocznij sesję chronioną enter", + "enter_password_instruction": "Wyświetlenie chronionej notatki wymaga podania hasła:", + "start_session_button": "Rozpocznij sesję chronioną", "started": "Sesja chroniona została rozpoczęta.", - "wrong_password": "Nieprawidłowe hasło.", + "wrong_password": "Błędne hasło.", "protecting-finished-successfully": "Ochrona zakończona pomyślnie.", - "unprotecting-finished-successfully": "Odblokowywanie zakończone pomyślnie.", + "unprotecting-finished-successfully": "Zdejmowanie ochrony zakończone pomyślnie.", "protecting-in-progress": "Ochrona w toku: {{count}}", - "unprotecting-in-progress-count": "Odblokowywanie w toku: {{count}}", + "unprotecting-in-progress-count": "Zdejmowanie ochrony w toku: {{count}}", "protecting-title": "Status ochrony", - "unprotecting-title": "Status odblokowywania" + "unprotecting-title": "Status zdejmowania ochrony" }, "relation_map": { "open_in_new_tab": "Otwórz w nowej karcie", @@ -1361,24 +1408,24 @@ "rename_note": "Zmień nazwę notatki", "enter_new_title": "Wprowadź nowy tytuł notatki:", "remove_relation": "Usuń relację", - "confirm_remove_relation": "Czy na pewno chcesz usunąć tę relację?", - "specify_new_relation_name": "Określ nową nazwę relacji (dozwolone znaki: alfanumeryczne, dwukropek i podkreślenie):", + "confirm_remove_relation": "Czy na pewno chcesz usunąć relację?", + "specify_new_relation_name": "Podaj nową nazwę relacji (dozwolone znaki: alfanumeryczne, dwukropek i podkreślenie):", "connection_exists": "Połączenie '{{name}}' między tymi notatkami już istnieje.", - "start_dragging_relations": "Zacznij przeciągać stąd relacje i upuść je na inną notatkę.", - "note_not_found": "Nie znaleziono notatki {{noteId}}!", + "start_dragging_relations": "Zacznij przeciągać relacje stąd i upuść je na innej notatce.", + "note_not_found": "Notatka {{noteId}} nie znaleziona!", "cannot_match_transform": "Nie można dopasować transformacji: {{transform}}", "note_already_in_diagram": "Notatka \"{{title}}\" jest już na diagramie.", "enter_title_of_new_note": "Wprowadź tytuł nowej notatki", "default_new_note_title": "nowa notatka", - "click_on_canvas_to_place_new_note": "Kliknij na płótno, aby umieścić nową notatkę" + "click_on_canvas_to_place_new_note": "Kliknij na płótnie, aby umieścić nową notatkę" }, "render": { - "note_detail_render_help_1": "Ta notatka pomocy jest wyświetlana, ponieważ ta notatka typu Renderuj HTML nie ma wymaganej relacji do prawidłowego działania.", - "note_detail_render_help_2": "Typ notatki Renderuj HTML jest używany do skryptowania. W skrócie, masz notatkę kodu HTML (opcjonalnie z pewnym JavaScriptem), a ta notatka ją wyrenderuje. Aby to zadziałało, musisz zdefiniować relację o nazwie \"renderNote\" wskazującą na notatkę HTML do wyrenderowania." + "note_detail_render_help_1": "Ta notatka pomocy jest wyświetlana, ponieważ ta notatka typu Render HTML nie ma wymaganej relacji do poprawnego działania.", + "note_detail_render_help_2": "Typ notatki Render HTML jest używany do skryptowania. W skrócie, masz notatkę kodu HTML (opcjonalnie z JavaScript) i ta notatka ją wyrenderuje. Aby to zadziałało, musisz zdefiniować relację o nazwie \"renderNote\" wskazującą na notatkę HTML do wyrenderowania." }, "web_view": { - "web_view": "Widok sieciowy", - "embed_websites": "Notatka typu Widok sieciowy pozwala na osadzanie stron internetowych w Trilium.", + "web_view": "Widok WWW", + "embed_websites": "Notatka typu Widok WWW pozwala na osadzanie stron internetowych w Trilium.", "create_label": "Aby rozpocząć, utwórz etykietę z adresem URL, który chcesz osadzić, np. #webViewSrc=\"https://www.google.com\"" }, "backend_log": { @@ -1388,31 +1435,31 @@ "title": "Sprawdzanie spójności", "find_and_fix_button": "Znajdź i napraw problemy ze spójnością", "finding_and_fixing_message": "Znajdowanie i naprawianie problemów ze spójnością...", - "issues_fixed_message": "Wszelkie problemy ze spójnością, które mogły zostać znalezione, są teraz naprawione." + "issues_fixed_message": "Wszelkie znalezione problemy ze spójnością zostały naprawione." }, "database_anonymization": { "title": "Anonimizacja bazy danych", "full_anonymization": "Pełna anonimizacja", - "full_anonymization_description": "Ta akcja utworzy nową kopię bazy danych i zanonimizuje ją (usunie całą zawartość notatek, pozostawiając tylko strukturę i niektóre niewrażliwe metadane) w celu udostępnienia online do celów debugowania bez obawy o wyciek danych osobowych.", + "full_anonymization_description": "Ta akcja utworzy nową kopię bazy danych i zanonimizuje ją (usunie całą treść notatek i pozostawi tylko strukturę oraz niektóre niewrażliwe metadane) w celu udostępnienia online do celów debugowania bez obawy o wyciek danych osobowych.", "save_fully_anonymized_database": "Zapisz w pełni zanonimizowaną bazę danych", "light_anonymization": "Lekka anonimizacja", - "light_anonymization_description": "Ta akcja utworzy nową kopię bazy danych i przeprowadzi na niej lekką anonimizację — w szczególności usunięta zostanie tylko zawartość wszystkich notatek, ale tytuły i atrybuty pozostaną. Dodatkowo niestandardowe notatki skryptów JS frontend/backend oraz niestandardowe widżety pozostaną. Zapewnia to więcej kontekstu do debugowania problemów.", - "choose_anonymization": "Możesz sam zdecydować, czy chcesz udostępnić w pełni, czy lekko zanonimizowaną bazę danych. Nawet w pełni zanonimizowana baza danych jest bardzo przydatna, jednak w niektórych przypadkach lekko zanonimizowana baza danych może przyspieszyć proces identyfikacji i naprawy błędów.", + "light_anonymization_description": "Ta akcja utworzy nową kopię bazy danych i wykona na niej lekką anonimizację — usunięta zostanie tylko treść wszystkich notatek, ale tytuły i atrybuty pozostaną. Dodatkowo, niestandardowe notatki skryptów JS frontend/backend oraz niestandardowe widżety pozostaną. Zapewnia to więcej kontekstu do debugowania problemów.", + "choose_anonymization": "Możesz sam zdecydować, czy chcesz dostarczyć w pełni, czy lekko zanonimizowaną bazę danych. Nawet w pełni zanonimizowana baza danych jest bardzo przydatna, jednak w niektórych przypadkach lekko zanonimizowana baza danych może przyspieszyć proces identyfikacji i naprawy błędów.", "save_lightly_anonymized_database": "Zapisz lekko zanonimizowaną bazę danych", "existing_anonymized_databases": "Istniejące zanonimizowane bazy danych", "creating_fully_anonymized_database": "Tworzenie w pełni zanonimizowanej bazy danych...", "creating_lightly_anonymized_database": "Tworzenie lekko zanonimizowanej bazy danych...", - "error_creating_anonymized_database": "Nie można utworzyć zanonimizowanej bazy danych, sprawdź logi backendu, aby uzyskać szczegółowe informacje", + "error_creating_anonymized_database": "Nie można utworzyć zanonimizowanej bazy danych, sprawdź logi backendu po szczegóły", "successfully_created_fully_anonymized_database": "Utworzono w pełni zanonimizowaną bazę danych w {{anonymizedFilePath}}", "successfully_created_lightly_anonymized_database": "Utworzono lekko zanonimizowaną bazę danych w {{anonymizedFilePath}}", - "no_anonymized_database_yet": "Brak jeszcze zanonimizowanej bazy danych." + "no_anonymized_database_yet": "Brak zanonimizowanej bazy danych." }, "database_integrity_check": { "title": "Sprawdzanie integralności bazy danych", - "description": "Sprawdzi to, czy baza danych nie jest uszkodzona na poziomie SQLite. Może to zająć trochę czasu, w zależności od rozmiaru bazy danych.", + "description": "To sprawdzi, czy baza danych nie jest uszkodzona na poziomie SQLite. Może to zająć trochę czasu, w zależności od rozmiaru bazy danych.", "check_button": "Sprawdź integralność bazy danych", "checking_integrity": "Sprawdzanie integralności bazy danych...", - "integrity_check_succeeded": "Sprawdzanie integralności zakończyło się pomyślnie - nie znaleziono żadnych problemów.", + "integrity_check_succeeded": "Sprawdzanie integralności powiodło się - nie znaleziono problemów.", "integrity_check_failed": "Sprawdzanie integralności nie powiodło się: {{results}}" }, "sync": { @@ -1426,59 +1473,60 @@ "failed": "Synchronizacja nie powiodła się: {{message}}" }, "vacuum_database": { - "title": "Odkurzanie bazy danych", - "description": "Spowoduje to przebudowanie bazy danych, co zazwyczaj skutkuje mniejszym plikiem bazy danych. Żadne dane nie zostaną faktycznie zmienione.", + "title": "Odkurzanie bazy danych (Vacuum)", + "description": "To przebuduje bazę danych, co zazwyczaj skutkuje mniejszym plikiem bazy danych. Żadne dane nie zostaną faktycznie zmienione.", "button_text": "Odkurz bazę danych", "vacuuming_database": "Odkurzanie bazy danych...", "database_vacuumed": "Baza danych została odkurzona" }, "fonts": { - "theme_defined": "Zdefiniowane przez motyw", + "theme_defined": "Zdefiniowana przez motyw", "fonts": "Czcionki", "main_font": "Główna czcionka", "font_family": "Rodzina czcionek", "size": "Rozmiar", "note_tree_font": "Czcionka drzewa notatek", "note_detail_font": "Czcionka szczegółów notatki", - "monospace_font": "Czcionka monospaced (kod)", - "note_tree_and_detail_font_sizing": "Pamiętaj, że rozmiar czcionki drzewa i szczegółów jest względny w stosunku do ustawienia rozmiaru czcionki głównej.", - "not_all_fonts_available": "Nie wszystkie wymienione czcionki mogą być dostępne w Twoim systemie.", - "apply_font_changes": "Aby zastosować zmiany czcionki, kliknij na", + "monospace_font": "Czcionka o stałej szerokości (kod)", + "note_tree_and_detail_font_sizing": "Zauważ, że rozmiar czcionki drzewa i szczegółów jest względny do ustawienia rozmiaru głównej czcionki.", + "not_all_fonts_available": "Nie wszystkie wymienione czcionki mogą być dostępne w twoim systemie.", + "apply_font_changes": "Aby zastosować zmiany czcionek, kliknij na", "reload_frontend": "przeładuj frontend", - "generic-fonts": "Czcionki generyczne", - "sans-serif-system-fonts": "Czcionki systemowe bezszeryfowe", - "serif-system-fonts": "Czcionki systemowe szeryfowe", - "monospace-system-fonts": "Czcionki systemowe monospaced", - "handwriting-system-fonts": "Czcionki systemowe odręczne", + "generic-fonts": "Czcionki ogólne", + "sans-serif-system-fonts": "Systemowe czcionki bezszeryfowe", + "serif-system-fonts": "Systemowe czcionki szeryfowe", + "monospace-system-fonts": "Systemowe czcionki o stałej szerokości", + "handwriting-system-fonts": "Systemowe czcionki odręczne", "serif": "Szeryfowa", "sans-serif": "Bezszeryfowa", - "monospace": "Monospaced", + "monospace": "O stałej szerokości", "system-default": "Domyślna systemowa" }, "max_content_width": { - "title": "Szerokość zawartości", - "default_description": "Trilium domyślnie ogranicza maksymalną szerokość zawartości, aby poprawić czytelność na zmaksymalizowanych ekranach o dużej szerokości.", - "max_width_label": "Maksymalna szerokość zawartości", - "max_width_unit": "piksele" + "title": "Szerokość treści", + "default_description": "Trilium domyślnie ogranicza maksymalną szerokość treści, aby poprawić czytelność na zmaksymalizowanych ekranach szerokokątnych.", + "max_width_label": "Maksymalna szerokość treści", + "max_width_unit": "pikseli", + "centerContent": "Utrzymuj treść wyśrodkowaną" }, "native_title_bar": { - "title": "Natywny pasek tytułu (wymaga ponownego uruchomienia aplikacji)", + "title": "Natywny pasek tytułu (wymaga restartu aplikacji)", "enabled": "włączony", "disabled": "wyłączony" }, "ribbon": { "widgets": "Widżety wstążki", - "promoted_attributes_message": "Karta wstążki Promowane atrybuty otworzy się automatycznie, jeśli na notatce znajdują się promowane atrybuty", - "edited_notes_message": "Karta wstążki Edytowane notatki otworzy się automatycznie w notatkach dziennych" + "promoted_attributes_message": "Karta wstążki Wyróżnione Atrybuty otworzy się automatycznie, jeśli w notatce obecne są wyróżnione atrybuty", + "edited_notes_message": "Karta wstążki Edytowane Notatki otworzy się automatycznie na notatkach dziennych" }, "theme": { "title": "Motyw aplikacji", "theme_label": "Motyw", "override_theme_fonts_label": "Nadpisz czcionki motywu", - "auto_theme": "Starszy (Dostosuj do schematu kolorów systemu)", - "light_theme": "Starszy (Jasny)", - "dark_theme": "Starszy (Ciemny)", - "triliumnext": "Trilium (Dostosuj do schematu kolorów systemu)", + "auto_theme": "Legacy (zgodny z systemem)", + "light_theme": "Legacy (Jasny)", + "dark_theme": "Legacy (Ciemny)", + "triliumnext": "Trilium (zgodny z systemem)", "triliumnext-light": "Trilium (Jasny)", "triliumnext-dark": "Trilium (Ciemny)", "layout": "Układ", @@ -1491,33 +1539,36 @@ "title": "Wydajność", "enable-motion": "Włącz przejścia i animacje", "enable-shadows": "Włącz cienie", - "enable-backdrop-effects": "Włącz efekty tła dla menu, wyskakujących okien i paneli", + "enable-backdrop-effects": "Włącz efekty tła dla menu, okienek i paneli", "enable-smooth-scroll": "Włącz płynne przewijanie", - "app-restart-required": "(ponowne uruchomienie aplikacji jest wymagane, aby zmiana zaczęła obowiązywać)" + "app-restart-required": "(wymagane jest ponowne uruchomienie aplikacji, aby zmiana weszła w życie)" }, "zoom_factor": { - "title": "Współczynnik powiększenia (tylko w wersji stacjonarnej)", - "description": "Powiększanie można również kontrolować za pomocą skrótów CTRL+- i CTRL+=" + "title": "Współczynnik powiększenia (tylko wersja desktop)", + "description": "Powiększaniem można sterować również za pomocą skrótów CTRL+- i CTRL+=." }, "code_auto_read_only_size": { "title": "Automatyczny rozmiar tylko do odczytu", - "description": "Automatyczny rozmiar notatki tylko do odczytu to rozmiar, po którym notatki będą wyświetlane w trybie tylko do odczytu (ze względów wydajnościowych).", - "label": "Automatyczny rozmiar tylko do odczytu (notatki kodowe)", - "unit": "znaki" + "description": "Automatyczny rozmiar notatki tylko do odczytu to rozmiar, po przekroczeniu którego notatki będą wyświetlane w trybie tylko do odczytu (ze względów wydajnościowych).", + "label": "Automatyczny rozmiar tylko do odczytu (notatki kodu)", + "unit": "znaków" }, "code-editor-options": { "title": "Edytor" }, "code_mime_types": { - "title": "Dostępne typy MIME w rozwijanym menu" + "title": "Dostępne typy MIME na liście rozwijanej", + "tooltip_syntax_highlighting": "Podświetlanie składni", + "tooltip_code_block_syntax": "Bloki kodu w notatkach tekstowych", + "tooltip_code_note_syntax": "Notatki kodu" }, "vim_key_bindings": { "use_vim_keybindings_in_code_notes": "Skróty klawiszowe Vim", - "enable_vim_keybindings": "Włącz skróty klawiszowe Vim w notatkach kodowych (bez trybu ex)" + "enable_vim_keybindings": "Włącz skróty klawiszowe Vim w notatkach kodu (brak trybu ex)" }, "wrap_lines": { - "wrap_lines_in_code_notes": "Zawijaj wiersze w notatkach kodowych", - "enable_line_wrap": "Włącz zawijanie wierszy (zmiana może wymagać ponownego załadowania frontendu, aby zaczęła obowiązywać)" + "wrap_lines_in_code_notes": "Zawijaj wiersze w notatkach kodu", + "enable_line_wrap": "Włącz zawijanie wierszy (zmiana może wymagać przeładowania frontendu)" }, "images": { "images_section_title": "Obrazy", @@ -1525,15 +1576,15 @@ "download_images_description": "Wklejony HTML może zawierać odniesienia do obrazów online, Trilium znajdzie te odniesienia i pobierze obrazy, aby były dostępne offline.", "enable_image_compression": "Włącz kompresję obrazów", "max_image_dimensions": "Maksymalna szerokość / wysokość obrazu (obraz zostanie przeskalowany, jeśli przekroczy to ustawienie).", - "max_image_dimensions_unit": "piksele", - "jpeg_quality_description": "Jakość JPEG (10 - najgorsza jakość, 100 - najlepsza jakość, 50 - 85 jest zalecane)" + "max_image_dimensions_unit": "pikseli", + "jpeg_quality_description": "Jakość JPEG (10 - najgorsza jakość, 100 - najlepsza jakość, zalecane 50 - 85)" }, "attachment_erasure_timeout": { - "attachment_erasure_timeout": "Limit czasu usuwania załączników", + "attachment_erasure_timeout": "Limit czasu wymazywania załączników", "attachment_auto_deletion_description": "Załączniki są automatycznie usuwane (i wymazywane), jeśli nie są już powiązane z ich notatką po określonym czasie.", "erase_attachments_after": "Wymaż nieużywane załączniki po:", - "manual_erasing_description": "Możesz również wywołać wymazywanie ręcznie (bez uwzględniania powyższego limitu czasu):", - "erase_unused_attachments_now": "Wymaż teraz nieużywane załączniki", + "manual_erasing_description": "Możesz również wywołać wymazywanie ręcznie (bez uwzględniania zdefiniowanego powyżej limitu czasu):", + "erase_unused_attachments_now": "Wymaż nieużywane załączniki teraz", "unused_attachments_erased": "Nieużywane załączniki zostały wymazane." }, "network_connections": { @@ -1541,46 +1592,46 @@ "check_for_updates": "Sprawdzaj aktualizacje automatycznie" }, "note_erasure_timeout": { - "note_erasure_timeout_title": "Limit czasu usuwania notatek", - "note_erasure_description": "Usunięte notatki (i atrybuty, wersje...) są na początku tylko oznaczane jako usunięte i można je odzyskać z okna dialogowego Ostatnie notatki. Po pewnym czasie usunięte notatki są \"wymazywane\", co oznacza, że ich zawartość nie jest już możliwa do odzyskania. To ustawienie pozwala skonfigurować długość okresu między usunięciem a wymazaniem notatki.", + "note_erasure_timeout_title": "Limit czasu wymazywania notatek", + "note_erasure_description": "Usunięte notatki (oraz atrybuty, wersje...) są początkowo tylko oznaczane jako usunięte i możliwe jest ich odzyskanie z okna Ostatnie notatki. Po pewnym czasie usunięte notatki są \"wymazywane\", co oznacza, że ich zawartość nie jest już możliwa do odzyskania. To ustawienie pozwala skonfigurować długość okresu między usunięciem a wymazaniem notatki.", "erase_notes_after": "Wymaż notatki po:", - "manual_erasing_description": "Możesz również wywołać wymazywanie ręcznie (bez uwzględniania powyższego limitu czasu):", - "erase_deleted_notes_now": "Wymaż teraz usunięte notatki", + "manual_erasing_description": "Możesz również wywołać wymazywanie ręcznie (bez uwzględniania zdefiniowanego powyżej limitu czasu):", + "erase_deleted_notes_now": "Wymaż usunięte notatki teraz", "deleted_notes_erased": "Usunięte notatki zostały wymazane." }, "revisions_snapshot_interval": { - "note_revisions_snapshot_interval_title": "Interwał migawki wersji notatki", - "note_revisions_snapshot_description": "Interwał migawki wersji notatki to czas, po którym dla notatki zostanie utworzona nowa wersja. Zobacz wiki, aby uzyskać więcej informacji.", - "snapshot_time_interval_label": "Interwał czasowy migawki wersji notatki:" + "note_revisions_snapshot_interval_title": "Interwał zrzutu wersji notatki", + "note_revisions_snapshot_description": "Interwał zrzutu wersji notatki to czas, po którym zostanie utworzona nowa wersja notatki. Zobacz wiki po więcej informacji.", + "snapshot_time_interval_label": "Interwał czasowy zrzutu wersji notatki:" }, "revisions_snapshot_limit": { - "note_revisions_snapshot_limit_title": "Limit migawek wersji notatki", - "note_revisions_snapshot_limit_description": "Limit liczby migawek wersji notatki odnosi się do maksymalnej liczby wersji, które można zapisać dla każdej notatki. Gdzie -1 oznacza brak limitu, 0 oznacza usunięcie wszystkich wersji. Możesz ustawić maksymalną liczbę wersji dla pojedynczej notatki za pomocą etykiety #versioningLimit.", - "snapshot_number_limit_label": "Limit liczby migawek wersji notatki:", - "snapshot_number_limit_unit": "migawki", - "erase_excess_revision_snapshots": "Wymaż teraz nadmiarowe migawki wersji", - "erase_excess_revision_snapshots_prompt": "Nadmiarowe migawki wersji zostały wymazane." + "note_revisions_snapshot_limit_title": "Limit zrzutów wersji notatki", + "note_revisions_snapshot_limit_description": "Limit liczby zrzutów wersji notatki odnosi się do maksymalnej liczby wersji, które mogą zostać zapisane dla każdej notatki. Gdzie -1 oznacza brak limitu, 0 oznacza usuwanie wszystkich wersji. Możesz ustawić maksymalną liczbę wersji dla pojedynczej notatki za pomocą etykiety #versioningLimit.", + "snapshot_number_limit_label": "Limit liczbowy zrzutów wersji notatki:", + "snapshot_number_limit_unit": "zrzutów", + "erase_excess_revision_snapshots": "Wymaż nadmiarowe zrzuty wersji teraz", + "erase_excess_revision_snapshots_prompt": "Nadmiarowe zrzuty wersji zostały wymazane." }, "search_engine": { "title": "Wyszukiwarka", - "custom_search_engine_info": "Niestandardowa wyszukiwarka wymaga ustawienia zarówno nazwy, jak i adresu URL. Jeśli którykolwiek z nich nie jest ustawiony, domyślną wyszukiwarką będzie DuckDuckGo.", + "custom_search_engine_info": "Niestandardowa wyszukiwarka wymaga ustawienia zarówno nazwy, jak i adresu URL. Jeśli którykolwiek z nich nie zostanie ustawiony, jako domyślna wyszukiwarka zostanie użyte DuckDuckGo.", "predefined_templates_label": "Predefiniowane szablony wyszukiwarek", "bing": "Bing", "baidu": "Baidu", "duckduckgo": "DuckDuckGo", "google": "Google", - "custom_name_label": "Niestandardowa nazwa wyszukiwarki", + "custom_name_label": "Nazwa niestandardowej wyszukiwarki", "custom_name_placeholder": "Dostosuj nazwę wyszukiwarki", - "custom_url_label": "Niestandardowy adres URL wyszukiwarki powinien zawierać {keyword} jako symbol zastępczy dla wyszukiwanego terminu.", - "custom_url_placeholder": "Dostosuj adres URL wyszukiwarki", + "custom_url_label": "URL niestandardowej wyszukiwarki powinien zawierać {keyword} jako symbol zastępczy dla wyszukiwanej frazy.", + "custom_url_placeholder": "Dostosuj URL wyszukiwarki", "save_button": "Zapisz" }, "tray": { - "title": "Zasobnik systemowy", - "enable_tray": "Włącz zasobnik (zmiana ta wymaga ponownego uruchomienia Trilium, aby zaczęła obowiązywać)" + "title": "Zasobnik systemowy (Tray)", + "enable_tray": "Włącz zasobnik (wymagany restart Trilium, aby zmiana weszła w życie)" }, "heading_style": { - "title": "Styl nagłówka", + "title": "Styl nagłówków", "plain": "Zwykły", "underline": "Podkreślenie", "markdown": "Styl Markdown" @@ -1588,33 +1639,33 @@ "highlights_list": { "title": "Lista wyróżnień", "description": "Możesz dostosować listę wyróżnień wyświetlaną w prawym panelu:", - "bold": "Pogrubiony tekst", - "italic": "Kursywa", - "underline": "Podkreślony tekst", - "color": "Kolorowy tekst", + "bold": "Tekst pogrubiony", + "italic": "Tekst pochylony", + "underline": "Tekst podkreślony", + "color": "Tekst kolorowy", "bg_color": "Tekst z kolorem tła", - "visibility_title": "Widoczność listy wyróżnień", + "visibility_title": "Widoczność Listy wyróżnień", "visibility_description": "Możesz ukryć widżet wyróżnień dla poszczególnych notatek, dodając etykietę #hideHighlightWidget.", - "shortcut_info": "Możesz skonfigurować skrót klawiaturowy do szybkiego przełączania prawego panelu (w tym wyróżnień) w Opcje -> Skróty (nazwa 'toggleRightPane')." + "shortcut_info": "Możesz skonfigurować skrót klawiszowy do szybkiego przełączania prawego panelu (w tym Wyróżnień) w Opcje -> Skróty (nazwa 'toggleRightPane')." }, "table_of_contents": { "title": "Spis treści", "description": "Spis treści pojawi się w notatkach tekstowych, gdy notatka ma więcej niż zdefiniowaną liczbę nagłówków. Możesz dostosować tę liczbę:", - "unit": "nagłówki", + "unit": "nagłówków", "disable_info": "Możesz również użyć tej opcji, aby skutecznie wyłączyć spis treści, ustawiając bardzo wysoką liczbę.", - "shortcut_info": "Możesz skonfigurować skrót klawiaturowy do szybkiego przełączania prawego panelu (w tym spisu treści) w Opcje -> Skróty (nazwa 'toggleRightPane')." + "shortcut_info": "Możesz skonfigurować skrót klawiszowy do szybkiego przełączania prawego panelu (w tym Spisu treści) w Opcje -> Skróty (nazwa 'toggleRightPane')." }, "text_auto_read_only_size": { "title": "Automatyczny rozmiar tylko do odczytu", - "description": "Automatyczny rozmiar notatki tylko do odczytu to rozmiar, po którym notatki będą wyświetlane w trybie tylko do odczytu (ze względów wydajnościowych).", + "description": "Automatyczny rozmiar notatki tylko do odczytu to rozmiar, po przekroczeniu którego notatki będą wyświetlane w trybie tylko do odczytu (ze względów wydajnościowych).", "label": "Automatyczny rozmiar tylko do odczytu (notatki tekstowe)", - "unit": "znaki" + "unit": "znaków" }, "custom_date_time_format": { - "title": "Niestandardowy format daty/czasu", - "description": "Dostosuj format daty i czasu wstawianego za pomocą lub paska narzędzi. Zobacz dokumentację Day.js dla dostępnych tokenów formatu.", + "title": "Niestandardowy format daty/godziny", + "description": "Dostosuj format daty i godziny wstawianej za pomocą lub paska narzędzi. Zobacz dokumentację Day.js dla dostępnych tokenów formatowania.", "format_string": "Ciąg formatujący:", - "formatted_time": "Sformatowana data/czas:" + "formatted_time": "Sformatowana data/godzina:" }, "i18n": { "title": "Lokalizacja", @@ -1632,29 +1683,29 @@ "first-week-contains-first-thursday": "Pierwszy tydzień zawiera pierwszy czwartek roku", "first-week-has-minimum-days": "Pierwszy tydzień ma minimalną liczbę dni", "min-days-in-first-week": "Minimalna liczba dni w pierwszym tygodniu", - "first-week-info": "Pierwszy tydzień zawiera pierwszy czwartek roku jest oparty na standardzie ISO 8601.", - "first-week-warning": "Zmiana opcji pierwszego tygodnia może powodować duplikaty z istniejącymi notatkami tygodniowymi, a istniejące notatki tygodniowe nie zostaną odpowiednio zaktualizowane.", + "first-week-info": "Pierwszy tydzień zawiera pierwszy czwartek roku bazuje na standardzie ISO 8601.", + "first-week-warning": "Zmiana opcji pierwszego tygodnia może spowodować duplikację istniejących notatek tygodniowych, a istniejące notatki tygodniowe nie zostaną odpowiednio zaktualizowane.", "formatting-locale": "Format daty i liczb", "formatting-locale-auto": "Na podstawie języka aplikacji" }, "backup": { "automatic_backup": "Automatyczna kopia zapasowa", - "automatic_backup_description": "Trilium może automatycznie tworzyć kopie zapasowe bazy danych:", + "automatic_backup_description": "Trilium może automatycznie tworzyć kopię zapasową bazy danych:", "enable_daily_backup": "Włącz codzienną kopię zapasową", - "enable_weekly_backup": "Włącz tygodniową kopię zapasową", - "enable_monthly_backup": "Włącz miesięczną kopię zapasową", + "enable_weekly_backup": "Włącz cotygodniową kopię zapasową", + "enable_monthly_backup": "Włącz comiesięczną kopię zapasową", "backup_recommendation": "Zaleca się włączenie kopii zapasowej, ale może to spowolnić uruchamianie aplikacji przy dużych bazach danych i/lub wolnych urządzeniach pamięci masowej.", "backup_now": "Utwórz kopię zapasową teraz", "backup_database_now": "Utwórz kopię zapasową bazy danych teraz", "existing_backups": "Istniejące kopie zapasowe", "date-and-time": "Data i godzina", "path": "Ścieżka", - "database_backed_up_to": "Baza danych została zarchiwizowana do {{backupFilePath}}", - "no_backup_yet": "brak jeszcze kopii zapasowej" + "database_backed_up_to": "Kopia zapasowa bazy danych została zapisana w {{backupFilePath}}", + "no_backup_yet": "brak kopii zapasowych" }, "etapi": { "title": "ETAPI", - "description": "ETAPI to interfejs API REST używany do programowego dostępu do instancji Trilium, bez interfejsu użytkownika.", + "description": "ETAPI to REST API służące do programowego dostępu do instancji Trilium, bez interfejsu użytkownika.", "create_token": "Utwórz nowy token ETAPI", "existing_tokens": "Istniejące tokeny", "no_tokens_yet": "Nie ma jeszcze żadnych tokenów. Kliknij przycisk powyżej, aby utworzyć jeden.", @@ -1662,36 +1713,36 @@ "created": "Utworzono", "actions": "Akcje", "new_token_title": "Nowy token ETAPI", - "new_token_message": "Wprowadź nazwę nowego tokenu", + "new_token_message": "Proszę wprowadzić nazwę nowego tokenu", "default_token_name": "nowy token", "error_empty_name": "Nazwa tokenu nie może być pusta", - "token_created_title": "Utworzono token ETAPI", - "token_created_message": "Skopiuj utworzony token do schowka. Trilium przechowuje token w postaci zaszyfrowanej i jest to ostatni raz, kiedy go widzisz.", + "token_created_title": "Token ETAPI utworzony", + "token_created_message": "Skopiuj utworzony token do schowka. Trilium przechowuje token zaszyfrowany i jest to ostatni raz, kiedy go widzisz.", "rename_token": "Zmień nazwę tego tokenu", "delete_token": "Usuń / dezaktywuj ten token", "rename_token_title": "Zmień nazwę tokenu", - "rename_token_message": "Wprowadź nową nazwę tokenu", + "rename_token_message": "Proszę wprowadzić nową nazwę tokenu", "delete_token_confirmation": "Czy na pewno chcesz usunąć token ETAPI \"{{name}}\"?" }, "options_widget": { "options_status": "Status opcji", - "options_change_saved": "Zmiany w opcjach zostały zapisane." + "options_change_saved": "Zmiana opcji została zapisana." }, "password": { "heading": "Hasło", - "alert_message": "Pamiętaj o zapamiętaniu nowego hasła. Hasło jest używane do logowania się do interfejsu internetowego i szyfrowania chronionych notatek. Jeśli zapomnisz hasła, wszystkie Twoje chronione notatki zostaną utracone na zawsze.", + "alert_message": "Pamiętaj, aby zapamiętać swoje nowe hasło. Hasło służy do logowania się do interfejsu webowego oraz do szyfrowania chronionych notatek. Jeśli zapomnisz hasła, wszystkie Twoje chronione notatki zostaną utracone na zawsze.", "reset_link": "Kliknij tutaj, aby je zresetować.", "old_password": "Stare hasło", "new_password": "Nowe hasło", "new_password_confirmation": "Potwierdzenie nowego hasła", "change_password": "Zmień hasło", "protected_session_timeout": "Limit czasu sesji chronionej", - "protected_session_timeout_description": "Limit czasu sesji chronionej to okres, po którym sesja chroniona jest usuwana z pamięci przeglądarki. Mierzy się go od ostatniej interakcji z chronionymi notatkami. Zobacz", + "protected_session_timeout_description": "Limit czasu sesji chronionej to okres, po którym sesja chroniona jest usuwana z pamięci przeglądarki. Jest to mierzone od ostatniej interakcji z chronionymi notatkami. Zobacz", "wiki": "wiki", - "for_more_info": "aby uzyskać więcej informacji.", + "for_more_info": "po więcej informacji.", "protected_session_timeout_label": "Limit czasu sesji chronionej:", - "reset_confirmation": "Resetując hasło, na zawsze utracisz dostęp do wszystkich istniejących chronionych notatek. Czy na pewno chcesz zresetować hasło?", - "reset_success_message": "Hasło zostało zresetowane. Ustaw nowe hasło", + "reset_confirmation": "Resetując hasło, na zawsze stracisz dostęp do wszystkich istniejących chronionych notatek. Czy na pewno chcesz zresetować hasło?", + "reset_success_message": "Hasło zostało zresetowane. Proszę ustawić nowe hasło", "change_password_heading": "Zmień hasło", "set_password_heading": "Ustaw hasło", "set_password": "Ustaw hasło", @@ -1699,24 +1750,24 @@ "password_changed_success": "Hasło zostało zmienione. Trilium zostanie przeładowane po naciśnięciu OK." }, "multi_factor_authentication": { - "title": "Uwierzytelnianie wieloskładnikowe", - "description": "Uwierzytelnianie wieloskładnikowe (MFA) dodaje dodatkową warstwę zabezpieczeń do Twojego konta. Zamiast wpisywać tylko hasło, aby się zalogować, MFA wymaga podania jednego lub więcej dodatkowych dowodów weryfikujących Twoją tożsamość. W ten sposób, nawet jeśli ktoś zdobędzie Twoje hasło, nadal nie będzie mógł uzyskać dostępu do Twojego konta bez drugiego elementu informacji. To jak dodanie dodatkowego zamka do drzwi, co znacznie utrudnia włamanie.

Postępuj zgodnie z poniższymi instrukcjami, aby włączyć MFA. Jeśli nie skonfigurujesz go poprawnie, logowanie powróci do samego hasła.", + "title": "Uwierzytelnianie wieloskładnikowe (MFA)", + "description": "Uwierzytelnianie wieloskładnikowe (MFA) dodaje dodatkową warstwę zabezpieczeń do Twojego konta. Zamiast tylko wpisywać hasło do logowania, MFA wymaga podania jednego lub więcej dodatkowych dowodów tożsamości. W ten sposób, nawet jeśli ktoś zdobędzie Twoje hasło, nadal nie będzie mógł uzyskać dostępu do Twojego konta bez drugiej informacji. To jak dodanie dodatkowego zamka do drzwi, utrudniającego włamanie.

Proszę postępować zgodnie z poniższymi instrukcjami, aby włączyć MFA. Jeśli nie skonfigurujesz poprawnie, logowanie powróci do samego hasła.", "mfa_enabled": "Włącz uwierzytelnianie wieloskładnikowe", "mfa_method": "Metoda MFA", - "electron_disabled": "Uwierzytelnianie wieloskładnikowe nie jest obecnie obsługiwane w wersji stacjonarnej.", - "totp_title": "Jednorazowe hasło czasowe (TOTP)", - "totp_description": "TOTP (Time-Based One-Time Password) to funkcja bezpieczeństwa, która generuje unikalny, tymczasowy kod, który zmienia się co 30 sekund. Używasz tego kodu wraz z hasłem do logowania się na swoje konto, co znacznie utrudnia dostęp do niego innym osobom.", + "electron_disabled": "Uwierzytelnianie wieloskładnikowe nie jest obecnie obsługiwane w wersji desktopowej.", + "totp_title": "Hasło jednorazowe oparte na czasie (TOTP)", + "totp_description": "TOTP (Time-Based One-Time Password) to funkcja bezpieczeństwa, która generuje unikalny, tymczasowy kod zmieniający się co 30 sekund. Używasz tego kodu wraz z hasłem do logowania się na konto, co znacznie utrudnia dostęp innym osobom.", "totp_secret_title": "Wygeneruj sekret TOTP", "totp_secret_generate": "Wygeneruj sekret TOTP", "totp_secret_regenerate": "Wygeneruj ponownie sekret TOTP", "no_totp_secret_warning": "Aby włączyć TOTP, musisz najpierw wygenerować sekret TOTP.", - "totp_secret_description_warning": "Po wygenerowaniu nowego sekretu TOTP będziesz musiał ponownie zalogować się przy użyciu nowego sekretu TOTP.", - "totp_secret_generated": "Wygenerowano sekret TOTP", - "totp_secret_warning": "Zapisz wygenerowany sekret w bezpiecznym miejscu. Nie zostanie on ponownie pokazany.", - "totp_secret_regenerate_confirm": "Czy na pewno chcesz wygenerować ponownie sekret TOTP? Spowoduje to unieważnienie poprzedniego sekretu TOTP i wszystkich istniejących kodów odzyskiwania.", - "recovery_keys_title": "Klucze odzyskiwania jednorazowego logowania", - "recovery_keys_description": "Klucze odzyskiwania jednorazowego logowania są używane do logowania w przypadku, gdy nie możesz uzyskać dostępu do swoich kodów Authenticator.", - "recovery_keys_description_warning": "Klucze odzyskiwania nie zostaną ponownie pokazane po opuszczeniu strony, przechowuj je w bezpiecznym miejscu.
Po użyciu klucza odzyskiwania nie można go użyć ponownie.", + "totp_secret_description_warning": "Po wygenerowaniu nowego sekretu TOTP będziesz musiał zalogować się ponownie przy użyciu nowego sekretu TOTP.", + "totp_secret_generated": "Sekret TOTP wygenerowany", + "totp_secret_warning": "Proszę zapisać wygenerowany sekret w bezpiecznym miejscu. Nie zostanie pokazany ponownie.", + "totp_secret_regenerate_confirm": "Czy na pewno chcesz ponownie wygenerować sekret TOTP? To unieważni poprzedni sekret TOTP i wszystkie istniejące kody odzyskiwania.", + "recovery_keys_title": "Klucze odzyskiwania logowania jednokrotnego (SSO)", + "recovery_keys_description": "Klucze odzyskiwania logowania jednokrotnego służą do logowania w przypadku braku dostępu do kodów Authenticator.", + "recovery_keys_description_warning": "Klucze odzyskiwania nie zostaną pokazane ponownie po opuszczeniu strony, przechowuj je w bezpiecznym miejscu.
Po użyciu klucza odzyskiwania nie można go użyć ponownie.", "recovery_keys_error": "Błąd generowania kodów odzyskiwania", "recovery_keys_no_key_set": "Nie ustawiono kodów odzyskiwania", "recovery_keys_generate": "Wygeneruj kody odzyskiwania", @@ -1724,15 +1775,15 @@ "recovery_keys_used": "Użyto: {{date}}", "recovery_keys_unused": "Kod odzyskiwania {{index}} jest nieużywany", "oauth_title": "OAuth/OpenID", - "oauth_description": "OpenID to standaryzowany sposób logowania się na strony internetowe przy użyciu konta z innej usługi, takiej jak Google, w celu zweryfikowania Twojej tożsamości. Domyślnym dostawcą jest Google, ale możesz zmienić go na dowolnego innego dostawcę OpenID. Sprawdź tutaj, aby uzyskać więcej informacji. Postępuj zgodnie z tymi instrukcjami, aby skonfigurować usługę OpenID za pośrednictwem Google.", - "oauth_description_warning": "Aby włączyć OAuth/OpenID, musisz ustawić podstawowy adres URL OAuth/OpenID, identyfikator klienta i sekret klienta w pliku config.ini i ponownie uruchomić aplikację. Jeśli chcesz ustawić je ze zmiennych środowiskowych, ustaw TRILIUM_OAUTH_BASE_URL, TRILIUM_OAUTH_CLIENT_ID i TRILIUM_OAUTH_CLIENT_SECRET.", + "oauth_description": "OpenID to standardowy sposób logowania do stron internetowych przy użyciu konta z innej usługi, takiej jak Google, w celu weryfikacji tożsamości. Domyślnym dostawcą jest Google, ale można go zmienić na dowolnego innego dostawcę OpenID. Sprawdź tutaj, aby uzyskać więcej informacji. Postępuj zgodnie z tymi instrukcjami, aby skonfigurować usługę OpenID przez Google.", + "oauth_description_warning": "Aby włączyć OAuth/OpenID, musisz ustawić bazowy URL OAuth/OpenID, ID klienta i sekret klienta w pliku config.ini i zrestartować aplikację. Jeśli chcesz ustawić je za pomocą zmiennych środowiskowych, ustaw TRILIUM_OAUTH_BASE_URL, TRILIUM_OAUTH_CLIENT_ID i TRILIUM_OAUTH_CLIENT_SECRET.", "oauth_missing_vars": "Brakujące ustawienia: {{-variables}}", "oauth_user_account": "Konto użytkownika: ", - "oauth_user_email": "E-mail użytkownika: ", - "oauth_user_not_logged_in": "Niezalogowany!" + "oauth_user_email": "Email użytkownika: ", + "oauth_user_not_logged_in": "Nie zalogowano!" }, "shortcuts": { - "keyboard_shortcuts": "Skróty klawiaturowe", + "keyboard_shortcuts": "Skróty klawiszowe", "multiple_shortcuts": "Wiele skrótów dla tej samej akcji można oddzielić przecinkiem.", "electron_documentation": "Zobacz dokumentację Electron dla dostępnych modyfikatorów i kodów klawiszy.", "type_text_to_filter": "Wpisz tekst, aby filtrować skróty...", @@ -1742,33 +1793,33 @@ "description": "Opis", "reload_app": "Przeładuj aplikację, aby zastosować zmiany", "set_all_to_default": "Ustaw wszystkie skróty na domyślne", - "confirm_reset": "Czy na pewno chcesz zresetować wszystkie skróty klawiaturowe do domyślnych?" + "confirm_reset": "Czy na pewno chcesz zresetować wszystkie skróty klawiszowe do domyślnych?" }, "spellcheck": { "title": "Sprawdzanie pisowni", - "description": "Te opcje dotyczą tylko wersji stacjonarnych, przeglądarki będą używać własnego natywnego sprawdzania pisowni.", + "description": "Te opcje dotyczą tylko wersji desktopowych, przeglądarki będą używać własnego natywnego sprawdzania pisowni.", "enable": "Włącz sprawdzanie pisowni", "language_code_label": "Kod(y) języka", - "language_code_placeholder": "na przykład \"en-US\", \"de-AT\"", - "multiple_languages_info": "Wiele języków można oddzielić przecinkiem, np. \"en-US, de-DE, cs\". ", + "language_code_placeholder": "na przykład \"pl-PL\", \"en-US\"", + "multiple_languages_info": "Wiele języków można oddzielić przecinkiem, np. \"en-US, de-DE, pl\". ", "available_language_codes_label": "Dostępne kody języków:", - "restart-required": "Zmiany w opcjach sprawdzania pisowni zaczną obowiązywać po ponownym uruchomieniu aplikacji." + "restart-required": "Zmiany w opcjach sprawdzania pisowni wejdą w życie po ponownym uruchomieniu aplikacji." }, "sync_2": { "config_title": "Konfiguracja synchronizacji", "server_address": "Adres instancji serwera", "timeout": "Limit czasu synchronizacji", - "timeout_unit": "milisekundy", + "timeout_unit": "milisekund", "proxy_label": "Serwer proxy synchronizacji (opcjonalnie)", - "note": "Notatka", - "note_description": "Jeśli pozostawisz ustawienie proxy puste, zostanie użyty systemowy serwer proxy (dotyczy tylko wersji stacjonarnej/electron).", - "special_value_description": "Inną specjalną wartością jest noproxy, która wymusza ignorowanie nawet systemowego serwera proxy i respektuje NODE_TLS_REJECT_UNAUTHORIZED.", + "note": "Uwaga", + "note_description": "Jeśli pozostawisz ustawienie proxy puste, zostanie użyte proxy systemowe (dotyczy tylko wersji desktop/electron).", + "special_value_description": "Inną wartością specjalną jest noproxy, która wymusza ignorowanie nawet proxy systemowego i respektuje NODE_TLS_REJECT_UNAUTHORIZED.", "save": "Zapisz", "help": "Pomoc", "test_title": "Test synchronizacji", - "test_description": "Sprawdzi to połączenie i uzgadnianie z serwerem synchronizacji. Jeśli serwer synchronizacji nie jest zainicjowany, spowoduje to jego skonfigurowanie do synchronizacji z lokalnym dokumentem.", + "test_description": "To przetestuje połączenie i handshake z serwerem synchronizacji. Jeśli serwer synchronizacji nie jest zainicjowany, skonfiguruje go do synchronizacji z lokalnym dokumentem.", "test_button": "Testuj synchronizację", - "handshake_failed": "Uzgadnianie serwera synchronizacji nie powiodło się, błąd: {{message}}" + "handshake_failed": "Handshake serwera synchronizacji nie powiódł się, błąd: {{message}}" }, "api_log": { "close": "Zamknij" @@ -1776,20 +1827,20 @@ "attachment_detail_2": { "will_be_deleted_in": "Ten załącznik zostanie automatycznie usunięty za {{time}}", "will_be_deleted_soon": "Ten załącznik zostanie wkrótce automatycznie usunięty", - "deletion_reason": ", ponieważ załącznik nie jest powiązany z treścią notatki. Aby zapobiec usunięciu, dodaj link do załącznika z powrotem do treści lub przekonwertuj załącznik na notatkę.", + "deletion_reason": ", ponieważ załącznik nie jest podlinkowany w treści notatki. Aby zapobiec usunięciu, dodaj link do załącznika z powrotem do treści lub przekonwertuj załącznik na notatkę.", "role_and_size": "Rola: {{role}}, Rozmiar: {{size}}", "link_copied": "Link do załącznika skopiowany do schowka.", "unrecognized_role": "Nierozpoznana rola załącznika '{{role}}'." }, "bookmark_switch": { "bookmark": "Zakładka", - "bookmark_this_note": "Dodaj tę notatkę do zakładek w lewym panelu bocznym", + "bookmark_this_note": "Dodaj tę notatkę do zakładek w lewym panelu", "remove_bookmark": "Usuń zakładkę" }, "editability_select": { "auto": "Auto", "read_only": "Tylko do odczytu", - "always_editable": "Zawsze edytowalny", + "always_editable": "Zawsze edytowalna", "note_is_editable": "Notatka jest edytowalna, jeśli nie jest zbyt długa.", "note_is_read_only": "Notatka jest tylko do odczytu, ale można ją edytować po kliknięciu przycisku.", "note_is_always_editable": "Notatka jest zawsze edytowalna, niezależnie od jej długości." @@ -1807,8 +1858,8 @@ "unarchive": "Przywróć z archiwum", "delete": "Usuń", "search-in-subtree": "Szukaj w poddrzewie", - "hoist-note": "Podnieś notatkę", - "unhoist-note": "Opuść notatkę", + "hoist-note": "Zawęź widok do notatki (Hoist)", + "unhoist-note": "Cofnij zawężenie (Unhoist)", "edit-branch-prefix": "Edytuj prefiks gałęzi", "advanced": "Zaawansowane", "expand-subtree": "Rozwiń poddrzewo", @@ -1818,9 +1869,9 @@ "convert-to-attachment": "Konwertuj na załącznik", "copy-note-path-to-clipboard": "Kopiuj ścieżkę notatki do schowka", "protect-subtree": "Chroń poddrzewo", - "unprotect-subtree": "Odblokuj poddrzewo", + "unprotect-subtree": "Zdejmij ochronę z poddrzewa", "copy-clone": "Kopiuj / klonuj", - "clone-to": "Klonuj do...", + "clone-to": "Sklonuj do...", "cut": "Wytnij", "move-to": "Przenieś do...", "paste-into": "Wklej do", @@ -1828,14 +1879,14 @@ "duplicate": "Duplikuj", "export": "Eksportuj", "import-into-note": "Importuj do notatki", - "apply-bulk-actions": "Zastosuj akcje zbiorcze", + "apply-bulk-actions": "Zastosuj akcje masowe", "converted-to-attachments": "{{count}} notatek zostało przekonwertowanych na załączniki.", - "convert-to-attachment-confirm": "Czy na pewno chcesz przekonwertować wybrane notatki na załączniki ich notatek nadrzędnych?", + "convert-to-attachment-confirm": "Czy na pewno chcesz przekonwertować wybrane notatki na załączniki ich notatek nadrzędnych? Ta operacja dotyczy tylko notatek Obrazów, inne notatki zostaną pominięte.", "open-in-popup": "Szybka edycja" }, "shared_info": { - "shared_publicly": "Ta notatka jest udostępniona publicznie na {{- link}}.", - "shared_locally": "Ta notatka jest udostępniona lokalnie na {{- link}}.", + "shared_publicly": "Ta notatka jest udostępniona publicznie pod adresem {{- link}}.", + "shared_locally": "Ta notatka jest udostępniona lokalnie pod adresem {{- link}}.", "help_link": "Aby uzyskać pomoc, odwiedź wiki." }, "note_types": { @@ -1848,15 +1899,15 @@ "book": "Kolekcja", "mermaid-diagram": "Diagram Mermaid", "canvas": "Płótno", - "web-view": "Widok sieciowy", + "web-view": "Widok WWW", "mind-map": "Mapa myśli", "file": "Plik", "image": "Obraz", - "launcher": "Program uruchamiający", + "launcher": "Launcher", "doc": "Dokument", "widget": "Widżet", - "confirm-change": "Nie zaleca się zmiany typu notatki, gdy zawartość notatki nie jest pusta. Czy chcesz kontynuować mimo to?", - "geo-map": "Mapa geograficzna", + "confirm-change": "Nie zaleca się zmiany typu notatki, gdy treść notatki nie jest pusta. Czy mimo to chcesz kontynuować?", + "geo-map": "Mapa Geo", "beta-feature": "Beta", "ai-chat": "Czat AI", "task-list": "Lista zadań", @@ -1865,39 +1916,45 @@ }, "protect_note": { "toggle-on": "Chroń notatkę", - "toggle-off": "Odblokuj notatkę", - "toggle-on-hint": "Notatka nie jest chroniona, kliknij, aby ją chronić", - "toggle-off-hint": "Notatka jest chroniona, kliknij, aby ją odblokować" + "toggle-off": "Zdejmij ochronę z notatki", + "toggle-on-hint": "Notatka nie jest chroniona, kliknij, aby włączyć ochronę", + "toggle-off-hint": "Notatka jest chroniona, kliknij, aby zdjąć ochronę" }, "shared_switch": { - "shared": "Udostępnione", + "shared": "Udostępniona", "toggle-on-title": "Udostępnij notatkę", "toggle-off-title": "Przestań udostępniać notatkę", - "shared-branch": "Ta notatka istnieje tylko jako notatka udostępniona, zaprzestanie udostępniania spowoduje jej usunięcie. Czy chcesz kontynuować i tym samym usunąć tę notatkę?", - "inherited": "Notatka nie może być tutaj nieudostępniona, ponieważ jest udostępniana poprzez dziedziczenie od przodka." + "shared-branch": "Ta notatka istnieje tylko jako notatka udostępniona, zaprzestanie udostępniania spowoduje jej usunięcie. Czy chcesz kontynuować i usunąć tę notatkę?", + "inherited": "Nie można przestać udostępniać notatki w tym miejscu, ponieważ jest ona udostępniona poprzez dziedziczenie od przodka." }, "template_switch": { "template": "Szablon", "toggle-on-hint": "Uczyń notatkę szablonem", - "toggle-off-hint": "Usuń notatkę jako szablon" + "toggle-off-hint": "Usuń notatkę z szablonów" }, "open-help-page": "Otwórz stronę pomocy", "find": { - "case_sensitive": "Uwzględniaj wielkość liter", - "match_words": "Dopasuj słowa", + "case_sensitive": "Uwzględnij wielkość liter", + "match_words": "Dopasuj całe słowa", "find_placeholder": "Znajdź w tekście...", - "replace_placeholder": "Zastąp...", - "replace": "Zastąp", - "replace_all": "Zastąp wszystko" + "replace_placeholder": "Zamień na...", + "replace": "Zamień", + "replace_all": "Zamień wszystko" }, "highlights_list_2": { "title": "Lista wyróżnień", - "options": "Opcje" + "options": "Opcje", + "modal_title": "Konfiguracja listy wyróżnień", + "menu_configure": "Konfiguracja listy wyróżnień...", + "no_highlights": "Nie znaleziono wyróżnień.", + "title_with_count_one": "{{count}} podświetlenie", + "title_with_count_few": "{{count}} podświetlenia", + "title_with_count_many": "{{count}} podświetleń" }, "quick-search": { "placeholder": "Szybkie wyszukiwanie", - "searching": "Wyszukiwanie...", - "no-results": "Nie znaleziono wyników", + "searching": "Szukanie...", + "no-results": "Brak wyników", "more-results": "... i {{number}} więcej wyników.", "show-in-full-search": "Pokaż w pełnym wyszukiwaniu" }, @@ -1910,31 +1967,41 @@ "automatically-collapse-notes-title": "Notatki zostaną zwinięte po okresie bezczynności, aby uporządkować drzewo.", "save-changes": "Zapisz i zastosuj zmiany", "auto-collapsing-notes-after-inactivity": "Automatyczne zwijanie notatek po bezczynności...", - "saved-search-note-refreshed": "Odświeżono zapisaną notatkę wyszukiwania.", - "hoist-this-note-workspace": "Podnieś tę notatkę (obszar roboczy)", - "refresh-saved-search-results": "Odśwież zapisane wyniki wyszukiwania", + "saved-search-note-refreshed": "Notatka zapisanego wyszukiwania odświeżona.", + "hoist-this-note-workspace": "Zawęź widok do tej notatki (obszar roboczy)", + "refresh-saved-search-results": "Odśwież wyniki zapisanego wyszukiwania", "create-child-note": "Utwórz notatkę podrzędną", - "unhoist": "Opuść", - "toggle-sidebar": "Przełącz pasek boczny" + "unhoist": "Cofnij zawężenie", + "toggle-sidebar": "Przełącz pasek boczny", + "dropping-not-allowed": "Upuszczanie notatek w tej lokalizacji jest niedozwolone." }, "title_bar_buttons": { - "window-on-top": "Trzymaj okno na wierzchu" + "window-on-top": "Utrzymuj okno na wierzchu" }, "note_detail": { - "could_not_find_typewidget": "Nie można znaleźć typeWidget dla typu '{{type}}'" + "could_not_find_typewidget": "Nie można znaleźć widżetu typu dla typu '{{type}}'", + "printing": "Drukowanie w toku...", + "printing_pdf": "Eksportowanie do PDF w toku..." }, "note_title": { - "placeholder": "wpisz tutaj tytuł notatki..." + "placeholder": "wpisz tytuł notatki tutaj...", + "created_on": "Utworzono ", + "last_modified": "Zmodyfikowano: ", + "note_type_switcher_label": "Zmień z {{type}} na:", + "note_type_switcher_others": "Inny typ notatki", + "note_type_switcher_templates": "Szablon", + "note_type_switcher_collection": "Kolekcja", + "edited_notes": "Edytowane notatki" }, "search_result": { - "no_notes_found": "Nie znaleziono żadnych notatek dla podanych parametrów wyszukiwania.", + "no_notes_found": "Nie znaleziono notatek dla podanych parametrów wyszukiwania.", "search_not_executed": "Wyszukiwanie nie zostało jeszcze wykonane. Kliknij przycisk \"Szukaj\" powyżej, aby zobaczyć wyniki." }, "spacer": { - "configure_launchbar": "Skonfiguruj pasek uruchamiania" + "configure_launchbar": "Konfiguruj pasek szybkiego dostępu" }, "sql_result": { - "no_rows": "Nie zwrócono żadnych wierszy dla tego zapytania" + "no_rows": "Dla tego zapytania nie zwrócono żadnych wierszy" }, "sql_table_schemas": { "tables": "Tabele" @@ -1946,14 +2013,15 @@ "close_other_tabs": "Zamknij inne karty", "close_right_tabs": "Zamknij karty po prawej", "close_all_tabs": "Zamknij wszystkie karty", - "reopen_last_tab": "Otwórz ponownie ostatnią zamkniętą kartę", + "reopen_last_tab": "Otwórz ponownie ostatnio zamkniętą kartę", "move_tab_to_new_window": "Przenieś tę kartę do nowego okna", "copy_tab_to_new_window": "Skopiuj tę kartę do nowego okna", "new_tab": "Nowa karta" }, "toc": { "table_of_contents": "Spis treści", - "options": "Opcje" + "options": "Opcje", + "no_headings": "Brak nagłówków." }, "watched_file_update_status": { "file_last_modified": "Plik został ostatnio zmodyfikowany .", @@ -1961,18 +2029,18 @@ "ignore_this_change": "Ignoruj tę zmianę" }, "app_context": { - "please_wait_for_save": "Poczekaj kilka sekund na zakończenie zapisywania, a następnie spróbuj ponownie." + "please_wait_for_save": "Poczekaj kilka sekund na zakończenie zapisu, a następnie spróbuj ponownie." }, "note_create": { "duplicated": "Notatka \"{{title}}\" została zduplikowana." }, "image": { "copied-to-clipboard": "Odniesienie do obrazu zostało skopiowane do schowka. Można je wkleić w dowolnej notatce tekstowej.", - "cannot-copy": "Nie można skopiować odniesienia do obrazu do schowka." + "cannot-copy": "Nie udało się skopiować odniesienia do obrazu do schowka." }, "clipboard": { - "cut": "Notatka(i) została(y) wycięta(e) do schowka.", - "copied": "Notatka(i) została(y) skopiowana(e) do schowka.", + "cut": "Notatka(-i) zostały wycięte do schowka.", + "copied": "Notatka(-i) zostały skopiowane do schowka.", "copy_failed": "Nie można skopiować do schowka z powodu problemów z uprawnieniami.", "copy_success": "Skopiowano do schowka." }, @@ -1982,7 +2050,7 @@ "sql-error": "Wystąpił błąd podczas wykonywania zapytania SQL: {{message}}" }, "branches": { - "cannot-move-notes-here": "Nie można przenieść tutaj notatek.", + "cannot-move-notes-here": "Nie można przenieść notatek tutaj.", "delete-status": "Status usuwania", "delete-notes-in-progress": "Usuwanie notatek w toku: {{count}}", "delete-finished-successfully": "Usuwanie zakończone pomyślnie.", @@ -1990,34 +2058,34 @@ "undeleting-notes-finished-successfully": "Przywracanie notatek zakończone pomyślnie." }, "frontend_script_api": { - "async_warning": "Przekazujesz funkcję asynchroniczną do `api.runOnBackend()`, co prawdopodobnie nie zadziała zgodnie z zamierzeniami.\\nAlbo uczyń funkcję synchroniczną (usuwając słowo kluczowe `async`), albo użyj `api.runAsyncOnBackendWithManualTransactionHandling()`.", + "async_warning": "Przekazujesz funkcję asynchroniczną do `api.runOnBackend()`, co prawdopodobnie nie zadziała zgodnie z Twoimi intencjami.\\nAlbo spraw, aby funkcja była synchroniczna (usuwając słowo kluczowe `async`), albo użyj `api.runAsyncOnBackendWithManualTransactionHandling()`.", "sync_warning": "Przekazujesz funkcję synchroniczną do `api.runAsyncOnBackendWithManualTransactionHandling()`,\\npodczas gdy prawdopodobnie powinieneś użyć `api.runOnBackend()`." }, "ws": { "sync-check-failed": "Sprawdzanie synchronizacji nie powiodło się!", - "consistency-checks-failed": "Sprawdzanie spójności nie powiodło się! Zobacz logi, aby uzyskać szczegółowe informacje.", + "consistency-checks-failed": "Sprawdzanie spójności nie powiodło się! Zobacz logi po szczegóły.", "encountered-error": "Napotkano błąd \"{{message}}\", sprawdź konsolę.", "lost-websocket-connection-title": "Utracono połączenie z serwerem", - "lost-websocket-connection-message": "Sprawdź konfigurację swojego odwrotnego serwera proxy (np. nginx lub Apache), aby upewnić się, że połączenia WebSocket są prawidłowo dozwolone i nie są blokowane." + "lost-websocket-connection-message": "Sprawdź konfigurację odwrotnego proxy (np. nginx lub Apache), aby upewnić się, że połączenia WebSocket są prawidłowo dozwolone i nie są blokowane." }, "hoisted_note": { - "confirm_unhoisting": "Żądana notatka '{{requestedNote}}' znajduje się poza poddrzewem podniesionej notatki '{{hoistedNote}}' i musisz ją opuścić, aby uzyskać do niej dostęp. Czy chcesz kontynuować opuszczanie?" + "confirm_unhoisting": "Żądana notatka '{{requestedNote}}' znajduje się poza poddrzewem zawężonej notatki '{{hoistedNote}}' i musisz cofnąć zawężenie, aby uzyskać do niej dostęp. Czy chcesz kontynuować cofanie zawężenia?" }, "launcher_context_menu": { - "reset_launcher_confirm": "Czy na pewno chcesz zresetować \"{{title}}\"? Wszystkie dane / ustawienia w tej notatce (i jej dzieciach) zostaną utracone, a program uruchamiający zostanie przywrócony do pierwotnej lokalizacji.", - "add-note-launcher": "Dodaj program uruchamiający notatkę", - "add-script-launcher": "Dodaj program uruchamiający skrypt", + "reset_launcher_confirm": "Czy na pewno chcesz zresetować \"{{title}}\"? Wszystkie dane / ustawienia w tej notatce (i jej elementach podrzędnych) zostaną utracone, a launcher zostanie przywrócony do pierwotnej lokalizacji.", + "add-note-launcher": "Dodaj launcher notatki", + "add-script-launcher": "Dodaj launcher skryptu", "add-custom-widget": "Dodaj niestandardowy widżet", "add-spacer": "Dodaj odstęp", "delete": "Usuń ", "reset": "Resetuj", - "move-to-visible-launchers": "Przenieś do widocznych programów uruchamiających", - "move-to-available-launchers": "Przenieś do dostępnych programów uruchamiających", - "duplicate-launcher": "Duplikuj program uruchamiający " + "move-to-visible-launchers": "Przenieś do widocznych launcherów", + "move-to-available-launchers": "Przenieś do dostępnych launcherów", + "duplicate-launcher": "Duplikuj launcher " }, "highlighting": { "title": "Bloki kodu", - "description": "Kontroluje podświetlanie składni dla bloków kodu w notatkach tekstowych, notatki kodowe nie będą miały wpływu.", + "description": "Kontroluje podświetlanie składni dla bloków kodu wewnątrz notatek tekstowych, notatki kodu nie zostaną zmienione.", "color-scheme": "Schemat kolorów" }, "code_block": { @@ -2038,18 +2106,18 @@ "label": "Pasek narzędzi formatowania", "floating": { "title": "Pływający", - "description": "narzędzia do edycji pojawiają się w pobliżu kursora;" + "description": "narzędzia edycji pojawiają się w pobliżu kursora;" }, "fixed": { "title": "Stały", - "description": "narzędzia do edycji pojawiają się na karcie wstążki \"Formatowanie\"." + "description": "narzędzia edycji pojawiają się w karcie wstążki \"Formatowanie\"." }, - "multiline-toolbar": "Wyświetlaj pasek narzędzi w wielu wierszach, jeśli się nie mieści." + "multiline-toolbar": "Wyświetl pasek narzędzi w wielu wierszach, jeśli się nie mieści." } }, "geo-map": { "create-child-note-title": "Utwórz nową notatkę podrzędną i dodaj ją do mapy", - "create-child-note-instruction": "Kliknij na mapę, aby utworzyć nową notatkę w tej lokalizacji, lub naciśnij Escape, aby anulować.", + "create-child-note-instruction": "Kliknij na mapie, aby utworzyć nową notatkę w tej lokalizacji lub naciśnij Escape, aby anulować.", "unable-to-load-map": "Nie można załadować mapy." }, "geo-map-context": { @@ -2067,6 +2135,98 @@ "presentation_view": { "edit-slide": "Edytuj ten slajd", "start-presentation": "Rozpocznij prezentację", - "slide-overview": "Przełącz podgląd slajdów" + "slide-overview": "Przełącz przegląd slajdów" + }, + "experimental_features": { + "title": "Opcje eksperymentalne", + "disclaimer": "Te opcje są eksperymentalne i mogą powodować niestabilność. Używaj z ostrożnością.", + "new_layout_name": "Nowy układ", + "new_layout_description": "Wypróbuj nowy układ dla nowocześniejszego wyglądu i lepszej użyteczności. Podlega znacznym zmianom w nadchodzących wydaniach." + }, + "read-only-info": { + "read-only-note": "Obecnie przeglądasz notatkę tylko do odczytu.", + "auto-read-only-note": "Ta notatka jest wyświetlana w trybie tylko do odczytu dla szybszego ładowania.", + "edit-note": "Edytuj notatkę" + }, + "calendar_view": { + "delete_note": "Usuń notatkę..." + }, + "note-color": { + "clear-color": "Wyczyść kolor notatki", + "set-color": "Ustaw kolor notatki", + "set-custom-color": "Ustaw niestandardowy kolor notatki" + }, + "popup-editor": { + "maximize": "Przełącz na pełny edytor" + }, + "server": { + "unknown_http_error_title": "Błąd komunikacji z serwerem", + "unknown_http_error_content": "Kod statusu: {{statusCode}}\nURL: {{method}} {{url}}\nWiadomość: {{message}}", + "traefik_blocks_requests": "Jeśli używasz odwrotnego proxy Traefik, wprowadziło ono zmianę łamiącą kompatybilność, która wpływa na komunikację z serwerem." + }, + "tab_history_navigation_buttons": { + "go-back": "Wróć do poprzedniej notatki", + "go-forward": "Przejdź dalej do następnej notatki" + }, + "breadcrumb_badges": { + "read_only_explicit": "Tylko do odczytu", + "read_only_explicit_description": "Ta notatka została ręcznie ustawiona jako tylko do odczytu.\nKliknij, aby ją tymczasowo edytować.", + "read_only_auto": "Auto tylko do odczytu", + "read_only_auto_description": "Ta notatka została ustawiona automatycznie w tryb tylko do odczytu ze względów wydajnościowych. Ten automatyczny limit można dostosować w ustawieniach.\n\nKliknij, aby ją tymczasowo edytować.", + "read_only_temporarily_disabled": "Tymczasowo edytowalna", + "read_only_temporarily_disabled_description": "Ta notatka jest obecnie edytowalna, ale normalnie jest tylko do odczytu. Notatka powróci do trybu tylko do odczytu, gdy tylko przejdziesz do innej notatki.\n\nKliknij, aby ponownie włączyć tryb tylko do odczytu.", + "shared_publicly": "Udostępniona publicznie", + "shared_locally": "Udostępniona lokalnie", + "clipped_note": "Wycinek WWW", + "clipped_note_description": "Ta notatka została pierwotnie pobrana z {{url}}.\n\nKliknij, aby przejść do źródłowej strony internetowej.", + "execute_script": "Uruchom skrypt", + "execute_script_description": "Ta notatka jest notatką skryptową. Kliknij, aby wykonać skrypt.", + "execute_sql": "Uruchom SQL", + "execute_sql_description": "Ta notatka jest notatką SQL. Kliknij, aby wykonać zapytanie SQL.", + "shared_copy_to_clipboard": "Kopiuj link do schowka", + "shared_open_in_browser": "Otwórz link w przeglądarce", + "shared_unshare": "Usuń udostępnienie" + }, + "status_bar": { + "language_title": "Zmień język treści", + "note_info_title": "Informacje o notatce (np. daty, rozmiar notatki)", + "backlinks_title_one": "Wyświetl link zwrotny", + "backlinks_title_few": "Wyświetl linki zwrotne", + "backlinks_title_many": "Wyświetl linki zwrotne", + "attachments_title_one": "Otwórz załącznik w nowej karcie", + "attachments_title_few": "Otwórz załączniki w nowej karcie", + "attachments_title_many": "Otwórz załączniki w nowej karcie", + "attributes_one": "{{count}} atrybut", + "attributes_few": "{{count}} atrybuty", + "attributes_many": "{{count}} atrybutów", + "attributes_title": "Atrybuty własne i atrybuty dziedziczone", + "note_paths_title": "Ścieżki notatek", + "code_note_switcher": "Zmień tryb języka", + "backlinks_one": "{{count}} link zwrotny", + "backlinks_few": "{{count}} linki zwrotne", + "backlinks_many": "{{count}} linków zwrotnych", + "attachments_one": "{{count}} załącznik", + "attachments_few": "{{count}} załączniki", + "attachments_many": "{{count}} załączników", + "note_paths_one": "{{count}} ścieżka", + "note_paths_few": "{{count}} ścieżki", + "note_paths_many": "{{count}} ścieżek" + }, + "breadcrumb": { + "hoisted_badge": "Wyróżniony", + "hoisted_badge_title": "Usuń wyróżnienie", + "workspace_badge": "Obszar roboczy", + "scroll_to_top_title": "Przejdź na początek notatki", + "create_new_note": "Utwórz nową notatkę podrzędną", + "empty_hide_archived_notes": "Ukryj zarchiwizowane notatki" + }, + "attributes_panel": { + "title": "Atrybuty notatki" + }, + "right_pane": { + "empty_message": "Brak elementów do wyświetlenia dla tej notatki", + "empty_button": "Ukryj panel", + "toggle": "Pokaż/ukryj prawy panel", + "custom_widget_go_to_source": "Przejdź do kodu źródłowego" } } diff --git a/apps/client/src/translations/pt_br/translation.json b/apps/client/src/translations/pt_br/translation.json index 6a875cee98..665171c840 100644 --- a/apps/client/src/translations/pt_br/translation.json +++ b/apps/client/src/translations/pt_br/translation.json @@ -29,7 +29,15 @@ "bundle-error": { "title": "Falha para carregar o script customizado", "message": "O script da nota com ID \"{{id}}\", intitulada \"{{title}}\", não pôde ser executado devido a:\n\n{{message}}" - } + }, + "widget-list-error": { + "title": "Falha ao obter a lista de widgets do servidor" + }, + "widget-render-error": { + "title": "Falha ao renderizar um widget React personalizado" + }, + "widget-missing-parent": "O widget personalizado não possui a propriedade obrigatória '{{property}}' definida.", + "open-script-note": "Abrir nota de script" }, "add_link": { "add_link": "Adicionar link", @@ -46,7 +54,10 @@ "save": "Salvar", "edit_branch_prefix": "Editar Prefixo do Branch", "help_on_tree_prefix": "Ajuda sobre o prefixo da árvore de notas", - "branch_prefix_saved": "O prefixo de ramificação foi salvo." + "branch_prefix_saved": "O prefixo de ramificação foi salvo.", + "edit_branch_prefix_multiple": "Editar prefixo do ramo para {{count}} ramos", + "branch_prefix_saved_multiple": "O prefixo do ramo foi salvo para {{count}} ramos.", + "affected_branches": "Ramos afetados ({{count}}):" }, "bulk_actions": { "bulk_actions": "Ações em massa", @@ -254,7 +265,8 @@ "export_status": "Status da exportação", "export_in_progress": "Exportação em andamento: {{progressCount}}", "export_finished_successfully": "Exportação concluída com sucesso.", - "format_pdf": "PDF – para impressão ou compartilhamento." + "format_pdf": "PDF – para impressão ou compartilhamento.", + "share-format": "HTML para publicação na web — usa o mesmo tema das notas compartilhadas, mas pode ser publicado como um site estático." }, "help": { "noteNavigation": "Navegação de notas", @@ -308,7 +320,8 @@ "other": "Outros", "quickSearch": "focar no campo de pesquisa rápida", "inPageSearch": "pesquisa na página", - "title": "Folha de Dicas" + "title": "Folha de Dicas", + "editShortcuts": "Editar atalhos de teclado" }, "import": { "importIntoNote": "Importar para a nota", @@ -334,7 +347,8 @@ }, "import-status": "Status da importação", "in-progress": "Importação em andamento: {{progress}}", - "successful": "Importação concluída com sucesso." + "successful": "Importação concluída com sucesso.", + "importZipRecommendation": "Ao importar um arquivo ZIP, a hierarquia de notas refletirá a estrutura de subdiretórios dentro do arquivo." }, "include_note": { "dialog_title": "Incluir nota", @@ -349,7 +363,8 @@ "info": { "modalTitle": "Mensagem informativa", "closeButton": "Fechar", - "okButton": "OK" + "okButton": "OK", + "copy_to_clipboard": "Copiar para a área de transferência" }, "jump_to_note": { "search_placeholder": "Pesquise uma nota pelo nome ou digite > para comandos...", @@ -771,7 +786,7 @@ "import-into-note": "Importar na nota", "apply-bulk-actions": "Aplicar ações em massa", "converted-to-attachments": "{{count}} notas foram convertidas em anexos.", - "convert-to-attachment-confirm": "Tem certeza de que deseja converter as notas selecionadas em anexos de suas notas-pai?", + "convert-to-attachment-confirm": "Tem certeza de que deseja converter as notas selecionadas em anexos de suas notas pai? Esta operação se aplica apenas a notas de imagem; outras notas serão ignoradas.", "open-in-popup": "Edição rápida", "archive": "Ficheiro", "unarchive": "Desarquivar" @@ -789,7 +804,7 @@ "show_attachments_description": "Exibir anexos da nota", "search_notes_title": "Buscar Notas", "search_notes_description": "Abrir busca avançada", - "configure_launch_bar_description": "Abrir a configuração da barra de lançamento, para adicionar ou remover itens." + "configure_launch_bar_description": "Abrir a configuração da barra de atalho, para adicionar ou remover itens." }, "delete_note": { "delete_note": "Excluir nota", @@ -882,7 +897,7 @@ "zoom_out": "Reduzir", "reset_zoom_level": "Redefinir Zoom", "zoom_in": "Aumentar", - "configure_launchbar": "Configurar Barra de Lançamento", + "configure_launchbar": "Configurar Barra de Atalhos", "show_shared_notes_subtree": "Exibir Subárvore de Notas Compartilhadas", "advanced": "Avançado", "open_dev_tools": "Abrir Ferramentas de Desenvolvedor", @@ -897,7 +912,9 @@ "logout": "Sair", "show-cheatsheet": "Exibir Cheatsheet", "toggle-zen-mode": "Modo Zen", - "reload_hint": "Recarregar pode ajudar com alguns problemas visuais sem reiniciar toda a aplicação." + "reload_hint": "Recarregar pode ajudar com alguns problemas visuais sem reiniciar toda a aplicação.", + "new-version-available": "Nova atualização disponível", + "download-update": "Obter a versão {{latestVersion}}" }, "zen_mode": { "button_exit": "Sair do Modo Zen" @@ -935,7 +952,14 @@ "convert_into_attachment_successful": "A nota '{{title}}' foi convertida para anexo.", "print_pdf": "Exportar como PDF…", "open_note_externally_title": "O arquivo será aberto em uma aplicação externa e monitorado por alterações. Você então poderá enviar a versão modificada de volta para o Trilium.", - "convert_into_attachment_prompt": "Você tem certeza que quer converter a nota '{{title}}' em um anexo da nota pai?" + "convert_into_attachment_prompt": "Você tem certeza que quer converter a nota '{{title}}' em um anexo da nota pai?", + "open_note_on_server": "Abrir nota no servidor", + "view_revisions": "Revisões da nota…", + "advanced": "Avançado", + "export_as_image": "Exportar como imagem", + "export_as_image_png": "PNG (raster)", + "export_as_image_svg": "SVG (vetorial)", + "note_map": "Mapa de notas" }, "protected_session_status": { "inactive": "Clique para entrar na sessão protegida", @@ -979,7 +1003,8 @@ "insert_child_note": "Inserir nota filha", "delete_this_note": "Excluir essa nota", "error_unrecognized_command": "Comando não reconhecido {{command}}", - "error_cannot_get_branch_id": "Não foi possível obter o branchId para o notePath '{{notePath}} '" + "error_cannot_get_branch_id": "Não foi possível obter o branchId para o notePath '{{notePath}} '", + "note_revisions": "Revisões de notas" }, "note_icon": { "change_note_icon": "Alterar ícone da nota", @@ -1007,7 +1032,12 @@ "table": "Tabela", "geo-map": "Mapa geográfico", "board": "Quadro", - "include_archived_notes": "Exibir notas arquivadas" + "include_archived_notes": "Exibir notas arquivadas", + "expand_tooltip": "Expande os filhos diretos desta coleção (um nível). Para mais opções, pressione a seta à direita.", + "expand_first_level": "Expandir filhos diretos", + "expand_nth_level": "Expandir {{depth}} níveis", + "expand_all_levels": "Expandir todos os níveis", + "presentation": "Apresentação" }, "edited_notes": { "no_edited_notes_found": "Ainda não há nenhuma nota editada neste dia…", @@ -1020,7 +1050,7 @@ "file_type": "Tipo do arquivo", "file_size": "Tamanho do arquivo", "download": "Baixar", - "open": "Abrir", + "open": "Abrir externamente", "upload_new_revision": "Enviar nova revisão", "upload_success": "Uma nova revisão de arquivo foi enviada.", "upload_failed": "O envio de uma nova revisão de arquivo falhou.", @@ -1040,7 +1070,8 @@ }, "inherited_attribute_list": { "title": "Atributos Herdados", - "no_inherited_attributes": "Nenhum atributo herdado." + "no_inherited_attributes": "Nenhum atributo herdado.", + "none": "nenhum" }, "note_info_widget": { "note_id": "ID da Nota", @@ -1051,7 +1082,9 @@ "calculate": "calcular", "title": "Informações da nota", "subtree_size": "(tamanho da subárvore: {{size}} em {{count}} notas)", - "note_size_info": "O tamanho da nota fornece uma estimativa aproximada dos requisitos de armazenamento para esta nota. Leva em conta o conteúdo e o conteúdo de suas revisões de nota." + "note_size_info": "O tamanho da nota fornece uma estimativa aproximada dos requisitos de armazenamento para esta nota. Leva em conta o conteúdo e o conteúdo de suas revisões de nota.", + "mime": "Tipo MIME", + "show_similar_notes": "Mostrar notas semelhantes" }, "note_map": { "open_full": "Expandir completamente", @@ -1111,7 +1144,8 @@ "search_note_saved": "Nota de pesquisa foi salva em {{- notePathTitle}}", "fast_search_description": "A opção de pesquisa rápida desabilita a pesquisa de texto completo do conteúdo de nota, o que pode acelerar a pesquisa em grandes bancos de dados.", "include_archived_notes_description": "As notas arquivadas são por padrão excluídas dos resultados da pesquisa, com esta opção elas serão incluídas.", - "debug_description": "A depuração irá imprimir informações adicionais no console para ajudar na depuração de consultas complexas" + "debug_description": "A depuração irá imprimir informações adicionais no console para ajudar na depuração de consultas complexas", + "view_options": "Ver opções:" }, "similar_notes": { "title": "Notas Similares", @@ -1192,7 +1226,13 @@ }, "editable_text": { "placeholder": "Digite o conteúdo da sua nota aqui…", - "auto-detect-language": "Detectado automaticamente" + "auto-detect-language": "Detectado automaticamente", + "editor_crashed_title": "O editor de texto travou", + "editor_crashed_content": "Seu conteúdo foi recuperado com sucesso, mas algumas das suas alterações mais recentes podem não ter sido salvas.", + "editor_crashed_details_button": "Veja mais detalhes...", + "editor_crashed_details_intro": "Se você encontrar este erro várias vezes, considere relatá-lo no GitHub colando as informações abaixo.", + "editor_crashed_details_title": "Informação técnica", + "keeps-crashing": "O componente de edição continua travando. Tente reiniciar o Trilium. Se o problema persistir, considere criar um relatório de bug." }, "empty": { "search_placeholder": "buscar uma nota pelo nome", @@ -1299,7 +1339,8 @@ "title": "Largura do Conteúdo", "max_width_label": "Largura máxima do conteúdo", "max_width_unit": "pixels", - "default_description": "Por padrão, o Trilium limita a largura máxima do conteúdo para melhorar a legibilidade em janelas maximizadas em telas wide." + "default_description": "Por padrão, o Trilium limita a largura máxima do conteúdo para melhorar a legibilidade em janelas maximizadas em telas wide.", + "centerContent": "Manter conteúdo centralizado" }, "native_title_bar": { "title": "Barra de Título Nativa (requer recarregar o app)", @@ -1319,11 +1360,11 @@ "layout": "Layout", "layout-vertical-title": "Vertical", "layout-horizontal-title": "Horizontal", - "layout-vertical-description": "barra de lançamento está a esquerda (padrão)", - "layout-horizontal-description": "barra de lançamento está abaixo da barra de abas, a barra de abas agora tem a largura total." + "layout-vertical-description": "barra de atalho está a esquerda (padrão)", + "layout-horizontal-description": "barra de atalho está abaixo da barra de abas, a barra de abas agora tem a largura total." }, "note_launcher": { - "this_launcher_doesnt_define_target_note": "Este lançador não define uma nota destino." + "this_launcher_doesnt_define_target_note": "Este atalho não define uma nota destino." }, "copy_image_reference_button": { "button_title": "Copiar referência da imagem para a área de transferência, pode ser colado em uma nota de texto." @@ -1378,7 +1419,10 @@ "title": "Editor" }, "code_mime_types": { - "title": "Tipos MIME disponíveis no dropdown" + "title": "Tipos MIME disponíveis no dropdown", + "tooltip_syntax_highlighting": "Realce de sintaxe", + "tooltip_code_block_syntax": "Blocos de código em notas de texto", + "tooltip_code_note_syntax": "Notas de código" }, "vim_key_bindings": { "use_vim_keybindings_in_code_notes": "Atribuições de teclas do Vim", @@ -1498,7 +1542,13 @@ "min-days-in-first-week": "Mínimo de dias da primeira semana", "first-week-info": "Primeira semana que contenha a primeira Quinta-feira do ano é baseado na ISO 8601.", "first-week-warning": "Alterar as opções de primeira semana pode causar duplicidade nas Notas Semanais existentes e estas Notas não serão atualizadas de acordo.", - "formatting-locale": "Formato de data e número" + "formatting-locale": "Formato de data e número", + "tuesday": "Terça-feira", + "wednesday": "Quarta-feira", + "thursday": "Quinta-feira", + "friday": "Sexta-feira", + "saturday": "Sábado", + "formatting-locale-auto": "Com base no idioma do aplicativo" }, "backup": { "automatic_backup": "Backup automático", @@ -1526,7 +1576,7 @@ "mind-map": "Mapa Mental", "file": "Arquivo", "image": "Imagem", - "launcher": "Lançador", + "launcher": "Atalho", "doc": "Documento", "widget": "Widget", "confirm-change": "Não é recomentado alterar o tipo da nota quando o conteúdo da nota não está vazio. Quer continuar assim mesmo?", @@ -1569,7 +1619,13 @@ }, "highlights_list_2": { "title": "Lista de Destaques", - "options": "Opções" + "options": "Opções", + "title_with_count_one": "{{count}} destaque", + "title_with_count_many": "{{count}} destaques", + "title_with_count_other": "{{count}} destaques", + "modal_title": "Configurar lista de destaques", + "menu_configure": "Configurar lista de destaques…", + "no_highlights": "Nenhum destaque encontrado." }, "quick-search": { "placeholder": "Busca rápida", @@ -1592,23 +1648,33 @@ "refresh-saved-search-results": "Atualizar resultados de pesquisa salvos", "create-child-note": "Criar nota filha", "unhoist": "Desafixar", - "toggle-sidebar": "Alternar barra lateral" + "toggle-sidebar": "Alternar barra lateral", + "dropping-not-allowed": "Não é permitido soltar notas neste local." }, "title_bar_buttons": { "window-on-top": "Manter Janela no Topo" }, "note_detail": { - "could_not_find_typewidget": "Não foi possível encontrar typeWidget para o tipo '{{type}}'" + "could_not_find_typewidget": "Não foi possível encontrar typeWidget para o tipo '{{type}}'", + "printing": "Impressão em andamento…", + "printing_pdf": "Exportação para PDF em andamento…" }, "note_title": { - "placeholder": "digite o título da nota aqui..." + "placeholder": "digite o título da nota aqui...", + "created_on": "Criado em ", + "last_modified": "Modificado em ", + "note_type_switcher_label": "Alternar de {{type}} para:", + "note_type_switcher_others": "Outro tipo de nota", + "note_type_switcher_templates": "Modelo", + "note_type_switcher_collection": "Coleção", + "edited_notes": "Notas editadas" }, "search_result": { "no_notes_found": "Nenhuma nota encontrada para os parâmetros de busca digitados.", "search_not_executed": "A busca ainda não foi executada. Clique no botão \"Buscar\" acima para ver os resultados." }, "spacer": { - "configure_launchbar": "Configurar Barra de Lançamento" + "configure_launchbar": "Configurar Barra de Atalhos" }, "sql_result": { "no_rows": "Nenhum linha foi retornada para esta consulta" @@ -1630,7 +1696,8 @@ }, "toc": { "table_of_contents": "Tabela de Conteúdos", - "options": "Opções" + "options": "Opções", + "no_headings": "Nenhum título." }, "watched_file_update_status": { "file_last_modified": "O arquivo foi modificado pela última vez em .", @@ -1673,22 +1740,24 @@ "ws": { "sync-check-failed": "A verificação de sincronização falhou!", "consistency-checks-failed": "A verificação de consistência falhou! Veja os logs para detalhes.", - "encountered-error": "Encontrado o erro \"{{message}}\", verifique o console." + "encountered-error": "Encontrado o erro \"{{message}}\", verifique o console.", + "lost-websocket-connection-title": "Conexão com o servidor perdida", + "lost-websocket-connection-message": "Verifique a configuração do seu proxy reverso (por exemplo, nginx ou Apache) para garantir que as conexões WebSocket estejam devidamente permitidas e não estejam sendo bloqueadas." }, "hoisted_note": { "confirm_unhoisting": "A nota solicitada '{{requestedNote}}' está fora da árvore da nota fixada '{{hoistedNote}}' e você precisa desafixar para acessar a nota. Quer prosseguir e desafixar?" }, "launcher_context_menu": { - "reset_launcher_confirm": "Você deseja realmente reiniciar \"{{title}}\"? Todos os dados / configurações desta nota (e suas filhas) serão perdidos o lançador irá retornar para sua localização original.", - "add-note-launcher": "Adicionar um lançador de nota", - "add-script-launcher": "Adicionar um lançador de script", + "reset_launcher_confirm": "Você deseja realmente reiniciar \"{{title}}\"? Todos os dados / configurações desta nota (e suas filhas) serão perdidos o atalho irá retornar para sua localização original.", + "add-note-launcher": "Adicionar um atalho de nota", + "add-script-launcher": "Adicionar um atalho de script", "add-custom-widget": "Adicionar um componente personalizado", "add-spacer": "Adicionar um espaçador", "delete": "Excluir ", "reset": "Reiniciar", - "move-to-visible-launchers": "Mover para lançadores visíveis", - "move-to-available-launchers": "Mover para lançadores disponíveis", - "duplicate-launcher": "Duplicar o lançador " + "move-to-visible-launchers": "Mover para atalhos visíveis", + "move-to-available-launchers": "Mover para atalhos disponíveis", + "duplicate-launcher": "Duplicar o atalho " }, "highlighting": { "title": "Blocos de Código", @@ -1722,7 +1791,8 @@ "copy-link": "Copiar link", "paste": "Colar", "paste-as-plain-text": "Colar como texto sem formatação", - "search_online": "Buscar por \"{{term}}\" usando {{searchEngine}}" + "search_online": "Buscar por \"{{term}}\" usando {{searchEngine}}", + "search_in_trilium": "Pesquisar por \"{{term}}\" no Trilium" }, "image_context_menu": { "copy_reference_to_clipboard": "Copiar referência para a área de transferência", @@ -1732,7 +1802,8 @@ "open_note_in_new_tab": "Abrir nota em nova aba", "open_note_in_new_split": "Abrir nota em nova divisão", "open_note_in_new_window": "Abrir nota em nova janela", - "open_note_in_popup": "Edição rápida" + "open_note_in_popup": "Edição rápida", + "open_note_in_other_split": "Abrir nota no outro painel dividido" }, "electron_integration": { "desktop-application": "Aplicação Desktop", @@ -1800,8 +1871,9 @@ "unknown_widget": "Componente desconhecido para \"{{id}}\"." }, "note_language": { - "not_set": "Não atribuído", - "configure-languages": "Configurar idiomas..." + "not_set": "Nenhum idioma definido", + "configure-languages": "Configurar idiomas...", + "help-on-languages": "Ajuda sobre idiomas de conteúdo…" }, "content_language": { "title": "Idiomas do conteúdo", @@ -1819,7 +1891,8 @@ "button_title": "Exportar diagrama como PNG" }, "svg": { - "export_to_png": "O diagrama não pôde ser exportado como PNG." + "export_to_png": "O diagrama não pôde ser exportado como PNG.", + "export_to_svg": "O diagrama não pôde ser exportado para SVG." }, "code_theme": { "title": "Aparência", @@ -1838,7 +1911,11 @@ "editorfeatures": { "title": "Recursos", "emoji_completion_enabled": "Habilitar auto-completar de Emoji", - "note_completion_enabled": "Habilitar auto-completar de notas" + "note_completion_enabled": "Habilitar auto-completar de notas", + "emoji_completion_description": "Se ativado, emojis podem ser inseridos facilmente no texto digitando`:`, seguido do nome do emoji.", + "note_completion_description": "Se ativado, links para notas podem ser criados digitando `@` seguido do título de uma nota.", + "slash_commands_enabled": "Ativar comandos de barra", + "slash_commands_description": "Se ativado, comandos de edição como inserir quebras de linha ou títulos podem ser acionados digitando`/`." }, "table_view": { "new-row": "Nova linha", @@ -1863,7 +1940,7 @@ "book_properties_config": { "hide-weekends": "Ocultar fins de semana", "display-week-numbers": "Exibir números de semana", - "map-style": "Estilo do mapa:", + "map-style": "Estilo do mapa", "max-nesting-depth": "Profundidade máxima de aninhamento:", "vector_light": "Vetor (Claro)", "vector_dark": "Vetor (Escuro)", @@ -1888,7 +1965,8 @@ "new-item-placeholder": "Escreva o título da nota...", "add-column-placeholder": "Escreva o nome da coluna...", "edit-note-title": "Clique para editar o título da nota", - "edit-column-title": "Clique para editar o título da coluna" + "edit-column-title": "Clique para editar o título da coluna", + "column-already-exists": "Esta coluna já existe no quadro." }, "call_to_action": { "next_theme_title": "Testar no novo tema do Trilium", @@ -1897,14 +1975,20 @@ "background_effects_title": "Efeitos de fundo estão estáveis agora", "background_effects_message": "Em dispositivos Windows, efeitos de fundo estão estáveis agora. Os efeitos de fundo adicionam um toque de cor à interface do usuário borrando o plano de fundo atrás dela. Esta técnica também é usada em outras aplicações como o Windows Explorer.", "background_effects_button": "Habilitar os efeitos de fundo", - "dismiss": "Dispensar" + "dismiss": "Dispensar", + "new_layout_title": "Novo layout", + "new_layout_message": "Introduzimos um layout modernizado para o Trilium. A faixa de opções foi removida e integrada de forma contínua à interface principal, com uma nova barra de status e seções expansíveis (como atributos promovidos) assumindo funções importantes.\n\nO novo layout vem ativado por padrão e pode ser desativado temporariamente em Opções → Aparência.", + "new_layout_button": "Mais informações" }, "settings": { "related_settings": "Configurações relacionadas" }, "settings_appearance": { "related_code_blocks": "Esquema de cores para blocos de código em notas de texto", - "related_code_notes": "Esquema de cores para notas de código" + "related_code_notes": "Esquema de cores para notas de código", + "ui": "Interface do usuário", + "ui_old_layout": "Layout antigo", + "ui_new_layout": "Novo Layout" }, "units": { "percentage": "%" @@ -2047,5 +2131,102 @@ }, "collections": { "rendering_error": "Não foi possível exibir o conteúdo devido a um erro." + }, + "experimental_features": { + "title": "Opções experimentais", + "disclaimer": "Essas opções são experimentais e podem causar instabilidade. Use com cautela.", + "new_layout_name": "Novo Layout", + "new_layout_description": "Experimente o novo layout para um visual mais moderno e melhor usabilidade. Pode sofrer alterações significativas nas próximas versões." + }, + "read-only-info": { + "read-only-note": "Você está visualizando uma nota somente leitura.", + "auto-read-only-note": "Esta nota é exibida em modo somente leitura para carregamento mais rápido.", + "edit-note": "Editar nota" + }, + "presentation_view": { + "edit-slide": "Editar este slide", + "start-presentation": "Iniciar apresentação", + "slide-overview": "Alternar a visualização geral dos slides" + }, + "calendar_view": { + "delete_note": "Excluir nota…" + }, + "note-color": { + "clear-color": "Limpar cor da nota", + "set-color": "Definir cor da nota", + "set-custom-color": "Definir cor personalizada da nota" + }, + "popup-editor": { + "maximize": "Alternar para editor completo" + }, + "server": { + "unknown_http_error_title": "Erro de comunicação com o servidor", + "unknown_http_error_content": "Código de status: {{statusCode}}\nURL: {{method}} {{url}}\nMensagem: {{message}}", + "traefik_blocks_requests": "Se você estiver usando o proxy reverso Traefik, ele introduziu uma alteração que afeta a comunicação com o servidor." + }, + "tab_history_navigation_buttons": { + "go-back": "Voltar para a nota anterior", + "go-forward": "Avançar para a próxima nota" + }, + "breadcrumb": { + "hoisted_badge": "Destacado", + "hoisted_badge_title": "Remover destaque", + "workspace_badge": "Espaço de trabalho", + "scroll_to_top_title": "Ir para o início da nota", + "create_new_note": "Criar nova nota filha", + "empty_hide_archived_notes": "Ocultar notas arquivadas" + }, + "breadcrumb_badges": { + "read_only_explicit": "Somente leitura", + "read_only_explicit_description": "Esta nota foi definida manualmente como somente leitura.\nClique para editá-la temporariamente.", + "read_only_auto": "Auto Somente leitura", + "read_only_auto_description": "Esta nota foi definida automaticamente como somente leitura por motivos de desempenho. Esse limite automático pode ser ajustado nas configurações.\n\nClique para editá-la temporariamente.", + "read_only_temporarily_disabled": "Editável temporariamente", + "read_only_temporarily_disabled_description": "Esta nota está atualmente editável, mas normalmente é somente leitura. A nota voltará a ser somente leitura assim que você navegar para outra nota.\n\nClique para reativar o modo somente leitura.", + "shared_publicly": "Compartilhado publicamente", + "shared_locally": "Compartilhado localmente", + "shared_copy_to_clipboard": "Copiar link para a área de transferência", + "shared_open_in_browser": "Abrir link no navegador", + "shared_unshare": "Remover compartilhamento", + "clipped_note": "Recorte da web", + "clipped_note_description": "Esta nota foi originalmente obtida de {{url}}.\n\nClique para navegar até a página de origem.", + "execute_script": "Executar script", + "execute_script_description": "Esta nota é uma nota de script. Clique para executar o script.", + "execute_sql": "Executar SQL", + "execute_sql_description": "Esta nota é uma nota SQL. Clique para executar a consulta SQL." + }, + "status_bar": { + "language_title": "Alterar idioma do conteúdo", + "note_info_title": "Ver informações da nota (por exemplo, datas, tamanho da nota)", + "backlinks_one": "{{count}} referência inversa", + "backlinks_many": "{{count}} referências inversas", + "backlinks_other": "{{count}} referências inversas", + "backlinks_title_one": "Ver referência inversa", + "backlinks_title_many": "Ver referências inversas", + "backlinks_title_other": "Ver referências inversas", + "attachments_one": "{{count}} anexo", + "attachments_many": "{{count}} anexos", + "attachments_other": "{{count}} anexos", + "attachments_title_one": "Visualizar anexo em uma nova aba", + "attachments_title_many": "Visualizar anexos em uma nova aba", + "attachments_title_other": "Visualizar anexos em uma nova aba", + "attributes_one": "{{count}} atributo", + "attributes_many": "{{count}} atributos", + "attributes_other": "{{count}} atributos", + "attributes_title": "Atributos próprios e atributos herdados", + "note_paths_one": "{{count}} caminho", + "note_paths_many": "{{count}} caminhos", + "note_paths_other": "{{count}} caminhos", + "note_paths_title": "Caminhos da nota", + "code_note_switcher": "Alterar modo de idioma" + }, + "attributes_panel": { + "title": "Atributos da nota" + }, + "right_pane": { + "empty_message": "Nada para exibir nesta nota", + "empty_button": "Ocultar o painel", + "toggle": "Alternar painel direito", + "custom_widget_go_to_source": "Ir para o código-fonte" } } diff --git a/apps/client/src/translations/ro/translation.json b/apps/client/src/translations/ro/translation.json index 4fba198908..03c5a4a6d1 100644 --- a/apps/client/src/translations/ro/translation.json +++ b/apps/client/src/translations/ro/translation.json @@ -493,7 +493,12 @@ "editable_text": { "placeholder": "Scrieți conținutul notiței aici...", "auto-detect-language": "Automat", - "keeps-crashing": "Componenta de editare se blochează în continuu. Încercați să reporniți Trilium. Dacă problema persistă, luați în considerare să raportați această problemă." + "keeps-crashing": "Componenta de editare se blochează în continuu. Încercați să reporniți Trilium. Dacă problema persistă, luați în considerare să raportați această problemă.", + "editor_crashed_title": "Editorul text a avut o eroare", + "editor_crashed_content": "Conținutul a fost recuperat cu succes, dar este posibil ca o parte din cele mai recente modificări ale dvs. să nu se fi salvat.", + "editor_crashed_details_button": "Mai multe detalii...", + "editor_crashed_details_intro": "Dacă întâmpinați frecvent această eroare, considerați să o raportați pe GitHub copiând informația de mai jos.", + "editor_crashed_details_title": "Informații tehnice" }, "edited_notes": { "deleted": "(șters)", @@ -785,7 +790,8 @@ "info": { "closeButton": "Închide", "modalTitle": "Mesaj informativ", - "okButton": "OK" + "okButton": "OK", + "copy_to_clipboard": "Copiază în clipboard" }, "inherited_attribute_list": { "no_inherited_attributes": "Niciun atribut moștenit.", @@ -867,12 +873,14 @@ "print_note": "Imprimare notiță", "re_render_note": "Reinterpretare notiță", "save_revision": "Salvează o nouă revizie", + "advanced": "Advansat", "search_in_note": "Caută în notiță", "convert_into_attachment_failed": "Nu s-a putut converti notița „{{title}}”.", "convert_into_attachment_successful": "Notița „{{title}}” a fost convertită în atașament.", "convert_into_attachment_prompt": "Doriți convertirea notiței „{{title}}” într-un atașament al notiței părinte?", "print_pdf": "Exportare ca PDF...", - "open_note_on_server": "Deschide notița pe server" + "open_note_on_server": "Deschide notița pe server", + "view_revisions": "Revizii ale notițelor..." }, "note_erasure_timeout": { "deleted_notes_erased": "Notițele șterse au fost eliminate permanent.", @@ -1407,7 +1415,7 @@ "hoist-note": "Focalizează notița", "unhoist-note": "Defocalizează notița", "converted-to-attachments": "{{count}} notițe au fost convertite în atașamente.", - "convert-to-attachment-confirm": "Doriți convertirea notițelor selectate în atașamente ale notiței părinte?", + "convert-to-attachment-confirm": "Doriți convertirea notițelor selectate în atașamente ale notiței părinte? Această operațiune se aplică doar notițelor de tip imagine, celelalte vor fi ignorate.", "open-in-popup": "Editare rapidă", "archive": "Arhivează", "unarchive": "Dezarhivează" @@ -1526,7 +1534,9 @@ "printing_pdf": "Exportare ca PDF în curs..." }, "note_title": { - "placeholder": "introduceți titlul notiței aici..." + "placeholder": "introduceți titlul notiței aici...", + "created_on": "Creată la ", + "last_modified": "Modificată la " }, "revisions_snapshot_limit": { "erase_excess_revision_snapshots": "Șterge acum reviziile excesive", @@ -1758,7 +1768,8 @@ }, "note_language": { "configure-languages": "Configurează limbile...", - "not_set": "Nedefinită" + "not_set": "Nicio limbă setată", + "help-on-languages": "Informații despre limba conținutului..." }, "png_export_button": { "button_title": "Exportă diagrama ca PNG" @@ -1954,7 +1965,8 @@ "oauth_user_not_logged_in": "Neautentificat!" }, "svg": { - "export_to_png": "Diagrama nu a putut fi exportată în PNG." + "export_to_png": "Diagrama nu a putut fi exportată în PNG.", + "export_to_svg": "Diagrama nu a putut fi exportată în SVG." }, "code_theme": { "title": "Afișare", @@ -2106,5 +2118,30 @@ }, "popup-editor": { "maximize": "Comută la editorul principal" + }, + "experimental_features": { + "title": "Opțiuni experimentale", + "disclaimer": "Aceste opțiuni sunt experimentale și pot cauza instabilitate. Folosiți cu prudență.", + "new_layout_name": "Aspect nou", + "new_layout_description": "Încercați noul aspect pentru un design mai modern și mai ușor de utilizat. Poate surveni modificări semnificative în următoarele release-uri." + }, + "server": { + "unknown_http_error_title": "Eroare de comunicare cu server-ul", + "unknown_http_error_content": "Cod: {{statusCode}}\nURL: {{method}} {{url}}\nMesaj: {{message}}", + "traefik_blocks_requests": "Dacă utilizați reverse proxy-ul Traefik, acesta a introdus o schimbare majoră ce afectează comunicarea cu server-ul." + }, + "tab_history_navigation_buttons": { + "go-back": "Înapoi la notița anterioară", + "go-forward": "Înainte către notița următoare" + }, + "breadcrumb_badges": { + "read_only_explicit": "Mod citire", + "read_only_explicit_description": "Această notiță a fost setată explicit să fie doar în citire.\nClick pentru a o edita temporar.", + "read_only_auto": "Mod citire auto", + "read_only_auto_description": "Această notița a fost setată automată să fie în mod doar de citire din motive de performanță. Această limită automată este ajustabilă din setări.\n\nClick pentru a o edita temporar.", + "read_only_temporarily_disabled": "Editabilă temporar", + "read_only_temporarily_disabled_description": "Această notiță se poate modifica, deși în mod normal ea este doar în citire. Notița va reveni la modul doar în citire imediat ce navigați către altă notiță.\n\nClick pentru a re-activa modul doar în citire.", + "shared_publicly": "Partajată public", + "shared_locally": "Partajată local" } } diff --git a/apps/client/src/translations/ru/translation.json b/apps/client/src/translations/ru/translation.json index a6b21b5aa9..a88c001497 100644 --- a/apps/client/src/translations/ru/translation.json +++ b/apps/client/src/translations/ru/translation.json @@ -21,8 +21,17 @@ }, "bundle-error": { "title": "Не удалось загрузить пользовательский скрипт", - "message": "Скрипт из заметки с идентификатором \"{{id}}\" и названием \"{{title}}\" не может быть выполнен по следующим причинам:\n\n{{message}}" - } + "message": "Скрипт не может быть выполнен. Причина:\n\n{{message}}" + }, + "widget-list-error": { + "title": "Не удалось получить список виджетов с сервера" + }, + "widget-render-error": { + "title": "Не удалось отобразить пользовательский React виджет" + }, + "widget-missing-parent": "В пользовательском виджете не определено обязательное свойство '{{property}}'.", + "open-script-note": "Открыть заметку со скриптом", + "scripting-error": "Ошибка пользовательского скрипта: {{title}}" }, "add_link": { "add_link": "Добавить ссылку", @@ -39,7 +48,10 @@ "edit_branch_prefix": "Редактировать префикс ветки", "prefix": "Префикс: ", "branch_prefix_saved": "Префикс ветки сохранен.", - "help_on_tree_prefix": "Помощь по префиксу дерева" + "help_on_tree_prefix": "Помощь по префиксу дерева", + "affected_branches": "Затронутые ветки ({{count}}):", + "branch_prefix_saved_multiple": "Префикс сохранен для {{count}} ветвей.", + "edit_branch_prefix_multiple": "Изменить префикс для {{count}} ветвей" }, "bulk_actions": { "available_actions": "Доступные действия", @@ -236,7 +248,8 @@ "export_status": "Статус экспорта", "export_in_progress": "Экспорт: {{progressCount}}", "export_finished_successfully": "Экспорт завершился успешно.", - "format_pdf": "PDF - для печати или обмена." + "format_pdf": "PDF - для печати или обмена.", + "share-format": "HTML для веб-публикаций — использует ту же тему оформления, что и общие заметки, но может быть опубликован как статический веб-сайт." }, "help": { "noteNavigation": "Навигация по заметке", @@ -290,7 +303,8 @@ "blockQuote": "начните строку с >, а затем пробела для блока цитаты", "quickSearch": "сфокусироваться на поле ввода быстрого поиска", "editNoteTitle": "в области дерева переключится с области дерева на заголовок заметки. Сочетание клавиш Enter из области заголовка заметки переключит фокус на текстовый редактор. Ctrl+. переключит обратно с редактора на область дерева.", - "title": "Справка" + "title": "Справка", + "editShortcuts": "Редактировать сочетания клавиш" }, "modal": { "close": "Закрыть", @@ -472,13 +486,13 @@ "app_css": "отмечает заметки CSS, которые загружаются в приложение Trilium и, таким образом, могут использоваться для изменения внешнего вида Trilium.", "app_theme_base": "установите значение \"next\", \"next-light\" или \"next-dark\", чтобы использовать соответствующую тему TriliumNext (автоматическую, светлую или темную) в качестве основы для пользовательской темы вместо устаревшей.", "exclude_from_note_map": "Заметки с этой меткой будут скрыты на карте заметок", - "workspace": "отмечает эту заметку как рабочее пространство, для удобного закрепления", - "workspace_icon_class": "определяет CSS-класс значка поля, который будет использоваться во вкладке при закреплении этой заметки", - "workspace_tab_background_color": "Цвет CSS, используемый во вкладке заметки при ее закреплении", - "workspace_template": "Эта заметка появится в списке доступных шаблонов при создании новой заметки, но только если она будет перемещена в рабочую область, содержащую этот шаблон", - "workspace_search_home": "новые заметки поиска будут созданы как дочерние записи этой заметки при перемещении их к какому-либо предку этой заметки рабочей области", + "workspace": "отмечает эту заметку как рабочее пространство, для удобной установки фокуса", + "workspace_icon_class": "определяет CSS-класс значка поля, который будет использоваться во вкладке при установке фокуса на этой заметке", + "workspace_tab_background_color": "Цвет CSS, используемый во вкладке заметки при установке на нее фокуса", + "workspace_template": "Эта заметка появится в списке доступных шаблонов при создании новой заметки, но только если будет установлен фокус на рабочую область с этим шаблоном", + "workspace_search_home": "новые заметки поиска будут созданы как дочерние записи этой заметки, когда установлен фокус на какую-либо родительскую заметку этого рабочего пространство", "workspace_calendar_root": "Определяет корень календаря для каждого рабочего пространства", - "hide_highlight_widget": "Скрыть виджет «Выделенное»", + "hide_highlight_widget": "Скрыть виджет «Акценты»", "is_owned_by_note": "принадлежит заметке", "and_more": "... и ещё {{count}}.", "app_theme": "отмечает заметки CSS, которые являются полноценными темами Trilium и, таким образом, доступны в опциях Trilium.", @@ -503,7 +517,7 @@ "custom_resource_provider": "см. Пользовательский обработчик запросов", "widget": "отмечает эту заметку как пользовательский виджет, который будет добавлен в дерево компонентов Trilium", "search_home": "новые заметки поиска будут созданы как дочерние записи этой заметки", - "workspace_inbox": "расположение в папке «Входящие» по умолчанию для новых заметок при перемещении их в некую родственную папку этой заметки в рабочей области", + "workspace_inbox": "расположение в папке «Входящие» по умолчанию для новых заметок, когда установлен фокус на какую-либо родительскую заметку этого рабочего пространство", "sql_console_home": "расположение заметок консоли SQL по умолчанию", "css_class": "значение этой метки затем добавляется как CSS-класс к узлу, представляющему данную заметку в дереве. Это может быть полезно для изменения внешнего вида заметки. Может использоваться в шаблонах заметок.", "bookmark_folder": "заметка с этой меткой появится в закладках как папка (с предоставлением доступа к ее дочерним элементам)", @@ -519,7 +533,7 @@ "share_index": "заметка с этой меткой будет содержать список всех корневых узлов общедоступных заметок", "toc": "#toc или #toc=show принудительно отобразят оглавление, #toc=hide — скроют его. Если метка отсутствует, применяется глобальная настройка", "color": "определяет цвет заметки в дереве заметок, ссылках и т. д. Используйте любое допустимое значение цвета CSS, например «red» или #a13d5f", - "keep_current_hoisting": "Открытие этой ссылки не изменит закрепление, даже если заметка не отображается в текущем закрепленном поддереве.", + "keep_current_hoisting": "Открытие этой ссылки не изменит фокус, даже если заметка не отображается в текущем закрепленном поддереве.", "execute_description": "Более подробное описание текущей заметки типа \"Код\", отображаемое вместе с кнопкой \"Выполнить\"", "run_on_note_creation": "выполняется при создании заметки на сервере. Используйте это отношение, если хотите запустить скрипт для всех заметок, созданных в определённом поддереве. В этом случае создайте его в корневой заметке поддерева и сделайте его наследуемым. Новая заметка, созданная в поддереве (любой глубины), запустит скрипт.", "run_on_child_note_creation": "выполняется, когда создается новая заметка под заметкой, в которой определено это отношение", @@ -567,7 +581,8 @@ "edit-column-title": "Нажмите, чтобы изменить заголовок столбца", "edit-note-title": "Нажмите, чтобы изменить название заметки", "add-column-placeholder": "Введите имя столбца...", - "new-item-placeholder": "Введите название заметки..." + "new-item-placeholder": "Введите название заметки...", + "column-already-exists": "Такая колонка уже добавлена на доску." }, "table_context_menu": { "delete_row": "Удалить строку" @@ -576,7 +591,7 @@ "vector_dark": "Vector (Темная)", "vector_light": "Vector (Светлая)", "max-nesting-depth": "Максимальная глубина вложенности:", - "map-style": "Стиль карты:", + "map-style": "Стиль карты", "display-week-numbers": "Отображать номера недель", "hide-weekends": "Скрыть выходные", "raster": "Растр", @@ -606,7 +621,8 @@ "title": "Внешний вид" }, "svg": { - "export_to_png": "Диаграмму не может быть экспортирована в PNG." + "export_to_png": "Диаграмму не может быть экспортирована в PNG.", + "export_to_svg": "Не удалось экспортировать диаграмму в SVG." }, "png_export_button": { "button_title": "Экспортировать диаграмму как PNG" @@ -621,7 +637,8 @@ }, "note_language": { "configure-languages": "Настроить языки...", - "not_set": "Не установлен" + "not_set": "Язык не установлен", + "help-on-languages": "Помощь по языкам содержимого..." }, "time_selector": { "invalid_input": "Введенное значение времени не является допустимым числом.", @@ -679,7 +696,8 @@ "open_note_in_popup": "Быстрое редактирование", "open_note_in_new_window": "Открыть заметку в новом окне", "open_note_in_new_tab": "Открыть заметку в новой вкладке", - "open_note_in_new_split": "Открыть заметку в новой панели" + "open_note_in_new_split": "Открыть заметку в новой панели", + "open_note_in_other_split": "Открыть заметку в другой панели" }, "image_context_menu": { "copy_image_to_clipboard": "Копировать изображение в буфер обмена", @@ -692,7 +710,8 @@ "copy": "Скопировать", "cut": "Вырезать", "search_online": "Поиск \"{{term}}\" в {{searchEngine}}", - "add-term-to-dictionary": "Добавить \"{{term}}\" в словарь" + "add-term-to-dictionary": "Добавить \"{{term}}\" в словарь", + "search_in_trilium": "Искать \"{{term}}\" в Trilium" }, "editing": { "editor_type": { @@ -740,23 +759,25 @@ }, "toc": { "table_of_contents": "Оглавление", - "options": "Параметры" + "options": "Параметры", + "no_headings": "Заголовки не найдены." }, "note_tree": { "hide-archived-notes": "Скрыть архивные заметки", "automatically-collapse-notes": "Автоматически сворачивать заметки", "tree-settings-title": "Настройки дерева", - "unhoist": "Открепить", + "unhoist": "Убрать фокус", "scroll-active-title": "Прокрутить к активной заметке", "collapse-title": "Свернуть дерево", - "hoist-this-note-workspace": "Закрепить заметку (рабочая область)", + "hoist-this-note-workspace": "Фокус на заметке (рабочая область)", "auto-collapsing-notes-after-inactivity": "Автоматическое сворачивание заметок после бездействия...", "create-child-note": "Создать дочернюю заметку", "save-changes": "Сохранить и применить изменения", "saved-search-note-refreshed": "Сохраненная поисковая заметка обновлена.", "refresh-saved-search-results": "Обновить сохраненные результаты поиска", "automatically-collapse-notes-title": "Заметки будут свернуты после определенного периода бездействия, чтобы навести порядок в дереве.", - "toggle-sidebar": "Переключить боковую панель" + "toggle-sidebar": "Переключить боковую панель", + "dropping-not-allowed": "Перетаскивание заметок в эту область не разрешено." }, "quick-search": { "no-results": "Результаты не найдены", @@ -793,7 +814,7 @@ "text": "Текст", "launcher": "Лаунчер", "doc": "Документация", - "relation-map": "Карта отношений", + "relation-map": "Карта связей", "note-map": "Карта заметок", "render-note": "Рендеринг заметки", "web-view": "Веб-страница", @@ -812,8 +833,8 @@ "export": "Экспорт", "open-in-a-new-tab": "Открыть в новой вкладке", "open-in-a-new-split": "Открыть в новой панели", - "unhoist-note": "Открепить заметку", - "hoist-note": "Закрепить заметку", + "unhoist-note": "Снять фокус", + "hoist-note": "Фокус на заметке", "protect-subtree": "Защитить поддерево", "unprotect-subtree": "Снять защиту с поддерева", "copy-clone": "Скопировать / Склонировать", @@ -833,7 +854,7 @@ "apply-bulk-actions": "Применить массовые действия", "recent-changes-in-subtree": "Последние изменения в поддереве", "copy-note-path-to-clipboard": "Копировать путь к заметке в буфер обмена", - "convert-to-attachment-confirm": "Вы уверены, что хотите преобразовать выбранные заметки во вложения их родительских заметок?", + "convert-to-attachment-confirm": "Вы уверены, что хотите преобразовать выбранные заметки во вложения их родительских заметок? Эта операция применяется только к заметкам в виде изображений; другие заметки будут пропущены.", "converted-to-attachments": "{{count}} заметок были преобразованы во вложения.", "archive": "Архивировать", "unarchive": "Разархивировать" @@ -841,7 +862,8 @@ "info": { "closeButton": "Закрыть", "okButton": "ОК", - "modalTitle": "Информация" + "modalTitle": "Информация", + "copy_to_clipboard": "Скопировать в буфер обмена" }, "jump_to_note": { "search_placeholder": "Найдите заметку по ее названию или введите > для команд...", @@ -978,13 +1000,14 @@ "show_shared_notes_subtree": "Поддерево общедоступных заметок", "switch_to_mobile_version": "Перейти на мобильную версию", "switch_to_desktop_version": "Переключиться на версию для ПК", - "new-version-available": "Доступно обновление" + "new-version-available": "Доступно обновление", + "download-update": "Обновить до {{latestVersion}}" }, "zpetne_odkazy": { "relation": "отношение", - "backlink_one": "{{count}} ссылки", - "backlink_few": "", - "backlink_many": "{{count}} ссылок" + "backlink_one": "{{count}} обратная ссылка", + "backlink_few": "{{count}} обратные ссылки", + "backlink_many": "{{count}} обратных ссылок" }, "note_icon": { "category": "Категория:", @@ -1012,7 +1035,12 @@ "geo-map": "Карта", "invalid_view_type": "Недопустимый тип представления '{{type}}'", "collapse_all_notes": "Свернуть все заметки", - "include_archived_notes": "Показать заархивированные заметки" + "include_archived_notes": "Показать заархивированные заметки", + "presentation": "Презентация", + "expand_all_levels": "Развернуть все вложенные уровни", + "expand_nth_level": "Развернуть уровни: {{depth}} шт.", + "expand_first_level": "Развернуть прямые дочерние уровни", + "expand_tooltip": "Разщвернуть дочерние элементы этой коллекции (на один уровень вложенности). Для получения дополнительных параметров нажмите стрелку справа." }, "edited_notes": { "deleted": "(удалено)", @@ -1052,7 +1080,9 @@ "title": "Информация", "calculate": "подсчитать", "note_size_info": "Размер заметки позволяет приблизительно оценить требования к объёму хранилища для данной заметки. Он учитывает её содержание и содержание её сохраненных версий.", - "subtree_size": "(размер поддерева: {{size}} в {{count}} заметках)" + "subtree_size": "(размер поддерева: {{size}} в {{count}} заметках)", + "mime": "MIME тип", + "show_similar_notes": "Похожие заметки" }, "note_paths": { "search": "Поиск", @@ -1060,7 +1090,7 @@ "clone_button": "Клонировать заметку в новое место...", "intro_placed": "Эта заметка размещена по следующим путям:", "intro_not_placed": "Эта заметка еще не помещена в дерево заметок.", - "outside_hoisted": "Этот путь находится за пределами закрепленной заметки, и вам придется снять закрепление.", + "outside_hoisted": "Этот путь находится за пределами сфокусированной заметки, и вам придется снять фокус.", "archived": "Архивировано" }, "note_properties": { @@ -1105,7 +1135,8 @@ "save_to_note": "Сохранить в заметку", "search_note_saved": "Заметка с настройкой поиска сохранена в {{- notePathTitle}}", "unknown_search_option": "Неизвестный параметр поиска {{searchOptionName}}", - "actions_executed": "Действия выполнены." + "actions_executed": "Действия выполнены.", + "view_options": "Просмотреть опции:" }, "ancestor": { "depth_label": "глубина", @@ -1201,7 +1232,8 @@ "max_width_unit": "пикселей", "title": "Ширина контентной области", "default_description": "Trilium по умолчанию ограничивает максимальную ширину контента, чтобы улучшить читаемость на широких экранах.", - "max_width_label": "Максимальная ширина контентной области" + "max_width_label": "Максимальная ширина контентной области", + "centerContent": "Размещать контент по центру" }, "native_title_bar": { "enabled": "включено", @@ -1409,7 +1441,13 @@ "min-days-in-first-week": "Минимальное количество дней в первой неделе", "first-week-info": "Первая неделя содержит первый четверг года в соответствии со стандартом ISO 8601.", "first-week-warning": "Изменение параметров первой недели может привести к дублированию существующих недельных заметок, и существующие недельные заметки не будут обновлены соответствующим образом.", - "formatting-locale": "Формат даты и числа" + "formatting-locale": "Формат даты и числа", + "formatting-locale-auto": "Выбирать на основе языка приложения", + "saturday": "Суббота", + "friday": "Пятница", + "thursday": "Четверг", + "wednesday": "Среда", + "tuesday": "Вторник" }, "backup": { "path": "Путь", @@ -1534,7 +1572,13 @@ }, "highlights_list_2": { "options": "Параметры", - "title": "Список выделенного" + "title": "Акценты", + "modal_title": "Настроить акценты", + "menu_configure": "Настроить акценты...", + "no_highlights": "Акценты в тексте не найдены.", + "title_with_count_one": "{{count}} акцент", + "title_with_count_few": "{{count}} акцента", + "title_with_count_many": "{{count}} акцентов" }, "include_note": { "dialog_title": "Вставить заметку", @@ -1609,7 +1653,14 @@ "convert_into_attachment_failed": "Не удалось преобразовать заметку '{{title}}'.", "open_note_externally_title": "Файл будет открыт во внешнем приложении и отслеживается на наличие изменений. После этого вы сможете загрузить изменённую версию обратно в Trilium.", "open_note_externally": "Открыть заметку вне приложения", - "open_note_custom": "Открыть заметку как..." + "open_note_custom": "Открыть заметку как...", + "export_as_image_svg": "SVG (вектор)", + "export_as_image_png": "PNG (растр)", + "export_as_image": "Экспорт изображения", + "open_note_on_server": "Открыть заметку на сервере", + "view_revisions": "История изменений...", + "note_map": "Карта заметок", + "advanced": "Дополнительно" }, "revisions_button": { "note_revisions": "Версии заметки" @@ -1634,7 +1685,7 @@ "zoom_in_title": "Увеличить масштаб", "zoom_out_title": "Уменьшить масштаб", "reset_pan_zoom_title": "Сбросить панорамирование и масштабирование", - "create_child_note_title": "Создать новую дочернюю заметку и добавить ее в эту карту отношений" + "create_child_note_title": "Создать новую дочернюю заметку и добавить ее в эту карту связей" }, "code_auto_read_only_size": { "unit": "символов", @@ -1644,7 +1695,8 @@ }, "inherited_attribute_list": { "title": "Унаследованные атрибуты", - "no_inherited_attributes": "Нет унаследованных атрибутов." + "no_inherited_attributes": "Нет унаследованных атрибутов.", + "none": "нет" }, "note_map": { "title": "Карта заметок", @@ -1689,7 +1741,7 @@ "remove_relation": "Удалить отношение", "default_new_note_title": "новая заметка", "open_in_new_tab": "Открыть в новой вкладке", - "confirm_remove_relation": "Вы уверены, что хотите удалить отношение?", + "confirm_remove_relation": "Вы уверены, что хотите удалить связь?", "enter_new_title": "Введите новое название заметки:", "note_not_found": "Заметка {{noteId}} не найдена!", "cannot_match_transform": "Невозможно сопоставить преобразование: {{transform}}", @@ -1697,7 +1749,7 @@ "click_on_canvas_to_place_new_note": "Щелкните по холсту, чтобы разместить новую заметку", "note_already_in_diagram": "Заметка \"{{title}}\" уже есть на диаграмме.", "connection_exists": "Связь '{{name}}' между этими заметками уже существует.", - "specify_new_relation_name": "Укажите новое имя отношения (допустимые символы: буквы, цифры, двоеточие и подчеркивание):", + "specify_new_relation_name": "Укажите новое имя связи (допустимые символы: буквы, цифры, двоеточие и подчеркивание):", "start_dragging_relations": "Начните перетягивать отношения отсюда на другую заметку." }, "vacuum_database": { @@ -1720,15 +1772,15 @@ "enable_tray": "Включить отображение иконки в системном трее (чтобы изменения вступили в силу, необходимо перезапустить Trilium)" }, "highlights_list": { - "title": "Список выделенного", + "title": "Акценты", "bold": "Жирный текст", "italic": "Наклонный текст", "underline": "Подчеркнутый текст", "color": "Цветной текст", - "description": "Вы можете настроить список выделенного, отображаемый на правой панели:", + "description": "Вы можете настроить список акцентов, отображаемый на правой панели:", "bg_color": "Текст с заливкой фона", - "visibility_title": "Видимость списка выделений", - "visibility_description": "Вы можете скрыть виджет списка выделенного, добавив атрибут #hideHighlightWidget к заметке.", + "visibility_title": "Видимость списка акцентов", + "visibility_description": "Вы можете скрыть виджет списка акцентов, добавив атрибут #hideHighlightWidget к заметке.", "shortcut_info": "Вы можете настроить сочетание клавиш для быстрого переключения правой панели (включая список выделенного) в меню Параметры -> Сочетания клавиш (название \"toggleRightPane\")." }, "custom_date_time_format": { @@ -1773,7 +1825,7 @@ "edit_this_note": "Редактировать заметку" }, "show_highlights_list_widget_button": { - "show_highlights_list": "Показать список выделенного" + "show_highlights_list": "Показать список акцентов" }, "zen_mode": { "button_exit": "Покинуть режим \"дзен\"" @@ -1785,7 +1837,8 @@ "error_unrecognized_command": "Нераспознанная команда {{command}}", "error_cannot_get_branch_id": "Невозможно получить branchId для notePath '{{notePath}}'", "delete_this_note": "Удалить эту заметку", - "insert_child_note": "Вставить дочернюю заметку" + "insert_child_note": "Вставить дочернюю заметку", + "note_revisions": "История изменений" }, "svg_export_button": { "button_title": "Экспортировать диаграмму как SVG" @@ -1842,7 +1895,10 @@ "next_theme_button": "Попробовать новую тему", "background_effects_message": "На устройствах Windows фоновые эффекты теперь полностью стабильны. Они добавляют цвет в пользовательский интерфейс, размывая фон за ним. Этот приём также используется в других приложениях, например, в проводнике Windows.", "background_effects_title": "Фоновые эффекты теперь стабильны", - "next_theme_title": "Попробуйте новую тему Trilium" + "next_theme_title": "Попробуйте новую тему Trilium", + "new_layout_button": "Подробнее", + "new_layout_message": "Мы обновили интерфейс Trilium. Старая лента инструментов была удалена и органично интегрирована в основной интерфейс, а ключевые функции теперь выполняет новая строка состояния и разворачиваемые разделы.\n\nНовый интерфейс включен по умолчанию и может быть временно отключен через «Параметры» → «Внешний вид».", + "new_layout_title": "Новый дизайн" }, "zoom_factor": { "description": "Масштабированием также можно управлять с помощью сочетаний клавиш CTRL+- и CTRL+=.", @@ -1852,7 +1908,10 @@ "show_toc": "Показать оглавление" }, "code_mime_types": { - "title": "Доступные типы в выпадающем списке" + "title": "Доступные типы в выпадающем списке", + "tooltip_syntax_highlighting": "Подсветка синтаксиса", + "tooltip_code_note_syntax": "Заметки с кодом", + "tooltip_code_block_syntax": "Блоки кода в текстовых заметках" }, "search_result": { "no_notes_found": "По заданным параметрам поиска заметки не найдены.", @@ -1975,7 +2034,15 @@ "deletion_reason": ", поскольку вложение не связано с содержимым заметки. Чтобы предотвратить удаление, добавьте ссылку на вложение обратно в содержимое или преобразуйте вложение в заметку." }, "note_title": { - "placeholder": "введите здесь название заметки..." + "placeholder": "введите здесь название заметки...", + "edited_notes": "Измененные в этот день заметки", + "note_type_switcher_collection": "Коллекция", + "note_type_switcher_templates": "Шаблон", + "note_type_switcher_others": "Другой тип заметки", + "note_type_switcher_label": "Переключить с {{type}} на:", + "last_modified": "Изменена ", + "created_on": "Создана в ", + "promoted_attributes": "Продвигаемые атрибуты" }, "units": { "percentage": "%" @@ -2014,7 +2081,10 @@ }, "settings_appearance": { "related_code_blocks": "Цветовая схема для блоков кода в текстовых заметках", - "related_code_notes": "Цветовая схема для заметок типа \"Код\"" + "related_code_notes": "Цветовая схема для заметок типа \"Код\"", + "ui_new_layout": "Новый дизайн", + "ui_old_layout": "Старый дизайн", + "ui": "Пользовательский интерфейс" }, "sql_result": { "no_rows": "По этому запросу не возвращено ни одной строки" @@ -2024,17 +2094,25 @@ }, "editable_text": { "placeholder": "Введите содержимое для заметки...", - "auto-detect-language": "Определен автоматически" + "auto-detect-language": "Определен автоматически", + "keeps-crashing": "Компонент редактирования вылетает. Пожалуйста, попробуйте перезапустить Trilium. Если проблема сохраняется, пожалуйста, создайте отчет об ошибке.", + "editor_crashed_details_title": "Техническая информация", + "editor_crashed_details_intro": "Если эта ошибка возникает несколько раз, пожалуйста, сообщите о ней на GitHub, сопроводив информаций ниже.", + "editor_crashed_content": "Ваши данные были успешно восстановлены, но некоторые из последних изменений могли не быть сохранены.", + "editor_crashed_details_button": "Подробнее...", + "editor_crashed_title": "Возникла ошибка в текстовом редакторе" }, "hoisted_note": { - "confirm_unhoisting": "Запрошенная заметка «{{requestedNote}}» находится за пределами поддерева закрепленной заметки \"{{hoistedNote}}\", и для доступа к ней необходимо снять закрепление. Открепить заметку?" + "confirm_unhoisting": "Запрошенная заметка «{{requestedNote}}» находится за пределами поддерева закрепленной заметки \"{{hoistedNote}}\", и для доступа к ней необходимо снять фокус. Снять фокус с заметки?" }, "frontend_script_api": { "sync_warning": "Вы передаете синхронную функцию в `api.runAsyncOnBackendWithManualTransactionHandling()`, \\nхотя вместо этого вам, скорее всего, следует использовать `api.runOnBackend()`.", "async_warning": "Вы передаете асинхронную функцию в `api.runOnBackend()`, которая, скорее всего, не будет работать так, как вы предполагали.\\nЛибо сделайте функцию синхронной (удалив ключевое слово `async`), либо используйте `api.runAsyncOnBackendWithManualTransactionHandling()`." }, "note_detail": { - "could_not_find_typewidget": "Не удалось найти typeWidget для типа '{{type}}'" + "could_not_find_typewidget": "Не удалось найти typeWidget для типа '{{type}}'", + "printing_pdf": "Выполняется экспорт PDF...", + "printing": "Выполняется печать..." }, "book": { "no_children_help": "В этой коллекции нет дочерних заметок, поэтому отображать нечего. Подробности см. в wiki.", @@ -2055,5 +2133,102 @@ "pagination": { "total_notes": "{{count}} заметок", "page_title": "Страница {{startIndex}} - {{endIndex}}" + }, + "status_bar": { + "attributes_one": "{{count}} атрибут", + "attributes_few": "{{count}} атрибута", + "attributes_many": "{{count}} атрибутов", + "note_info_title": "Просмотр информации о заметке, (даты, размер)", + "language_title": "Изменить язык содержимого", + "code_note_switcher": "Изменить режим языка", + "note_paths_title": "Расположения заметки", + "note_paths_one": "{{count}} место", + "note_paths_few": "{{count}} места", + "note_paths_many": "{{count}} мест", + "attributes_title": "Собственные и унаследованные атрибуты", + "attachments_title_one": "Открыть вложение в новой вкладке", + "attachments_title_few": "Открыть вложения в новой вкладке", + "attachments_title_many": "Открыть вложения в новой вкладке", + "attachments_one": "{{count}} вложение", + "attachments_few": "{{count}} вложения", + "attachments_many": "{{count}} вложений", + "backlinks_one": "{{count}} обратная ссылка", + "backlinks_few": "{{count}} обратные ссылки", + "backlinks_many": "{{count}} обратных ссылок", + "backlinks_title_one": "Обратная ссылка", + "backlinks_title_few": "Обратные ссылки", + "backlinks_title_many": "Обратные ссылки" + }, + "breadcrumb_badges": { + "execute_sql_description": "Эта заметка - SQL-запрос. Нажмите, чтобы выполнить его.", + "execute_sql": "Выполнить SQL", + "execute_script_description": "Это заметка содержит скрипт. Нажмите, чтобы выполнить его.", + "execute_script": "Выполнить скрипт", + "clipped_note_description": "Эта заметка первоначально взята с сайта {{url}}.\n\nНажмите, чтобы перейти на исходную веб-страницу.", + "shared_publicly": "Доступно публично", + "shared_locally": "Доступно локально", + "clipped_note": "Web фрагмент", + "shared_unshare": "Убрать публичный доступ", + "shared_open_in_browser": "Открыть ссылку в браузере", + "shared_copy_to_clipboard": "Скопировать ссылку", + "read_only_temporarily_disabled_description": "В данный момент эта заметка доступна для редактирования, но обычно она находится только в режиме чтения. Заметка снова станет доступна только для чтения, как только вы перейдете к другой заметке.\n\nНажмите, чтобы снова включить режим только для чтения.", + "read_only_temporarily_disabled": "Временное редактирование", + "read_only_auto_description": "Эта заметка была автоматически переведена в режим только для чтения по соображениям производительности. Это автоматическое ограничение можно изменить в настройках.\n\nНажмите, чтобы временно отредактировать её.", + "read_only_auto": "Автоматический режим \"только для чтения\"", + "read_only_explicit_description": "Эта заметка была вручную установлена в режим «только для чтения».\nНажмите, чтобы временно отредактировать её.", + "read_only_explicit": "Только для чтения" + }, + "breadcrumb": { + "hoisted_badge_title": "Снять фокус", + "hoisted_badge": "Фокус", + "empty_hide_archived_notes": "Скрыть заметки в архиве", + "create_new_note": "Новая дочерняя заметка", + "scroll_to_top_title": "К началу заметки", + "workspace_badge": "Рабочее пространство" + }, + "tab_history_navigation_buttons": { + "go-forward": "Перейти к следующей заметке", + "go-back": "Перейти к предыдущей заметке" + }, + "server": { + "traefik_blocks_requests": "Если вы используете обратный прокси-сервер Traefik, то следует учитывать, что в него внесены критические изменения, влияющие на связь с сервером.", + "unknown_http_error_content": "Код: {{statusCode}}\nURL: {{method}} {{url}}\nСообщение: {{message}}", + "unknown_http_error_title": "Ошибка связи с сервером" + }, + "note-color": { + "set-color": "Установить цвет заметки", + "clear-color": "Убрать цвет заметки", + "set-custom-color": "Установить другой цвет" + }, + "calendar_view": { + "delete_note": "Удалить заметку..." + }, + "presentation_view": { + "start-presentation": "Начать презентацию", + "edit-slide": "Редактировать слайд", + "slide-overview": "Переключить общий просмотр слайдов" + }, + "read-only-info": { + "edit-note": "Изменить заметку", + "auto-read-only-note": "Заметка отображена в режиме \"только для чтения\" для быстрой загрузки.", + "read-only-note": "Заметка отображается в режиме \"только для чтения\"." + }, + "experimental_features": { + "new_layout_description": "Попробуйте новый современный и удобный дизайн. В будущих обновлениях возможны его существенные изменения.", + "new_layout_name": "Новый дизайн", + "title": "Экспериментальные параметры", + "disclaimer": "Эти параметры экспериментальные и могут повлиять на стабильность. Используйте с осторожностью." + }, + "popup-editor": { + "maximize": "Переключить на полный редактор" + }, + "right_pane": { + "custom_widget_go_to_source": "Исходный код", + "toggle": "Переключить панель справа", + "empty_button": "Скрыть панель", + "empty_message": "Нечего отобразить для текущей заметки" + }, + "attributes_panel": { + "title": "Атрибуты заметки" } } diff --git a/apps/client/src/translations/tw/translation.json b/apps/client/src/translations/tw/translation.json index e9f88c0297..028a75a56f 100644 --- a/apps/client/src/translations/tw/translation.json +++ b/apps/client/src/translations/tw/translation.json @@ -22,7 +22,15 @@ "bundle-error": { "title": "載入自訂腳本失敗", "message": "來自 ID 為 \"{{id}}\"、標題為 \"{{title}}\" 的筆記的腳本因以下原因無法執行:\n\n{{message}}" - } + }, + "widget-list-error": { + "title": "無法從伺服器取得元件清單" + }, + "widget-render-error": { + "title": "無法渲染自訂 React 元件" + }, + "widget-missing-parent": "自訂元件未定義強制性的 \"{{property}}\" 屬性。", + "open-script-note": "打開腳本筆記" }, "add_link": { "add_link": "新增連結", @@ -205,7 +213,8 @@ "info": { "modalTitle": "資訊消息", "closeButton": "關閉", - "okButton": "確定" + "okButton": "確定", + "copy_to_clipboard": "複製到剪貼簿" }, "jump_to_note": { "search_button": "全文搜尋", @@ -689,7 +698,13 @@ "convert_into_attachment_successful": "筆記 '{{title}}' 已成功轉換為附件。", "convert_into_attachment_prompt": "確定要將筆記 '{{title}}' 轉換為父級筆記的附件嗎?", "print_pdf": "匯出為 PDF…", - "open_note_on_server": "在伺服器上開啟筆記" + "open_note_on_server": "在伺服器上開啟筆記", + "view_revisions": "筆記歷史版本...", + "advanced": "進階", + "export_as_image": "匯出為圖片", + "export_as_image_png": "PNG (點陣)", + "export_as_image_svg": "SVG (向量)", + "note_map": "筆記地圖" }, "onclick_button": { "no_click_handler": "按鈕元件'{{componentId}}'沒有定義點擊時的處理方式" @@ -788,7 +803,7 @@ "file_type": "檔案類型", "file_size": "檔案大小", "download": "下載", - "open": "打開", + "open": "以外部程式打開", "upload_new_revision": "上傳新版本", "upload_success": "已上傳新檔案版本。", "upload_failed": "新檔案版本上傳失敗。", @@ -808,7 +823,8 @@ }, "inherited_attribute_list": { "title": "繼承的屬性", - "no_inherited_attributes": "沒有繼承的屬性。" + "no_inherited_attributes": "沒有繼承的屬性。", + "none": "無" }, "note_info_widget": { "note_id": "筆記 ID", @@ -819,7 +835,9 @@ "note_size_info": "筆記大小提供了該筆記儲存需求的粗略估計。它考慮了筆記及其歷史的內容。", "calculate": "計算", "subtree_size": "(子階層大小: {{size}}, 共計 {{count}} 個筆記)", - "title": "筆記資訊" + "title": "筆記資訊", + "mime": "MIME 類型", + "show_similar_notes": "顯示相似筆記" }, "note_map": { "open_full": "展開顯示", @@ -882,7 +900,8 @@ "search_parameters": "搜尋參數", "unknown_search_option": "未知的搜尋選項 {{searchOptionName}}", "search_note_saved": "搜尋筆記已儲存至 {{- notePathTitle}}", - "actions_executed": "已執行操作。" + "actions_executed": "已執行操作。", + "view_options": "查看選項:" }, "similar_notes": { "title": "相似筆記", @@ -986,7 +1005,12 @@ "editable_text": { "placeholder": "在這裡輸入您的筆記內容…", "auto-detect-language": "自動檢測", - "keeps-crashing": "編輯元件持續發生崩潰。請嘗試重新啟動 Trilium。若問題仍存在,請考慮提交錯誤報告。" + "keeps-crashing": "編輯元件持續發生崩潰。請嘗試重新啟動 Trilium。若問題仍存在,請考慮提交錯誤報告。", + "editor_crashed_title": "文字編輯器崩潰", + "editor_crashed_content": "您的內容已成功恢復,但最近的幾項變更可能未被儲存。", + "editor_crashed_details_button": "檢視更多資訊⋯", + "editor_crashed_details_intro": "若您多次遇到此錯誤,請考慮在 GitHub 回報以下資訊。", + "editor_crashed_details_title": "技術資訊" }, "empty": { "open_note_instruction": "透過在下面的輸入框中輸入筆記標題或在樹中選擇筆記來打開筆記。", @@ -1496,7 +1520,12 @@ }, "highlights_list_2": { "title": "高亮列表", - "options": "選項" + "options": "選項", + "title_with_count_one": "{{count}} 處高亮", + "title_with_count_other": "{{count}} 處高亮", + "modal_title": "設定高亮列表", + "menu_configure": "設定高亮列表…", + "no_highlights": "未找到高亮內容。" }, "quick-search": { "placeholder": "快速搜尋", @@ -1531,7 +1560,14 @@ "printing_pdf": "正在匯出為 PDF…" }, "note_title": { - "placeholder": "請輸入筆記標題..." + "placeholder": "請輸入筆記標題...", + "created_on": "建立於 ", + "last_modified": "修改於 ", + "note_type_switcher_label": "從 {{type}} 切換至:", + "note_type_switcher_others": "其他筆記類型", + "note_type_switcher_templates": "模板", + "note_type_switcher_collection": "集合", + "edited_notes": "編輯過的筆記" }, "search_result": { "no_notes_found": "沒有找到符合搜尋條件的筆記。", @@ -1560,7 +1596,8 @@ }, "toc": { "table_of_contents": "目錄", - "options": "選項" + "options": "選項", + "no_headings": "無標題。" }, "watched_file_update_status": { "file_last_modified": "檔案 最後修改時間為 。", @@ -1934,8 +1971,9 @@ "unknown_widget": "未知元件:\"{{id}}\"。" }, "note_language": { - "not_set": "不設定", - "configure-languages": "設定語言…" + "not_set": "未設定語言", + "configure-languages": "設定語言…", + "help-on-languages": "設定內容語言說明…" }, "content_language": { "title": "內文語言", @@ -2002,7 +2040,7 @@ "book_properties_config": { "hide-weekends": "隱藏週末", "display-week-numbers": "顯示週數", - "map-style": "地圖樣式:", + "map-style": "地圖樣式", "max-nesting-depth": "最大嵌套深度:", "raster": "柵格", "vector_light": "向量(淺色)", @@ -2059,14 +2097,20 @@ "next_theme_title": "試用新 Trilium 主題", "next_theme_message": "您正在使用舊版主題,要試用新主題嗎?", "next_theme_button": "試用新主題", - "dismiss": "關閉" + "dismiss": "關閉", + "new_layout_title": "新版面配置", + "new_layout_button": "更多資訊", + "new_layout_message": "我們為 Trilium 推出了現代化版面配置。功能區分頁已移除並無縫整合至主介面,取而代之的是全新狀態列與可擴展區塊(例如提升屬性)承擔其主要功能。\n\n新版面配置預設為啟用狀態,您可透過「選項 → 外觀」暫時停用。" }, "settings": { "related_settings": "相關設定" }, "settings_appearance": { "related_code_blocks": "文字筆記中程式碼區塊的配色方案", - "related_code_notes": "程式碼筆記的配色方案" + "related_code_notes": "程式碼筆記的配色方案", + "ui": "使用者介面", + "ui_old_layout": "舊版面配置", + "ui_new_layout": "新版面配置" }, "units": { "percentage": "%" @@ -2106,5 +2150,75 @@ }, "popup-editor": { "maximize": "切換至完整編輯器" + }, + "experimental_features": { + "title": "實驗性選項", + "disclaimer": "這些選項屬實驗性質,可能導致系統不穩定。請謹慎使用。", + "new_layout_name": "新版面配置", + "new_layout_description": "體驗全新版面配置,呈現更現代的外觀與更佳的使用體驗。在未來版本將進行大幅調整。" + }, + "server": { + "unknown_http_error_title": "與伺服器通訊錯誤", + "unknown_http_error_content": "狀態碼:{{statusCode}}\n網址:{{method}} {{url}}\n訊息:{{message}}", + "traefik_blocks_requests": "若您正在使用 Traefik 反向代理,該代理已引入一項重大變更影響與伺服器的通訊。" + }, + "tab_history_navigation_buttons": { + "go-back": "返回前一筆記", + "go-forward": "前往下一筆記" + }, + "breadcrumb_badges": { + "read_only_explicit": "唯讀", + "read_only_auto": "自動唯讀", + "shared_publicly": "公開分享", + "shared_locally": "本地分享", + "read_only_explicit_description": "此筆記已被手動設定為唯讀。\n點擊以臨時編輯。", + "read_only_temporarily_disabled": "臨時編輯", + "shared_copy_to_clipboard": "複製連結至剪貼簿", + "shared_open_in_browser": "在瀏覽器中打開連結", + "shared_unshare": "取消分享", + "clipped_note": "網頁擷取", + "execute_script": "運行腳本", + "execute_sql": "運行 SQL", + "read_only_auto_description": "基於效能考量,此筆記已自動設定為唯讀模式。此自動限制可於設定中調整。\n\n點擊此處可臨時編輯。", + "read_only_temporarily_disabled_description": "此筆記目前可編輯,但通常為唯讀狀態。當您切換至其他筆記時,本筆記將立即恢復為唯讀模式。\n\n點擊此處重新啟用唯讀模式。", + "clipped_note_description": "本筆記原始來源為 {{url}}。\n\n點擊此處前往原網頁。", + "execute_script_description": "此筆記為腳本筆記。點擊以執行腳本。", + "execute_sql_description": "此筆記為 SQL 筆記。點擊以執行 SQL 查詢。" + }, + "breadcrumb": { + "hoisted_badge": "聚焦", + "hoisted_badge_title": "取消聚焦", + "workspace_badge": "工作空間", + "scroll_to_top_title": "跳轉至筆記開頭", + "create_new_note": "新增子筆記", + "empty_hide_archived_notes": "隱藏已歸檔的筆記" + }, + "status_bar": { + "language_title": "更改內容語言", + "note_info_title": "查看筆記資訊(如日期、筆記大小)", + "backlinks_one": "{{count}} 個反連結", + "backlinks_other": "", + "backlinks_title_one": "查看反連結", + "backlinks_title_other": "", + "attachments_one": "{{count}} 個附件", + "attachments_other": "", + "attachments_title_one": "在新分頁中查看附件", + "attachments_title_other": "", + "attributes_one": "{{count}} 個屬性", + "attributes_other": "", + "attributes_title": "自有屬性及繼承屬性", + "note_paths_one": "{{count}} 條路徑", + "note_paths_other": "", + "note_paths_title": "筆記路徑", + "code_note_switcher": "更改語言模式" + }, + "right_pane": { + "empty_button": "隱藏面板", + "toggle": "切換右側面板", + "custom_widget_go_to_source": "跳轉至原始碼", + "empty_message": "此筆記無內容可顯示" + }, + "attributes_panel": { + "title": "筆記屬性" } } diff --git a/apps/client/src/widgets/FloatingButtonsDefinitions.tsx b/apps/client/src/widgets/FloatingButtonsDefinitions.tsx index 65743984e9..35dbc92ae8 100644 --- a/apps/client/src/widgets/FloatingButtonsDefinitions.tsx +++ b/apps/client/src/widgets/FloatingButtonsDefinitions.tsx @@ -1,25 +1,27 @@ +import { BacklinkCountResponse, BacklinksResponse, SaveSqlConsoleResponse } from "@triliumnext/commons"; import { VNode } from "preact"; +import { useCallback, useEffect, useLayoutEffect, useRef, useState } from "preact/hooks"; + import appContext, { EventData, EventNames } from "../components/app_context"; import Component from "../components/component"; import NoteContext from "../components/note_context"; import FNote from "../entities/fnote"; -import ActionButton, { ActionButtonProps } from "./react/ActionButton"; -import { useIsNoteReadOnly, useNoteLabelBoolean, useTriliumEvent, useTriliumOption, useWindowSize } from "./react/hooks"; -import { useEffect, useLayoutEffect, useMemo, useRef, useState } from "preact/hooks"; -import { createImageSrcUrl, openInAppHelpFromUrl } from "../services/utils"; -import server from "../services/server"; -import { BacklinkCountResponse, BacklinksResponse, SaveSqlConsoleResponse } from "@triliumnext/commons"; -import toast from "../services/toast"; +import attributes from "../services/attributes"; +import { isExperimentalFeatureEnabled } from "../services/experimental_features"; +import froca from "../services/froca"; import { t } from "../services/i18n"; import { copyImageReferenceToClipboard } from "../services/image"; -import tree from "../services/tree"; import { getHelpUrlForNote } from "../services/in_app_help"; -import froca from "../services/froca"; +import LoadResults from "../services/load_results"; +import server from "../services/server"; +import toast from "../services/toast"; +import tree from "../services/tree"; +import { createImageSrcUrl, openInAppHelpFromUrl } from "../services/utils"; +import { ViewTypeOptions } from "./collections/interface"; +import ActionButton, { ActionButtonProps } from "./react/ActionButton"; +import { useIsNoteReadOnly, useNoteLabelBoolean, useTriliumEvent, useTriliumOption, useWindowSize } from "./react/hooks"; import NoteLink from "./react/NoteLink"; import RawHtml from "./react/RawHtml"; -import { ViewTypeOptions } from "./collections/interface"; -import attributes from "../services/attributes"; -import LoadResults from "../services/load_results"; export interface FloatingButtonContext { parentComponent: Component; @@ -37,7 +39,7 @@ function FloatingButton({ className, ...props }: ActionButtonProps) { className={`floating-button ${className ?? ""}`} noIconActionClass {...props} - /> + />; } export type FloatingButtonsList = ((context: FloatingButtonContext) => false | VNode)[]; @@ -82,7 +84,7 @@ function RefreshBackendLogButton({ note, parentComponent, noteContext, isDefault text={t("backend_log.refresh")} icon="bx bx-refresh" onClick={() => parentComponent.triggerEvent("refreshData", { ntxId: noteContext.ntxId })} - /> + />; } function SwitchSplitOrientationButton({ note, isReadOnly, isDefaultViewMode }: FloatingButtonContext) { @@ -94,7 +96,7 @@ function SwitchSplitOrientationButton({ note, isReadOnly, isDefaultViewMode }: F text={upcomingOrientation === "vertical" ? t("switch_layout_button.title_vertical") : t("switch_layout_button.title_horizontal")} icon={upcomingOrientation === "vertical" ? "bx bxs-dock-bottom" : "bx bxs-dock-left"} onClick={() => setSplitEditorOrientation(upcomingOrientation)} - /> + />; } function ToggleReadOnlyButton({ note, viewType, isDefaultViewMode }: FloatingButtonContext) { @@ -106,7 +108,7 @@ function ToggleReadOnlyButton({ note, viewType, isDefaultViewMode }: FloatingBut text={isReadOnly ? t("toggle_read_only_button.unlock-editing") : t("toggle_read_only_button.lock-editing")} icon={isReadOnly ? "bx bx-lock-open-alt" : "bx bx-lock-alt"} onClick={() => setReadOnly(!isReadOnly)} - /> + />; } function EditButton({ note, noteContext }: FloatingButtonContext) { @@ -129,7 +131,7 @@ function EditButton({ note, noteContext }: FloatingButtonContext) { icon="bx bx-pencil" className={animationClass} onClick={() => enableEditing()} - /> + />; } function ShowTocWidgetButton({ note, noteContext, isDefaultViewMode }: FloatingButtonContext) { @@ -147,7 +149,7 @@ function ShowTocWidgetButton({ note, noteContext, isDefaultViewMode }: FloatingB appContext.triggerEvent("showTocWidget", { noteId: noteContext.noteId }); } }} - /> + />; } function ShowHighlightsListWidgetButton({ note, noteContext, isDefaultViewMode }: FloatingButtonContext) { @@ -165,16 +167,16 @@ function ShowHighlightsListWidgetButton({ note, noteContext, isDefaultViewMode } appContext.triggerEvent("showHighlightsListWidget", { noteId: noteContext.noteId }); } }} - /> + />; } function RunActiveNoteButton({ note }: FloatingButtonContext) { - const isEnabled = note.mime.startsWith("application/javascript") || note.mime === "text/x-sqlite;schema=trilium"; + const isEnabled = (note.mime.startsWith("application/javascript") || note.mime === "text/x-sqlite;schema=trilium"); return isEnabled && + />; } function OpenTriliumApiDocsButton({ note }: FloatingButtonContext) { @@ -183,7 +185,7 @@ function OpenTriliumApiDocsButton({ note }: FloatingButtonContext) { icon="bx bx-help-circle" text={t("code_buttons.trilium_api_docs_button_title")} onClick={() => openInAppHelpFromUrl(note.mime.endsWith("frontend") ? "Q2z6av6JZVWm" : "MEtfsqa5VwNi")} - /> + />; } function SaveToNoteButton({ note }: FloatingButtonContext) { @@ -191,17 +193,21 @@ function SaveToNoteButton({ note }: FloatingButtonContext) { return isEnabled && { - e.preventDefault(); - const { notePath } = await server.post("special-notes/save-sql-console", { sqlConsoleNoteId: note.noteId }); - if (notePath) { - toast.showMessage(t("code_buttons.sql_console_saved_message", { "note_path": await tree.getNotePathTitle(notePath) })); - // TODO: This hangs the navigation, for some reason. - //await ws.waitForMaxKnownEntityChangeId(); - await appContext.tabManager.getActiveContext()?.setNote(notePath); - } - }} - /> + onClick={buildSaveSqlToNoteHandler(note)} + />; +} + +export function buildSaveSqlToNoteHandler(note: FNote) { + return async (e: MouseEvent) => { + e.preventDefault(); + const { notePath } = await server.post("special-notes/save-sql-console", { sqlConsoleNoteId: note.noteId }); + if (notePath) { + toast.showMessage(t("code_buttons.sql_console_saved_message", { "note_path": await tree.getNotePathTitle(notePath) })); + // TODO: This hangs the navigation, for some reason. + //await ws.waitForMaxKnownEntityChangeId(); + await appContext.tabManager.getActiveContext()?.setNote(notePath); + } + }; } function RelationMapButtons({ note, isDefaultViewMode, triggerEvent }: FloatingButtonContext) { @@ -234,7 +240,7 @@ function RelationMapButtons({ note, isDefaultViewMode, triggerEvent }: FloatingB /> - ) + ); } function GeoMapButtons({ triggerEvent, viewType, isReadOnly }: FloatingButtonContext) { @@ -250,8 +256,10 @@ function GeoMapButtons({ triggerEvent, viewType, isReadOnly }: FloatingButtonCon function CopyImageReferenceButton({ note, isDefaultViewMode }: FloatingButtonContext) { const hiddenImageCopyRef = useRef(null); - const isEnabled = ["mermaid", "canvas", "mindMap", "image"].includes(note?.type ?? "") - && note?.isContentAvailable() && isDefaultViewMode; + const isEnabled = ( + ["mermaid", "canvas", "mindMap", "image"].includes(note?.type ?? "") + && note?.isContentAvailable() && isDefaultViewMode + ); return isEnabled && ( <> @@ -272,7 +280,7 @@ function CopyImageReferenceButton({ note, isDefaultViewMode }: FloatingButtonCon position: "absolute" // Take out of the the hidden image from flexbox to prevent the layout being affected }} /> - ) + ); } function ExportImageButtons({ note, triggerEvent, isDefaultViewMode }: FloatingButtonContext) { @@ -292,38 +300,26 @@ function ExportImageButtons({ note, triggerEvent, isDefaultViewMode }: FloatingB onClick={() => triggerEvent("exportPng")} /> - ) + ); } function InAppHelpButton({ note }: FloatingButtonContext) { const helpUrl = getHelpUrlForNote(note); + const isEnabled = !!helpUrl; - return !!helpUrl && ( + return isEnabled && ( helpUrl && openInAppHelpFromUrl(helpUrl)} /> - ) + ); } function Backlinks({ note, isDefaultViewMode }: FloatingButtonContext) { - let [ backlinkCount, setBacklinkCount ] = useState(0); - let [ popupOpen, setPopupOpen ] = useState(false); + const [ popupOpen, setPopupOpen ] = useState(false); const backlinksContainerRef = useRef(null); - - function refresh() { - if (!isDefaultViewMode) return; - - server.get(`note-map/${note.noteId}/backlink-count`).then(resp => { - setBacklinkCount(resp.count); - }); - } - - useEffect(() => refresh(), [ note ]); - useTriliumEvent("entitiesReloaded", ({ loadResults }) => { - if (needsRefresh(note, loadResults)) refresh(); - }); + const backlinkCount = useBacklinkCount(note, isDefaultViewMode); // Determine the max height of the container. const { windowHeight } = useWindowSize(); @@ -355,15 +351,34 @@ function Backlinks({ note, isDefaultViewMode }: FloatingButtonContext) { ); } -function BacklinksList({ note }: { note: FNote }) { +export function useBacklinkCount(note: FNote | null | undefined, isDefaultViewMode: boolean) { + const [ backlinkCount, setBacklinkCount ] = useState(0); + + const refresh = useCallback(() => { + if (!note || !isDefaultViewMode) return; + + server.get(`note-map/${note.noteId}/backlink-count`).then(resp => { + setBacklinkCount(resp.count); + }); + }, [ isDefaultViewMode, note ]); + + useEffect(() => refresh(), [ refresh ]); + useTriliumEvent("entitiesReloaded", ({ loadResults }) => { + if (note && needsRefresh(note, loadResults)) refresh(); + }); + + return backlinkCount; +} + +export function BacklinksList({ note }: { note: FNote }) { const [ backlinks, setBacklinks ] = useState([]); function refresh() { server.get(`note-map/${note.noteId}/backlinks`).then(async (backlinks) => { // prefetch all const noteIds = backlinks - .filter(bl => "noteId" in bl) - .map((bl) => bl.noteId); + .filter(bl => "noteId" in bl) + .map((bl) => bl.noteId); await froca.getNotes(noteIds); setBacklinks(backlinks); }); @@ -375,7 +390,7 @@ function BacklinksList({ note }: { note: FNote }) { }); return backlinks.map(backlink => ( -
+
  • )) )} -
  • + )); } diff --git a/apps/client/src/widgets/NoteDetail.tsx b/apps/client/src/widgets/NoteDetail.tsx index 272385d258..894bb4ac54 100644 --- a/apps/client/src/widgets/NoteDetail.tsx +++ b/apps/client/src/widgets/NoteDetail.tsx @@ -1,16 +1,18 @@ -import { useNoteContext, useTriliumEvent } from "./react/hooks" -import FNote from "../entities/fnote"; -import protected_session_holder from "../services/protected_session_holder"; -import { useEffect, useRef, useState } from "preact/hooks"; -import NoteContext from "../components/note_context"; -import { isValidElement, VNode } from "preact"; -import { TypeWidgetProps } from "./type_widgets/type_widget"; import "./NoteDetail.css"; + +import { isValidElement, VNode } from "preact"; +import { useEffect, useRef, useState } from "preact/hooks"; + +import NoteContext from "../components/note_context"; +import FNote from "../entities/fnote"; import attributes from "../services/attributes"; -import { ExtendedNoteType, TYPE_MAPPINGS, TypeWidget } from "./note_types"; -import { dynamicRequire, isElectron, isMobile } from "../services/utils"; -import toast from "../services/toast.js"; import { t } from "../services/i18n"; +import protected_session_holder from "../services/protected_session_holder"; +import toast from "../services/toast.js"; +import { dynamicRequire, isElectron, isMobile } from "../services/utils"; +import { ExtendedNoteType, TYPE_MAPPINGS, TypeWidget } from "./note_types"; +import { useNoteContext, useTriliumEvent } from "./react/hooks"; +import { TypeWidgetProps } from "./type_widgets/type_widget"; /** * The note detail is in charge of rendering the content of a note, by determining its type (e.g. text, code) and using the appropriate view widget. @@ -80,7 +82,7 @@ export default function NoteDetail() { parentComponent.handleEvent("noteTypeMimeChanged", { noteId: note.noteId }); } else if (note.noteId && loadResults.isNoteReloaded(note.noteId, parentComponent.componentId) - && (type !== (await getWidgetType(note, noteContext)) || mime !== note?.mime)) { + && (type !== (await getExtendedWidgetType(note, noteContext)) || mime !== note?.mime)) { // this needs to have a triggerEvent so that e.g., note type (not in the component subtree) is updated parentComponent.triggerEvent("noteTypeMimeChanged", { noteId: note.noteId }); } else { @@ -212,7 +214,7 @@ export default function NoteDetail() { isVisible={type === itemType} isFullHeight={isFullHeight} props={props} - /> + />; })} ); @@ -254,7 +256,7 @@ function useNoteInfo() { const [ mime, setMime ] = useState(); function refresh() { - getWidgetType(actualNote, noteContext).then(type => { + getExtendedWidgetType(actualNote, noteContext).then(type => { setNote(actualNote); setType(type); setMime(actualNote?.mime); @@ -282,12 +284,12 @@ async function getCorrespondingWidget(type: ExtendedNoteType): Promise { +export async function getExtendedWidgetType(note: FNote | null | undefined, noteContext: NoteContext | undefined): Promise { if (!noteContext) return undefined; if (!note) { // If the note is null, then it's a new tab. If it's undefined, then it's not loaded yet. @@ -299,8 +301,10 @@ async function getWidgetType(note: FNote | null | undefined, noteContext: NoteCo if (noteContext?.viewScope?.viewMode === "source") { resultingType = "readOnlyCode"; - } else if (noteContext?.viewScope && noteContext.viewScope.viewMode === "attachments") { + } else if (noteContext.viewScope?.viewMode === "attachments") { resultingType = noteContext.viewScope.attachmentId ? "attachmentDetail" : "attachmentList"; + } else if (noteContext.viewScope?.viewMode === "note-map") { + resultingType = "noteMap"; } else if (type === "text" && (await noteContext?.isReadOnly())) { resultingType = "readOnlyText"; } else if ((type === "code" || type === "mermaid") && (await noteContext?.isReadOnly())) { @@ -322,7 +326,7 @@ async function getWidgetType(note: FNote | null | undefined, noteContext: NoteCo return resultingType; } -function checkFullHeight(noteContext: NoteContext | undefined, type: ExtendedNoteType | undefined) { +export function checkFullHeight(noteContext: NoteContext | undefined, type: ExtendedNoteType | undefined) { if (!noteContext) return false; // https://github.com/zadam/trilium/issues/2522 diff --git a/apps/client/src/widgets/PromotedAttributes.tsx b/apps/client/src/widgets/PromotedAttributes.tsx index e25420f68c..cb6dc26713 100644 --- a/apps/client/src/widgets/PromotedAttributes.tsx +++ b/apps/client/src/widgets/PromotedAttributes.tsx @@ -1,19 +1,21 @@ -import { Dispatch, StateUpdater, useEffect, useRef, useState } from "preact/hooks"; import "./PromotedAttributes.css"; -import { useNoteContext, useNoteLabel, useTriliumEvent, useUniqueName } from "./react/hooks"; -import { Attribute } from "../services/attribute_parser"; -import FAttribute from "../entities/fattribute"; + +import { UpdateAttributeResponse } from "@triliumnext/commons"; import clsx from "clsx"; +import { ComponentChild, HTMLInputTypeAttribute, InputHTMLAttributes, MouseEventHandler, TargetedEvent, TargetedInputEvent } from "preact"; +import { Dispatch, StateUpdater, useEffect, useRef, useState } from "preact/hooks"; + +import FAttribute from "../entities/fattribute"; +import FNote from "../entities/fnote"; +import { Attribute } from "../services/attribute_parser"; +import attributes from "../services/attributes"; +import debounce from "../services/debounce"; import { t } from "../services/i18n"; import { DefinitionObject, extractAttributeDefinitionTypeAndName, LabelType } from "../services/promoted_attribute_definition_parser"; import server from "../services/server"; -import FNote from "../entities/fnote"; -import { ComponentChild, HTMLInputTypeAttribute, InputHTMLAttributes, MouseEventHandler, TargetedEvent, TargetedInputEvent } from "preact"; -import NoteAutocomplete from "./react/NoteAutocomplete"; import ws from "../services/ws"; -import { UpdateAttributeResponse } from "@triliumnext/commons"; -import attributes from "../services/attributes"; -import debounce from "../services/debounce"; +import { useNoteContext, useNoteLabel, useTriliumEvent, useUniqueName } from "./react/hooks"; +import NoteAutocomplete from "./react/NoteAutocomplete"; interface Cell { uniqueId: string; @@ -39,6 +41,15 @@ type OnChangeListener = (e: OnChangeEventData) => Promise; export default function PromotedAttributes() { const { note, componentId } = useNoteContext(); const [ cells, setCells ] = usePromotedAttributeData(note, componentId); + return ; +} + +export function PromotedAttributesContent({ note, componentId, cells, setCells }: { + note: FNote | null | undefined; + componentId: string; + cells: Cell[] | undefined; + setCells: Dispatch>; +}) { const [ cellToFocus, setCellToFocus ] = useState(); return ( @@ -62,7 +73,7 @@ export default function PromotedAttributes() { * * The cells are returned as a state since they can also be altered internally if needed, for example to add a new empty cell. */ -function usePromotedAttributeData(note: FNote | null | undefined, componentId: string): [ Cell[] | undefined, Dispatch> ] { +export function usePromotedAttributeData(note: FNote | null | undefined, componentId: string): [ Cell[] | undefined, Dispatch> ] { const [ viewType ] = useNoteLabel(note, "viewType"); const [ cells, setCells ] = useState(); @@ -156,7 +167,7 @@ function PromotedAttributeCell(props: CellProps) { {correspondingInput} - ) + ); } const LABEL_MAPPINGS: Record = { @@ -219,29 +230,29 @@ function LabelInput({ inputId, ...props }: CellProps & { inputId: string }) { - - } else { - return ( -
    - {inputNode} - { definition.labelType === "color" && } - { definition.labelType === "url" && ( - { - const inputEl = document.getElementById(inputId) as HTMLInputElement | null; - const url = inputEl?.value; - if (url) { - window.open(url, "_blank"); - } - }} - /> - )} -
    - ); + ; } + return ( +
    + {inputNode} + { definition.labelType === "color" && } + { definition.labelType === "url" && ( + { + const inputEl = document.getElementById(inputId) as HTMLInputElement | null; + const url = inputEl?.value; + if (url) { + window.open(url, "_blank"); + } + }} + /> + )} +
    + ); + } @@ -282,7 +293,7 @@ function ColorPicker({ cell, onChange, inputId }: CellProps & { }} /> - ) + ); } function RelationInput({ inputId, ...props }: CellProps & { inputId: string }) { @@ -295,7 +306,7 @@ function RelationInput({ inputId, ...props }: CellProps & { inputId: string }) { await updateAttribute(note, cell, componentId, value, setCells); }} /> - ) + ); } function MultiplicityCell({ cell, cells, setCells, setCellToFocus, note, componentId }: CellProps) { @@ -346,13 +357,13 @@ function MultiplicityCell({ cell, cells, setCells, setCellToFocus, note, compone name: cell.valueName, value: "" } - }) + }); } setCells(cells.toSpliced(index, 1, ...newOnesToInsert)); }} /> - ) + ); } function PromotedActionButton({ icon, title, onClick }: { @@ -366,7 +377,7 @@ function PromotedActionButton({ icon, title, onClick }: { title={title} onClick={onClick} /> - ) + ); } function InputButton({ icon, className, title, onClick }: { @@ -381,7 +392,7 @@ function InputButton({ icon, className, title, onClick }: { title={title} onClick={onClick} /> - ) + ); } function setupTextLabelAutocomplete(el: HTMLInputElement, valueAttr: Attribute, onChangeListener: OnChangeListener) { @@ -406,7 +417,7 @@ function setupTextLabelAutocomplete(el: HTMLInputElement, valueAttr: Attribute, [ { displayKey: "value", - source: function (term, cb) { + source (term, cb) { term = term.toLowerCase(); const filtered = attributeValues.filter((attr) => attr.value.toLowerCase().includes(term)); diff --git a/apps/client/src/widgets/TabHistoryNavigationButtons.css b/apps/client/src/widgets/TabHistoryNavigationButtons.css new file mode 100644 index 0000000000..4d040b9a5f --- /dev/null +++ b/apps/client/src/widgets/TabHistoryNavigationButtons.css @@ -0,0 +1,7 @@ +.component.tab-history-navigation-buttons { + contain: none; + flex-shrink: 0; + display: flex; + align-items: center; + margin-inline-end: 0.5em; +} diff --git a/apps/client/src/widgets/TabHistoryNavigationButtons.tsx b/apps/client/src/widgets/TabHistoryNavigationButtons.tsx new file mode 100644 index 0000000000..42b461df0c --- /dev/null +++ b/apps/client/src/widgets/TabHistoryNavigationButtons.tsx @@ -0,0 +1,64 @@ +import "./TabHistoryNavigationButtons.css"; + +import { useEffect, useMemo, useState } from "preact/hooks"; + +import { t } from "../services/i18n"; +import { dynamicRequire, isElectron } from "../services/utils"; +import { handleHistoryContextMenu } from "./launch_bar/HistoryNavigation"; +import ActionButton from "./react/ActionButton"; +import { useLauncherVisibility } from "./react/hooks"; + +export default function TabHistoryNavigationButtons() { + const webContents = useMemo(() => isElectron() ? dynamicRequire("@electron/remote").getCurrentWebContents() : undefined, []); + const onContextMenu = webContents ? handleHistoryContextMenu(webContents) : undefined; + const { canGoBack, canGoForward } = useBackForwardState(webContents); + const legacyBackVisible = useLauncherVisibility("_lbBackInHistory"); + const legacyForwardVisible = useLauncherVisibility("_lbForwardInHistory"); + + return ( +
    + {!legacyBackVisible && } + {!legacyForwardVisible && } +
    + ); +} + +function useBackForwardState(webContents: Electron.WebContents | undefined) { + const [ canGoBack, setCanGoBack ] = useState(webContents?.navigationHistory.canGoBack()); + const [ canGoForward, setCanGoForward ] = useState(webContents?.navigationHistory.canGoForward()); + + useEffect(() => { + if (!webContents) return; + + const updateNavigationState = () => { + setCanGoBack(webContents.navigationHistory.canGoBack()); + setCanGoForward(webContents.navigationHistory.canGoForward()); + }; + + webContents.on("did-navigate", updateNavigationState); + webContents.on("did-navigate-in-page", updateNavigationState); + + return () => { + webContents.removeListener("did-navigate", updateNavigationState); + webContents.removeListener("did-navigate-in-page", updateNavigationState); + }; + }, [ webContents ]); + + if (!webContents) { + return { canGoBack: true, canGoForward: true }; + } + + return { canGoBack, canGoForward }; +} diff --git a/apps/client/src/widgets/Toast.css b/apps/client/src/widgets/Toast.css index 519e3b62d1..ecc20c2056 100644 --- a/apps/client/src/widgets/Toast.css +++ b/apps/client/src/widgets/Toast.css @@ -54,6 +54,16 @@ display: flex; gap: 1em; justify-content: space-between; + + .btn { + color: var(--bs-toast-color); + background: var(--modal-control-button-background); + + &:hover { + background: var(--modal-control-button-hover-background); + color: var(--bs-toast-color); + } + } } .toast-progress { diff --git a/apps/client/src/widgets/attribute_widgets/attribute_detail.ts b/apps/client/src/widgets/attribute_widgets/attribute_detail.ts index 2a7a55aef1..607af49952 100644 --- a/apps/client/src/widgets/attribute_widgets/attribute_detail.ts +++ b/apps/client/src/widgets/attribute_widgets/attribute_detail.ts @@ -12,6 +12,7 @@ import shortcutService from "../../services/shortcuts.js"; import appContext from "../../components/app_context.js"; import type { Attribute } from "../../services/attribute_parser.js"; import { focusSavedElement, saveFocusedElement } from "../../services/focus.js"; +import { isExperimentalFeatureEnabled } from "../../services/experimental_features.js"; const TPL = /*html*/`
    @@ -81,7 +82,7 @@ const TPL = /*html*/`
    ${t("attribute_detail.attr_detail_title")}
    - +
    ${t("attribute_detail.attr_is_owned_by")}
    @@ -309,6 +310,8 @@ interface SearchRelatedResponse { count: number; } +const isNewLayout = isExperimentalFeatureEnabled("new-layout"); + export default class AttributeDetailWidget extends NoteContextAwareWidget { private $title!: JQuery; private $inputName!: JQuery; @@ -579,6 +582,13 @@ export default class AttributeDetailWidget extends NoteContextAwareWidget { .css("top", y - offset.top + 70) .css("max-height", outerHeight + y > height - 50 ? height - y - 50 : 10000); + if (isNewLayout) { + this.$widget + .css("top", "unset") + .css("bottom", 70) + .css("max-height", "80vh"); + } + if (focus === "name") { this.$inputName.trigger("focus").trigger("select"); } diff --git a/apps/client/src/widgets/basic_widget.ts b/apps/client/src/widgets/basic_widget.ts index 3c97889437..eb6b55b0d6 100644 --- a/apps/client/src/widgets/basic_widget.ts +++ b/apps/client/src/widgets/basic_widget.ts @@ -1,8 +1,9 @@ import { isValidElement, VNode } from "preact"; + import Component, { TypedComponent } from "../components/component.js"; import froca from "../services/froca.js"; import { t } from "../services/i18n.js"; -import toastService from "../services/toast.js"; +import toastService, { showErrorForScriptNote } from "../services/toast.js"; import { renderReactWidget } from "./react/react_utils.jsx"; export class TypedBasicWidget> extends TypedComponent { @@ -56,9 +57,8 @@ export class TypedBasicWidget> extends TypedCompon optChild(condition: boolean, ...components: (T | VNode)[]) { if (condition) { return this.child(...components); - } else { - return this; } + return this; } id(id: string) { @@ -172,16 +172,11 @@ export class TypedBasicWidget> extends TypedCompon const noteId = this._noteId; if (this._noteId) { froca.getNote(noteId, true).then((note) => { - toastService.showPersistent({ - id: `custom-widget-failure-${noteId}`, - title: t("toast.widget-error.title"), - icon: "bx bx-error-circle", - message: t("toast.widget-error.message-custom", { - id: noteId, - title: note?.title, - message: e.message || e.toString() - }) - }); + showErrorForScriptNote(noteId, t("toast.widget-error.message-custom", { + id: noteId, + title: note?.title, + message: e.message || e.toString() + })); }); } else { toastService.showPersistent({ @@ -213,7 +208,7 @@ export class TypedBasicWidget> extends TypedCompon toggleInt(show: boolean | null | undefined) { this.$widget.toggleClass("hidden-int", !show) - .toggleClass("visible", !!show); + .toggleClass("visible", !!show); } isHiddenInt() { @@ -222,7 +217,7 @@ export class TypedBasicWidget> extends TypedCompon toggleExt(show: boolean | null | "" | undefined) { this.$widget.toggleClass("hidden-ext", !show) - .toggleClass("visible", !!show); + .toggleClass("visible", !!show); } isHiddenExt() { @@ -250,9 +245,8 @@ export class TypedBasicWidget> extends TypedCompon getClosestNtxId() { if (this.$widget) { return this.$widget.closest("[data-ntx-id]").attr("data-ntx-id"); - } else { - return null; } + return null; } cleanup() {} diff --git a/apps/client/src/widgets/buttons/global_menu.tsx b/apps/client/src/widgets/buttons/global_menu.tsx index 12cd870eba..255cf89c9f 100644 --- a/apps/client/src/widgets/buttons/global_menu.tsx +++ b/apps/client/src/widgets/buttons/global_menu.tsx @@ -1,16 +1,19 @@ -import Dropdown from "../react/Dropdown"; import "./global_menu.css"; -import { useStaticTooltip, useStaticTooltipWithKeyboardShortcut, useTriliumOption, useTriliumOptionBool, useTriliumOptionInt } from "../react/hooks"; -import { useContext, useEffect, useRef, useState } from "preact/hooks"; -import { t } from "../../services/i18n"; -import { FormDropdownDivider, FormDropdownSubmenu, FormListHeader, FormListItem } from "../react/FormList"; -import { CommandNames } from "../../components/app_context"; -import KeyboardShortcut from "../react/KeyboardShortcut"; + import { KeyboardActionNames } from "@triliumnext/commons"; -import { ComponentChildren } from "preact"; +import { ComponentChildren, RefObject } from "preact"; +import { useContext, useEffect, useRef, useState } from "preact/hooks"; + +import { CommandNames } from "../../components/app_context"; import Component from "../../components/component"; +import { ExperimentalFeature, ExperimentalFeatureId, experimentalFeatures, isExperimentalFeatureEnabled, toggleExperimentalFeature } from "../../services/experimental_features"; +import { t } from "../../services/i18n"; +import utils, { dynamicRequire, isElectron, isMobile, reloadFrontendApp } from "../../services/utils"; +import Dropdown from "../react/Dropdown"; +import { FormDropdownDivider, FormDropdownSubmenu, FormListHeader, FormListItem } from "../react/FormList"; +import { useStaticTooltip, useStaticTooltipWithKeyboardShortcut, useTriliumOption, useTriliumOptionBool, useTriliumOptionInt } from "../react/hooks"; +import KeyboardShortcut from "../react/KeyboardShortcut"; import { ParentComponent } from "../react/react_utils"; -import utils, { dynamicRequire, isElectron, isMobile } from "../../services/utils"; interface MenuItemProps { icon: string, @@ -27,15 +30,17 @@ export default function GlobalMenu({ isHorizontalLayout }: { isHorizontalLayout: const parentComponent = useContext(ParentComponent); const { isUpdateAvailable, latestVersion } = useTriliumUpdateStatus(); const isMobileLocal = isMobile(); + const logoRef = useRef(null); + useStaticTooltip(logoRef); return ( - {isVerticalLayout && } + {isVerticalLayout && } {isUpdateAvailable && } } noDropdownListStyle @@ -54,7 +59,7 @@ export default function GlobalMenu({ isHorizontalLayout }: { isHorizontalLayout: - + @@ -65,18 +70,19 @@ export default function GlobalMenu({ isHorizontalLayout }: { isHorizontalLayout: {isUpdateAvailable && <> window.open("https://github.com/TriliumNext/Trilium/releases/latest")} - icon="bx bx-download" - text={t("global_menu.download-update", {latestVersion})} /> + icon="bx bx-download" + text={t("global_menu.download-update", {latestVersion})} /> } {!isElectron() && } + {glob.isDev && } - ) + ); } -function AdvancedMenu() { +function AdvancedMenu({ dropStart }: { dropStart: boolean }) { return ( - + @@ -89,7 +95,7 @@ function AdvancedMenu() { {isElectron() && } - ) + ); } function BrowserOnlyOptions() { @@ -99,14 +105,41 @@ function BrowserOnlyOptions() { ; } +function DevelopmentOptions({ dropStart }: { dropStart: boolean }) { + return <> + + Development Options + + {experimentalFeatures.map((feature) => ( + + ))} + + ; +} + +function ExperimentalFeatureToggle({ experimentalFeature }: { experimentalFeature: ExperimentalFeature }) { + const featureEnabled = isExperimentalFeatureEnabled(experimentalFeature.id as ExperimentalFeatureId); + + return ( + { + await toggleExperimentalFeature(experimentalFeature.id as ExperimentalFeatureId, !featureEnabled); + reloadFrontendApp(); + }} + >{experimentalFeature.name} + ); +} + function SwitchToOptions() { if (isElectron()) { return; } else if (!isMobile()) { - return - } else { - return + return ; } + return ; + } function MenuItem({ icon, text, title, command, disabled, active }: MenuItemProps void)>) { @@ -117,7 +150,7 @@ function MenuItem({ icon, text, title, command, disabled, active }: MenuItemProp onClick={typeof command === "function" ? command : undefined} disabled={disabled} active={active} - >{text} + >{text}; } function KeyboardActionMenuItem({ text, command, ...props }: MenuItemProps) { @@ -125,13 +158,10 @@ function KeyboardActionMenuItem({ text, command, ...props }: MenuItemProps{text} } - /> + />; } -function VerticalLayoutIcon() { - const logoRef = useRef(null); - useStaticTooltip(logoRef); - +export function VerticalLayoutIcon({ logoRef }: { logoRef?: RefObject }) { return ( @@ -148,7 +178,7 @@ function VerticalLayoutIcon() { - ) + ); } function ZoomControls({ parentComponent }: { parentComponent?: Component | null }) { @@ -172,7 +202,7 @@ function ZoomControls({ parentComponent }: { parentComponent?: Component | null }} className={`dropdown-item-button ${icon}`} >{children} - ) + ); } return isElectron() ? ( @@ -213,7 +243,7 @@ function ToggleWindowOnTop() { setIsAlwaysOnTop(newState); }} /> - ) + ); } function useTriliumUpdateStatus() { @@ -224,7 +254,7 @@ function useTriliumUpdateStatus() { async function updateVersionStatus() { const RELEASES_API_URL = "https://api.github.com/repos/TriliumNext/Trilium/releases/latest"; - let latestVersion: string | undefined = undefined; + let latestVersion: string | undefined; try { const resp = await fetch(RELEASES_API_URL); const data = await resp.json(); diff --git a/apps/client/src/widgets/buttons/right_pane_toggle.tsx b/apps/client/src/widgets/buttons/right_pane_toggle.tsx new file mode 100644 index 0000000000..53bf67ae20 --- /dev/null +++ b/apps/client/src/widgets/buttons/right_pane_toggle.tsx @@ -0,0 +1,21 @@ +import clsx from "clsx"; + +import { t } from "../../services/i18n"; +import ActionButton from "../react/ActionButton"; +import { useTriliumOptionBool } from "../react/hooks"; + +export default function RightPaneToggle() { + const [ rightPaneVisible, setRightPaneVisible ] = useTriliumOptionBool("rightPaneVisible"); + + return ( + setRightPaneVisible(!rightPaneVisible)} + /> + ); +} diff --git a/apps/client/src/widgets/collections/board/index.tsx b/apps/client/src/widgets/collections/board/index.tsx index a50213a317..39e715f97c 100644 --- a/apps/client/src/widgets/collections/board/index.tsx +++ b/apps/client/src/widgets/collections/board/index.tsx @@ -243,7 +243,7 @@ function AddNewColumn({ api, isInRelationMode }: { api: BoardApi, isInRelationMo export function TitleEditor({ currentValue, placeholder, save, dismiss, mode, isNewItem }: { currentValue?: string; placeholder?: string; - save: (newValue: string) => void; + save: (newValue: string) => void | Promise; dismiss: () => void; isNewItem?: boolean; mode?: "normal" | "multiline" | "relation"; diff --git a/apps/client/src/widgets/collections/presentation/index.css b/apps/client/src/widgets/collections/presentation/index.css index 5aafffd9f0..ac3d628c39 100644 --- a/apps/client/src/widgets/collections/presentation/index.css +++ b/apps/client/src/widgets/collections/presentation/index.css @@ -2,9 +2,13 @@ position: absolute; top: 1em; right: 1em; + + .floating-buttons-children { + top: 0; + } } .presentation-container { width: 100%; height: 100%; -} \ No newline at end of file +} diff --git a/apps/client/src/widgets/containers/content_header.css b/apps/client/src/widgets/containers/content_header.css new file mode 100644 index 0000000000..768f8afda3 --- /dev/null +++ b/apps/client/src/widgets/containers/content_header.css @@ -0,0 +1 @@ +/** Intentionally left empty for now **/ diff --git a/apps/client/src/widgets/containers/right_pane_container.ts b/apps/client/src/widgets/containers/right_pane_container.ts index 1c88f36959..5e267851d5 100644 --- a/apps/client/src/widgets/containers/right_pane_container.ts +++ b/apps/client/src/widgets/containers/right_pane_container.ts @@ -1,9 +1,9 @@ -import FlexContainer from "./flex_container.js"; -import splitService from "../../services/resizer.js"; -import type RightPanelWidget from "../right_panel_widget.js"; import type { EventData, EventNames } from "../../components/app_context.js"; +import splitService from "../../services/resizer.js"; +import type BasicWidget from "../basic_widget.js"; +import FlexContainer from "./flex_container.js"; -export default class RightPaneContainer extends FlexContainer { +export default class RightPaneContainer extends FlexContainer { private rightPaneHidden: boolean; private firstRender: boolean; diff --git a/apps/client/src/widgets/containers/root_container.ts b/apps/client/src/widgets/containers/root_container.ts index d2622e6e2f..03df4a8ec6 100644 --- a/apps/client/src/widgets/containers/root_container.ts +++ b/apps/client/src/widgets/containers/root_container.ts @@ -5,6 +5,7 @@ import FlexContainer from "./flex_container.js"; import options from "../../services/options.js"; import type BasicWidget from "../basic_widget.js"; import utils from "../../services/utils.js"; +import { getEnabledExperimentalFeatureIds } from "../../services/experimental_features.js"; /** * The root container is the top-most widget/container, from which the entire layout derives. @@ -37,6 +38,7 @@ export default class RootContainer extends FlexContainer { this.#setBackdropEffects(); this.#setThemeCapabilities(); this.#setLocaleAndDirection(options.get("locale")); + this.#setExperimentalFeatures(); return super.render(); } @@ -56,7 +58,7 @@ export default class RootContainer extends FlexContainer { if (loadResults.isOptionReloaded("maxContentWidth") || loadResults.isOptionReloaded("centerContent")) { - + this.#setMaxContentWidth(); } } @@ -99,6 +101,12 @@ export default class RootContainer extends FlexContainer { document.body.classList.toggle("theme-supports-background-effects", useBgfx); } + #setExperimentalFeatures() { + for (const featureId of getEnabledExperimentalFeatureIds()) { + document.body.classList.add(`experimental-feature-${featureId}`); + } + } + #setLocaleAndDirection(locale: string) { const correspondingLocale = LOCALES.find(l => l.id === locale); document.body.lang = locale; diff --git a/apps/client/src/widgets/containers/scrolling_container.css b/apps/client/src/widgets/containers/scrolling_container.css index 5bea624180..b9af1ccde7 100644 --- a/apps/client/src/widgets/containers/scrolling_container.css +++ b/apps/client/src/widgets/containers/scrolling_container.css @@ -4,6 +4,14 @@ position: relative; } -.note-split.type-code:not(.mime-text-x-sqlite) > .scrolling-container { - background-color: var(--code-background-color); -} \ No newline at end of file +.note-split.type-code:not(.mime-text-x-sqlite) { + &> .scrolling-container { + background-color: var(--code-background-color); + --scrollbar-background-color: var(--main-background-color); + } + + .inline-title, + .title-actions { + background-color: var(--main-background-color); + } +} diff --git a/apps/client/src/widgets/containers/scrolling_container.ts b/apps/client/src/widgets/containers/scrolling_container.ts index c6b67724f2..736bda8e03 100644 --- a/apps/client/src/widgets/containers/scrolling_container.ts +++ b/apps/client/src/widgets/containers/scrolling_container.ts @@ -49,7 +49,7 @@ export default class ScrollingContainer extends Container { } } - scrollContainerToCommand({ position }: CommandListenerData<"scrollContainerToCommand">) { + scrollContainerToCommand({ position }: CommandListenerData<"scrollContainerTo">) { this.$widget.scrollTop(position); } } diff --git a/apps/client/src/widgets/dialogs/PopupEditor.css b/apps/client/src/widgets/dialogs/PopupEditor.css index 41a1d87368..68172e6290 100644 --- a/apps/client/src/widgets/dialogs/PopupEditor.css +++ b/apps/client/src/widgets/dialogs/PopupEditor.css @@ -31,10 +31,12 @@ body.mobile .modal.popup-editor-dialog .modal-dialog { flex-grow: 1; display: flex; align-items: center; + margin-block: 0; } .modal.popup-editor-dialog .modal-header .note-title-widget { - margin-top: 8px; + display: flex; + align-items: center; } .modal.popup-editor-dialog .modal-body { @@ -42,19 +44,18 @@ body.mobile .modal.popup-editor-dialog .modal-dialog { height: 75vh; overflow: auto; display: flex; - flex-direction: column; + flex-direction: column; } .modal.popup-editor-dialog .title-row, .modal.popup-editor-dialog .modal-title, .modal.popup-editor-dialog .note-icon-widget { height: 32px; + min-height: unset; } -.modal.popup-editor-dialog .note-icon-widget { - width: 32px; - margin: 0; - padding: 0; +:root div.modal.popup-editor-dialog div.note-title-widget { + --note-title-padding-inline: 8px; } .modal.popup-editor-dialog .note-icon-widget button.note-icon, @@ -99,10 +100,10 @@ body.mobile .modal.popup-editor-dialog .modal-dialog { } .modal.popup-editor-dialog .note-detail-code-editor { - padding: 0; + padding: 0; & .cm-editor { margin: 0; border-radius: 0; } -} +} \ No newline at end of file diff --git a/apps/client/src/widgets/dialogs/PopupEditor.tsx b/apps/client/src/widgets/dialogs/PopupEditor.tsx index c85dcd3b37..887568d379 100644 --- a/apps/client/src/widgets/dialogs/PopupEditor.tsx +++ b/apps/client/src/widgets/dialogs/PopupEditor.tsx @@ -1,26 +1,32 @@ -import { useContext, useEffect, useMemo, useRef, useState } from "preact/hooks"; -import Modal from "../react/Modal"; import "./PopupEditor.css"; -import { useNoteContext, useNoteLabel, useTriliumEvent } from "../react/hooks"; -import NoteTitleWidget from "../note_title"; -import NoteIcon from "../note_icon"; -import NoteContext from "../../components/note_context"; -import { NoteContextContext, ParentComponent } from "../react/react_utils"; -import NoteDetail from "../NoteDetail"; + import { ComponentChildren } from "preact"; +import { useContext, useEffect, useMemo, useRef, useState } from "preact/hooks"; + +import appContext from "../../components/app_context"; +import NoteContext from "../../components/note_context"; +import froca from "../../services/froca"; +import { t } from "../../services/i18n"; +import tree from "../../services/tree"; +import utils from "../../services/utils"; import NoteList from "../collections/NoteList"; -import StandaloneRibbonAdapter from "../ribbon/components/StandaloneRibbonAdapter"; -import FormattingToolbar from "../ribbon/FormattingToolbar"; -import PromotedAttributes from "../PromotedAttributes"; import FloatingButtons from "../FloatingButtons"; import { DESKTOP_FLOATING_BUTTONS, MOBILE_FLOATING_BUTTONS, POPUP_HIDDEN_FLOATING_BUTTONS } from "../FloatingButtonsDefinitions"; -import utils from "../../services/utils"; -import tree from "../../services/tree"; -import froca from "../../services/froca"; +import NoteIcon from "../note_icon"; +import NoteTitleWidget from "../note_title"; +import NoteDetail from "../NoteDetail"; +import PromotedAttributes from "../PromotedAttributes"; +import { useNoteContext, useNoteLabel, useTriliumEvent } from "../react/hooks"; +import Modal from "../react/Modal"; +import { NoteContextContext, ParentComponent } from "../react/react_utils"; import ReadOnlyNoteInfoBar from "../ReadOnlyNoteInfoBar"; +import StandaloneRibbonAdapter from "../ribbon/components/StandaloneRibbonAdapter"; +import FormattingToolbar from "../ribbon/FormattingToolbar"; import MobileEditorToolbar from "../type_widgets/text/mobile_editor_toolbar"; -import { t } from "../../services/i18n"; -import appContext from "../../components/app_context"; +import NoteBadges from "../layout/NoteBadges"; +import { isExperimentalFeatureEnabled } from "../../services/experimental_features"; + +const isNewLayout = isExperimentalFeatureEnabled("new-layout"); export default function PopupEditor() { const [ shown, setShown ] = useState(false); @@ -61,7 +67,10 @@ export default function PopupEditor() { } + title={<> + + {isNewLayout && } + } customTitleBarButtons={[{ iconClassName: "bx-expand-alt", title: t("popup-editor.maximize"), @@ -75,19 +84,17 @@ export default function PopupEditor() { className="popup-editor-dialog" size="lg" show={shown} - onShown={() => { - parentComponent?.handleEvent("focusOnDetail", { ntxId: noteContext.ntxId }); - }} + onShown={() => parentComponent?.handleEvent("focusOnDetail", { ntxId: noteContext.ntxId })} onHidden={() => setShown(false)} keepInDom // needed for faster loading noFocus // automatic focus breaks block popup > - + {!isNewLayout && } {isMobile - ? - : } + ? + : } @@ -95,7 +102,7 @@ export default function PopupEditor() { - ) + ); } export function DialogWrapper({ children }: { children: ComponentChildren }) { @@ -107,7 +114,7 @@ export function DialogWrapper({ children }: { children: ComponentChildren }) {
    {children}
    - ) + ); } export function TitleRow() { @@ -116,5 +123,5 @@ export function TitleRow() {
    - ) + ); } diff --git a/apps/client/src/widgets/dialogs/call_to_action.tsx b/apps/client/src/widgets/dialogs/call_to_action.tsx index 1ae4a14ebb..4f6da5293c 100644 --- a/apps/client/src/widgets/dialogs/call_to_action.tsx +++ b/apps/client/src/widgets/dialogs/call_to_action.tsx @@ -1,11 +1,12 @@ import { useMemo, useState } from "preact/hooks"; + +import { t } from "../../services/i18n"; import Button from "../react/Button"; import Modal from "../react/Modal"; import { dismissCallToAction, getCallToActions } from "./call_to_action_definitions"; -import { t } from "../../services/i18n"; export default function CallToActionDialog() { - const activeCallToActions = useMemo(() => getCallToActions(), []); + const activeCallToActions = useMemo(() => getCallToActions(), []); const [ activeIndex, setActiveIndex ] = useState(0); const [ shown, setShown ] = useState(true); const activeItem = activeCallToActions[activeIndex]; @@ -36,11 +37,11 @@ export default function CallToActionDialog() { await dismissCallToAction(activeItem.id); await button.onClick(); goToNext(); - }}/> + }}/> )} } > -

    {activeItem.message}

    +

    {activeItem.message}

    - ) + ); } diff --git a/apps/client/src/widgets/dialogs/call_to_action_definitions.ts b/apps/client/src/widgets/dialogs/call_to_action_definitions.ts index 31982689e4..d783b1dbba 100644 --- a/apps/client/src/widgets/dialogs/call_to_action_definitions.ts +++ b/apps/client/src/widgets/dialogs/call_to_action_definitions.ts @@ -1,6 +1,7 @@ -import utils from "../../services/utils"; -import options from "../../services/options"; +import appContext from "../../components/app_context"; import { t } from "../../services/i18n"; +import options from "../../services/options"; +import utils from "../../services/utils"; /** * A "call-to-action" is an interactive message for the user, generally to present new features. @@ -46,18 +47,15 @@ function isNextTheme() { const CALL_TO_ACTIONS: CallToAction[] = [ { - id: "next_theme", - title: t("call_to_action.next_theme_title"), - message: t("call_to_action.next_theme_message"), - enabled: () => !isNextTheme(), + id: "new_layout", + title: t("call_to_action.new_layout_title"), + message: t("call_to_action.new_layout_message"), + enabled: () => true, buttons: [ { - text: t("call_to_action.next_theme_button"), - async onClick() { - await options.save("theme", "next"); - await options.save("backgroundEffects", "true"); - utils.reloadFrontendApp("call-to-action"); - } + + text: t("call_to_action.new_layout_button"), + onClick: () => appContext.tabManager.openInNewTab("_help_IjZS7iK5EXtb", "_help", true) } ] }, @@ -75,6 +73,22 @@ const CALL_TO_ACTIONS: CallToAction[] = [ } } ] + }, + { + id: "next_theme", + title: t("call_to_action.next_theme_title"), + message: t("call_to_action.next_theme_message"), + enabled: () => !isNextTheme(), + buttons: [ + { + text: t("call_to_action.next_theme_button"), + async onClick() { + await options.save("theme", "next"); + await options.save("backgroundEffects", "true"); + utils.reloadFrontendApp("call-to-action"); + } + } + ] } ]; diff --git a/apps/client/src/widgets/dialogs/note_type_chooser.tsx b/apps/client/src/widgets/dialogs/note_type_chooser.tsx index 7db061c1a7..efb44f48c9 100644 --- a/apps/client/src/widgets/dialogs/note_type_chooser.tsx +++ b/apps/client/src/widgets/dialogs/note_type_chooser.tsx @@ -8,7 +8,7 @@ import note_types from "../../services/note_types"; import { MenuCommandItem, MenuItem } from "../../menus/context_menu"; import { TreeCommandNames } from "../../menus/tree_context_menu"; import { Suggestion } from "../../services/note_autocomplete"; -import Badge from "../react/Badge"; +import SimpleBadge from "../react/Badge"; import { useTriliumEvent } from "../react/hooks"; export interface ChooseNoteTypeResponse { @@ -108,7 +108,7 @@ export default function NoteTypeChooserDialogComponent() { value={[ item.type, item.templateNoteId ].join(",") } icon={item.uiIcon}> {item.title} - {item.badges && item.badges.map((badge) => )} + {item.badges && item.badges.map((badge) => )} ; } })} diff --git a/apps/client/src/widgets/highlights_list.ts b/apps/client/src/widgets/highlights_list.ts index 5023facb90..b6e3f2e6f0 100644 --- a/apps/client/src/widgets/highlights_list.ts +++ b/apps/client/src/widgets/highlights_list.ts @@ -5,14 +5,14 @@ * - For example, if there is a formula in the middle of the highlighted text, the two ends of the formula will be regarded as two entries */ -import { t } from "../services/i18n.js"; -import attributeService from "../services/attributes.js"; -import RightPanelWidget from "./right_panel_widget.js"; -import options from "../services/options.js"; -import OnClickButtonWidget from "./buttons/onclick_button.js"; import appContext, { type EventData } from "../components/app_context.js"; import type FNote from "../entities/fnote.js"; +import attributeService from "../services/attributes.js"; +import { t } from "../services/i18n.js"; import katex from "../services/math.js"; +import options from "../services/options.js"; +import OnClickButtonWidget from "./buttons/onclick_button.js"; +import RightPanelWidget from "./right_panel_widget.js"; const TPL = /*html*/`