Compare commits

..

40 Commits

Author SHA1 Message Date
Jin
64f191b83b Merge branch 'main' into feat/clean-share-url 2025-10-07 23:39:38 +01:00
JYC333
979fbe2e76 Merge branch 'main' into feat/clean-share-url 2025-08-13 18:28:27 +02:00
Jin
ea5564c6e6 docs: ✏️ update docs 2025-06-26 23:48:05 +02:00
Jin
6ab8750726 feat: 🎸 update translation 2025-06-26 23:15:23 +02:00
Jin
923eabd750 feat: 🎸 Allow multi-segement path 2025-06-26 23:08:54 +02:00
Jin
c52d6a6384 Merge branch 'main' into feat/clean-share-url 2025-06-26 22:53:35 +02:00
Jin
519b9648c6 test: 💍 Fix test for path input 2025-06-26 22:30:24 +02:00
Jin
b25fd6ca3a feat: 🎸 update custom share path without restart server 2025-06-26 22:30:24 +02:00
Panagiotis Papadopoulos
2bd8c215ff Merge branch 'develop' into feat/clean-share-url 2025-05-12 20:38:28 +02:00
Panagiotis Papadopoulos
34e7901de9 refactor: remove "cleanUrl" related string for now
that should be part of a later PR
2025-04-25 09:12:29 +02:00
Panagiotis Papadopoulos
30a191cedf fix(share_settings): disallow "/" as share root for now as it is not working
this will be handled by cleanUrl PR later on
2025-04-25 08:53:13 +02:00
Panagiotis Papadopoulos
128d8907c3 chore(share_settings): add a TODO hint for currently active bug 2025-04-25 08:48:28 +02:00
Panagiotis Papadopoulos
3b1d7d045e feat: improve example and wording for share_path_description
needs to currently mention, that a server restart is required
2025-04-25 08:40:43 +02:00
Panagiotis Papadopoulos
0ae9a29e0d refactor: remove "cleanUrl" related code for now
that should be part of a later PR
2025-04-25 08:38:48 +02:00
Panagiotis Papadopoulos
f4b5ed73ad refactor(options_init): remove sharePath normalization
normalization is happening in the share settings options widget in the meantime, making it more obvious to the user
2025-04-25 08:31:27 +02:00
Panagiotis Papadopoulos
43166dbeb5 refactor: remove "cleanUrl" related code for now
that should be part of a later PR
2025-04-25 08:27:01 +02:00
Panagiotis Papadopoulos
00b5aef890 feat(share_settings): add support for adding "/" as sharePath 2025-04-21 10:45:41 +02:00
Panagiotis Papadopoulos
1b7266f083 chore(share_settings): remove unnecessary comment 2025-04-21 10:25:09 +02:00
Panagiotis Papadopoulos
d1d4b47111 test(share_settings): add initial test for normalizeSharePathInput
it currently fails trying to import the class though
a "manual" importing of the function did pass all checks though

-> will need to investigate why importing the class does not work like that
2025-04-21 09:15:48 +02:00
Panagiotis Papadopoulos
c90364bd76 feat(share_settings): improve sharePath input handling
* add normalization helper to ensure string does not start with multiple trailing slashes or ends with a trailing slash
* fall back to default "/share" when empty string is entered
2025-04-21 09:10:21 +02:00
Panagiotis Papadopoulos
6dc687ef43 feat(share_settings): improve checkShareRoot
* add rudimental error handling
* add handling of special case, where one has multiple shared notes with a #shareRoot label
* refactor styling into auxiliary setCheckShareRootStyle function
2025-04-21 07:54:24 +02:00
Panagiotis Papadopoulos
0e31aab1ab refactor(share_settings): use this.$shareRootCheck instead of creating new local $button variable 2025-04-20 19:24:58 +02:00
Panagiotis Papadopoulos
b0030f89b7 feat(share_settings): group options that belong together logically 2025-04-20 19:21:38 +02:00
Panagiotis Papadopoulos
9f0a0238cc fix(share_settings): stop runnning checkShareRoot on init and on redirectBareDomain change
→ that is what the shareRootCheck button is there for
2025-04-20 19:19:30 +02:00
Panagiotis Papadopoulos
dabdfaddec fix(share/routes): remove unnecessary redirects that cause loops 2025-04-20 10:40:20 +02:00
Panagiotis Papadopoulos
a8901e6dc8 chore: revert back unnecessary changes from unclean merge
c9d151289c
2025-04-18 11:53:56 +02:00
Panagiotis Papadopoulos
ab901a5d32 refactor(share_settings): get rid of save() method
there's no need to execute PUT requests for *all* Share Settings, when any option changes

moved the code to inside the "change" event handlers
2025-04-18 02:05:40 +02:00
Panagiotis Papadopoulos
56fc2d9b30 fix(share_settings): fix not being able to set share path
caused by having other several save operation inside the save() method (which doesn't even make sense to begin with, as far as I can tell)

moving it to inside the "change" event handler allows us to set and store a custom share path again
2025-04-18 02:00:23 +02:00
Panagiotis Papadopoulos
df45fa2e1e fix(share/routes): fix redirect loop
commented out for now, to make sure we get back to it – not sure if it was suppossed to have any special other reason to exist
2025-04-18 01:49:34 +02:00
Panagiotis Papadopoulos
9a11fc13d7 fix(share_settings): fix missing class in redirect-bare-domain input 2025-04-18 01:07:54 +02:00
Panagiotis Papadopoulos
d72a0d3c69 fix(services/auth): fix crash on clean DB startup when options are not set 2025-04-18 00:15:25 +02:00
Panagiotis Papadopoulos
0be508ed70 fix(share/routes): fix crash on clean DB startup when sharePath option is not set 2025-04-18 00:10:29 +02:00
Panagiotis Papadopoulos
37f3a9b19d Merge branch 'develop' into feat/clean-share-url 2025-04-17 23:43:18 +02:00
Jin
81d2fbc057 fix: 🐛 add back missing translation 2025-04-11 17:54:54 +02:00
Jin
1aecf66cbe Merge branch 'develop' into feat/clean-share-url 2025-04-10 21:47:44 +02:00
Jin
fbe7d64e00 Merge branch 'develop' into feat/clean-share-url 2025-04-04 19:06:10 +02:00
matt wilkie
c9d151289c conflicts fixed - Merge remote-tracking branch 'origin/develop'
1st time using Meld. I'm not sure if the conflict resolve is clean
2025-03-08 09:49:06 -07:00
matt wilkie
bba2f6db64 wip: another attempt (and use translation syntax this time) 2025-03-08 09:35:52 -07:00
matt wilkie
6725f81a00 WIP: options page works, but routing broken when logged out 2025-02-26 03:10:55 -07:00
matt wilkie
8487c8cd03 WIP: allow no share path url prefix at all (not working yet) 2025-02-25 14:51:29 -07:00
383 changed files with 19275 additions and 30572 deletions

View File

@@ -10,7 +10,7 @@ runs:
steps:
- uses: pnpm/action-setup@v4
- name: Set up node & dependencies
uses: actions/setup-node@v6
uses: actions/setup-node@v5
with:
node-version: 22
cache: "pnpm"

View File

@@ -67,7 +67,7 @@ jobs:
# Initializes the CodeQL tools for scanning.
- name: Initialize CodeQL
uses: github/codeql-action/init@v4
uses: github/codeql-action/init@v3
with:
languages: ${{ matrix.language }}
build-mode: ${{ matrix.build-mode }}
@@ -95,6 +95,6 @@ jobs:
exit 1
- name: Perform CodeQL Analysis
uses: github/codeql-action/analyze@v4
uses: github/codeql-action/analyze@v3
with:
category: "/language:${{matrix.language}}"

View File

@@ -55,7 +55,7 @@ jobs:
- name: Setup Python
uses: actions/setup-python@v6
with:
python-version: '3.14'
python-version: '3.13'
cache: 'pip'
cache-dependency-path: 'requirements-docs.txt'
@@ -72,7 +72,7 @@ jobs:
# Setup Node.js with pnpm
- name: Setup Node.js
uses: actions/setup-node@v6
uses: actions/setup-node@v5
with:
node-version: '22'
cache: 'pnpm'
@@ -118,7 +118,6 @@ jobs:
- name: Deploy
uses: ./.github/actions/deploy-to-cloudflare-pages
if: github.repository == ${{ vars.REPO_MAIN }}
with:
project_name: "trilium-docs"
comment_body: "📚 Documentation preview is ready"

View File

@@ -28,7 +28,7 @@ jobs:
- uses: pnpm/action-setup@v4
- name: Set up node & dependencies
uses: actions/setup-node@v6
uses: actions/setup-node@v5
with:
node-version: 22
cache: "pnpm"

View File

@@ -44,7 +44,7 @@ jobs:
- uses: pnpm/action-setup@v4
- name: Set up node & dependencies
uses: actions/setup-node@v6
uses: actions/setup-node@v5
with:
node-version: 22
cache: "pnpm"
@@ -144,7 +144,7 @@ jobs:
uses: actions/checkout@v5
- uses: pnpm/action-setup@v4
- name: Set up node & dependencies
uses: actions/setup-node@v6
uses: actions/setup-node@v5
with:
node-version: 22
cache: 'pnpm'

View File

@@ -50,7 +50,7 @@ jobs:
- uses: actions/checkout@v5
- uses: pnpm/action-setup@v4
- name: Set up node & dependencies
uses: actions/setup-node@v6
uses: actions/setup-node@v5
with:
node-version: 22
cache: 'pnpm'
@@ -77,7 +77,7 @@ jobs:
GPG_SIGNING_KEY: ${{ secrets.GPG_SIGN_KEY }}
- name: Publish release
uses: softprops/action-gh-release@v2.4.1
uses: softprops/action-gh-release@v2.3.4
if: ${{ github.event_name != 'pull_request' }}
with:
make_latest: false
@@ -118,7 +118,7 @@ jobs:
arch: ${{ matrix.arch }}
- name: Publish release
uses: softprops/action-gh-release@v2.4.1
uses: softprops/action-gh-release@v2.3.4
if: ${{ github.event_name != 'pull_request' }}
with:
make_latest: false

View File

@@ -22,7 +22,7 @@ jobs:
fetch-depth: 0
- uses: pnpm/action-setup@v4
- uses: actions/setup-node@v6
- uses: actions/setup-node@v5
with:
node-version: 22
cache: 'pnpm'

View File

@@ -48,7 +48,7 @@ jobs:
- uses: actions/checkout@v5
- uses: pnpm/action-setup@v4
- name: Set up node & dependencies
uses: actions/setup-node@v6
uses: actions/setup-node@v5
with:
node-version: 22
cache: 'pnpm'
@@ -127,7 +127,7 @@ jobs:
path: upload
- name: Publish stable release
uses: softprops/action-gh-release@v2.4.1
uses: softprops/action-gh-release@v2.3.4
with:
draft: false
body_path: docs/Release Notes/Release Notes/${{ github.ref_name }}.md

View File

@@ -11,9 +11,6 @@ on:
paths:
- "apps/website/**"
release:
types: [ released ]
jobs:
build-and-deploy:
runs-on: ubuntu-latest
@@ -28,7 +25,7 @@ jobs:
- uses: actions/checkout@v5
- uses: pnpm/action-setup@v4
- name: Set up node & dependencies
uses: actions/setup-node@v6
uses: actions/setup-node@v5
with:
node-version: 22
cache: "pnpm"

View File

@@ -14,7 +14,6 @@ usageMatchRegex:
# the `{key}` will be placed by a proper keypath matching regex,
# you can ignore it and use your own matching rules as well
- "[^\\w\\d]t\\(['\"`]({key})['\"`]"
- <Trans\s*i18nKey="({key})"[^>]*>
# A RegEx to set a custom scope range. This scope will be used as a prefix when detecting keys
# and works like how the i18next framework identifies the namespace scope from the

View File

@@ -5,8 +5,7 @@
"i18n-ally.keystyle": "nested",
"i18n-ally.localesPaths": [
"apps/server/src/assets/translations",
"apps/client/src/translations",
"apps/website/public/translations"
"apps/client/src/translations"
],
"npm.exclude": [
"**/dist",

View File

@@ -1,14 +1,3 @@
<div align="center">
<sup>Special thanks to:</sup><br />
<a href="https://go.warp.dev/Trilium" target="_blank">
<img alt="Warp sponsorship" width="400" src="https://github.com/warpdotdev/brand-assets/blob/main/Github/Sponsor/Warp-Github-LG-03.png"><br />
Warp, built for coding with multiple AI agents<br />
</a>
<sup>Available for macOS, Linux and Windows</sup>
</div>
<hr />
# Trilium Notes
![GitHub Sponsors](https://img.shields.io/github/sponsors/eliandoran) ![LiberaPay patrons](https://img.shields.io/liberapay/patrons/ElianDoran)
@@ -24,10 +13,6 @@ See [screenshots](https://triliumnext.github.io/Docs/Wiki/screenshot-tour) for q
<a href="https://triliumnext.github.io/Docs/Wiki/screenshot-tour"><img src="./docs/app.png" alt="Trilium Screenshot" width="1000"></a>
## ⏬ Download
- [Latest release](https://github.com/TriliumNext/Trilium/releases/latest) stable version, recommended for most users.
- [Nightly build](https://github.com/TriliumNext/Trilium/releases/tag/nightly) unstable development version, updated daily with the latest features and fixes.
## 📚 Documentation
**Visit our comprehensive documentation at [docs.triliumnotes.org](https://docs.triliumnotes.org/)**
@@ -182,7 +167,7 @@ Please view the [documentation guide](https://github.com/TriliumNext/Trilium/blo
## 👏 Shoutouts
* [zadam](https://github.com/zadam) for the original concept and implementation of the application.
* [Sarah Hussein](https://github.com/Sarah-Hussein) for designing the application icon.
* [Larsa](https://github.com/LarsaSara) for designing the application icon.
* [nriver](https://github.com/nriver) for his work on internationalization.
* [Thomas Frei](https://github.com/thfrei) for his original work on the Canvas.
* [antoniotejada](https://github.com/nriver) for the original syntax highlight widget.

View File

@@ -35,22 +35,22 @@
"chore:generate-openapi": "tsx bin/generate-openapi.js"
},
"devDependencies": {
"@playwright/test": "1.56.1",
"@stylistic/eslint-plugin": "5.5.0",
"@playwright/test": "1.56.0",
"@stylistic/eslint-plugin": "5.4.0",
"@types/express": "5.0.3",
"@types/node": "22.18.11",
"@types/node": "22.18.8",
"@types/yargs": "17.0.33",
"@vitest/coverage-v8": "3.2.4",
"eslint": "9.38.0",
"eslint": "9.37.0",
"eslint-plugin-simple-import-sort": "12.1.1",
"esm": "3.2.25",
"jsdoc": "4.0.5",
"jsdoc": "4.0.4",
"lorem-ipsum": "2.0.8",
"rcedit": "4.0.1",
"rimraf": "6.0.1",
"tslib": "2.8.1",
"typedoc": "0.28.14",
"typedoc-plugin-missing-exports": "4.1.2"
"typedoc": "0.28.13",
"typedoc-plugin-missing-exports": "4.1.0"
},
"optionalDependencies": {
"appdmg": "0.6.6"

View File

@@ -1,3 +1,4 @@
import type child_process from "child_process";
import { describe, beforeAll, afterAll } from "vitest";
let etapiAuthToken: string | undefined;
@@ -11,6 +12,8 @@ type SpecDefinitionsFunc = () => void;
function describeEtapi(description: string, specDefinitions: SpecDefinitionsFunc): void {
describe(description, () => {
let appProcess: ReturnType<typeof child_process.spawn>;
beforeAll(async () => {});
afterAll(() => {});

View File

@@ -1,6 +1,6 @@
{
"name": "@triliumnext/client",
"version": "0.99.2",
"version": "0.99.1",
"description": "JQuery-based client for TriliumNext, used for both web and desktop (via Electron)",
"private": true,
"license": "AGPL-3.0-only",
@@ -15,7 +15,7 @@
"circular-deps": "dpdm -T src/**/*.ts --tree=false --warning=false --skip-dynamic-imports=circular"
},
"dependencies": {
"@eslint/js": "9.38.0",
"@eslint/js": "9.37.0",
"@excalidraw/excalidraw": "0.18.0",
"@fullcalendar/core": "6.1.19",
"@fullcalendar/daygrid": "6.1.19",
@@ -35,31 +35,29 @@
"autocomplete.js": "0.38.1",
"bootstrap": "5.3.8",
"boxicons": "2.1.4",
"color": "5.0.2",
"dayjs": "1.11.18",
"dayjs-plugin-utc": "0.1.2",
"debounce": "2.2.0",
"draggabilly": "3.0.0",
"force-graph": "1.51.0",
"globals": "16.4.0",
"i18next": "25.6.0",
"i18next": "25.5.3",
"i18next-http-backend": "3.0.2",
"jquery": "3.7.1",
"jquery.fancytree": "2.38.5",
"jsplumb": "2.15.6",
"katex": "0.16.25",
"katex": "0.16.23",
"knockout": "3.5.1",
"leaflet": "1.9.4",
"leaflet-gpx": "2.2.0",
"mark.js": "8.11.1",
"marked": "16.4.1",
"marked": "16.3.0",
"mermaid": "11.12.0",
"mind-elixir": "5.3.3",
"mind-elixir": "5.1.1",
"normalize.css": "8.0.1",
"panzoom": "9.4.3",
"preact": "10.27.2",
"react-i18next": "16.1.0",
"reveal.js": "5.2.1",
"react-i18next": "16.0.0",
"split.js": "1.6.5",
"svg-pan-zoom": "3.6.2",
"tabulator-tables": "6.3.1",
@@ -70,14 +68,13 @@
"@preact/preset-vite": "2.10.2",
"@types/bootstrap": "5.2.10",
"@types/jquery": "3.5.33",
"@types/leaflet": "1.9.21",
"@types/leaflet": "1.9.20",
"@types/leaflet-gpx": "1.3.8",
"@types/mark.js": "8.11.12",
"@types/reveal.js": "5.2.1",
"@types/tabulator-tables": "6.2.11",
"copy-webpack-plugin": "13.0.1",
"happy-dom": "20.0.7",
"happy-dom": "19.0.2",
"script-loader": "0.7.2",
"vite-plugin-static-copy": "3.1.4"
"vite-plugin-static-copy": "3.1.3"
}
}

View File

@@ -326,11 +326,9 @@ class NoteContext extends Component implements EventListener<"entitiesReloaded">
}
// Collections must always display a note list, even if no children.
if (note.type === "book") {
const viewType = note.getLabelValue("viewType") ?? "grid";
if (!["list", "grid"].includes(viewType)) {
return true;
}
const viewType = note.getLabelValue("viewType") ?? "grid";
if (!["list", "grid"].includes(viewType)) {
return true;
}
if (!note.hasChildren()) {
@@ -440,22 +438,4 @@ class NoteContext extends Component implements EventListener<"entitiesReloaded">
}
}
export function openInCurrentNoteContext(evt: MouseEvent | JQuery.ClickEvent | JQuery.MouseDownEvent | React.PointerEvent<HTMLCanvasElement> | null, notePath: string, viewScope?: ViewScope) {
const ntxId = $(evt?.target as Element)
.closest("[data-ntx-id]")
.attr("data-ntx-id");
const noteContext = ntxId ? appContext.tabManager.getNoteContextById(ntxId) : appContext.tabManager.getActiveContext();
if (noteContext) {
noteContext.setNote(notePath, { viewScope }).then(() => {
if (noteContext !== appContext.tabManager.getActiveContext()) {
appContext.tabManager.activateNoteContext(noteContext.ntxId);
}
});
} else {
appContext.tabManager.openContextWithNote(notePath, { viewScope, activate: true });
}
}
export default NoteContext;

View File

@@ -10,6 +10,7 @@ import { t } from "./services/i18n.js";
import options from "./services/options.js";
import type ElectronRemote from "@electron/remote";
import type Electron from "electron";
import "bootstrap/dist/css/bootstrap.min.css";
import "boxicons/css/boxicons.min.css";
import "autocomplete.js/index_jquery.js";

View File

@@ -1,5 +1,6 @@
import server from "../services/server.js";
import noteAttributeCache from "../services/note_attribute_cache.js";
import ws from "../services/ws.js";
import protectedSessionHolder from "../services/protected_session_holder.js";
import cssClassManager from "../services/css_class_manager.js";
import type { Froca } from "../services/froca-interface.js";
@@ -585,7 +586,7 @@ export default class FNote {
let childBranches = this.getChildBranches();
if (!childBranches) {
console.error(`No children for '${this.noteId}'. This shouldn't happen.`);
ws.logError(`No children for '${this.noteId}'. This shouldn't happen.`);
return [];
}

View File

@@ -138,7 +138,7 @@ export default class DesktopLayout {
.child(new PromotedAttributesWidget())
.child(<SqlTableSchemas />)
.child(new NoteDetailWidget())
.child(<NoteList media="screen" />)
.child(<NoteList />)
.child(<SearchResult />)
.child(<SqlResults />)
.child(<ScrollPadding />)

View File

@@ -66,6 +66,6 @@ export function applyModals(rootContainer: RootContainer) {
.child(<PopupEditorFormattingToolbar />)
.child(new PromotedAttributesWidget())
.child(new NoteDetailWidget())
.child(<NoteList media="screen" displayOnlyCollections />))
.child(<NoteList displayOnlyCollections />))
.child(<CallToActionDialog />);
}

View File

@@ -40,8 +40,8 @@ kbd {
border: none;
cursor: pointer;
font-size: 1.25em;
padding-inline-start: 0.5em;
padding-inline-end: 0.5em;
padding-left: 0.5em;
padding-right: 0.5em;
color: var(--main-text-color);
}
.quick-search {
@@ -59,7 +59,7 @@ const FANCYTREE_CSS = `
margin-top: 0px;
overflow-y: auto;
contain: content;
padding-inline-start: 10px;
padding-left: 10px;
}
.fancytree-custom-icon {
@@ -68,7 +68,7 @@ const FANCYTREE_CSS = `
.fancytree-title {
font-size: 1.5em;
margin-inline-start: 0.6em !important;
margin-left: 0.6em !important;
}
.fancytree-node {
@@ -81,7 +81,7 @@ const FANCYTREE_CSS = `
span.fancytree-expander {
width: 24px !important;
margin-inline-end: 5px;
margin-right: 5px;
}
.fancytree-loading span.fancytree-expander {
@@ -101,7 +101,7 @@ span.fancytree-expander {
.tree-wrapper .scroll-to-active-note-button,
.tree-wrapper .tree-settings-button {
position: fixed;
margin-inline-end: 16px;
margin-right: 16px;
display: none;
}
@@ -126,8 +126,8 @@ export default class MobileLayout {
.class("d-md-flex d-lg-flex d-xl-flex col-12 col-sm-5 col-md-4 col-lg-3 col-xl-3")
.id("mobile-sidebar-wrapper")
.css("max-height", "100%")
.css("padding-inline-start", "0")
.css("padding-inline-end", "0")
.css("padding-left", "0")
.css("padding-right", "0")
.css("contain", "content")
.child(new FlexContainer("column").filling().id("mobile-sidebar-wrapper").child(new QuickSearchWidget()).child(new NoteTreeWidget().cssBlock(FANCYTREE_CSS)))
)
@@ -154,7 +154,7 @@ export default class MobileLayout {
.filling()
.contentSized()
.child(new NoteDetailWidget())
.child(<NoteList media="screen" />)
.child(<NoteList />)
.child(<FilePropertiesWrapper />)
)
.child(<MobileEditorToolbar />)

View File

@@ -1,3 +1,5 @@
import "bootstrap/dist/css/bootstrap.min.css";
// @ts-ignore - module = undefined
// Required for correct loading of scripts in Electron
if (typeof module === 'object') {window.module = module; module = undefined;}

View File

@@ -150,8 +150,8 @@ class ContextMenu {
this.$widget
.css({
display: "block",
top,
left
top: top,
left: left
})
.addClass("show");
}
@@ -187,7 +187,7 @@ class ContextMenu {
}
// Create a new group to avoid column breaks before and after the seaparator / header.
// This is a workaround for Firefox not supporting break-before / break-after: avoid
// This is a workaround for Firefox not supporting break-before / break-after: avoid
// for columns.
if (shouldStartNewGroup) {
$group = $("<div class='dropdown-no-break'>");
@@ -313,7 +313,7 @@ class ContextMenu {
}
$group.append($item);
// After adding a menu item, if the previous item was a separator or header,
// reset the group so that the next item will be appended directly to the parent.
if (shouldResetGroup) {

View File

@@ -1,6 +1,7 @@
import appContext from "./components/app_context.js";
import noteAutocompleteService from "./services/note_autocomplete.js";
import glob from "./services/glob.js";
import "bootstrap/dist/css/bootstrap.min.css";
import "boxicons/css/boxicons.min.css";
import "autocomplete.js/index_jquery.js";

View File

@@ -1,155 +0,0 @@
:root {
--print-font-size: 11pt;
--ck-content-color-image-caption-background: transparent !important;
}
html,
body {
width: 100%;
height: 100%;
color: black;
}
@page {
margin: 2cm;
}
.note-list-widget.full-height,
.note-list-widget.full-height .note-list-widget-content {
height: unset !important;
}
.component {
contain: none !important;
}
body[data-note-type="text"] .ck-content {
font-size: var(--print-font-size);
text-align: justify;
}
.ck-content figcaption {
font-style: italic;
}
.ck-content a {
text-decoration: none;
}
.ck-content a:not([href^="#root/"]) {
text-decoration: underline;
color: #374a75;
}
.ck-content .todo-list__label * {
-webkit-print-color-adjust: exact;
print-color-adjust: exact;
}
@supports selector(.todo-list__label__description:has(*)) and (height: 1lh) {
.ck-content .todo-list__label__description {
/* The percentage of the line height that the check box occupies */
--box-ratio: 0.75;
/* The size of the gap between the check box and the caption */
--box-text-gap: 0.25em;
--box-size: calc(1lh * var(--box-ratio));
--box-vert-offset: calc((1lh - var(--box-size)) / 2);
display: inline-block;
padding-inline-start: calc(var(--box-size) + var(--box-text-gap));
/* Source: https://pictogrammers.com/library/mdi/icon/checkbox-blank-outline/ */
background-image: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='currentColor'%3e%3cpath d='M19%2c3H5C3.89%2c3 3%2c3.89 3%2c5V19A2%2c2 0 0%2c0 5%2c21H19A2%2c2 0 0%2c0 21%2c19V5C21%2c3.89 20.1%2c3 19%2c3M19%2c5V19H5V5H19Z' /%3e%3c/svg%3e");
background-position: 0 var(--box-vert-offset);
background-size: var(--box-size);
background-repeat: no-repeat;
}
.ck-content .todo-list__label:has(input[type="checkbox"]:checked) .todo-list__label__description {
/* Source: https://pictogrammers.com/library/mdi/icon/checkbox-outline/ */
background-image: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='currentColor'%3e%3cpath d='M19%2c3H5A2%2c2 0 0%2c0 3%2c5V19A2%2c2 0 0%2c0 5%2c21H19A2%2c2 0 0%2c0 21%2c19V5A2%2c2 0 0%2c0 19%2c3M19%2c5V19H5V5H19M10%2c17L6%2c13L7.41%2c11.58L10%2c14.17L16.59%2c7.58L18%2c9' /%3e%3c/svg%3e");
}
.ck-content .todo-list__label input[type="checkbox"] {
display: none !important;
}
}
/* #region Footnotes */
.footnote-reference a,
.footnote-back-link a {
text-decoration: none !important;
}
li.footnote-item {
position: relative;
width: fit-content;
}
.ck-content .footnote-back-link {
margin-right: 0.25em;
}
.ck-content .footnote-content {
display: inline-block;
width: unset;
}
/* #endregion */
/* #region Widows and orphans */
p,
blockquote {
widows: 4;
orphans: 4;
}
pre > code {
widows: 6;
orphans: 6;
overflow: auto;
white-space: pre-wrap !important;
}
h1,
h2,
h3,
h4,
h5,
h6 {
page-break-after: avoid;
break-after: avoid;
}
/* #endregion */
/* #region Tables */
.table thead th,
.table td,
.table th {
/* Fix center vertical alignment of table cells */
vertical-align: middle;
}
pre {
box-shadow: unset !important;
border: 0.75pt solid gray !important;
border-radius: 2pt !important;
}
th,
span[style] {
print-color-adjust: exact;
-webkit-print-color-adjust: exact;
}
/* #endregion */
/* #region Page breaks */
.page-break {
page-break-after: always;
break-after: always;
}
.page-break > *,
.page-break::after {
display: none !important;
}
/* #endregion */

View File

@@ -1,92 +0,0 @@
import FNote from "./entities/fnote";
import { render } from "preact";
import { CustomNoteList } from "./widgets/collections/NoteList";
import { useCallback, useLayoutEffect, useRef } from "preact/hooks";
import content_renderer from "./services/content_renderer";
interface RendererProps {
note: FNote;
onReady: () => void;
}
async function main() {
const notePath = window.location.hash.substring(1);
const noteId = notePath.split("/").at(-1);
if (!noteId) return;
await import("./print.css");
const froca = (await import("./services/froca")).default;
const note = await froca.getNote(noteId);
render(<App note={note} noteId={noteId} />, document.body);
}
function App({ note, noteId }: { note: FNote | null | undefined, noteId: string }) {
const sentReadyEvent = useRef(false);
const onReady = useCallback(() => {
if (sentReadyEvent.current) return;
window.dispatchEvent(new Event("note-ready"));
window._noteReady = true;
sentReadyEvent.current = true;
}, []);
const props: RendererProps | undefined | null = note && { note, onReady };
if (!note || !props) return <Error404 noteId={noteId} />
useLayoutEffect(() => {
document.body.dataset.noteType = note.type;
}, [ note ]);
return (
<>
{note.type === "book"
? <CollectionRenderer {...props} />
: <SingleNoteRenderer {...props} />
}
</>
);
}
function SingleNoteRenderer({ note, onReady }: RendererProps) {
const containerRef = useRef<HTMLDivElement>(null);
useLayoutEffect(() => {
async function load() {
if (note.type === "text") {
await import("@triliumnext/ckeditor5/src/theme/ck-content.css");
}
const { $renderedContent } = await content_renderer.getRenderedContent(note, { noChildrenList: true });
containerRef.current?.replaceChildren(...$renderedContent);
}
load().then(() => requestAnimationFrame(onReady))
}, [ note ]);
return <>
<h1>{note.title}</h1>
<main ref={containerRef} />
</>;
}
function CollectionRenderer({ note, onReady }: RendererProps) {
return <CustomNoteList
isEnabled
note={note}
notePath={note.getBestNotePath().join("/")}
ntxId="print"
highlightedTokens={null}
media="print"
onReady={onReady}
/>;
}
function Error404({ noteId }: { noteId: string }) {
return (
<main>
<p>The note you are trying to print could not be found.</p>
<small>{noteId}</small>
</main>
)
}
main();

View File

@@ -1,15 +1,5 @@
import $ from "jquery";
async function loadBootstrap() {
if (document.body.dir === "rtl") {
await import("bootstrap/dist/css/bootstrap.rtl.min.css");
} else {
await import("bootstrap/dist/css/bootstrap.min.css");
}
}
(window as any).$ = $;
(window as any).jQuery = $;
await loadBootstrap();
$("body").show();

View File

@@ -23,13 +23,11 @@ interface Options {
tooltip?: boolean;
trim?: boolean;
imageHasZoom?: boolean;
/** If enabled, it will prevent the default behavior in which an empty note would display a list of children. */
noChildrenList?: boolean;
}
const CODE_MIME_TYPES = new Set(["application/json"]);
export async function getRenderedContent(this: {} | { ctx: string }, entity: FNote | FAttachment, options: Options = {}) {
async function getRenderedContent(this: {} | { ctx: string }, entity: FNote | FAttachment, options: Options = {}) {
options = Object.assign(
{
@@ -44,7 +42,7 @@ export async function getRenderedContent(this: {} | { ctx: string }, entity: FNo
const $renderedContent = $('<div class="rendered-content">');
if (type === "text" || type === "book") {
await renderText(entity, $renderedContent, options);
await renderText(entity, $renderedContent);
} else if (type === "code") {
await renderCode(entity, $renderedContent);
} else if (["image", "canvas", "mindMap"].includes(type)) {
@@ -116,7 +114,7 @@ export async function getRenderedContent(this: {} | { ctx: string }, entity: FNo
};
}
async function renderText(note: FNote | FAttachment, $renderedContent: JQuery<HTMLElement>, options: Options = {}) {
async function renderText(note: FNote | FAttachment, $renderedContent: JQuery<HTMLElement>) {
// entity must be FNote
const blob = await note.getBlob();
@@ -137,7 +135,7 @@ async function renderText(note: FNote | FAttachment, $renderedContent: JQuery<HT
}
await formatCodeBlocks($renderedContent);
} else if (note instanceof FNote && !options.noChildrenList) {
} else if (note instanceof FNote) {
await renderChildrenList($renderedContent, note);
}
}

View File

@@ -1,39 +1,21 @@
import {readCssVar} from "../utils/css-var";
import Color, { ColorInstance } from "color";
const registeredClasses = new Set<string>();
// Read the color lightness limits defined in the theme as CSS variables
function createClassForColor(color: string | null) {
if (!color?.trim()) {
return "";
}
const lightThemeColorMaxLightness = readCssVar(
document.documentElement,
"tree-item-light-theme-max-color-lightness"
).asNumber(70);
const normalizedColorName = color.replace(/[^a-z0-9]/gi, "");
const darkThemeColorMinLightness = readCssVar(
document.documentElement,
"tree-item-dark-theme-min-color-lightness"
).asNumber(50);
if (!normalizedColorName.trim()) {
return "";
}
function createClassForColor(colorString: string | null) {
if (!colorString?.trim()) return "";
const color = parseColor(colorString);
if (!color) return "";
const className = `color-${color.hex().substring(1)}`;
const className = `color-${normalizedColorName}`;
if (!registeredClasses.has(className)) {
const adjustedColor = adjustColorLightness(color, lightThemeColorMaxLightness!,
darkThemeColorMinLightness!);
$("head").append(`<style>
.${className}, span.fancytree-active.${className} {
--light-theme-custom-color: ${adjustedColor.lightThemeColor};
--dark-theme-custom-color: ${adjustedColor.darkThemeColor};
--custom-color-hue: ${getHue(color) ?? 'unset'};
}
</style>`);
// make the active fancytree selector more specific than the normal color setting
$("head").append(`<style>.${className}, span.fancytree-active.${className} { color: ${color} !important; }</style>`);
registeredClasses.add(className);
}
@@ -41,41 +23,6 @@ function createClassForColor(colorString: string | null) {
return className;
}
function parseColor(color: string) {
try {
return Color(color);
} catch (ex) {
console.error(ex);
}
}
/**
* Returns a pair of colors — one optimized for light themes and the other for dark themes, derived
* from the specified color to maintain sufficient contrast with each theme.
* The adjustment is performed by limiting the colors lightness in the CIELAB color space,
* according to the lightThemeMaxLightness and darkThemeMinLightness parameters.
*/
function adjustColorLightness(color: ColorInstance, lightThemeMaxLightness: number, darkThemeMinLightness: number) {
const labColor = color.lab();
const lightness = labColor.l();
// For the light theme, limit the maximum lightness
const lightThemeColor = labColor.l(Math.min(lightness, lightThemeMaxLightness)).hex();
// For the dark theme, limit the minimum lightness
const darkThemeColor = labColor.l(Math.max(lightness, darkThemeMinLightness)).hex();
return {lightThemeColor, darkThemeColor};
}
/** Returns the hue of the specified color, or undefined if the color is grayscale. */
function getHue(color: ColorInstance) {
const hslColor = color.hsl();
if (hslColor.saturationl() > 0) {
return hslColor.hue();
}
}
export default {
createClassForColor
};

View File

@@ -40,23 +40,20 @@ class FrocaImpl implements Froca {
constructor() {
this.initializedPromise = this.loadInitialTree();
this.#clear();
}
async loadInitialTree() {
const resp = await server.get<SubtreeResponse>("tree");
// clear the cache only directly before adding new content which is important for e.g., switching to protected session
this.#clear();
this.addResp(resp);
}
#clear() {
this.notes = {};
this.branches = {};
this.attributes = {};
this.attachments = {};
this.blobPromises = {};
this.addResp(resp);
}
async loadSubTree(subTreeNoteId: string) {

View File

@@ -6,7 +6,7 @@ import { describe, expect, it } from "vitest";
describe("i18n", () => {
it("translations are valid JSON", () => {
for (const locale of LOCALES) {
if (locale.contentOnly || locale.id === "en_rtl") {
if (locale.contentOnly) {
continue;
}

View File

@@ -27,8 +27,7 @@ export const byBookType: Record<ViewTypeOptions, string | null> = {
calendar: "xWbu3jpNWapp",
table: "2FvYrpmOXm29",
geoMap: "81SGnPGMk7Xc",
board: "CtBQqbwXDx1w",
presentation: null
board: "CtBQqbwXDx1w"
};
export function getHelpUrlForNote(note: FNote | null | undefined) {

View File

@@ -4,7 +4,6 @@ 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 { openInCurrentNoteContext } from "../components/note_context.js";
function getNotePathFromUrl(url: string) {
const notePathMatch = /#(root[A-Za-z0-9_/]*)$/.exec(url);
@@ -317,7 +316,21 @@ function goToLinkExt(evt: MouseEvent | JQuery.ClickEvent | JQuery.MouseDownEvent
viewScope
});
} else if (isLeftClick) {
openInCurrentNoteContext(evt, notePath, viewScope);
const ntxId = $(evt?.target as any)
.closest("[data-ntx-id]")
.attr("data-ntx-id");
const noteContext = ntxId ? appContext.tabManager.getNoteContextById(ntxId) : appContext.tabManager.getActiveContext();
if (noteContext) {
noteContext.setNote(notePath, { viewScope }).then(() => {
if (noteContext !== appContext.tabManager.getActiveContext()) {
appContext.tabManager.activateNoteContext(noteContext.ntxId);
}
});
} else {
appContext.tabManager.openContextWithNote(notePath, { viewScope, activate: true });
}
}
} else if (hrefLink) {
const withinEditLink = $link?.hasClass("ck-link-actions__preview");

View File

@@ -168,8 +168,7 @@ async function getBuiltInTemplates(title: string | null, command: TreeCommandNam
}
for (const templateNote of childNotes) {
if (templateNote.hasLabel("collection") !== filterCollections ||
!templateNote.hasLabel("template")) {
if (templateNote.hasLabel("collection") !== filterCollections) {
continue;
}

View File

@@ -61,11 +61,7 @@ export async function applySingleBlockSyntaxHighlight($codeBlock: JQuery<HTMLEle
highlightedText = highlightAuto(text);
} else if (normalizedMimeType) {
await ensureMimeTypesForHighlighting(normalizedMimeType);
try {
highlightedText = highlight(text, { language: normalizedMimeType });
} catch (e) {
console.warn("Unable to apply syntax highlight.", e);
}
highlightedText = highlight(text, { language: normalizedMimeType });
}
if (highlightedText) {
@@ -80,7 +76,7 @@ export async function ensureMimeTypesForHighlighting(mimeTypeHint?: string) {
// Load theme.
const currentThemeName = String(options.get("codeBlockTheme"));
await loadHighlightingTheme(currentThemeName);
loadHighlightingTheme(currentThemeName);
// Load mime types.
let mimeTypes: MimeType[];
@@ -102,16 +98,17 @@ export async function ensureMimeTypesForHighlighting(mimeTypeHint?: string) {
highlightingLoaded = true;
}
export async function loadHighlightingTheme(themeName: string) {
export function loadHighlightingTheme(themeName: string) {
const themePrefix = "default:";
let theme: Theme | null = null;
if (glob.device === "print") {
theme = Themes.vs;
} else if (themeName.includes(themePrefix)) {
if (themeName.includes(themePrefix)) {
theme = Themes[themeName.substring(themePrefix.length)];
}
if (!theme) {
theme = Themes.default;
}
await loadTheme(theme ?? Themes.default);
loadTheme(theme);
}
/**

View File

@@ -869,18 +869,6 @@ export function getErrorMessage(e: unknown) {
}
}
/**
* Handles left or right placement of e.g. tooltips in case of right-to-left languages. If the current language is a RTL one, then left and right are swapped. Other directions are unaffected.
* @param placement a string optionally containing a "left" or "right" value.
* @returns a left/right value swapped if needed, or the same as input otherwise.
*/
export function handleRightToLeftPlacement<T extends string>(placement: T) {
if (!glob.isRtl) return placement;
if (placement === "left") return "right";
if (placement === "right") return "left";
return placement;
}
export default {
reloadFrontendApp,
restartDesktopApp,

View File

@@ -304,8 +304,6 @@ async function sendPing() {
}
setTimeout(() => {
if (glob.device === "print") return;
ws = connectWebSocket();
lastPingTs = Date.now();

View File

@@ -1,3 +1,4 @@
import "bootstrap/dist/css/bootstrap.min.css";
import "./stylesheets/auth.css";
// @TriliumNextTODO: is this even needed anymore?

View File

@@ -1,6 +1,7 @@
import "jquery";
import utils from "./services/utils.js";
import ko from "knockout";
import "bootstrap/dist/css/bootstrap.min.css";
// TriliumNextTODO: properly make use of below types
// type SetupModelSetupType = "new-document" | "sync-from-desktop" | "sync-from-server" | "";

View File

@@ -60,7 +60,7 @@
appearance: none;
text-align: center;
border: 0;
border-inline-start: unset;
border-left: unset;
background-color: var(--menu-background-color);
font-weight: bold;
outline: 0;
@@ -102,7 +102,7 @@
content: '';
position: absolute;
top: 0;
inset-inline-end: 0;
right: 0;
bottom: 0;
width: 1px;
background-color: var(--main-border-color);

View File

@@ -299,7 +299,7 @@
content: '';
position: absolute;
top: 0;
inset-inline-start: -100%;
left: -100%;
width: 100%;
height: 100%;
background: linear-gradient(90deg, transparent, var(--hover-item-background-color, rgba(0, 0, 0, 0.03)), transparent);
@@ -406,10 +406,10 @@
@keyframes shimmer {
0% {
inset-inline-start: -100%;
left: -100%;
}
100% {
inset-inline-start: 100%;
left: 100%;
}
}

View File

@@ -0,0 +1,322 @@
:root {
--main-background-color: white;
--root-background: var(--main-background-color);
--launcher-pane-background-color: var(--main-background-color);
--main-text-color: black;
--input-text-color: var(--main-text-color);
--print-font-size: 11pt;
}
@page {
margin: 2cm;
}
.ck-content {
font-size: var(--print-font-size);
text-align: justify;
}
.note-detail-readonly-text {
padding: 0 !important;
}
.no-print,
.no-print *,
.tab-row-container,
.tab-row-widget,
.title-bar-buttons,
#launcher-pane,
#left-pane,
#center-pane > *:not(.split-note-container-widget),
#right-pane,
.title-row .note-icon-widget,
.title-row .icon-action,
.ribbon-container,
.promoted-attributes-widget,
.scroll-padding-widget,
.note-list-widget,
.spacer {
display: none !important;
}
body.mobile #mobile-sidebar-wrapper,
body.mobile .classic-toolbar-widget,
body.mobile .action-button {
display: none !important;
}
body.mobile #detail-container {
max-height: unset;
}
body.mobile .note-title-widget {
padding: 0 !important;
}
body,
#root-widget,
#rest-pane > div.component:first-child,
.note-detail-printable,
.note-detail-editable-text-editor {
height: unset !important;
overflow: auto;
}
.ck.ck-editor__editable_inline {
overflow: hidden !important;
}
.note-title-widget input,
.note-detail-editable-text,
.note-detail-editable-text-editor {
padding: 0 !important;
}
html,
body {
width: unset !important;
height: unset !important;
overflow: visible;
position: unset;
/* https://github.com/zadam/trilium/issues/3202 */
color: black;
}
#root-widget,
#horizontal-main-container,
#rest-pane,
#vertical-main-container,
#center-pane,
.split-note-container-widget,
.note-split:not(.hidden-ext),
body.mobile #mobile-rest-container {
display: block !important;
overflow: auto;
border-radius: 0 !important;
}
#center-pane,
#rest-pane,
.note-split,
body.mobile #detail-container {
width: unset !important;
max-width: unset !important;
}
.component {
contain: none !important;
}
/* Respect page breaks */
.page-break {
page-break-after: always;
break-after: always;
}
.page-break > * {
display: none !important;
}
.relation-map-wrapper {
height: 100vh !important;
}
.table thead th,
.table td,
.table th {
/* Fix center vertical alignment of table cells */
vertical-align: middle;
}
pre {
box-shadow: unset !important;
border: 0.75pt solid gray !important;
border-radius: 2pt !important;
}
th,
span[style] {
print-color-adjust: exact;
-webkit-print-color-adjust: exact;
}
/*
* Text note specific fixes
*/
.ck-widget {
outline: none !important;
}
.ck-placeholder,
.ck-widget__type-around,
.ck-widget__selection-handle {
display: none !important;
}
.ck-widget.table td.ck-editor__nested-editable.ck-editor__nested-editable_focused,
.ck-widget.table td.ck-editor__nested-editable:focus,
.ck-widget.table th.ck-editor__nested-editable.ck-editor__nested-editable_focused,
.ck-widget.table th.ck-editor__nested-editable:focus {
background: unset !important;
outline: unset !important;
}
.include-note .include-note-content {
max-height: unset !important;
overflow: unset !important;
}
/* TODO: This will break once we translate the language */
.ck-content pre[data-language="Auto-detected"]:after {
display: none !important;
}
/*
* Code note specific fixes.
*/
.note-detail-code pre {
border: unset !important;
border-radius: unset !important;
}
/*
* Links
*/
.note-detail-printable a {
text-decoration: none;
}
.note-detail-printable a:not([href^="#root/"]) {
text-decoration: underline;
color: #374a75;
}
.note-detail-printable a::after {
/* Hide the external link trailing arrow */
display: none !important;
}
/*
* TODO list check boxes
*/
.note-detail-printable .todo-list__label * {
-webkit-print-color-adjust: exact;
print-color-adjust: exact;
}
@supports selector(.todo-list__label__description:has(*)) and (height: 1lh) {
.note-detail-printable .todo-list__label__description {
/* The percentage of the line height that the check box occupies */
--box-ratio: 0.75;
/* The size of the gap between the check box and the caption */
--box-text-gap: 0.25em;
--box-size: calc(1lh * var(--box-ratio));
--box-vert-offset: calc((1lh - var(--box-size)) / 2);
display: inline-block;
padding-left: calc(var(--box-size) + var(--box-text-gap));
/* Source: https://pictogrammers.com/library/mdi/icon/checkbox-blank-outline/ */
background-image: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='currentColor'%3e%3cpath d='M19%2c3H5C3.89%2c3 3%2c3.89 3%2c5V19A2%2c2 0 0%2c0 5%2c21H19A2%2c2 0 0%2c0 21%2c19V5C21%2c3.89 20.1%2c3 19%2c3M19%2c5V19H5V5H19Z' /%3e%3c/svg%3e");
background-position: 0 var(--box-vert-offset);
background-size: var(--box-size);
background-repeat: no-repeat;
}
.note-detail-printable .todo-list__label:has(input[type="checkbox"]:checked) .todo-list__label__description {
/* Source: https://pictogrammers.com/library/mdi/icon/checkbox-outline/ */
background-image: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='currentColor'%3e%3cpath d='M19%2c3H5A2%2c2 0 0%2c0 3%2c5V19A2%2c2 0 0%2c0 5%2c21H19A2%2c2 0 0%2c0 21%2c19V5A2%2c2 0 0%2c0 19%2c3M19%2c5V19H5V5H19M10%2c17L6%2c13L7.41%2c11.58L10%2c14.17L16.59%2c7.58L18%2c9' /%3e%3c/svg%3e");
}
.note-detail-printable .todo-list__label input[type="checkbox"] {
display: none !important;
}
}
/*
* Blockquotes
*/
.note-detail-printable blockquote {
box-shadow: unset;
}
/*
* Figures
*/
.note-detail-printable figcaption {
--accented-background-color: transparent;
font-style: italic;
}
/*
* Footnotes
*/
.note-detail-printable .footnote-reference a,
.footnote-back-link a {
text-decoration: none;
}
/* Make the "^" link cover the whole area of the footnote item */
.footnote-section {
clear: both;
}
.note-detail-printable li.footnote-item {
position: relative;
width: fit-content;
}
.note-detail-printable .footnote-back-link,
.note-detail-printable .footnote-back-link *,
.note-detail-printable .footnote-back-link a {
display: block;
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
}
.note-detail-printable .footnote-back-link a {
color: transparent;
}
.note-detail-printable .footnote-content {
display: inline-block;
width: unset;
}
/*
* Widows and orphans
*/
p,
blockquote {
widows: 4;
orphans: 4;
}
pre > code {
widows: 6;
orphans: 6;
overflow: auto;
white-space: pre-wrap !important;
}
h1,
h2,
h3,
h4,
h5,
h6 {
page-break-after: avoid;
break-after: avoid;
}

View File

@@ -62,7 +62,7 @@
.note-detail-relation-map .endpoint {
position: absolute;
bottom: 37%;
inset-inline-end: 5px;
right: 5px;
width: 1em;
height: 1em;
background-color: #333;

View File

@@ -174,12 +174,12 @@ textarea,
/* Add a gap between consecutive radios / check boxes */
label.tn-radio + label.tn-radio,
label.tn-checkbox + label.tn-checkbox {
margin-inline-start: 12px;
margin-left: 12px;
}
label.tn-radio input[type="radio"],
label.tn-checkbox input[type="checkbox"] {
margin-inline-end: .5em;
margin-right: .5em;
}
#left-pane input,
@@ -226,7 +226,7 @@ samp {
.badge {
--bs-badge-color: var(--muted-text-color);
margin-inline-start: 8px;
margin-left: 8px;
background: var(--accented-background-color);
}
@@ -338,8 +338,8 @@ button kbd {
}
.ui-menu kbd {
margin-inline-start: 30px;
float: inline-end;
margin-left: 30px;
float: right;
}
.suppressed {
@@ -360,8 +360,7 @@ button kbd {
}
.dropdown-menu,
.tabulator-popup-container,
:root .excalidraw .popover {
.tabulator-popup-container {
color: var(--menu-text-color) !important;
font-size: inherit;
background: var(--menu-background-color) !important;
@@ -372,9 +371,7 @@ button kbd {
}
body.desktop .dropdown-menu,
body.desktop .tabulator-popup-container,
:root .excalidraw .dropdown-menu .dropdown-menu-container,
:root .excalidraw .popover {
body.desktop .tabulator-popup-container {
border: 1px solid var(--dropdown-border-color);
column-rule: 1px solid var(--dropdown-border-color);
box-shadow: 0px 10px 20px rgba(0, 0, 0, var(--dropdown-shadow-opacity));
@@ -395,7 +392,7 @@ body.desktop .tabulator-popup-container,
}
.dropend .dropdown-toggle::after {
margin-inline-start: 0.5em;
margin-left: 0.5em;
color: var(--muted-text-color);
}
@@ -406,7 +403,7 @@ body.desktop .tabulator-popup-container,
.dropdown-menu .disabled .disabled-tooltip {
pointer-events: all;
margin-inline-start: 8px;
margin-left: 8px;
font-size: 0.5em;
color: var(--disabled-tooltip-icon-color);
cursor: help;
@@ -419,8 +416,7 @@ body.desktop .tabulator-popup-container,
.dropdown-menu a:hover:not(.disabled),
.dropdown-item:hover:not(.disabled, .dropdown-container-item),
.tabulator-menu-item:hover,
:root .excalidraw .context-menu .context-menu-item:hover {
.tabulator-menu-item:hover {
color: var(--hover-item-text-color) !important;
background-color: var(--hover-item-background-color) !important;
border-color: var(--hover-item-border-color) !important;
@@ -447,7 +443,7 @@ body #context-menu-container .dropdown-item > span {
.dropdown-item span.keyboard-shortcut,
.dropdown-item *:not(.keyboard-shortcut) > kbd {
flex-grow: 1;
text-align: end;
text-align: right;
padding-inline-start: 12px;
}
@@ -461,8 +457,7 @@ body #context-menu-container .dropdown-item > span {
}
.dropdown-item,
.dropdown-header,
:root .excalidraw .context-menu .context-menu-item:hover {
.dropdown-header {
color: var(--menu-text-color) !important;
border: 1px solid transparent !important;
}
@@ -509,7 +504,7 @@ body #context-menu-container .dropdown-item > span {
body .cm-editor .cm-gutters {
background-color: inherit !important;
border-inline-end: none;
border-right: none;
}
body .cm-editor .cm-placeholder {
@@ -591,10 +586,6 @@ button.btn-sm {
z-index: 1000;
}
body[dir=rtl] .ck.ck-block-toolbar-button {
transform: translateX(-7px);
}
pre:not(.hljs) {
color: var(--main-text-color) !important;
white-space: pre-wrap;
@@ -613,11 +604,11 @@ pre:not(.hljs) {
pre > button.copy-button {
position: absolute;
top: var(--copy-button-margin-size);
inset-inline-end: var(--copy-button-margin-size);
right: var(--copy-button-margin-size);
}
:root pre:has(> button.copy-button) {
padding-inline-end: calc(var(--copy-button-width) + (var(--copy-button-margin-size) * 2));
padding-right: calc(var(--copy-button-width) + (var(--copy-button-margin-size) * 2));
}
pre > button.copy-button:hover {
@@ -643,31 +634,31 @@ pre > button.copy-button:active {
.full-text-search-button {
cursor: pointer;
font-size: 1.3em;
padding-inline-start: 5px;
padding-inline-end: 5px;
padding-left: 5px;
padding-right: 5px;
}
.input-clearer-button {
cursor: pointer;
font-size: 1.3em;
background: inherit !important;
padding-inline-start: 5px;
padding-inline-end: 5px;
padding-left: 5px;
padding-right: 5px;
}
.open-external-link-button {
cursor: pointer;
font-size: 1.3em;
padding-inline-start: 5px;
padding-inline-end: 5px;
padding-left: 5px;
padding-right: 5px;
padding-top: 8px;
}
.go-to-selected-note-button {
cursor: pointer;
font-size: 1.3em;
padding-inline-start: 4px;
padding-inline-end: 3px;
padding-left: 4px;
padding-right: 3px;
}
.go-to-selected-note-button.disabled,
@@ -680,7 +671,7 @@ pre > button.copy-button:active {
.note-autocomplete-input {
/* this is for seamless integration of "input clearer" button */
border-inline-end: 0;
border-right: 0;
}
table.promoted-attributes-in-tooltip {
@@ -713,10 +704,10 @@ table.promoted-attributes-in-tooltip th {
border-top-color: var(--main-border-color) !important;
}
.bs-tooltip-left .tooltip-arrow::before {
border-inline-start-color: var(--main-border-color) !important;
border-left-color: var(--main-border-color) !important;
}
.bs-tooltip-right .tooltip-arrow::before {
border-inline-end-color: var(--main-border-color) !important;
border-right-color: var(--main-border-color) !important;
}
.bs-tooltip-bottom .tooltip-arrow::after {
@@ -726,17 +717,17 @@ table.promoted-attributes-in-tooltip th {
border-top-color: var(--tooltip-background-color) !important;
}
.bs-tooltip-left .tooltip-arrow::after {
border-inline-start-color: var(--tooltip-background-color) !important;
border-left-color: var(--tooltip-background-color) !important;
}
.bs-tooltip-right .tooltip-arrow::after {
border-inline-end-color: var(--tooltip-background-color) !important;
border-right-color: var(--tooltip-background-color) !important;
}
.bs-tooltip-auto[data-popper-placement^="left"] .tooltip-arrow::before,
.bs-tooltip-left .tooltip-arrow::before {
inset-inline-start: -1px;
left: -1px;
border-width: 0.4rem 0 0.4rem 0.4rem;
border-inline-start-color: var(--main-border-color) !important;
border-left-color: var(--main-border-color) !important;
}
.bs-tooltip-auto[data-popper-placement^="bottom"] .tooltip-arrow::before,
@@ -748,9 +739,9 @@ table.promoted-attributes-in-tooltip th {
.bs-tooltip-auto[data-popper-placement^="right"] .tooltip-arrow::before,
.bs-tooltip-right .tooltip-arrow::before {
inset-inline-end: -1px;
right: -1px;
border-width: 0.4rem 0.4rem 0.4rem 0;
border-inline-end-color: var(--main-border-color) !important;
border-right-color: var(--main-border-color) !important;
}
.bs-tooltip-auto[data-popper-placement^="top"] .tooltip-arrow::before,
@@ -762,9 +753,9 @@ table.promoted-attributes-in-tooltip th {
.bs-tooltip-auto[data-popper-placement^="left"] .tooltip-arrow::after,
.bs-tooltip-left .tooltip-arrow::after {
inset-inline-start: -1px;
left: -1px;
border-width: 0.4rem 0 0.4rem 0.4rem;
border-inline-start-color: var(--tooltip-background-color) !important;
border-left-color: var(--tooltip-background-color) !important;
}
.bs-tooltip-auto[data-popper-placement^="bottom"] .tooltip-arrow::after,
@@ -776,9 +767,9 @@ table.promoted-attributes-in-tooltip th {
.bs-tooltip-auto[data-popper-placement^="right"] .tooltip-arrow::after,
.bs-tooltip-right .tooltip-arrow::after {
inset-inline-end: -1px;
right: -1px;
border-width: 0.4rem 0.4rem 0.4rem 0;
border-inline-end-color: var(--tooltip-background-color) !important;
border-right-color: var(--tooltip-background-color) !important;
}
.bs-tooltip-auto[data-popper-placement^="top"] .tooltip-arrow::after,
@@ -797,7 +788,7 @@ table.promoted-attributes-in-tooltip th {
background-color: var(--tooltip-background-color) !important;
border: 1px solid var(--main-border-color);
border-radius: 5px;
text-align: start;
text-align: left;
color: var(--main-text-color) !important;
max-width: 500px;
box-shadow: 10px 10px 93px -25px #aaaaaa;
@@ -830,7 +821,7 @@ table.promoted-attributes-in-tooltip th {
.note-tooltip-content .open-popup-button {
position: absolute;
inset-inline-end: 15px;
right: 15px;
bottom: 8px;
font-size: 1.2em;
color: inherit;
@@ -850,7 +841,7 @@ table.promoted-attributes-in-tooltip th {
}
.tooltip-inner figure.image-style-side {
float: inline-end;
float: right;
}
.tooltip.show {
@@ -899,7 +890,7 @@ table.promoted-attributes-in-tooltip th {
.aa-dropdown-menu .aa-suggestion .text {
display: inline-block;
width: calc(100% - 20px);
padding-inline-start: 4px;
padding-left: 4px;
}
.aa-dropdown-menu .aa-suggestion .search-result-title {
@@ -925,7 +916,7 @@ table.promoted-attributes-in-tooltip th {
}
.help-button {
float: inline-end;
float: right;
background: none;
font-weight: 900;
color: orange;
@@ -1013,7 +1004,7 @@ svg.ck-icon .note-icon {
--ck-content-line-height: var(--bs-body-line-height);
}
:root .ck-content .table table:not(.layout-table) th {
.ck-content .table table th {
background-color: var(--accented-background-color);
}
@@ -1042,7 +1033,7 @@ svg.ck-icon .note-icon {
counter-increment: footnote-counter;
display: flex;
list-style: none;
margin-inline-start: 0.5em;
margin-left: 0.5em;
}
.ck-content .footnote-item > * {
@@ -1050,13 +1041,13 @@ svg.ck-icon .note-icon {
}
.ck-content .footnote-back-link {
margin-inline-end: 0.1em;
margin-right: 0.1em;
position: relative;
top: -0.2em;
}
.ck-content .footnotes .footnote-back-link > sup {
margin-inline-end: 0;
margin-right: 0;
}
.ck-content .footnote-item:before {
@@ -1064,8 +1055,8 @@ svg.ck-icon .note-icon {
display: inline-block;
min-width: fit-content;
position: relative;
inset-inline-end: 0.2em;
text-align: end;
right: 0.2em;
text-align: right;
}
.ck-content .footnote-content {
@@ -1081,11 +1072,11 @@ svg.ck-icon .note-icon {
}
#options-dialog input[type="number"] {
text-align: end;
text-align: right;
}
.help-cards ul {
padding-inline-start: 20px;
padding-left: 20px;
}
.help-cards kbd {
@@ -1162,8 +1153,8 @@ a.external:not(.no-arrow):after, a[href^="http://"]:not(.no-arrow):after, a[href
}
.toast.no-title .toast-body {
padding-inline-start: 0;
padding-inline-end: 0;
padding-left: 0;
padding-right: 0;
}
.toast.no-title .toast-header {
@@ -1283,8 +1274,8 @@ a.external:not(.no-arrow):after, a[href^="http://"]:not(.no-arrow):after, a[href
#context-menu-cover.show {
position: fixed;
top: 0;
inset-inline-start: 0;
inset-inline-end: 0;
left: 0;
right: 0;
bottom: 0;
z-index: 1000;
background: rgba(0, 0, 0, 0.1);
@@ -1297,8 +1288,8 @@ a.external:not(.no-arrow):after, a[href^="http://"]:not(.no-arrow):after, a[href
body.mobile #context-menu-container.mobile-bottom-menu {
position: fixed !important;
inset-inline-start: 0 !important;
inset-inline-end: 0 !important;
left: 0 !important;
right: 0 !important;
bottom: 0 !important;
top: unset !important;
max-height: 70vh;
@@ -1348,7 +1339,7 @@ body.desktop li.dropdown-submenu:hover > ul.dropdown-menu {
.dropdown-submenu > .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 */
left: 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 */
@@ -1357,7 +1348,7 @@ body.desktop li.dropdown-submenu:hover > ul.dropdown-menu {
}
body:not(.mobile) #launcher-pane.horizontal .dropdown-submenu > .dropdown-menu {
inset-inline-start: calc(-100% + 10px);
left: calc(-100% + 10px);
}
.right-dropdown-widget {
@@ -1423,7 +1414,7 @@ body:not(.mobile) #launcher-pane.horizontal .dropdown-submenu > .dropdown-menu {
.ck.ck-slash-command-button__text-part,
.ck.ck-template-form__text-part {
margin-inline-start: 0.5em;
margin-left: 0.5em;
line-height: 1.2em !important;
}
@@ -1454,8 +1445,8 @@ body:not(.mobile) #launcher-pane.horizontal .dropdown-submenu > .dropdown-menu {
}
.area-expander-text {
padding-inline-start: 20px;
padding-inline-end: 20px;
padding-left: 20px;
padding-right: 20px;
white-space: nowrap;
}
@@ -1542,16 +1533,16 @@ body:not(.mobile) #launcher-pane.horizontal .dropdown-submenu > .dropdown-menu {
position: fixed !important;
bottom: calc(var(--mobile-bottom-offset) + var(--launcher-pane-size)) !important;
top: unset !important;
inset-inline-start: 0 !important;
inset-inline-end: 0 !important;
left: 0 !important;
right: 0 !important;
transform: unset !important;
}
#mobile-sidebar-container {
position: fixed;
top: 0;
inset-inline-start: 0;
inset-inline-end: 0;
left: 0;
right: 0;
bottom: 0;
z-index: 1000;
transition: background-color 250ms ease-in-out;
@@ -1566,7 +1557,7 @@ body:not(.mobile) #launcher-pane.horizontal .dropdown-submenu > .dropdown-menu {
#mobile-sidebar-wrapper {
position: absolute;
top: 0;
inset-inline-start: 0;
left: 0;
bottom: 0;
width: 85vw;
padding-top: env(safe-area-inset-top);
@@ -1598,8 +1589,8 @@ body:not(.mobile) #launcher-pane.horizontal .dropdown-submenu > .dropdown-menu {
body.mobile .modal-dialog {
position: fixed;
bottom: 0;
inset-inline-start: 0;
inset-inline-end: 0;
left: 0;
right: 0;
margin: 0 !important;
max-height: 85vh;
display: flex;
@@ -1757,8 +1748,8 @@ body:not(.mobile) #launcher-pane.horizontal .dropdown-submenu > .dropdown-menu {
display: flex;
flex-shrink: 0;
flex-direction: column;
margin-inline-start: 10px;
margin-inline-end: 5px;
margin-left: 10px;
margin-right: 5px;
}
#right-pane .card-header {
@@ -1798,7 +1789,7 @@ body:not(.mobile) #launcher-pane.horizontal .dropdown-submenu > .dropdown-menu {
}
#right-pane .card-body ul {
padding-inline-start: 25px;
padding-left: 25px;
margin-bottom: 5px;
}
@@ -1809,8 +1800,8 @@ body:not(.mobile) #launcher-pane.horizontal .dropdown-submenu > .dropdown-menu {
}
.note-split {
margin-inline-start: auto;
margin-inline-end: auto;
margin-left: auto;
margin-right: auto;
}
.note-split.full-content-width {
@@ -1829,7 +1820,7 @@ button.close:hover {
.reference-link .bx {
position: relative;
top: 1px;
margin-inline-end: 3px;
margin-right: 3px;
}
.options-section:first-of-type h4 {
@@ -1867,7 +1858,7 @@ textarea {
.attachment-help-button {
display: inline-block;
margin-inline-start: 10px;
margin-left: 10px;
vertical-align: middle;
font-size: 1em;
}
@@ -1975,7 +1966,7 @@ textarea {
}
body.electron.platform-darwin:not(.native-titlebar) .tab-row-container {
padding-inline-start: 1em;
padding-left: 1em;
}
#tab-row-left-spacer {
@@ -1983,12 +1974,8 @@ body.electron.platform-darwin:not(.native-titlebar) .tab-row-container {
-webkit-app-region: drag;
}
body.electron.platform-darwin:not(.native-titlebar) #tab-row-left-spacer {
width: 80px;
}
.tab-row-widget {
padding-inline-end: calc(100vw - env(titlebar-area-width, 100vw));
padding-right: calc(100vw - env(titlebar-area-width, 100vw));
}
.tab-row-container .toggle-button {
@@ -2051,7 +2038,7 @@ body.zen .split-note-container-widget > .gutter {
body.zen #launcher-pane {
position: absolute !important;
top: 0 !important;
inset-inline-end: 0 !important;
right: 0 !important;
width: 64px !important;
height: 64px !important;
background: transparent !important;
@@ -2062,8 +2049,8 @@ 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);
padding-left: env(titlebar-area-x);
padding-right: calc(100vw - env(titlebar-area-width, 100vw) + 2.5em);
}
body.zen .floating-buttons {
@@ -2071,7 +2058,7 @@ body.zen .floating-buttons {
}
body.zen .floating-buttons-children {
inset-inline-end: 0;
right: 0;
}
body.zen .floating-buttons-children .button-widget {
@@ -2230,7 +2217,7 @@ footer.webview-footer button {
.chat-input {
width: 100%;
resize: none;
padding-inline-end: 40px;
padding-right: 40px;
}
.chat-buttons {
@@ -2286,13 +2273,14 @@ footer.webview-footer button {
.admonition {
--accent-color: var(--card-border-color);
background: color-mix(in srgb, var(--accent-color) 15%, transparent);
border: 1px solid var(--accent-color);
box-shadow: var(--card-box-shadow);
background: var(--card-background-color);
border-radius: 0.5em;
padding: 1em;
margin: 1.25em 0;
position: relative;
padding-inline-start: 2.5em;
padding-left: 2.5em;
overflow: hidden;
}
@@ -2305,7 +2293,7 @@ footer.webview-footer button {
font-family: boxicons !important;
position: absolute;
top: 1em;
inset-inline-start: 1em;
left: 1em;
}
.admonition.note { --accent-color: var(--admonition-note-accent-color); }
@@ -2331,18 +2319,18 @@ footer.webview-footer button {
display: flex;
align-items: center;
font-size: 0.9em;
margin-inline-end: 15px;
margin-right: 15px;
cursor: pointer;
}
.chat-option input[type="checkbox"] {
margin-inline-end: 5px;
margin-right: 5px;
}
/* Style for thinking process in chat responses */
.thinking-process {
background-color: rgba(0, 0, 0, 0.05);
border-inline-start: 3px solid var(--main-text-color);
border-left: 3px solid var(--main-text-color);
padding: 10px;
margin: 10px 0;
border-radius: 4px;
@@ -2350,23 +2338,23 @@ footer.webview-footer button {
.thinking-step {
margin-bottom: 8px;
padding-inline-start: 10px;
padding-left: 10px;
}
.thinking-step.observation {
border-inline-start: 2px solid #69c7ff;
border-left: 2px solid #69c7ff;
}
.thinking-step.hypothesis {
border-inline-start: 2px solid #9839f7;
border-left: 2px solid #9839f7;
}
.thinking-step.evidence {
border-inline-start: 2px solid #40c025;
border-left: 2px solid #40c025;
}
.thinking-step.conclusion {
border-inline-start: 2px solid #e2aa03;
border-left: 2px solid #e2aa03;
font-weight: bold;
}
@@ -2381,17 +2369,17 @@ footer.webview-footer button {
.content-floating-buttons.top-left {
top: 10px;
inset-inline-start: 10px;
left: 10px;
}
.content-floating-buttons.bottom-left {
bottom: 10px;
inset-inline-start: 10px;
left: 10px;
}
.content-floating-buttons.bottom-right {
bottom: 10px;
inset-inline-end: 10px;
right: 10px;
}
.content-floating-buttons button.bx {
@@ -2422,14 +2410,4 @@ footer.webview-footer button {
.revision-diff-removed {
background: rgba(255, 100, 100, 0.5);
text-decoration: line-through;
}
iframe.print-iframe {
position: absolute;
top: 0;
left: -600px;
right: -600px;
bottom: 0;
width: 0;
height: 0;
}

View File

@@ -67,13 +67,13 @@
}
.tabulator div.tabulator-header .tabulator-frozen.tabulator-frozen-left {
margin-inline-start: var(--cell-editing-border-width);
margin-left: var(--cell-editing-border-width);
}
.tabulator div.tabulator-header .tabulator-col,
.tabulator div.tabulator-header .tabulator-frozen.tabulator-frozen-left {
background: var(--col-header-background-color);
border-inline-end: var(--col-header-separator-border);
border-right: var(--col-header-separator-border);
}
/* Table body */
@@ -90,8 +90,8 @@
}
.tabulator-row .tabulator-cell input {
padding-inline-start: var(--cell-horiz-padding-size) !important;
padding-inline-end: var(--cell-horiz-padding-size) !important;
padding-left: var(--cell-horiz-padding-size) !important;
padding-right: var(--cell-horiz-padding-size) !important;
}
.tabulator-row {
@@ -117,12 +117,12 @@
/* Cell */
.tabulator-row .tabulator-cell.tabulator-frozen.tabulator-frozen-left {
margin-inline-end: var(--cell-editing-border-width);
margin-right: var(--cell-editing-border-width);
}
.tabulator-row .tabulator-cell.tabulator-frozen.tabulator-frozen-left,
.tabulator-row .tabulator-cell {
border-inline-end-color: transparent;
border-right-color: transparent;
}
.tabulator-row .tabulator-cell:not(.tabulator-editable) {
@@ -156,14 +156,14 @@
/* Align items without children/expander to the ones with. */
.tabulator-cell[tabulator-field="title"] > span:first-child, /* 1st level */
.tabulator-cell[tabulator-field="title"] > div:first-child + span { /* sub-level */
padding-inline-start: 21px;
padding-left: 21px;
}
/* Checkbox cells */
.tabulator .tabulator-cell:has(svg),
.tabulator .tabulator-cell:has(input[type="checkbox"]) {
padding-inline-start: 8px;
padding-left: 8px;
display: inline-flex;
flex-direction: column;
justify-content: center;

View File

@@ -82,10 +82,6 @@ body ::-webkit-calendar-picker-indicator {
filter: invert(1);
}
#left-pane .fancytree-node.tinted {
--custom-color: var(--dark-theme-custom-color);
}
.excalidraw.theme--dark {
--theme-filter: invert(80%) hue-rotate(180deg) !important;
}

View File

@@ -81,7 +81,3 @@ html {
--mermaid-theme: default;
--native-titlebar-background: #ffffff00;
}
#left-pane .fancytree-node.tinted {
--custom-color: var(--light-theme-custom-color);
}

View File

@@ -160,9 +160,6 @@
--launcher-pane-horiz-background-color-bgfx: #ffffff17; /* When background effects enabled */
--launcher-pane-horiz-border-color-bgfx: #00000080; /* When background effects enabled */
--global-menu-update-available-badge-background-color: #7dbe61;
--global-menu-update-available-badge-color: black;
--protected-session-active-icon-color: #8edd8e;
--sync-status-error-pulse-color: #f47871;
@@ -268,15 +265,6 @@
* Dark color scheme tweaks
*/
#left-pane .fancytree-node.tinted {
--custom-color: var(--dark-theme-custom-color);
/* The background color of the active item in the note tree.
* The --custom-color-hue variable contains the hue of the user-selected note color.
* This value is unset for gray tones. */
--custom-bg-color: hsl(var(--custom-color-hue), 20%, 33%, 0.4);
}
body ::-webkit-calendar-picker-indicator {
filter: invert(1);
}
@@ -287,4 +275,4 @@ body ::-webkit-calendar-picker-indicator {
body .todo-list input[type="checkbox"]:not(:checked):before {
border-color: var(--muted-text-color) !important;
}
}

View File

@@ -127,7 +127,7 @@
--left-pane-item-selected-color: black;
--left-pane-item-selected-shadow: 1px 1px 2px rgba(0, 0, 0, 0.2);
--left-pane-item-action-button-background: rgba(0, 0, 0, 0.11);
--left-pane-item-action-button-color: var(--left-pane-text-color);
--left-pane-item-action-button-color: inherit;
--left-pane-item-action-button-hover-background: white;
--left-pane-item-action-button-hover-shadow: 2px 2px 3px rgba(0, 0, 0, 0.15);
--left-pane-item-selected-action-button-hover-shadow: 2px 2px 10px rgba(0, 0, 0, 0.25);
@@ -153,9 +153,6 @@
--launcher-pane-horiz-background-color-bgfx: #ffffffb3; /* When background effects enabled */
--launcher-pane-horiz-border-color-bgfx: #00000026; /* When background effects enabled */
--global-menu-update-available-badge-background-color: #4fa450;
--global-menu-update-available-badge-color: white;
--protected-session-active-icon-color: #16b516;
--sync-status-error-pulse-color: #ff5528;
@@ -261,13 +258,5 @@
--ck-editor-toolbar-button-on-color: black;
--ck-editor-toolbar-button-on-shadow: none;
--ck-editor-toolbar-dropdown-button-open-background: #0000000f;
}
#left-pane .fancytree-node.tinted {
--custom-color: var(--light-theme-custom-color);
/* The background color of the active item in the note tree.
* The --custom-color-hue variable contains the hue of the user-selected note color.
* This value is unset for gray tones. */
--custom-bg-color: hsl(var(--custom-color-hue), 37%, 89%, 1);
}

View File

@@ -4,7 +4,6 @@
@import url(./pages.css);
@import url(./ribbon.css);
@import url(./notes/text.css);
@import url(./notes/canvas.css);
@import url(./notes/collections/table.css);
@font-face {
@@ -82,20 +81,6 @@
/* Theme capabilities */
--tab-note-icons: true;
/* To ensure that a tree item's custom color remains sufficiently contrasted and readable,
* 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;
}
body.backdrop-effects-disabled {
@@ -111,10 +96,9 @@ body.backdrop-effects-disabled {
* supported when this class is used.
*/
.dropdown-menu:not(.static),
:root .excalidraw .popover {
.dropdown-menu:not(.static) {
border-radius: var(--dropdown-border-radius);
padding: var(--padding, var(--menu-padding-size)) !important;
padding: var(--menu-padding-size) !important;
font-size: 0.9rem !important;
}
@@ -130,15 +114,14 @@ body.mobile .dropdown-menu .dropdown-menu {
}
body.desktop .dropdown-menu::before,
:root .ck.ck-dropdown__panel::before,
:root .excalidraw .popover::before {
:root .ck.ck-dropdown__panel::before {
content: "";
backdrop-filter: var(--dropdown-backdrop-filter);
border-radius: var(--dropdown-border-radius);
position: absolute;
top: 0;
inset-inline-start: 0;
inset-inline-end: 0;
left: 0;
right: 0;
bottom: 0;
z-index: -1;
}
@@ -165,17 +148,9 @@ body.desktop .dropdown-submenu .dropdown-menu {
}
.dropdown-item,
body.mobile .dropdown-submenu .dropdown-toggle,
.excalidraw .context-menu .context-menu-item {
--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;
body.mobile .dropdown-submenu .dropdown-toggle {
padding: 2px 2px 2px 8px !important;
padding-inline-end: 22px !important;
/* Note: the right padding should also accommodate the submenu arrow. */
border-radius: 6px;
cursor: default !important;
@@ -227,8 +202,7 @@ html body .dropdown-item[disabled] {
}
/* Menu item keyboard shortcut */
.dropdown-item kbd,
.excalidraw .context-menu-item__shortcut {
.dropdown-item kbd {
font-family: unset !important;
font-size: unset !important;
color: var(--menu-item-keyboard-shortcut-color) !important;
@@ -237,23 +211,21 @@ html body .dropdown-item[disabled] {
.dropdown-item span.keyboard-shortcut {
color: var(--menu-item-keyboard-shortcut-color) !important;
margin-inline-start: 16px;
margin-left: 16px;
}
.dropdown-divider,
.excalidraw .context-menu hr {
.dropdown-divider {
position: relative;
border-color: transparent !important;
overflow: visible;
}
.dropdown-divider::after,
.excalidraw .context-menu hr::before {
.dropdown-divider::after {
position: absolute;
content: "";
top: -1px;
inset-inline-start: calc(0px - var(--menu-padding-size));
inset-inline-end: calc(0px - var(--menu-padding-size));
left: calc(0px - var(--menu-padding-size));
right: calc(0px - var(--menu-padding-size));
border-top: 1px solid var(--menu-item-delimiter-color);
}
@@ -265,7 +237,7 @@ html body .dropdown-item[disabled] {
align-items: center;
justify-content: center;
top: 0;
inset-inline-end: 0;
right: 0;
margin: unset !important;
border: unset !important;
padding: 0 4px;
@@ -274,16 +246,10 @@ html body .dropdown-item[disabled] {
color: var(--menu-item-arrow-color) !important;
}
body[dir=rtl] .dropdown-menu:not([data-popper-placement="bottom-start"]) .dropdown-toggle::after {
content: "\ea4d" !important;
}
/* Menu item group heading */
/* The heading body */
.dropdown-menu h6,
.excalidraw .dropdown-menu-container .dropdown-menu-group-title,
.excalidraw .dropdown-menu-container div[data-testid="canvas-background-label"] {
.dropdown-menu h6 {
position: relative;
background: transparent;
padding: 1em 8px 14px 8px;
@@ -294,14 +260,12 @@ body[dir=rtl] .dropdown-menu:not([data-popper-placement="bottom-start"]) .dropdo
}
/* The delimiter line */
.dropdown-menu h6::before,
.excalidraw .dropdown-menu-container .dropdown-menu-group-title::before,
.excalidraw .dropdown-menu-container div[data-testid="canvas-background-label"]::before {
.dropdown-menu h6::before {
content: "";
position: absolute;
bottom: 8px;
inset-inline-start: calc(0px - var(--menu-padding-size));
inset-inline-end: calc(0px - var(--menu-padding-size));
left: calc(0px - var(--menu-padding-size));
right: calc(0px - var(--menu-padding-size));
border-top: 1px solid var(--menu-item-delimiter-color);
}
@@ -393,13 +357,13 @@ li.dropdown-item a.dropdown-item-button:focus-visible {
}
#toast-container .toast:not(.no-title) .bx {
margin-inline-end: 0.5em;
margin-right: 0.5em;
font-size: 1.1em;
opacity: 0.85;
}
#toast-container .toast.no-title .bx {
margin-inline-end: 0;
margin-right: 0;
font-size: 1.3em;
}

View File

@@ -29,7 +29,7 @@
display: flex;
justify-content: center;
align-items: center;
margin-inline-start: 8px;
margin-left: 8px;
border: 0;
border-radius: 50%;
padding: 0;
@@ -56,7 +56,7 @@
}
.modal .modal-header .help-button {
margin-inline-end: 0;
margin-right: 0;
font-size: calc(var(--modal-control-button-size) * .75);
font-family: unset;
font-weight: bold;
@@ -141,7 +141,7 @@ div.tn-tool-dialog {
/* Search box wrapper */
.jump-to-note-dialog .input-group {
margin-inline-end: 16px;
margin-right: 16px;
}
.jump-to-note-dialog .input-group:hover {
@@ -197,8 +197,8 @@ div.tn-tool-dialog {
border: unset;
padding-top: var(--timeline-item-top-padding);
padding-bottom: var(--timeline-item-bottom-padding);
padding-inline-start: calc(var(--timeline-left-gap) + var(--timeline-right-gap));
padding-inline-end: var(--timeline-left-gap);
padding-left: calc(var(--timeline-left-gap) + var(--timeline-right-gap));
padding-right: var(--timeline-left-gap);
color: var(--active-item-text-color);
}
@@ -259,7 +259,7 @@ div.tn-tool-dialog {
position: absolute;
content: "";
top: var(--connector-top, 0);
inset-inline-start: calc(var(--timeline-left-gap) + ((var(--timeline-bullet-size) - var(--timeline-connector-size)) / 2));
left: calc(var(--timeline-left-gap) + ((var(--timeline-bullet-size) - var(--timeline-connector-size)) / 2));
bottom: var(--connector-bottom, 0);
width: var(--timeline-connector-size);
border-radius: var(--connector-radius, 0) var(--connector-radius, 0) 0 0;
@@ -291,7 +291,7 @@ div.tn-tool-dialog {
position: absolute;
content: "";
top: calc(var(--timeline-item-top-padding) + var(--timeline-bullet-vertical-pos));
inset-inline-start: var(--timeline-left-gap);
left: var(--timeline-left-gap);
width: var(--timeline-bullet-size);
height: var(--timeline-bullet-size);
border-radius: 50%;
@@ -374,7 +374,7 @@ div.tn-tool-dialog {
}
.help-dialog .help-cards kbd:first-child {
margin-inline-start: 0;
margin-left: 0;
}
/* Inline code - used for Markdown samples */
@@ -392,7 +392,7 @@ div.tn-tool-dialog {
}
.delete-notes-list .note-path {
padding-inline-end: 8px;
padding-left: 8px;
}
/*
@@ -401,7 +401,7 @@ div.tn-tool-dialog {
/* Labels */
.attr-edit-table th {
padding-inline-end: 12px;
padding-right: 12px;
font-weight: normal;
white-space: nowrap;
}
@@ -419,5 +419,5 @@ div.tn-tool-dialog {
}
.note-type-chooser-dialog div.note-type-dropdown .dropdown-item span.bx {
margin-inline-end: .25em;
margin-right: .25em;
}

View File

@@ -62,7 +62,7 @@ button.btn.btn-secondary span.bx,
button.btn.btn-sm span.bx,
button.btn.btn-success span.bx {
color: var(--cmd-button-icon-color);
padding-inline-end: 0.35em;
padding-right: 0.35em;
font-size: 1.2em;
}
@@ -71,7 +71,7 @@ button.btn.btn-primary kbd,
button.btn.btn-secondary kbd,
button.btn.btn-sm kbd,
button.btn.btn-success kbd {
margin-inline-start: 0.5em;
margin-left: 0.5em;
background: var(--cmd-button-keyboard-shortcut-background);
color: var(--cmd-button-keyboard-shortcut-color);
font-size: 0.6em;
@@ -102,7 +102,7 @@ button.btn.btn-success kbd {
}
.btn-group .tn-tool-button + .tn-tool-button {
margin-inline-start: 4px !important;
margin-left: 4px !important;
}
/* The "x" icon button */
@@ -237,7 +237,7 @@ input::selection,
outline-offset: 6px;
background: var(--input-background-color);
border-radius: 6px;
padding-inline-end: 8px;
padding-right: 8px;
color: var(--quick-search-color);
flex-wrap: nowrap;
}
@@ -357,20 +357,13 @@ select.form-control,
outline: 3px solid transparent;
outline-offset: 6px;
padding-inline-end: calc(15px + 1.5rem);
background: var(--input-background-color) var(--dropdown-arrow);;
padding-right: calc(15px + 1.5rem);
background: var(--input-background-color) var(--dropdown-arrow);
color: var(--input-text-color);
border: unset;
border-radius: 0.375rem;
}
body[dir=rtl] select,
body[dir=rtl] select.form-select,
body[dir=rtl] select.form-control,
body[dir=rtl] .select-button.dropdown-toggle.btn {
background-position: left 0.75rem center;
}
select:hover,
select.form-select:hover,
select.form-control:hover,
@@ -451,7 +444,7 @@ optgroup {
content: "\eae1";
width: 2em;
height: 100%;
inset-inline-end: 0;
right: 0;
top: 0;
font-size: 1.2em;
font-family: boxicons;
@@ -469,7 +462,7 @@ optgroup {
--box-label-gap: 0.5em;
position: relative;
padding-inline-start: calc(var(--box-size) + var(--box-label-gap)) !important;
padding-left: calc(var(--box-size) + var(--box-label-gap)) !important;
user-select: none;
}
@@ -478,7 +471,7 @@ optgroup {
label.tn-checkbox > input[type="checkbox"] {
position: absolute;
top: 0;
inset-inline-start: 0;
left: 0;
width: var(--box-size);
height: 100%;
margin: unset;
@@ -492,7 +485,7 @@ optgroup {
content: "";
position: absolute;
top: 50%;
inset-inline-start: 0;
left: 0;
translate: 0 -50%;
width: var(--box-size);
height: var(--box-size);

View File

@@ -19,11 +19,11 @@
}
.chat-message.user-message {
margin-inline-start: auto;
margin-left: auto;
}
.chat-message.assistant-message {
margin-inline-end: auto;
margin-right: auto;
}
.message-avatar {
@@ -33,7 +33,7 @@
display: flex;
align-items: center;
justify-content: center;
margin-inline-end: 8px;
margin-right: 8px;
}
.user-message .message-avatar {

View File

@@ -1,261 +0,0 @@
:root .excalidraw {
--ui-font: var(--main-font-family);
/* Button hover background color */
--button-hover-bg: var(--hover-item-background-color);
--color-surface-high: var(--hover-item-background-color);
--button-active-border: transparent;
--color-brand-active: transparent;
--color-surface-mid: transparent;
--color-surface-low: transparent;
/* Slider colors */
--color-slider-track: var(--menu-item-delimiter-color);
--color-slider-thumb: var(--muted-text-color);
/* Selected button icon fill color */
--color-on-primary-container: var(--ck-editor-toolbar-button-on-color);
--color-primary: var(--ck-editor-toolbar-button-on-color);
/* Selected button icon background color */
--color-surface-primary-container: var(--ck-editor-toolbar-button-on-background);
--color-primary-light: var(--ck-editor-toolbar-button-on-background);
--island-bg-color: var(--floating-button-background-color);
}
/* Dark theme tweaks */
:root body .excalidraw.theme--dark {
--color-surface-high: transparent;
--color-brand-hover: transparent;
}
:root .excalidraw.theme--dark.excalidraw .App-mobile-menu,
:root .excalidraw.theme--dark.excalidraw .App-menu__left {
--button-hover-bg: var(--hover-item-background-color);
}
:root .excalidraw.theme--dark.excalidraw .dropdown-menu-button:hover {
--background: var(--hover-item-background-color);
}
/* Backdrop blur pseudo-element */
.Island:not(.App-menu__left)::before,
.excalidraw .picker::before,
:root .App-menu__left > .panelColumn > fieldset::before,
:root .App-menu__left > .panelColumn > label::before,
:root .App-menu__left > .panelColumn > div:has(> *)::before {
display: block;
position: absolute;
content: "";
top: 0;
left: 0;
width: 100%;
height: 100%;
border-radius: inherit;
backdrop-filter: blur(10px) saturate(6);
z-index: -1;
}
/* Note's root */
:root .type-canvas {
--floating-buttons-vert-offset: 20px;
}
/* Context menus */
/* Context menu - outer wrapper */
:root .excalidraw .popover {
--padding: 0;
max-width: unset;
overflow: hidden;
font-family: var(--main-font-family);
}
/* Context menu - inner wrapper */
:root .excalidraw .popover > .context-menu {
margin: 0;
padding: 8px !important;
overflow-y: auto;
overflow-x: hidden;
height: 100%;
border: none;
padding: 0;
box-shadow: none;
background: transparent;
}
/* Context menu item */
:root .excalidraw .context-menu .context-menu-item {
--menu-item-start-padding: 22px;
border: 1px solid transparent;
}
/* Context menu item icon */
:root .excalidraw .dropdown-menu-item__icon {
color: var(--menu-item-icon-color);
}
/* Context menu item label */
:root .excalidraw .context-menu-item__label,
:root .excalidraw .context-menu-item.dangerous .context-menu-item__label {
color: var(--menu-text-color);
}
:root .excalidraw .context-menu-item:hover .context-menu-item__label {
color: var(--hover-item-text-color);
}
/* Context menu item keyboard shortcut */
:root .excalidraw .context-menu-item__shortcut {
padding: 0;
opacity: 1;
}
/* Context menu separator */
.excalidraw .context-menu .context-menu-item-separator {
margin: 8px 0;
opacity: 1;
}
/* Main menu */
/* Hide separators - no longer needed as the menu group headers feature a delimiter line */
.excalidraw .Island.dropdown-menu-container>div:not(:has(>*)) {
display: none;
}
/* Menu group header */
.excalidraw .dropdown-menu-container .dropdown-menu-group-title,
.excalidraw .Island.dropdown-menu-container div[data-testid="canvas-background-label"] {
margin: 0 !important;
}
/* Header */
.excalidraw .App-menu.App-menu_top {
align-items: center;
}
.excalidraw .App-menu.App-menu_top .App-menu_top__left {
/* Fixes a layout glitch with the header when the options panel is visbile */
--gap: 0 !important;
}
/* The parent element of the "Library" button */
.excalidraw .App-menu.App-menu_top > div:nth-child(3) {
flex-direction: row-reverse;
}
/* Panels */
.excalidraw .zoom-actions,
.undo-redo-buttons {
box-shadow: 1px 1px 1px var(--floating-button-shadow-color);
backdrop-filter: blur(10px) saturate(6);
}
:root .excalidraw .main-menu-trigger,
:root .excalidraw .sidebar-trigger,
:root .excalidraw .help-icon {
box-shadow: none;
}
/* Selected color outline */
:root .excalidraw .color-picker__button.active .color-picker__button-outline {
box-shadow: 0 0 0 2px var(--input-focus-outline-color);
}
:root .excalidraw .buttonList label.active {
border-color: transparent;
}
/* Options panel */
.excalidraw .Island.App-menu__left {
box-shadow: none;
background: transparent;
backdrop-filter: none;
width: 13.2em;
}
body[dir=ltr] .excalidraw .Island.App-menu__left {
right: 0;
}
body[dir=rtl] .excalidraw .Island.App-menu__left {
left: 0;
}
:root .App-menu__left > .panelColumn {
row-gap: 5px;
}
/* Options panel card */
:root .App-menu__left > .panelColumn > fieldset,
:root .App-menu__left > .panelColumn > label,
:root .App-menu__left > .panelColumn > div:has(> *) {
position: relative;
margin: 0;
border-radius: 4px;
box-shadow: 1px 1px 1px var(--floating-button-shadow-color);
background: var(--floating-button-background-color);
padding: 8px 12px;
/* backdrop: blur() creates a new stacking context that prevents some popovers like the
* arrowheads picker from being positioned correctly. To workaround this, the backdrop blur
* effect is applyed using a pseudo-element instead. */
}
/* Options panel card title */
:root .App-menu__left fieldset > legend,
:root .App-menu__left div > h3,
:root .App-menu__left > .panelColumn > label {
text-transform: uppercase;
font-size: .65rem;
letter-spacing: 1pt;
color: var(--muted-text-color);
}
/* Options panel button bar */
:root .excalidraw .App-menu__left .buttonList {
padding: 0;
}
/* Picker */
body[dir=ltr] .excalidraw .App-menu__left .buttonList .picker {
translate: -80% 0;
}
/* Properties panel */
body[dir=ltr] .excalidraw .exc-stats {
left: 0;
}
body[dir=rtl] .excalidraw .exc-stats {
right: 0;
}
/* Sidebar */
.split-note-container-widget > .component.type-canvas:has(.excalidraw-container > .Island.default-sidebar) > .floating-buttons {
/* Hide the floating buttons when the sidebar is open */
display: none;
}
/* Pickers */
.excalidraw .picker {
position: relative;
}

View File

@@ -117,9 +117,9 @@
content: "";
position: absolute;
top: var(--negative-padding);
inset-inline-end: var(--negative-padding);
right: var(--negative-padding);
bottom: var(--negative-padding);
inset-inline-start: var(--negative-padding);
left: var(--negative-padding);
border-radius: var(--dropdown-border-radius);
backdrop-filter: var(--dropdown-backdrop-filter);
z-index: -1;
@@ -210,7 +210,7 @@
/* Separator */
:root .ck .ck-list__separator {
margin: .5em 0;
margin-inline-start: calc(0px - var(--ck-editor-popup-padding));
margin-left: calc(0px - var(--ck-editor-popup-padding));
width: calc(100% + (var(--ck-editor-popup-padding) * 2));
background: var(--menu-item-delimiter-color);
}
@@ -233,8 +233,8 @@
position: absolute;
top: 0;
bottom: var(--negative-padding);
inset-inline-start: var(--negative-padding);
inset-inline-end: var(--negative-padding);
left: var(--negative-padding);
right: var(--negative-padding);
border-top: 1px solid var(--ck-editor-popup-border-color);
background: var(--menu-section-background-color);
}
@@ -255,7 +255,7 @@
:root .ck.ck-toolbar .ck.ck-toolbar__separator {
background: transparent;
border-inline-start: 1px solid var(--ck-color-toolbar-border);
border-left: 1px solid var(--ck-color-toolbar-border);
}
/* The last separator of the toolbar */
@@ -354,8 +354,7 @@
align-items: center;
width: 100%;
margin: 4px;
background: color-mix(in srgb, var(--accent) 15%, var(--main-background-color));
padding-inline-end: 2em;
padding-right: 2em;
border: 1px solid var(--accent);
border-radius: 6px;
}
@@ -493,7 +492,7 @@ button.ck.ck-button:is(.ck-button-action, .ck-button-save, .ck-button-cancel).ck
/* Move the label above the text box regardless of the text box state */
transform: translate(0, calc(-.2em - var(--ck-input-label-height))) !important;
padding-inline-start: 0 !important;
padding-left: 0 !important;
background: transparent;
font-size: .85em;
font-weight: 600;
@@ -557,7 +556,7 @@ pre button.copy-button.icon-action {
}
:root pre:has(> button.copy-button) {
padding-inline-end: calc(var(--icon-button-size) + (var(--copy-button-margin-size) * 2));
padding-right: calc(var(--icon-button-size) + (var(--copy-button-margin-size) * 2));
}
html .note-detail-editable-text :not(figure, .include-note, hr):first-child {
@@ -616,12 +615,12 @@ html .note-detail-editable-text :not(figure, .include-note, hr):first-child {
.ck-content blockquote:before {
content: "“";
inset-inline-start: 0.2em;
left: 0.2em;
}
.ck-content blockquote:after {
content: "”";
inset-inline-end: 0.35em;
right: 0.35em;
}
.ck-content h2,

View File

@@ -52,7 +52,7 @@
background-color: #f5f5f5;
}
.google-login-btn img {
margin-inline-end: 10px;
margin-right: 10px;
width: 18px;
height: 18px;
}
@@ -199,7 +199,7 @@ body.desktop .option-section:not(.tn-no-card) {
color: var(--launcher-pane-text-color);
margin-top: calc(-1 * var(--options-card-padding) - var(--options-title-font-size) - var(--options-title-offset)) !important;
margin-bottom: calc(var(--options-title-offset) + var(--options-card-padding)) !important;
margin-inline-start: calc(-1 * var(--options-card-padding));
margin-left: calc(-1 * var(--options-card-padding));
}
.options-section:not(.tn-no-card) h5 {
@@ -216,8 +216,8 @@ body.desktop .option-section:not(.tn-no-card) {
.options-section hr {
--bs-border-width: 2px;
margin-inline-start: calc(var(--options-card-padding) * -1);
margin-inline-end: calc(var(--options-card-padding) * -1);
margin-left: calc(var(--options-card-padding) * -1);
margin-right: calc(var(--options-card-padding) * -1);
opacity: 1;
color: var(--root-background);
}

View File

@@ -95,7 +95,7 @@ div.promoted-attributes-container {
/* Note type dropdown */
ul.note-type-dropdown .check {
margin-inline-end: 6px;
margin-right: 6px;
}
ul.note-type-dropdown li.dropdown-item {
@@ -105,7 +105,7 @@ ul.note-type-dropdown li.dropdown-item {
/* Editability dropdown */
ul.editability-dropdown li.dropdown-item > div {
margin-inline-start: 4px;
margin-left: 4px;
}
.editability-dropdown .dropdown-item .description {
@@ -142,12 +142,12 @@ ul.editability-dropdown li.dropdown-item > div {
}
.attribute-list .save-attributes-button {
inset-inline-end: 30px;
right: 30px;
}
/* Note path in attribute detail dialog */
.attr-detail .note-path {
margin-inline-start: 8px;
margin-left: 8px;
}
/*

View File

@@ -18,7 +18,7 @@
body {
--native-titlebar-darwin-x-offset: 10;
--native-titlebar-darwin-y-offset: 12 !important;
--native-titlebar-darwin-y-offset: 17 !important;
}
body.layout-horizontal {
@@ -69,7 +69,7 @@ body.background-effects.platform-win32.layout-vertical #vertical-main-container
/* Add a border to the vertical launch bar if collapsed. */
body.layout-vertical #horizontal-main-container.left-pane-hidden #launcher-pane.vertical {
border-inline-end: 2px solid var(--left-pane-collapsed-border-color);
border-right: 2px solid var(--left-pane-collapsed-border-color);
}
body.background-effects.zen #root-widget {
@@ -100,7 +100,7 @@ body.layout-horizontal > .horizontal {
align-items: center;
}
body[dir=ltr] #launcher-container {
#launcher-container {
scrollbar-gutter: stable both-edges;
}
@@ -279,13 +279,16 @@ body[dir=ltr] #launcher-container {
animation: sync-status-pulse 1s ease-in-out alternate-reverse infinite;
}
#launcher-pane button.global-menu-button {
--update-badge-x-offset: 3%;
--update-badge-y-offset: -12%;
#launcher-pane .global-menu-button {
--hover-item-background-color: transparent;
}
#launcher-pane.horizontal .global-menu-button .global-menu-button-update-available {
right: -23px;
bottom: -22px;
transform: scale(0.85);
}
.tooltip .tooltip-arrow {
display: none;
}
@@ -397,9 +400,9 @@ body[dir=ltr] #launcher-container {
content: "";
position: absolute;
top: var(--vertical-margin);
inset-inline-end: var(--horiz-margin);
right: var(--horiz-margin);
bottom: var(--vertical-margin);
inset-inline-start: var(--horiz-margin);
left: var(--horiz-margin);
border-radius: 6px;
background: var(--calendar-day-highlight-background);
z-index: -1;
@@ -447,7 +450,7 @@ div.bookmark-folder-widget .note-link:hover {
}
div.bookmark-folder-widget .note-link a {
padding-inline-start: 8px;
padding-left: 8px;
color: var(--menu-text-color);
cursor: default;
}
@@ -468,8 +471,8 @@ div.bookmark-folder-widget .note-link .bx {
div.quick-search {
--padding-top: 8px;
--padding-inline-start: 8px;
--padding-inline-end: 8px;
--padding-left: 8px;
--padding-right: 8px;
--padding-bottom: 8px;
position: relative;
@@ -477,7 +480,7 @@ div.quick-search {
align-items: center;
height: unset;
contain: unset;
padding: var(--padding-top) var(--padding-inline-end) var(--padding-bottom) var(--padding-inline-start);
padding: var(--padding-top) var(--padding-right) var(--padding-bottom) var(--padding-left);
}
div.quick-search,
@@ -493,9 +496,9 @@ div.quick-search::before {
position: absolute;
content: "";
top: var(--padding-top);
inset-inline-start: var(--padding-inline-start);
left: var(--padding-left);
bottom: var(--padding-bottom);
inset-inline-end: var(--padding-inline-end);
right: var(--padding-right);
z-index: 0;
border: 2px solid transparent;
border-radius: 6px;
@@ -517,7 +520,7 @@ div.quick-search:focus-within:before {
}
div.quick-search input {
padding-inline-start: 15px !important;
padding-left: 15px !important;
box-shadow: unset !important;
background: transparent !important;
}
@@ -536,7 +539,7 @@ div.quick-search .search-button {
justify-content: center;
width: 25px;
height: 25px;
margin-inline-end: 8px;
margin-right: 8px;
border-radius: 50%;
padding: 0;
color: var(--quick-search-color) !important;
@@ -628,18 +631,18 @@ body.layout-vertical.background-effects div.quick-search .dropdown-menu {
}
#left-pane .ui-fancytree ul {
padding-inline-start: 10px;
padding-left: 10px;
}
/* The root element of the tree */
#left-pane .fancytree-container > li:first-child > span {
padding-inline-start: 12px;
padding-left: 12px;
}
#left-pane span.fancytree-node.fancytree-active {
position: relative;
background: transparent !important;
color: var(--custom-color, var(--left-pane-item-selected-color));
color: var(--left-pane-item-selected-color) !important;
}
@keyframes left-pane-item-select {
@@ -655,10 +658,10 @@ body.layout-vertical.background-effects div.quick-search .dropdown-menu {
position: absolute;
content: "";
top: var(--left-pane-item-selected-shadow-size);
inset-inline-start: var(--left-pane-item-selected-shadow-size);
left: var(--left-pane-item-selected-shadow-size);
bottom: var(--left-pane-item-selected-shadow-size);
inset-inline-end: var(--left-pane-item-selected-shadow-size);
background: var(--custom-bg-color, var(--left-pane-item-selected-background)) !important;
right: var(--left-pane-item-selected-shadow-size);
background: var(--left-pane-item-selected-background) !important;
box-shadow: var(--left-pane-item-selected-shadow);
border-radius: 6px;
animation: left-pane-item-select 200ms ease-out;
@@ -673,7 +676,7 @@ body.layout-vertical.background-effects div.quick-search .dropdown-menu {
#left-pane span.fancytree-node.protected > span.fancytree-custom-icon:after {
position: absolute;
bottom: 0;
inset-inline-end: 0;
right: 0;
font-size: 14px;
content: "\eb4a";
font-family: "boxicons";
@@ -682,10 +685,6 @@ body.layout-vertical.background-effects div.quick-search .dropdown-menu {
border-radius: 50%;
}
body[dir=rtl] #left-pane span.fancytree-node.protected > span.fancytree-custom-icon:after {
transform: translateX(-25%);
}
body.mobile .fancytree-expander::before,
body.mobile .fancytree-title,
body.mobile .fancytree-node > span {
@@ -700,7 +699,7 @@ body.mobile .fancytree-node > span {
body.mobile:not(.force-fixed-tree) #mobile-sidebar-wrapper {
border-top-right-radius: 12px;
border-bottom-right-radius: 12px;
border-inline-end: 1px solid var(--subtle-border-color);
border-right: 1px solid var(--subtle-border-color);
}
}
@@ -718,6 +717,9 @@ body.mobile .fancytree-node > span {
margin-top: 0; /* Use this to align the icon with the tree view item's caption */
}
#left-pane span .fancytree-title {
margin-top: -5px;
}
#left-pane span.fancytree-active .fancytree-title {
font-weight: normal;
@@ -732,7 +734,7 @@ body.mobile .fancytree-node > span {
}
#left-pane .tree-item-button {
margin-inline-end: 6px;
margin-right: 6px;
border: unset;
border-radius: 50%;
background: var(--left-pane-item-action-button-background);
@@ -766,12 +768,12 @@ body.mobile .fancytree-node > span {
/* Toolbar container (collapsed state) */
#left-pane .tree-actions {
max-width: var(--tree-actions-toolbar-collapsed-width);
inset-inline-end: var(--tree-actions-toolbar-horizontal-margin);
right: var(--tree-actions-toolbar-horizontal-margin);
bottom: var(--tree-actions-toolbar-vertical-margin);
overflow: hidden;
border: 1px solid transparent;
padding: var(--tree-actions-toolbar-padding-size);
padding-inline-end: var(--tree-actions-toolbar-collapsed-width);
padding-right: var(--tree-actions-toolbar-collapsed-width);
background: transparent;
transition:
max-width 400ms ease-out,
@@ -815,7 +817,7 @@ body.mobile .fancytree-node > span {
justify-content: center;
align-items: center;
top: 50%;
inset-inline-end: calc((var(--tree-actions-toolbar-collapsed-width) - var(--tree-actions-toolbar-expand-button-size)) / 2);
right: calc((var(--tree-actions-toolbar-collapsed-width) - var(--tree-actions-toolbar-expand-button-size)) / 2);
width: var(--tree-actions-toolbar-expand-button-size);
height: var(--tree-actions-toolbar-expand-button-size);
box-shadow: 2px 2px 6px var(--left-pane-background-color);
@@ -904,8 +906,8 @@ body.electron.background-effects.layout-horizontal .tab-row-container .toggle-bu
content: "";
position: absolute;
bottom: 0;
inset-inline-start: -10px;
inset-inline-end: -10px;
left: -10px;
right: -10px;
top: 32px;
height: 1px;
border-bottom: 1px solid var(--launcher-pane-horiz-border-color);
@@ -916,13 +918,13 @@ body.electron.background-effects.layout-horizontal .tab-row-container .tab-scrol
position: relative;
}
body.electron.background-effects.layout-horizontal .tab-row-container .tab-scroll-button-inset-inline-start:after,
body.electron.background-effects.layout-horizontal .tab-row-container .tab-scroll-button-inset-inline-end:after {
body.electron.background-effects.layout-horizontal .tab-row-container .tab-scroll-button-left:after,
body.electron.background-effects.layout-horizontal .tab-row-container .tab-scroll-button-right:after {
content: "";
position: absolute;
bottom: 0;
inset-inline-start: 0px;
inset-inline-end: 0px;
left: 0px;
right: 0px;
height: 1px;
border-bottom: 1px solid var(--launcher-pane-horiz-border-color);
}
@@ -931,9 +933,9 @@ body.electron.background-effects.layout-horizontal .tab-row-container .note-tab[
content: "";
position: absolute;
bottom: 0;
inset-inline-start: -32768px;
left: -32768px;
top: var(--tab-height);
inset-inline-end: calc(100% - 1px);
right: calc(100% - 1px);
height: 1px;
border-bottom: 1px solid var(--launcher-pane-horiz-border-color);
}
@@ -942,9 +944,9 @@ body.electron.background-effects.layout-horizontal .tab-row-container .note-tab[
content: "";
position: absolute;
bottom: 0;
inset-inline-start: 100%;
left: 100%;
top: var(--tab-height);
inset-inline-end: 0;
right: 0;
width: 100vw;
height: 1px;
border-bottom: 1px solid var(--launcher-pane-horiz-border-color);
@@ -954,9 +956,9 @@ body.electron.background-effects.layout-horizontal .tab-row-container .note-new-
content: "";
position: absolute;
bottom: 0;
inset-inline-start: -4px;
left: -4px;
top: calc(var(--tab-height), -1);
inset-inline-end: 0;
right: 0;
width: 100vw;
height: 1px;
border-bottom: 1px solid var(--launcher-pane-horiz-border-color);
@@ -1043,18 +1045,18 @@ body.layout-horizontal .tab-row-widget .note-tab .note-tab-wrapper {
content: "";
position: absolute;
top: 0;
inset-inline-start: 0;
inset-inline-end: 0;
left: 0;
right: 0;
height: 3px;
background-color: var(--workspace-tab-background-color);
}
body:not([dir=rtl]) .tab-row-widget .note-tab:nth-child(1) {
.tab-row-widget .note-tab:nth-child(1) {
transform: translate3d(var(--tab-first-item-horiz-offset), 0, 0);
}
:root .tab-row-widget .note-tab .note-tab-icon {
padding-inline-end: 5px; /* The gap between the icon and the title */
padding-right: 5px; /* The gap between the icon and the title */
}
.tab-row-widget .note-tab[active] .note-tab-icon {
@@ -1099,7 +1101,7 @@ body.layout-vertical .tab-row-widget-is-sorting .note-tab.note-tab-is-dragging .
.tab-row-widget .note-new-tab {
position: relative;
margin-inline-start: 3px;
margin-left: 3px;
color: transparent; /* Prevent the original "+" from being displayed */
}
@@ -1112,7 +1114,7 @@ body.layout-vertical .tab-row-widget-is-sorting .note-tab.note-tab-is-dragging .
position: absolute;
content: "";
top: calc((var(--tab-height) - var(--new-tab-button-size)) / 2);
inset-inline-start: calc((var(--tab-height) - var(--new-tab-button-size)) / 2);
left: calc((var(--tab-height) - var(--new-tab-button-size)) / 2);
width: var(--new-tab-button-size);
height: var(--new-tab-button-size);
background: var(--new-tab-button-background);
@@ -1137,7 +1139,7 @@ body.layout-vertical .tab-row-widget-is-sorting .note-tab.note-tab-is-dragging .
display: flex;
position: absolute;
content: "\ebc0";
inset-inline-start: 0;
left: 0;
top: 0;
width: 100%;
height: 100%;
@@ -1219,23 +1221,23 @@ body.mobile .note-title {
}
.title-row > *:first-child {
margin-inline-end: 0;
margin-right: 0;
}
.title-row > *:nth-child(2) {
margin-inline-start: 0;
margin-left: 0;
}
.title-row {
/* Aligns the "Create new split" button with the note menu button (the three dots button) */
padding-inline-end: 3px;
padding-right: 3px;
}
.note-title-widget input {
--input-background-color: transparent;
border-radius: 8px;
padding-inline-start: 12px;
padding-left: 12px;
}
/* The "Change note icon" button */
@@ -1310,7 +1312,7 @@ body.mobile .note-title {
/* The promoted attributes section */
div.promoted-attributes-container {
display: flex;
margin-inline-end: 10%;
margin-right: 10%;
padding: 6px 0;
gap: 8px;
align-items: stretch;
@@ -1324,8 +1326,8 @@ div.promoted-attributes-container input {
/* A promoted attribute card */
div.promoted-attribute-cell {
--pa-card-padding-inline-start: 16px;
--pa-card-padding-inline-end: 2px;
--pa-card-padding-left: 16px;
--pa-card-padding-right: 2px;
--input-background-color: transparent;
box-shadow: 1px 1px 2px var(--promoted-attribute-card-shadow-color);
@@ -1333,7 +1335,7 @@ div.promoted-attribute-cell {
display: inline-flex;
margin: 0;
border-radius: 8px;
padding: 2px var(--pa-card-padding-inline-end) 2px var(--pa-card-padding-inline-start);
padding: 2px var(--pa-card-padding-right) 2px var(--pa-card-padding-left);
background: var(--promoted-attribute-card-background-color);
overflow-y: visible;
}
@@ -1348,7 +1350,7 @@ div.promoted-attribute-cell {
/* A promoted attribute card (boolean attribute) */
div.promoted-attribute-cell:has(input[type="checkbox"]):not(:has(.multiplicity > span)) {
/* Checbox attribute, without multiplicity */
padding-inline-end: var(--pa-card-padding-inline-start);
padding-right: var(--pa-card-padding-left);
}
div.promoted-attribute-cell > * {
@@ -1398,15 +1400,15 @@ div.promoted-attribute-cell .tn-checkbox {
/* Relocate the checkbox before the label */
div.promoted-attribute-cell.promoted-attribute-label-boolean > div:first-of-type {
order: -1;
margin-inline-end: 1.5em;
margin-right: 1.5em;
}
/* The element containing the "new attribute" and "remove this attribute button" */
div.promoted-attribute-cell .multiplicity:has(span) {
--icon-button-size: 24px;
margin-inline-start: 8px;
margin-inline-end: calc(var(--pa-card-padding-inline-start) - var(--pa-card-padding-inline-end));
margin-left: 8px;
margin-right: calc(var(--pa-card-padding-left) - var(--pa-card-padding-right));
font-size: 0; /* Prevent whitespaces creating a gap between buttons */
display: flex;
}
@@ -1434,10 +1436,6 @@ div#center-pane .floating-buttons-children {
opacity 250ms ease-out;
}
body[dir=rtl] div#center-pane .floating-buttons-children {
transform-origin: left;
}
/* Floating buttons container (collapsed) */
div#center-pane .floating-buttons-children.temporarily-hidden {
display: flex !important;
@@ -1549,7 +1547,7 @@ div.floating-buttons-children .close-floating-buttons {
}
div.floating-buttons-children .close-floating-buttons {
margin-inline-start: 0 !important;
margin-left: 0 !important;
background: var(--floating-button-hide-button-background);
color: var(--floating-button-hide-button-color);
}
@@ -1639,12 +1637,12 @@ div.find-replace-widget div.find-widget-found-wrapper > span {
}
.find-replace-widget .form-check {
padding-inline-start: 0;
padding-left: 0;
white-space: nowrap;
}
.find-replace-widget .form-check .form-check-input {
margin-inline-start: 0;
margin-left: 0;
}
/* Narrow version */
@@ -1664,13 +1662,13 @@ div.find-replace-widget div.find-widget-found-wrapper > span {
.find-widget-box,
.replace-widget-box {
padding-inline-end: 3em !important;
padding-right: 3em !important;
}
.find-widget-close-button {
position: absolute;
top: .85em;
inset-inline-end: .5em;
right: .5em;
}
.find-widget-box > * {
@@ -1702,7 +1700,7 @@ div.find-replace-widget div.find-widget-found-wrapper > span {
}
.replace-widget-box > * {
margin-inline-end: unset !important;
margin-right: unset !important;
}
div.replace-widget-box button.btn.btn-sm {
@@ -1745,7 +1743,7 @@ div.find-replace-widget div.find-widget-found-wrapper > span {
#right-pane .toc li,
#right-pane .highlights-list li {
padding-top: 2px;
padding-inline-end: 8px;
padding-right: 8px;
padding-bottom: 2px;
border-radius: 4px;
text-align: unset;
@@ -1784,6 +1782,10 @@ div.find-replace-widget div.find-widget-found-wrapper > span {
--border-radius-lg: 6px;
}
.excalidraw .Island {
backdrop-filter: var(--dropdown-backdrop-filter);
}
.excalidraw .Island.App-toolbar {
--island-bg-color: var(--floating-button-background-color);
--shadow-island: 1px 1px 1px var(--floating-button-shadow-color);
@@ -1804,8 +1806,8 @@ div.find-replace-widget div.find-widget-found-wrapper > span {
}
.excalidraw .dropdown-menu .dropdown-menu-container > div:not([class]):not(:last-child) {
margin-inline-start: calc(var(--padding) * var(--space-factor) * -1) !important;
margin-inline-end: calc(var(--padding) * var(--space-factor) * -1) !important;
margin-left: calc(var(--padding) * var(--space-factor) * -1) !important;
margin-right: calc(var(--padding) * var(--space-factor) * -1) !important;
}
.excalidraw .dropdown-menu:before {

View File

@@ -1,5 +1,5 @@
ul.fancytree-container {
padding-inline-start: 0;
padding-left: 0;
}
ul.fancytree-container li {
@@ -15,8 +15,10 @@ span.fancytree-node.fancytree-hide {
flex-shrink: 1;
flex-grow: 1;
overflow: hidden;
margin-inline-start: 7px;
margin-left: 7px;
outline: none;
position: relative;
top: 2px;
}
.fancytree-expander {
@@ -40,7 +42,6 @@ span.fancytree-node.fancytree-hide {
text-overflow: ellipsis;
user-select: none !important;
-webkit-user-select: none !important;
color: var(--custom-color, inherit);
}
.fancytree-node:not(.fancytree-loading) .fancytree-expander {
@@ -58,11 +59,7 @@ span.fancytree-node.fancytree-hide {
line-height: 1;
position: relative;
top: 2px;
margin-inline-end: 5px;
}
body[dir=rtl] .fancytree-node:not(.fancytree-loading):not(.fancytree-expanded) .fancytree-expander:before {
content: "\ea4d"; /* bx bx-chevron-left */
margin-right: 5px;
}
.fancytree-loading span.fancytree-expander {
@@ -83,7 +80,7 @@ body[dir=rtl] .fancytree-node:not(.fancytree-loading):not(.fancytree-expanded) .
width: 12px;
height: 12px;
margin-top: 2px;
margin-inline-start: 1px;
margin-left: 1px;
border-width: 1px;
border-style: solid;
}
@@ -172,15 +169,15 @@ span.fancytree-node.fancytree-active-clone:not(.fancytree-active) .fancytree-tit
/* first nesting level has lower left padding to avoid extra left padding. Other levels are not affected */
.ui-fancytree > li > ul {
padding-inline-start: 5px;
padding-left: 5px;
}
.ui-fancytree ul {
padding-inline-start: 20px;
padding-left: 20px;
}
span.fancytree-active {
color: var(--active-item-text-color);
color: var(--active-item-text-color) !important;
background-color: var(--active-item-background-color) !important;
border-color: transparent; /* invisible border */
border-radius: 5px;
@@ -232,14 +229,14 @@ span.fancytree-node.archived {
display: none;
font-size: 120%;
cursor: pointer;
margin-inline-start: 8px;
margin-left: 8px;
padding: 1px;
border: 1px solid transparent;
border-radius: 5px;
}
.unhoist-button.bx.tree-item-button {
margin-inline-start: 0; /* unhoist button is on the left and doesn't need more margin */
margin-left: 0; /* unhoist button is on the left and doesn't need more margin */
display: block; /* keep always visible */
}

View File

@@ -3,8 +3,6 @@ import FNote from "../entities/fnote.js";
import froca from "../services/froca.js";
import FAttribute from "../entities/fattribute.js";
import noteAttributeCache from "../services/note_attribute_cache.js";
import FBranch from "../entities/fbranch.js";
import FBlob from "../entities/fblob.js";
type AttributeDefinitions = { [key in `#${string}`]: string; };
type RelationDefinitions = { [key in `~${string}`]: string; };
@@ -12,8 +10,6 @@ type RelationDefinitions = { [key in `~${string}`]: string; };
interface NoteDefinition extends AttributeDefinitions, RelationDefinitions {
id?: string | undefined;
title: string;
children?: NoteDefinition[];
content?: string;
}
/**
@@ -51,38 +47,6 @@ export function buildNote(noteDef: NoteDefinition) {
blobId: ""
});
froca.notes[note.noteId] = note;
let childNotePosition = 0;
// Manage content.
const content = noteDef.content ?? "";
note.getContent = async () => content;
const blob = new FBlob({
blobId: utils.randomString(10),
content,
contentLength: content.length,
dateModified: new Date().toISOString(),
utcDateModified: new Date().toISOString()
});
note.getBlob = async () => blob;
// Manage children.
if (noteDef.children) {
for (const childDef of noteDef.children) {
const childNote = buildNote(childDef);
const branchId = `${note.noteId}_${childNote.noteId}`;
const branch = new FBranch(froca, {
branchId,
noteId: childNote.noteId,
parentNoteId: note.noteId,
notePosition: childNotePosition,
fromSearchNote: false
});
froca.branches[branchId] = branch;
note.addChild(childNote.noteId, branchId, false);
childNotePosition += 10;
}
}
let position = 0;
for (const [ key, value ] of Object.entries(noteDef)) {

File diff suppressed because it is too large Load Diff

View File

@@ -646,9 +646,7 @@
"about": "关于 TriliumNext 笔记",
"logout": "登出",
"show-cheatsheet": "显示快捷帮助",
"toggle-zen-mode": "禅模式",
"new-version-available": "新更新可用",
"download-update": "取得版本 {{latestVersion}}"
"toggle-zen-mode": "禅模式"
},
"zen_mode": {
"button_exit": "退出禅模式"
@@ -738,8 +736,7 @@
"insert_child_note": "插入子笔记",
"delete_this_note": "删除此笔记",
"error_cannot_get_branch_id": "无法获取 notePath '{{notePath}}' 的 branchId",
"error_unrecognized_command": "无法识别的命令 {{command}}",
"note_revisions": "笔记历史版本"
"error_unrecognized_command": "无法识别的命令 {{command}}"
},
"note_icon": {
"change_note_icon": "更改笔记图标",
@@ -752,7 +749,7 @@
"editable": "可编辑",
"basic_properties": "基本属性",
"language": "语言",
"configure_code_notes": "配置代码笔记…"
"configure_code_notes": "配置代码注释..."
},
"book_properties": {
"view_type": "视图类型",
@@ -768,8 +765,7 @@
"table": "表格",
"geo-map": "地理地图",
"board": "看板",
"include_archived_notes": "展示归档笔记",
"presentation": "演示"
"include_archived_notes": "展示归档笔记"
},
"edited_notes": {
"no_edited_notes_found": "今天还没有编辑过的笔记...",
@@ -1262,13 +1258,7 @@
"min-days-in-first-week": "第一周的最小天数",
"first-week-info": "第一周包含一年的第一个周四,基于 <a href=\"https://en.wikipedia.org/wiki/ISO_week_date#First_week\">ISO 8601</a> 标准。",
"first-week-warning": "更改第一周选项可能会导致与现有周笔记重复,已创建的周笔记将不会相应更新。",
"formatting-locale": "日期和数字格式",
"tuesday": "周二",
"wednesday": "周三",
"thursday": "周四",
"friday": "周五",
"saturday": "周六",
"formatting-locale-auto": "依应用的语言设置"
"formatting-locale": "日期和数字格式"
},
"backup": {
"automatic_backup": "自动备份",
@@ -1753,9 +1743,17 @@
"show_login_link": "在共享主题中显示登录链接",
"show_login_link_description": "在共享页面底部添加登录链接",
"check_share_root": "检查共享根状态",
"check_share_root_error": "检查共享根状态时发生意外错误,请检查日志以获取更多信息。",
"share_note_title": "'{{noteTitle}}'",
"share_root_found": "共享根笔记 '{{noteTitle}}' 已准备好",
"share_root_not_found": "未找到带有 #shareRoot 标签的笔记",
"share_root_not_shared": "笔记 '{{noteTitle}}' 具有 #shareRoot 标签,但未共享"
"share_root_not_shared": "笔记 '{{noteTitle}}' 具有 #shareRoot 标签,但未共享",
"share_root_multiple_found": "找到多个具有 #shareRoot 标签的共享笔记:{{- foundNoteTitles}}。将使用笔记 {{- activeNoteTitle}} 作为共享根笔记。",
"share_path": "共享路径",
"share_path_description": "共享笔记的 URL 前缀(例如 '/share' --> '/share/noteId' 或 '/custom-path' --> '/custom-path/noteId')。支持多级嵌套(例如 '/custom-path/sub-path' --> '/custom-path/sub-path/noteId')。刷新页面以应用更改。",
"share_path_placeholder": "/share 或 /custom-path",
"share_subtree": "共享子树",
"share_subtree_description": "共享整个子树,而不是仅共享笔记"
},
"time_selector": {
"invalid_input": "输入的时间值不是有效数字。",
@@ -2075,10 +2073,5 @@
},
"collections": {
"rendering_error": "出现错误无法显示内容。"
},
"presentation_view": {
"edit-slide": "编辑此幻灯片",
"start-presentation": "开始演示",
"slide-overview": "切换幻灯片概览"
}
}

View File

@@ -4,7 +4,7 @@
"homepage": "Domovská stránka:",
"app_version": "Verze aplikace:",
"db_version": "Verze DB:",
"sync_version": "Verze synchronizace:",
"sync_version": "Verze sync:",
"build_date": "Datum sestavení:",
"build_revision": "Revize sestavení:",
"data_directory": "Datový adresář:"
@@ -36,29 +36,6 @@
"add_link": "Přidat odkaz",
"help_on_links": "Nápověda k odkazům",
"note": "Poznámka",
"search_note": "hledat poznámku podle názvu",
"link_title": "Název odkazu",
"button_add_link": "Přidat odkaz"
},
"branch_prefix": {
"prefix": "Prefix: ",
"save": "Uložit"
},
"bulk_actions": {
"bulk_actions": "Hromadné akce",
"affected_notes": "Ovlivněné poznámky",
"notes": "Poznámky"
},
"confirm": {
"cancel": "Zrušit",
"ok": "OK"
},
"delete_notes": {
"cancel": "Zrušit",
"ok": "OK",
"close": "Zavřít"
},
"export": {
"close": "Zavřít"
"search_note": "hledat poznámku podle názvu"
}
}

View File

@@ -646,8 +646,7 @@
"about": "Über Trilium Notes",
"logout": "Abmelden",
"show-cheatsheet": "Cheatsheet anzeigen",
"toggle-zen-mode": "Zen Modus",
"new-version-available": "Neues Update verfügbar"
"toggle-zen-mode": "Zen Modus"
},
"sync_status": {
"unknown": "<p>Der Synchronisations-Status wird bekannt, sobald der nächste Synchronisierungsversuch gestartet wird.</p><p>Klicke, um eine Synchronisierung jetzt auszulösen.</p>",
@@ -734,8 +733,7 @@
"insert_child_note": "Untergeordnete Notiz einfügen",
"delete_this_note": "Diese Notiz löschen",
"error_cannot_get_branch_id": "BranchId für notePath „{{notePath}}“ kann nicht abgerufen werden",
"error_unrecognized_command": "Unbekannter Befehl {{command}}",
"note_revisions": "Notiz Revisionen"
"error_unrecognized_command": "Unbekannter Befehl {{command}}"
},
"note_icon": {
"change_note_icon": "Notiz-Icon ändern",
@@ -764,8 +762,7 @@
"table": "Tabelle",
"geo-map": "Weltkarte",
"board": "Tafel",
"include_archived_notes": "Zeige archivierte Notizen",
"presentation": "Präsentation"
"include_archived_notes": "Zeige archivierte Notizen"
},
"edited_notes": {
"no_edited_notes_found": "An diesem Tag wurden noch keine Notizen bearbeitet...",
@@ -1258,13 +1255,7 @@
"min-days-in-first-week": "Mindestanzahl an Tagen in erster Woche",
"first-week-info": "Die erste Woche, die den ersten Donnerstag des Jahres enthält, basiert auf dem Standard <a href=\"https://en.wikipedia.org/wiki/ISO_week_date#First_week\">ISO 8601</a>.",
"first-week-warning": "Das Ändern der Optionen für die erste Woche kann zu Duplikaten mit bestehenden Wochen-Notizen führen. Bestehende Wochen-Notizen werden nicht entsprechend aktualisiert.",
"formatting-locale": "Datums- und Zahlenformat",
"tuesday": "Dienstag",
"wednesday": "Mittwoch",
"thursday": "Donnerstag",
"friday": "Freitag",
"saturday": "Samstag",
"formatting-locale-auto": "Basierend auf die Anwendungssprache"
"formatting-locale": "Datums- und Zahlenformat"
},
"backup": {
"automatic_backup": "Automatische Sicherung",
@@ -2076,9 +2067,5 @@
},
"collections": {
"rendering_error": "Aufgrund eines Fehlers können keine Inhalte angezeigt werden."
},
"presentation_view": {
"edit-slide": "Diese Folie bearbeiten",
"start-presentation": "Präsentation starten"
}
}

View File

@@ -164,7 +164,6 @@
"importIntoNote": "Import into note",
"chooseImportFile": "Choose import file",
"importDescription": "Content of the selected file(s) will be imported as child note(s) into",
"importZipRecommendation": "When importing a ZIP file, the note hierarchy will reflect the subdirectory structure within the archive.",
"options": "Options",
"safeImportTooltip": "Trilium <code>.zip</code> export files can contain executable scripts which may contain harmful behavior. Safe import will deactivate automatic execution of all imported scripts. Uncheck \"Safe import\" only if the imported archive is supposed to contain executable scripts and you completely trust the contents of the import file.",
"safeImport": "Safe import",
@@ -647,9 +646,7 @@
"about": "About Trilium Notes",
"logout": "Logout",
"show-cheatsheet": "Show Cheatsheet",
"toggle-zen-mode": "Zen Mode",
"new-version-available": "New Update Available",
"download-update": "Get Version {{latestVersion}}"
"toggle-zen-mode": "Zen Mode"
},
"zen_mode": {
"button_exit": "Exit Zen Mode"
@@ -738,7 +735,6 @@
"mobile_detail_menu": {
"insert_child_note": "Insert child note",
"delete_this_note": "Delete this note",
"note_revisions": "Note revisions",
"error_cannot_get_branch_id": "Cannot get branchId for notePath '{{notePath}}'",
"error_unrecognized_command": "Unrecognized command {{command}}"
},
@@ -769,7 +765,6 @@
"table": "Table",
"geo-map": "Geo Map",
"board": "Board",
"presentation": "Presentation",
"include_archived_notes": "Show archived notes"
},
"edited_notes": {
@@ -1418,13 +1413,8 @@
"title": "Localization",
"language": "Language",
"first-day-of-the-week": "First day of the week",
"monday": "Monday",
"tuesday": "Tuesday",
"wednesday": "Wednesday",
"thursday": "Thursday",
"friday": "Friday",
"saturday": "Saturday",
"sunday": "Sunday",
"monday": "Monday",
"first-week-of-the-year": "First week of the year",
"first-week-contains-first-day": "First week contains first day of the year",
"first-week-contains-first-thursday": "First week contains first Thursday of the year",
@@ -1432,8 +1422,7 @@
"min-days-in-first-week": "Minimum days in first week",
"first-week-info": "First week contains first Thursday of the year is based on <a href=\"https://en.wikipedia.org/wiki/ISO_week_date#First_week\">ISO 8601</a> standard.",
"first-week-warning": "Changing first week options may cause duplicate with existing Week Notes and the existing Week Notes will not be updated accordingly.",
"formatting-locale": "Date & number format",
"formatting-locale-auto": "Based on the application's language"
"formatting-locale": "Date & number format"
},
"backup": {
"automatic_backup": "Automatic backup",
@@ -1723,9 +1712,7 @@
"window-on-top": "Keep Window on Top"
},
"note_detail": {
"could_not_find_typewidget": "Could not find typeWidget for type '{{type}}'",
"printing": "Printing in progress...",
"printing_pdf": "Exporting to PDF in progress..."
"could_not_find_typewidget": "Could not find typeWidget for type '{{type}}'"
},
"note_title": {
"placeholder": "type note's title here..."
@@ -1920,9 +1907,17 @@
"show_login_link": "Show Login link in Share theme",
"show_login_link_description": "Add a login link to the Share page footer",
"check_share_root": "Check Share Root Status",
"check_share_root_error": "An unexpected error happened while checking the Share Root Status, please check the logs for more information.",
"share_note_title": "'{{noteTitle}}'",
"share_root_found": "Share root note '{{noteTitle}}' is ready",
"share_root_not_found": "No note with #shareRoot label found",
"share_root_not_shared": "Note '{{noteTitle}}' has #shareRoot label but is not shared"
"share_root_not_shared": "Note '{{noteTitle}}' has #shareRoot label but is not Shared",
"share_root_multiple_found": "Found multiple shared notes with a #shareRoot label: {{- foundNoteTitles}}. The note {{- activeNoteTitle}} will be used as shared root note.",
"share_path": "Share path",
"share_path_description": "The url prefix for shared notes (e.g. '/share' --> '/share/noteId' or '/custom-path' --> '/custom-path/noteId'). Multiple levels of nesting are supported (e.g. '/custom-path/sub-path' --> '/custom-path/sub-path/noteId'). Refresh the page to apply the changes.",
"share_path_placeholder": "/share or /custom-path",
"share_subtree": "Share subtree",
"share_subtree_description": "Share the entire subtree, not just the note"
},
"time_selector": {
"invalid_input": "The entered time value is not a valid number.",
@@ -2033,11 +2028,6 @@
"edit-note-title": "Click to edit note title",
"edit-column-title": "Click to edit column title"
},
"presentation_view": {
"edit-slide": "Edit this slide",
"start-presentation": "Start presentation",
"slide-overview": "Toggle an overview of the slides"
},
"command_palette": {
"tree-action-name": "Tree: {{name}}",
"export_note_title": "Export Note",

View File

@@ -354,7 +354,7 @@
"calendar_root": "marca la nota que debe usarse como raíz para las notas del día. Sólo uno debe estar marcado como tal.",
"archived": "las notas con esta etiqueta no serán visibles de forma predeterminada en los resultados de búsqueda (tampoco en los cuadros de diálogo Saltar a, Agregar vínculo, etc.).",
"exclude_from_export": "las notas (con su subárbol) no se incluirán en ninguna exportación de notas",
"run": "define en qué eventos debe ejecutarse el script. Los valores posibles son:\n<ul>\n<li>frontendStartup - cuando Trilium frontend se inicia (o se actualiza), pero no en móvil.</li>\n<li>mobileStartup - cuando Trilium frontend se inicia (o se actualiza), en móvil.</li>\n<li>backendStartup - cuando Trilium backend se inicia</li>\n<li>hourly - se ejecuta una vez por hora. Se puede usar la etiqueta adicional <code>runAtHour</code> para especificar a qué hora.</li>\n<li>daily - se ejecuta una vez al día</li>\n</ul>",
"run": "define en qué eventos debe ejecutarse el script. Los valores posibles son:\n<ul>\n<li>frontendStartup - cuando el frontend de Trilium inicia (o es recargado), pero no en dispositivos móviles. </li>\n<li>backendStartup - cuando el backend de Trilium se inicia </li>\n<li>hourly - se ejecuta una vez cada hora. Puede usar etiqueta adicional <code>runAtHour</code> para especificar a la hora. </li>\n<li>daily - ejecutar una vez al día </li>\n</ul>",
"run_on_instance": "Definir en qué instancia de Trilium se debe ejecutar esto. Predeterminado para todas las instancias.",
"run_at_hour": "¿A qué hora debería funcionar? Debe usarse junto con <code>#run=hourly</code>. Se puede definir varias veces para varias ejecuciones durante el día.",
"disable_inclusion": "los scripts con esta etiqueta no se incluirán en la ejecución del script principal.",
@@ -384,7 +384,7 @@
"inbox": "ubicación predeterminada de la bandeja de entrada para nuevas notas - cuando crea una nota usando el botón \"nueva nota\" en la barra lateral, las notas serán creadas como subnotas de la nota marcada con la etiqueta <code>#inbox</code>.",
"workspace_inbox": "ubicación predeterminada de la bandeja de entrada para nuevas notas cuando se anclan a algún antecesor de esta nota del espacio de trabajo",
"sql_console_home": "ubicación predeterminada de las notas de la consola SQL",
"bookmark_folder": "la nota con esta etiqueta aparecerá en los marcadores como carpeta (permitiendo el acceso a sus elementos hijos)",
"bookmark_folder": "la nota con esta etiqueta aparecerá en los marcadores como carpeta (permitiendo el acceso a sus elementos hijos).",
"share_hidden_from_tree": "esta nota está oculta en el árbol de navegación izquierdo, pero aún se puede acceder a ella con su URL",
"share_external_link": "la nota actuará como un enlace a un sitio web externo en el árbol compartido",
"share_alias": "define un alias que al usar la nota va a estar disponible en https://your_trilium_host/share/[tu_alias]",
@@ -646,9 +646,7 @@
"about": "Acerca de Trilium Notes",
"logout": "Cerrar sesión",
"show-cheatsheet": "Mostrar hoja de trucos",
"toggle-zen-mode": "Modo Zen",
"new-version-available": "Nueva actualización disponible",
"download-update": "Obtener versión {{latestVersion}}"
"toggle-zen-mode": "Modo Zen"
},
"zen_mode": {
"button_exit": "Salir del modo Zen"
@@ -738,8 +736,7 @@
"insert_child_note": "Insertar subnota",
"delete_this_note": "Eliminar esta nota",
"error_cannot_get_branch_id": "No se puede obtener el branchID del notePath '{{notePath}}'",
"error_unrecognized_command": "Comando no reconocido {{command}}",
"note_revisions": "Revisiones de notas"
"error_unrecognized_command": "Comando no reconocido {{command}}"
},
"note_icon": {
"change_note_icon": "Cambiar icono de nota",
@@ -768,8 +765,7 @@
"table": "Tabla",
"geo-map": "Mapa Geo",
"board": "Tablero",
"include_archived_notes": "Mostrar notas archivadas",
"presentation": "Presentación"
"include_archived_notes": "Mostrar notas archivadas"
},
"edited_notes": {
"no_edited_notes_found": "Aún no hay notas editadas en este día...",
@@ -1014,7 +1010,7 @@
"start_dragging_relations": "Empiece a arrastrar relaciones desde aquí y suéltelas en otra nota.",
"note_not_found": "¡Nota {{noteId}} no encontrada!",
"cannot_match_transform": "No se puede coincidir con la transformación: {{transform}}",
"note_already_in_diagram": "La nota \"{{title}}\" ya está en el diagrama.",
"note_already_in_diagram": "Note \"{{title}}\" is already in the diagram.",
"enter_title_of_new_note": "Ingrese el título de la nueva nota",
"default_new_note_title": "nueva nota",
"click_on_canvas_to_place_new_note": "Haga clic en el lienzo para colocar una nueva nota"
@@ -1256,9 +1252,8 @@
"indexing_stopped": "Indexado detenido",
"indexing_in_progress": "Indexado en progreso...",
"last_indexed": "Último indexado",
"n_notes_queued_0": "{{ count }} nota agregada a la cola para indexar",
"n_notes_queued_1": "{{ count }} notas agregadas a la cola para indexar",
"n_notes_queued_2": "",
"n_notes_queued": "{{ count }} nota agregada a la cola para indexado",
"n_notes_queued_plural": "{{ count }} notas agregadas a la cola para indexado",
"note_chat": "Chat de nota",
"notes_indexed": "{{ count }} nota indexada",
"notes_indexed_plural": "{{ count }} notas indexadas",
@@ -1419,13 +1414,7 @@
"min-days-in-first-week": "Días mínimos en la primer semana",
"first-week-info": "Primer semana que contiene al primer jueves del año está basado en el estándar<a href=\"https://en.wikipedia.org/wiki/ISO_week_date#First_week\">ISO 8601</a>.",
"first-week-warning": "Cambiar las opciones de primer semana puede causar duplicados con las Notas Semanales existentes y las Notas Semanales existentes no serán actualizadas respectivamente.",
"formatting-locale": "Fecha y formato de número",
"tuesday": "Martes",
"wednesday": "Miércoles",
"thursday": "Jueves",
"friday": "Viernes",
"saturday": "Sábado",
"formatting-locale-auto": "Basado en el idioma de la aplicación"
"formatting-locale": "Fecha y formato de número"
},
"backup": {
"automatic_backup": "Copia de seguridad automática",
@@ -1518,7 +1507,7 @@
"recovery_keys_used": "Usado: {{date}}",
"recovery_keys_unused": "El código de recuperación {{index}} está sin usar",
"oauth_title": "OAuth/OpenID",
"oauth_description": "OpenID es un método estandarizado que permite iniciar sesión en sitios web usando una cuenta de otro servicio, como Google, para verificar tu identidad. El emisor predeterminado es Google, pero se puede cambiar a cualquier otro proveedor de OpenID. Consulta <a href=\"#root/_hidden/_help/_help_Otzi9La2YAUX/_help_WOcw2SLH6tbX/_help_7DAiwaf8Z7Rz\">aquí</a> para más información. Sigue estas <a href=\"https://developers.google.com/identity/openid-connect/openid-connect\">instrucciones</a> para configurar un servicio OpenID a través de Google.",
"oauth_description": "OpenID es una forma estandarizada de permitirle iniciar sesión en sitios web utilizando una cuenta de otro servicio, como Google, para verificar su identidad. Siga estas <a href = \"https://developers.google.com/identity/openid-connect/openid-connect\">instrucciones</a> para configurar un servicio OpenID a través de Google.",
"oauth_description_warning": "Para habilitar OAuth/OpenID, necesita establecer la URL base de OAuth/OpenID, ID de cliente y secreto de cliente en el archivo config.ini y reiniciar la aplicación. Si desea establecerlas desde variables de ambiente, por favor establezca TRILIUM_OAUTH_BASE_URL, TRILIUM_OAUTH_CLIENT_ID y TRILIUM_OAUTH_CLIENT_SECRET.",
"oauth_missing_vars": "Ajustes faltantes: {{-variables}}",
"oauth_user_account": "Cuenta de usuario: ",
@@ -1628,8 +1617,8 @@
"unarchive": "Desarchivar"
},
"shared_info": {
"shared_publicly": "Esta nota está compartida públicamente en {{- link}}.",
"shared_locally": "Esta nota está compartida localmente en {{- link}}.",
"shared_publicly": "Esta nota está compartida públicamente en {{- link}}",
"shared_locally": "Esta nota está compartida localmente en {{- link}}",
"help_link": "Para obtener ayuda visite <a href=\"https://triliumnext.github.io/Docs/Wiki/sharing.html\">wiki</a>."
},
"note_types": {
@@ -1991,8 +1980,7 @@
"new-item-placeholder": "Ingresar título de la nota...",
"add-column-placeholder": "Ingresar título de la columna...",
"edit-note-title": "Haga clic para editar el título de la nota",
"edit-column-title": "Haga clic para editar el título de la columna",
"remove-from-board": "Eliminar del tablero"
"edit-column-title": "Haga clic para editar el título de la columna"
},
"content_renderer": {
"open_externally": "Abrir externamente"
@@ -2047,7 +2035,7 @@
},
"call_to_action": {
"next_theme_title": "Prueba el nuevo tema de Trilium",
"next_theme_message": "Estás usando actualmente el tema heredado. ¿Te gustaría probar el nuevo tema?",
"next_theme_message": "Estas usando actualmente el tema heredado, ¿Te gustaría probar el nuevo tema?",
"next_theme_button": "Prueba el nuevo tema",
"background_effects_title": "Los efectos de fondo son ahora estables",
"background_effects_message": "En los dispositivos Windows, los efectos de fondo ya son totalmente estables. Los efectos de fondo añaden un toque de color a la interfaz de usuario difuminando el fondo que hay detrás. Esta técnica también se utiliza en otras aplicaciones como el Explorador de Windows.",
@@ -2075,13 +2063,5 @@
"pagination": {
"total_notes": "{{count}} notas",
"page_title": "Página de {{startIndex}} - {{endIndex}}"
},
"presentation_view": {
"edit-slide": "Editar este slide",
"start-presentation": "Iniciar presentación",
"slide-overview": "Alternar vista general de los slides"
},
"collections": {
"rendering_error": "No se puede mostrar contenido debido a un error."
}
}

View File

@@ -276,12 +276,7 @@
"preview": "Aperçu :",
"preview_not_available": "L'aperçu n'est pas disponible pour ce type de note.",
"restore_button": "Restaurer",
"delete_button": "Supprimer",
"diff_on": "Afficher les différences",
"diff_off": "Afficher le contenu",
"diff_on_hint": "Cliquez pour afficher les différences de la note d'origine",
"diff_off_hint": "Cliquez pour afficher le contenu de la note",
"diff_not_available": "La comparaison n'est pas disponible."
"delete_button": "Supprimer"
},
"sort_child_notes": {
"sort_children_by": "Trier les enfants par...",
@@ -736,8 +731,7 @@
"insert_child_note": "Insérer une note enfant",
"delete_this_note": "Supprimer cette note",
"error_cannot_get_branch_id": "Impossible d'obtenir branchId pour notePath '{{notePath}}'",
"error_unrecognized_command": "Commande non reconnue {{command}}",
"note_revisions": "Révision de la note"
"error_unrecognized_command": "Commande non reconnue {{command}}"
},
"note_icon": {
"change_note_icon": "Changer l'icône de note",
@@ -1631,8 +1625,7 @@
"link_context_menu": {
"open_note_in_new_tab": "Ouvrir la note dans un nouvel onglet",
"open_note_in_new_split": "Ouvrir la note dans une nouvelle division",
"open_note_in_new_window": "Ouvrir la note dans une nouvelle fenêtre",
"open_note_in_popup": "Édition rapide"
"open_note_in_new_window": "Ouvrir la note dans une nouvelle fenêtre"
},
"electron_integration": {
"desktop-application": "Application de bureau",
@@ -1770,14 +1763,7 @@
"reprocess_index": "Rafraîchir l'index de recherche",
"reprocessing_index": "Mise à jour...",
"reprocess_index_started": "L'optimisation de l'indice de recherche à commencer en arrière-plan",
"reprocess_index_error": "Erreur dans le rafraichissement de l'indice de recherche",
"failed_notes": "Notes échouées",
"last_processed": "Dernier traitement",
"restore_provider": "Restaurer le fournisseur de la recherche",
"index_rebuild_progress": "Progression de la reconstruction de l'index",
"index_rebuilding": "Optimisation de l'index ({{percentage}}%)",
"index_rebuild_complete": "Optimisation de l'index terminée",
"index_rebuild_status_error": "Erreur lors de la vérification de l'état de reconstruction de l'index"
"reprocess_index_error": "Erreur dans le rafraichissement de l'indice de recherche"
},
"ui-performance": {
"title": "Performance",

View File

@@ -1,32 +0,0 @@
{
"about": {
"title": "Tentang Trilium Notes",
"homepage": "Halaman utama:",
"app_version": "Versi Aplikasi:",
"db_version": "Versi DB:",
"sync_version": "Versi sinkronisasi:",
"build_date": "Tanggal pembuatan:",
"build_revision": "Revisi pembuatan:",
"data_directory": "Direktori data:"
},
"toast": {
"critical-error": {
"title": "Kesalahan kritis",
"message": "Telah terjadi kesalahan kritis yang mencegah aplikasi klien untuk memulai:\n\n{{message}}\n\nHal ini kemungkinan besar disebabkan oleh skrip yang gagal secara tidak terduga. Coba jalankan aplikasi dalam mode aman dan atasi masalahnya."
},
"widget-error": {
"title": "Gagal menginisialisasi widget",
"message-custom": "Widget kustom dari catatan dengan ID \"{{id}}\", berjudul \"{{title}}\" tidak dapat diinisialisasi karena:\n\n{{message}}",
"message-unknown": "Widget tidak dikenal tidak dapat diinisialisasi karena:\n\n{{message}}"
},
"bundle-error": {
"title": "Gagal memuat skrip kustom",
"message": "Skrip dari catatan dengan ID \"{{id}}\", berjudul \"{{title}}\" tidak dapat dijalankan karena:\n\n{{message}}"
}
},
"add_link": {
"add_link": "Tambah tautan",
"help_on_links": "Bantuan pada tautan",
"note": "Catatan"
}
}

View File

@@ -20,7 +20,7 @@
},
"widget-error": {
"title": "Impossibile inizializzare un widget",
"message-custom": "Il widget personalizzato dalla nota con ID {{id}}”, intitolato “{{title}}”, non è stato possibile inizializzare a causa di:\n\n{{message}}",
"message-custom": "Il widget personalizzato della nota con ID \"{{id}}\", dal titolo \"{{title}}\" non è stato inizializzato a causa di:\n\n{{message}}",
"message-unknown": "Un widget sconosciuto non è stato inizializzato a causa di:\n\n{{message}}"
}
},
@@ -83,15 +83,14 @@
"erase_notes_description": "L'eliminazione normale (soft) marca le note come eliminate e potranno essere recuperate entro un certo lasso di tempo (dalla finestra dei cambiamenti recenti). Selezionando questa opzione le note si elimineranno immediatamente e non sarà possibile recuperarle.",
"erase_notes_warning": "Elimina le note in modo permanente (non potrà essere disfatto), compresi tutti i cloni. Ciò forzerà un nuovo caricamento dell'applicazione.",
"cancel": "Annulla",
"notes_to_be_deleted": "Le seguenti note saranno eliminate ({{notesCount}})",
"notes_to_be_deleted": "Le seguenti note saranno eliminate ({{- noteCount}})",
"no_note_to_delete": "Nessuna nota sarà eliminata (solo i cloni).",
"broken_relations_to_be_deleted": "Le seguenti relazioni saranno interrotte ed eliminate ({{relationCount}})",
"broken_relations_to_be_deleted": "Le seguenti relazioni saranno interrotte ed eliminate ({{- relationCount}})",
"deleted_relation_text": "La nota {{- note}} (da eliminare) è referenziata dalla relazione {{- relation}} originata da {{- source}}."
},
"info": {
"okButton": "OK",
"closeButton": "Chiudi",
"modalTitle": "Messaggio informativo"
"closeButton": "Chiudi"
},
"export": {
"close": "Chiudi",
@@ -113,23 +112,17 @@
},
"password_not_set": {
"body1": "Le note protette sono crittografate utilizzando una password utente, ma la password non è stata ancora impostata.",
"body2": "Per proteggere le note, clicca sul pulsante sottostante per aprire la finestra di dialogo Opzioni e impostare la tua password.",
"title": "La password non è impostata",
"go_to_password_options": "Vai alle opzioni della password"
"body2": "Per proteggere le note, fare clic su <a class=\"open-password-options-button\" href=\"javascript:\">qui</a> per aprire la finestra di dialogo Opzioni e impostare la password."
},
"protected_session_password": {
"close_label": "Chiudi",
"modal_title": "Sessione protetta",
"help_title": "Aiuto sulle note protette",
"form_label": "Per procedere con lazione richiesta, è necessario avviare una sessione protetta inserendo la password:",
"start_button": "Avvia sessione protetta"
"close_label": "Chiudi"
},
"abstract_bulk_action": {
"remove_this_search_action": "Rimuovi questa azione di ricerca"
},
"etapi": {
"new_token_title": "Nuovo token ETAPI",
"new_token_message": "Inserisci il nome del nuovo token"
"new_token_message": "Inserire il nuovo nome del token"
},
"electron_integration": {
"zoom-factor": "Fattore di ingrandimento",
@@ -137,7 +130,7 @@
},
"note_autocomplete": {
"search-for": "Cerca \"{{term}}\"",
"create-note": "Crea e collega la nota secondaria {{term}}",
"create-note": "Crea e collega la nota figlia \"{{term}}\"",
"insert-external-link": "Inserisci il collegamento esterno a \"{{term}}\"",
"clear-text-field": "Pulisci il campo di testo",
"show-recent-notes": "Mostra le note recenti",
@@ -162,20 +155,20 @@
},
"database_anonymization": {
"light_anonymization": "Anonimizzazione parziale",
"title": "Anonimizzazione dei database",
"title": "Anonimizzazione del Database",
"full_anonymization": "Anonimizzazione completa",
"full_anonymization_description": "Questa azione creerà una nuova copia del database e la renderà anonima (rimuovendo tutto il contenuto delle note e lasciando solo la struttura e alcuni metadati non sensibili) per poterla condividere online a scopo di debug senza timore di divulgare i tuoi dati personali.",
"save_fully_anonymized_database": "Salva database completamente anonimizzato",
"full_anonymization_description": "Questa azione creerà una nuova copia del database e lo anonimizzerà (rimuove tutti i contenuti delle note, lasciando solo la struttura e qualche metadato non sensibile) per condividerlo online allo scopo di debugging, senza paura di far trapelare i tuoi dati personali.",
"save_fully_anonymized_database": "Salva il database completamente anonimizzato",
"light_anonymization_description": "Questa azione creerà una nuova copia del database e lo anonimizzerà in parzialmente — in particolare, solo il contenuto delle note sarà rimosso, ma i titoli e gli attributi rimarranno. Inoltre, note con script personalizzati JS di frontend/backend e widget personalizzati lasciando rimarranno. Ciò mette a disposizione più contesto per il debug dei problemi.",
"choose_anonymization": "Puoi decidere da solo se fornire un database completamente o parzialmente anonimizzato. Anche un database completamente anonimizzato è molto utile, sebbene in alcuni casi i database parzialmente anonimizzati possono accelerare il processo di identificazione dei bug e la loro correzione.",
"no_anonymized_database_yet": "Ancora nessun database anonimizzato.",
"save_lightly_anonymized_database": "Salva database leggermente anonimizzato",
"no_anonymized_database_yet": "Nessun database ancora anonimizzato.",
"save_lightly_anonymized_database": "Salva il database parzialmente anonimizzato",
"successfully_created_fully_anonymized_database": "Database completamente anonimizzato creato in {{anonymizedFilePath}}",
"successfully_created_lightly_anonymized_database": "Database parzialmente anonimizzato creato in {{anonymizedFilePath}}"
},
"cpu_arch_warning": {
"title": "Per favore scarica la versione ARM64",
"continue_anyway": "Continua comunque",
"continue_anyway": "Continua Comunque",
"dont_show_again": "Non mostrare più questo avviso",
"download_link": "Scarica la Versione Nativa"
},
@@ -255,7 +248,7 @@
"debug": "debug",
"action": "azione",
"add_search_option": "Aggiungi un opzione di ricerca:",
"search_string": "stringa di ricerca",
"search_string": "cerca la stringa",
"limit": "limite"
},
"modal": {
@@ -276,10 +269,8 @@
"date-and-time": "Data e ora",
"path": "Percorso",
"database_backed_up_to": "Il database è stato archiviato in {{backupFilePath}}",
"enable_daily_backup": "Abilita i backup giornalieri",
"no_backup_yet": "Ancora nessuna archiviazione",
"automatic_backup": "Backup Automatico",
"automatic_backup_description": "Trilium può eseguire automaticamente il backup del database:"
"enable_daily_backup": "Abilita le archiviazioni giornaliere",
"no_backup_yet": "Ancora nessuna archiviazione"
},
"backend_log": {
"refresh": "Aggiorna"
@@ -340,12 +331,12 @@
},
"heading_style": {
"title": "Stile dell'Intestazione",
"plain": "Semplice",
"plain": "Normale",
"underline": "Sottolineato",
"markdown": "Stile Markdown"
},
"highlights_list": {
"title": "Elenco dei punti salienti"
"title": "Punti salienti"
},
"highlights_list_2": {
"title": "Punti salienti",
@@ -360,346 +351,6 @@
"collapseExpand": "collassa/espande il nodo",
"notSet": "non impostato",
"goBackForwards": "indietro/avanti nella cronologia",
"showJumpToNoteDialog": "mostra <a class=\"external\" href=\"https://triliumnext.github.io/Docs/Wiki/note-navigation.html#jump-to-note\">finestra di dialogo “Vai a”</a>",
"title": "Scheda riassuntiva",
"noteNavigation": "Nota navigazione",
"scrollToActiveNote": "scorri fino alla nota attiva",
"jumpToParentNote": "vai alla nota principale",
"collapseWholeTree": "comprimi l'intero albero delle note",
"collapseSubTree": "comprimi sottoalbero",
"tabShortcuts": "Scorciatoie delle schede",
"newTabNoteLink": "Il link alla nota apre la nota in una nuova scheda",
"newTabWithActivationNoteLink": "Il link alla nota si apre e attiva la nota in una nuova scheda",
"onlyInDesktop": "Solo nella versione desktop (Electron build)",
"openEmptyTab": "apri scheda vuota",
"closeActiveTab": "chiudi scheda attiva",
"activateNextTab": "attiva la scheda successiva",
"activatePreviousTab": "attiva la scheda precedente",
"creatingNotes": "Creazione di note",
"createNoteAfter": "crea una nuova nota dopo quella attiva",
"createNoteInto": "crea una nuova sotto-nota nella nota attiva",
"editBranchPrefix": "modifica <a class=\"external\" href=\"https://triliumnext.github.io/Docs/Wiki/tree-concepts.html#prefix\">prefisso</a> del clone della nota attiva",
"movingCloningNotes": "Spostamento / clonazione delle note",
"moveNoteUpDown": "spostare la nota verso l'alto/verso il basso nell'elenco delle note",
"moveNoteUpHierarchy": "spostare la nota verso l'alto nella gerarchia",
"multiSelectNote": "nota multi-selezione sopra/sotto",
"selectAllNotes": "seleziona tutte le note del livello corrente",
"selectNote": "seleziona nota",
"copyNotes": "copia la nota attiva (o la selezione corrente) negli appunti (utilizzata per la <a class=\"external\" href=\"https://triliumnext.github.io/Docs/Wiki/cloning-notes.html#cloning-notes\">clonazione</a>)",
"cutNotes": "taglia la nota corrente (o la selezione corrente) negli appunti (utilizzato per spostare le note)",
"pasteNotes": "Incolla le note come sotto-note nella nota attiva (che viene spostata o clonata a seconda che sia stata copiata o tagliata negli appunti)",
"deleteNotes": "eliminazione nota / sottoalbero",
"editingNotes": "Modifica delle note",
"editNoteTitle": "nel riquadro ad albero passa dal riquadro ad albero al titolo della nota. Premendo Invio dal titolo della nota, il focus passerà all'editor di testo. <kbd>Ctrl+.</kbd> riporterà il focus dall'editor al riquadro ad albero.",
"createEditLink": "crea / modifica collegamento esterno",
"createInternalLink": "creare un collegamento interno",
"followLink": "segui il link sotto il cursore",
"insertDateTime": "inserisci la data e l'ora correnti nella posizione del cursore",
"jumpToTreePane": "passa al riquadro dell'albero e scorri fino alla nota attiva",
"markdownAutoformat": "Formattazione automatica simile a Markdown",
"headings": "<code>##</code>, <code>###</code>, <code>####</code> ecc. seguiti da uno spazio per i titoli",
"bulletList": "<code>*</code> o <code>-</code> seguito da uno spazio per un elenco puntato",
"numberedList": "<code>1.</code> o <code>1)</code> seguito da uno spazio per un elenco numerato",
"blockQuote": "inizia una riga con <code>></code> seguito da uno spazio per il blocco di citazione",
"troubleshooting": "Risoluzione dei problemi",
"reloadFrontend": "ricarica il frontend Trilium",
"showDevTools": "mostra strumenti di sviluppo",
"showSQLConsole": "mostra console SQL",
"other": "Altro",
"quickSearch": "concentrati sull'input della ricerca rapida",
"inPageSearch": "ricerca all'interno della pagina"
},
"i18n": {
"saturday": "Sabato",
"sunday": "Domenica",
"first-week-of-the-year": "Prima settimana dell'anno",
"first-week-contains-first-day": "La prima settimana contiene il primo giorno dell'anno",
"first-week-contains-first-thursday": "La prima settimana contiene il primo giovedì dell'anno",
"first-week-has-minimum-days": "La prima settimana ha giorni ridotti",
"min-days-in-first-week": "Giorni minimi nella prima settimana",
"first-week-info": "La prima settimana che contiene il primo giovedì dell'anno si basa su <a href=\"https://en.wikipedia.org/wiki/ISO_week_date#First_week\">ISO 8601</a> standard.",
"first-week-warning": "La modifica delle opzioni della prima settimana può causare duplicati con le note settimanali esistenti e queste ultime non verranno aggiornate di conseguenza.",
"formatting-locale": "Formato data e numero",
"formatting-locale-auto": "In base alla lingua dell'applicazione"
},
"ai_llm": {
"n_notes_queued_0": "{{ count }} nota in coda per l'indicizzazione",
"n_notes_queued_1": "{{ count }} note in coda per l'indicizzazione",
"n_notes_queued_2": "{{ count }} note in coda per l'indicizzazione",
"notes_indexed_0": "{{ count }} nota indicizzata",
"notes_indexed_1": "{{ count }} note indicizzate",
"notes_indexed_2": "{{ count }} note indicizzate"
},
"import": {
"importIntoNote": "Importa nella nota",
"chooseImportFile": "Scegli file di importazione",
"importDescription": "Il contenuto dei file selezionati verranno importati come note secondarie in",
"options": "Opzioni",
"safeImportTooltip": "I file di esportazione Trilium <code>.zip</code> possono contenere script eseguibili che potrebbero avere comportamenti dannosi. L'importazione sicura disattiverà l'esecuzione automatica di tutti gli script importati. Deseleziona “Importazione sicura” solo se l'archivio importato dovrebbe contenere script eseguibili e ti fidi completamente del contenuto del file di importazione.",
"safeImport": "Importazione sicura",
"explodeArchivesTooltip": "Se questa opzione è selezionata, Trilium leggerà i file <code>.zip</code>, <code>.enex</code> e <code>.opml</code> e creerà delle note dai file contenuti in tali archivi. Se l'opzione non è selezionata, Trilium allegherà gli archivi stessi alla nota.",
"shrinkImages": "Riduci immagini",
"explodeArchives": "Leggi il contenuto degli archivi <code>.zip</code>, <code>.enex</code> e <code>.opml</code> .",
"html_import_tags": {
"title": "Tag di importazione HTML",
"description": "Configura quali tag HTML devono essere mantenuti durante l'importazione delle note. I tag che non sono presenti in questo elenco verranno rimossi durante l'importazione. Alcuni tag (come 'script') vengono sempre rimossi per motivi di sicurezza.",
"placeholder": "Inserisci i tag HTML, uno per riga",
"reset_button": "Ripristina elenco predefinito"
},
"import-status": "Stato importazione",
"in-progress": "Importazione in corso: {{progress}}",
"successful": "Importazione completata con successo.",
"shrinkImagesTooltip": "<p>Se selezioni questa opzione, Trilium tenterà di ridurre le immagini importate tramite ridimensionamento e ottimizzazione, il che potrebbe influire sulla qualità percepita dellimmagine. Se non selezionata, le immagini verranno importate senza modifiche.</p><p>Questo non si applica alle importazioni <code>.zip</code> con metadati, poiché si presume che questi file siano già ottimizzati.</p>",
"textImportedAsText": "Importa HTML, Markdown e TXT come note di testo se non è chiaro dai metadati",
"codeImportedAsCode": "Importa i file di codice riconosciuti (ad esempio <code>.json</code>) come note di codice se non è chiaro dai metadati",
"replaceUnderscoresWithSpaces": "Sostituisci i trattini bassi con spazi nei nomi delle note importate",
"import": "Importa",
"failed": "Importazione fallita: {{message}}."
},
"include_note": {
"dialog_title": "Includi nota",
"label_note": "Note",
"placeholder_search": "cerca una nota per nome",
"box_size_prompt": "Dimensione della casella della nota inclusa:",
"box_size_small": "piccola (~ 10 righe)",
"box_size_medium": "media (~ 30 righe)",
"box_size_full": "completa (la casella mostra il testo completo)",
"button_include": "Includi nota"
},
"jump_to_note": {
"search_placeholder": "Cerca una nota per nome oppure digita > per i comandi...",
"search_button": "Cerca nel testo completo"
},
"markdown_import": {
"dialog_title": "Importazione Markdown",
"modal_body_text": "A causa del sandbox del browser non è possibile leggere direttamente gli appunti tramite JavaScript. Incolla il Markdown da importare nell'area di testo sottostante e clicca sul pulsante Importa",
"import_button": "Importa",
"import_success": "Il contenuto Markdown è stato importato nel documento."
},
"move_to": {
"target_parent_note": "Nota principale di destinazione",
"dialog_title": "Sposta note in ...",
"notes_to_move": "Note da spostare",
"search_placeholder": "cerca una nota per nome",
"move_button": "Sposta nella nota selezionata",
"error_no_path": "Nessun percorso in cui spostarsi.",
"move_success_message": "Le note selezionate sono state spostate in "
},
"note_type_chooser": {
"change_path_prompt": "Cambia dove creare la nuova nota:",
"search_placeholder": "cerca percorso per nome (predefinito se vuoto)",
"modal_title": "Scegli il tipo di nota",
"modal_body": "Scegli il tipo / modello della nuova nota:",
"templates": "Modelli",
"builtin_templates": "Modelli incorporati"
},
"prompt": {
"title": "Richiesta",
"ok": "OK",
"defaultTitle": "Richiesta"
},
"recent_changes": {
"title": "Modifiche recenti",
"erase_notes_button": "Cancella ora le note eliminate",
"deleted_notes_message": "Le note eliminate sono state cancellate.",
"no_changes_message": "Nessuna modifica ancora...",
"undelete_link": "ripristinare",
"confirm_undelete": "Vuoi ripristinare questa nota e le sue sotto-note?"
},
"revisions": {
"note_revisions": "Note Revisioni",
"delete_all_revisions": "Elimina tutte le revisioni di questa nota",
"delete_all_button": "Elimina tutte le revisioni",
"help_title": "Aiuto sulle revisioni delle note",
"revision_last_edited": "Questa revisione è stata modificata l'ultima volta il {{date}}",
"confirm_delete_all": "Vuoi eliminare tutte le revisioni di questa nota?",
"no_revisions": "Ancora nessuna revisione per questa nota...",
"restore_button": "Ripristina",
"diff_on": "Mostra differenze",
"diff_off": "Mostra contenuto",
"diff_on_hint": "Clicca per mostrare la fonte della nota diff",
"diff_off_hint": "Clicca per visualizzare il contenuto della nota",
"diff_not_available": "Diff non è disponibile.",
"confirm_restore": "Vuoi ripristinare questa revisione? Questo sovrascriverà il titolo e il contenuto attuali della nota con questa revisione.",
"delete_button": "Elimina",
"confirm_delete": "Vuoi eliminare questa revisione?",
"revisions_deleted": "Le revisioni delle note sono state eliminate.",
"revision_restored": "La revisione della nota è stata ripristinata.",
"revision_deleted": "La revisione della nota è stata eliminata.",
"snapshot_interval": "Nota Intervallo di revisione istantanea: {{seconds}}.",
"maximum_revisions": "Nota Limite istantaneo di revisione: {{number}}.",
"settings": "Nota Impostazioni di revisione",
"download_button": "Scarica",
"mime": "MIME: ",
"file_size": "Dimensione del file:",
"preview": "Anteprima:",
"preview_not_available": "L'anteprima non è disponibile per questo tipo di nota."
},
"sort_child_notes": {
"sort_children_by": "Ordina i bambini per...",
"sorting_criteria": "Criteri di ordinamento",
"title": "titolo",
"date_created": "data di creazione",
"date_modified": "data di modifica",
"sorting_direction": "Direzione",
"ascending": "ascendente",
"descending": "discendente",
"folders": "Cartelle",
"sort_folders_at_top": "ordina le cartelle in alto",
"natural_sort": "Ordinamento naturale",
"sort_with_respect_to_different_character_sorting": "ordinare in base alle diverse regole di ordinamento e collazione dei caratteri nelle diverse lingue o regioni.",
"natural_sort_language": "Linguaggio di ordinamento naturale",
"the_language_code_for_natural_sort": "Il codice lingua per l'ordinamento naturale, ad esempio \"zh-CN\" per il cinese.",
"sort": "Ordina"
},
"upload_attachments": {
"upload_attachments_to_note": "Carica allegati alla nota",
"choose_files": "Scegli i file",
"files_will_be_uploaded": "I file saranno caricati come allegati in {{noteTitle}}",
"options": "Opzioni",
"shrink_images": "Riduci immagini",
"upload": "Carica",
"tooltip": "Se selezioni questa opzione, Trilium tenterà di ridurre le immagini caricate tramite ridimensionamento e ottimizzazione, il che potrebbe influire sulla qualità percepita delle immagini. Se non selezionata, le immagini verranno caricate senza modifiche."
},
"attribute_detail": {
"attr_detail_title": "Titolo dettagli attributo",
"close_button_title": "Annulla modifiche e chiudi",
"attr_is_owned_by": "L'attributo è di proprietà di",
"attr_name_title": "Il nome dell'attributo può essere composto solo da caratteri alfanumerici, due punti e trattino basso",
"name": "Nome",
"app_theme_base": "impostare su \"next\", \"next-light\" o \"next-dark\" per utilizzare il tema TriliumNext corrispondente (automatico, chiaro o scuro) come base per un tema personalizzato, invece di quello precedente.",
"css_class": "Il valore di questa etichetta viene quindi aggiunto come classe CSS al nodo che rappresenta una determinata nota nell'albero. Ciò può essere utile per la personalizzazione avanzata dei temi. Può essere utilizzato nelle note dei modelli.",
"icon_class": "Il valore di questa etichetta viene aggiunto come classe CSS all'icona sull'albero, il che può aiutare a distinguere visivamente le note nell'albero. Un esempio potrebbe essere bx bx-home - le icone sono prese da boxicons. Può essere utilizzato nelle note del modello.",
"page_size": "numero di elementi per pagina nell'elenco delle note",
"custom_request_handler": "vedi <a href=\"javascript:\" data-help-page=\"custom-request-handler.html\">Gestore richieste personalizzato</a>",
"custom_resource_provider": "vedi <a href=\"javascript:\" data-help-page=\"custom-request-handler.html\">Gestore richieste personalizzato</a>",
"widget": "contrassegna questa nota come widget personalizzato che verrà aggiunto all'albero dei componenti Trilium",
"workspace": "contrassegna questa nota come area di lavoro che consente un facile ancoraggio",
"workspace_icon_class": "definisce la classe CSS dell'icona della casella che verrà utilizzata nella scheda quando viene sollevata su questa nota",
"workspace_tab_background_color": "Colore CSS utilizzato nella scheda delle note quando viene sollevato su questa nota",
"workspace_calendar_root": "Definisce la radice del calendario per ogni area di lavoro",
"workspace_template": "Questa nota apparirà nella selezione dei modelli disponibili quando si crea una nuova nota, ma solo se inserita in un'area di lavoro che contiene questo modello",
"search_home": "verranno create nuove note di ricerca come sottovoci di questa nota",
"value": "Valore",
"target_note_title": "La relazione è una connessione denominata tra la nota di origine e la nota di destinazione.",
"target_note": "Nota obiettivo",
"promoted_title": "L'attributo promosso viene visualizzato in modo ben visibile sulla nota.",
"promoted": "Promosso",
"promoted_alias_title": "Il nome da visualizzare nell'interfaccia utente degli attributi promossi.",
"promoted_alias": "Alias",
"multiplicity_title": "La molteplicità definisce quanti attributi con lo stesso nome possono essere creati: al massimo 1 o più di 1.",
"multiplicity": "Molteplicità",
"single_value": "Valore singolo",
"multi_value": "Valore multiplo",
"label_type_title": "Il tipo di etichetta aiuterà Trilium a scegliere l'interfaccia adatta per inserire il valore dell'etichetta.",
"label_type": "Tipo",
"text": "Testo",
"number": "Numero",
"boolean": "Booleano",
"date": "Data",
"date_time": "Data e Ora",
"time": "Ora",
"url": "URL",
"precision_title": "Quante cifre dopo la virgola mobile dovrebbero essere disponibili nell'interfaccia di impostazione del valore.",
"precision": "Precisione",
"digits": "cifre",
"inverse_relation_title": "Impostazione facoltativa per definire a quale relazione è opposta questa. Esempio: padre e figlio sono relazioni inverse l'una rispetto all'altra.",
"inheritable": "Ereditabile",
"inverse_relation": "Relazione inversa",
"inheritable_title": "L'attributo ereditario verrà ereditato da tutti i discendenti sotto questo albero.",
"save_and_close": "Salva e chiudi <kbd>Ctrl+Enter</kbd>",
"delete": "Eliminazione",
"related_notes_title": "Altre note con questa etichetta",
"more_notes": "Altre note",
"label": "Dettagli etichetta",
"label_definition": "Dettagli definizione etichetta",
"relation": "Dettagli relazione",
"relation_definition": "Dettagli definizione relazione",
"disable_versioning": "disabilita il versioning automatico. Utile ad esempio per note di grandi dimensioni ma non importanti, come le grandi librerie JS utilizzate per lo scripting",
"calendar_root": "segna le note che devono essere utilizzate come note principali per le note giornaliere. Solo una deve essere contrassegnata come tale.",
"archived": "Le note con questa etichetta non saranno visibili per impostazione predefinita nei risultati di ricerca (anche nelle finestre di dialogo Vai a, Aggiungi collegamento ecc.).",
"run_on_instance": "Definire su quale istanza di Trilium eseguire questa operazione. L'impostazione predefinita è tutte le istanze.",
"exclude_from_export": "le note (con la loro sottostruttura) non saranno incluse in nessuna esportazione di note",
"run": "definisce su quali eventi deve essere eseguito lo script. I valori possibili sono:\n<ul>\n<li>frontendStartup - quando il frontend Trilium viene avviato (o aggiornato), ma non su dispositivi mobili.</li>\n<li>mobileStartup - quando il frontend Trilium viene avviato (o aggiornato) su dispositivi mobili.</li>\n<li>backendStartup - quando viene avviato il backend Trilium</li>\n<li>hourly - eseguire una volta all'ora. È possibile utilizzare l'etichetta aggiuntiva <code>runAtHour</code> per specificare a che ora.</li>\n<li>daily - eseguire una volta al giorno</li>\n</ul>",
"run_at_hour": "A che ora deve essere eseguito. Deve essere utilizzato insieme a <code>#run=hourly</code>. Può essere definito più volte per più esecuzioni durante il giorno.",
"disable_inclusion": "gli script con questa etichetta non saranno inclusi nell'esecuzione dello script principale.",
"sorted": "mantiene le note figlie ordinate alfabeticamente per titolo",
"sort_direction": "ASC (impostazione predefinita) o DESC",
"sort_folders_first": "Le cartelle (note con figlie) devono essere ordinate in cima",
"top": "mantieni la nota in cima al suo genitore (si applica solo ai genitori ordinati)",
"hide_promoted_attributes": "Nascondi gli attributi promossi in questa nota",
"read_only": "L'editor è in modalità di sola lettura. Funziona solo per note di testo e codice.",
"auto_read_only_disabled": "Le note di testo/codice possono essere impostate automaticamente in modalità di lettura quando sono troppo grandi. È possibile disabilitare questo comportamento per ogni singola nota aggiungendo questa etichetta alla nota",
"app_css": "contrassegna le note CSS che vengono caricate nell'applicazione Trilium e possono quindi essere utilizzate per modificare l'aspetto di Trilium.",
"app_theme": "contrassegna le note CSS che sono temi Trilium completi e sono quindi disponibili nelle opzioni Trilium.",
"workspace_search_home": "nuove note di ricerca verranno create come figlie di questa nota quando sollevate a qualche antenato di questa nota dell'area di lavoro",
"inbox": "Posizione predefinita della casella di posta in arrivo per le nuove note: quando crei una nota utilizzando il pulsante \"Nuova nota\" nella barra laterale, le note verranno create come note secondarie nella nota contrassegnata con l'etichetta <code>#inbox</code>.",
"workspace_inbox": "posizione predefinita della casella di posta in arrivo per le nuove note quando vengono trasferite a un antenato di questa nota dell'area di lavoro",
"sql_console_home": "posizione predefinita delle note della console SQL",
"bookmark_folder": "le note con questa etichetta appariranno nei segnalibri come cartelle (consentendo l'accesso ai loro elementi secondari)",
"share_hidden_from_tree": "questa nota è nascosta dall'albero di navigazione a sinistra, ma è comunque accessibile tramite il suo URL",
"share_external_link": "La nota fungerà da collegamento a un sito web esterno nell'albero di condivisione",
"share_alias": "definisci un alias con cui la nota sarà disponibile all'indirizzo https://your_trilium_host/share/[your_alias]",
"share_omit_default_css": "Il CSS predefinito della pagina di condivisione verrà omesso. Utilizzarlo quando si apportano modifiche stilistiche significative.",
"keep_current_hoisting": "L'apertura di questo link non modificherà l'ancoraggio anche se la nota non è visualizzabile nell'attuale sottoalbero ancorato.",
"share_description": "definire il testo da aggiungere al meta tag HTML per la descrizione",
"share_raw": "La nota verrà visualizzata nel suo formato originale, senza wrapper HTML",
"share_disallow_robot_indexing": "impedirà l'indicizzazione robotica di questa nota tramite l'intestazione <code>X-Robots-Tag: noindex</code>",
"share_credentials": "richiedono credenziali per accedere a questa nota condivisa. Il valore deve essere nel formato 'username:password'. Non dimenticare di renderlo ereditabile affinché si applichi alle note/immagini secondarie.",
"share_index": "La nota con questa etichetta elencherà tutte le radici delle note condivise",
"display_relations": "nomi delle relazioni delimitati da virgola che devono essere visualizzati. Tutti gli altri saranno nascosti.",
"hide_relations": "nomi delle relazioni delimitati da virgola che devono essere nascosti. Tutti gli altri saranno visualizzati.",
"title_template": "titolo predefinito delle note create come figlie di questa nota. Il valore viene valutato come stringa JavaScript. \n e quindi può essere arricchito con contenuti dinamici tramite le variabili <code>now</code> e <code>parentNote</code> inserite. Esempi:\n \n <ul>\n <li><code>${parentNote.getLabelValue('authorName')}'s opere letterarie</code></li>\n <li><code>Log per ${now.format('YYYY-MM-DD HH:mm:ss')}</code></li>\n </ul>\n \n Per ulteriori dettagli, consultare <a href=\"https://triliumnext.github.io/Docs/Wiki/default-note-title.html\">wiki con i dettagli</a>, la documentazione API per <a href=\"https://zadam.github.io/trilium/backend_api/Note.html\">parentNote</a> e <a href=\"https://day.js.org/docs/en/display/format\">now</a>.",
"template": "Questa nota apparirà nella selezione dei modelli disponibili durante la creazione di una nuova nota",
"toc": "<code>#toc</code> o <code>#toc=show</code> forzeranno la visualizzazione del sommario, mentre <code>#toc=hide</code> ne forzerà la non visualizzazione. Se l'etichetta non esiste, verrà applicata l'impostazione globale",
"color": "definisce il colore della nota nell'albero delle note, nei link ecc. Utilizza qualsiasi valore di colore CSS valido come \"red\" o #a13d5f",
"keyboard_shortcut": "Definisce una scorciatoia da tastiera che consentirà di passare immediatamente a questa nota. Esempio: \"ctrl+alt+e\". Per rendere effettiva la modifica è necessario ricaricare il frontend.",
"execute_button": "Titolo del pulsante che eseguirà il codice della nota corrente",
"execute_description": "Descrizione più dettagliata della nota di codice corrente visualizzata insieme al pulsante di esecuzione",
"exclude_from_note_map": "Le note con questa etichetta saranno nascoste dalla mappa delle note",
"new_notes_on_top": "Le nuove note verranno create nella parte superiore della nota principale, non nella parte inferiore.",
"hide_highlight_widget": "Nascondi widget Elenco evidenziazioni",
"run_on_note_creation": "Viene eseguito quando viene creata una nota sul backend. Utilizza questa relazione se desideri eseguire lo script per tutte le note create in una sottostruttura specifica. In tal caso, crealo sulla nota radice della sottostruttura e rendilo ereditabile. Una nuova nota creata all'interno della sottostruttura (a qualsiasi profondità) attiverà lo script.",
"run_on_child_note_creation": "viene eseguito quando viene creata una nuova nota sotto la nota in cui è definita questa relazione",
"run_on_note_title_change": "viene eseguito quando viene modificato il titolo della nota (include anche la creazione della nota)",
"run_on_note_content_change": "Viene eseguito quando il contenuto della nota viene modificato (compresa la creazione della nota).",
"run_on_note_change": "Viene eseguito quando la nota viene modificata (compresa la creazione della nota). Non include le modifiche al contenuto",
"run_on_note_deletion": "viene eseguito quando la nota viene eliminata",
"run_on_branch_creation": "Viene eseguito quando viene creato un ramo. Il ramo è un collegamento tra la nota principale e la nota secondaria e viene creato, ad esempio, quando si clona o si sposta una nota.",
"run_on_branch_change": "viene eseguito quando un ramo viene aggiornato.",
"run_on_branch_deletion": "Viene eseguito quando viene eliminato un ramo. Il ramo è un collegamento tra una nota padre e una nota figlio e viene eliminato, ad esempio, quando si sposta una nota (il vecchio ramo/collegamento viene eliminato).",
"run_on_attribute_creation": "viene eseguito quando viene creato un nuovo attributo per la nota che definisce questa relazione",
"run_on_attribute_change": " viene eseguito quando viene modificato l'attributo di una nota che definisce questa relazione. Viene attivato anche quando l'attributo viene eliminato",
"relation_template": "Gli attributi della nota saranno ereditati anche senza una relazione padre-figlio, mentre il contenuto e la sottostruttura della nota saranno aggiunti alle note dell'istanza se vuote. Per ulteriori dettagli, consultare la documentazione.",
"inherit": "Gli attributi della nota saranno ereditati anche senza una relazione padre-figlio. Vedi relazione modello per un concetto simile. Vedi eredità degli attributi nella documentazione.",
"render_note": "le note di tipo \"renderizza nota HTML\" saranno renderizzate utilizzando una nota codice (HTML o script) ed è necessario indicare utilizzando questa relazione quale nota deve essere renderizzata",
"widget_relation": "L'obiettivo di questa relazione verrà eseguito e visualizzato come widget nella barra laterale",
"share_css": "Nota CSS che verrà inserita nella pagina condivisa. Anche la nota CSS deve trovarsi nella sottostruttura condivisa. Valuta anche l'utilizzo di 'share_hidden_from_tree' e 'share_omit_default_css'.",
"share_js": "Nota JavaScript che verrà inserita nella pagina di condivisione. Anche la nota JS deve trovarsi nella sottostruttura condivisa. Valuta l'utilizzo di 'share_hidden_from_tree'.",
"share_template": "Nota JavaScript incorporata che verrà utilizzata come modello per la visualizzazione della nota condivisa. Se non disponibile, verrà utilizzato il modello predefinito. Si consiglia di utilizzare 'share_hidden_from_tree'.",
"share_favicon": "Nota Favicon da impostare nella pagina condivisa. In genere è preferibile impostarla su \"condivisione radice\" e renderla ereditabile. Anche la nota Favicon deve trovarsi nella sottostruttura condivisa. Valutare l'utilizzo di 'share_hidden_from_tree'.",
"is_owned_by_note": "è di proprietà di nota",
"other_notes_with_name": "Altre note con {{attributeType}} nome \"{{attributeName}}\"",
"and_more": "... e altri {{count}}.",
"print_landscape": "Quando si esporta in PDF, cambia l'orientamento della pagina da verticale a orizzontale.",
"print_page_size": "Quando si esporta in PDF, modifica le dimensioni della pagina. Valori supportati: <code>A0</code>, <code>A1</code>, <code>A2</code>, <code>A3</code>, <code>A4</code>, <code>A5</code>, <code>A6</code>, <code>Legal</code>, <code>Letter</code>, <code>Tabloid</code>, <code>Ledger</code>.",
"color_type": "Colore",
"share_root": "segna la nota che viene servita su /share root."
},
"attribute_editor": {
"help_text_body1": "Per aggiungere un'etichetta, basta digitare ad esempio <code>#rock</code> oppure, se si desidera aggiungere anche un valore, ad esempio <code>#year = 2020</code>",
"help_text_body2": "Per la relazione, digita <code>~author = @</code>, che dovrebbe far apparire un completamento automatico in cui puoi cercare la nota desiderata.",
"help_text_body3": "In alternativa, è possibile aggiungere etichette e relazioni utilizzando il pulsante <code>+</code> sul lato destro.",
"save_attributes": "Salva attributi <enter>",
"add_a_new_attribute": "Aggiungi un nuovo attributo",
"add_new_label": "Aggiungi nuova etichetta <kbd data-command=\"addNewLabel\"></kbd>",
"add_new_relation": "Aggiungi nuova relazione <kbd data-command=\"addNewRelation\"></kbd>",
"add_new_relation_definition": "Aggiungi una nuova definizione di relazione",
"placeholder": "Digitare qui le etichette e le relazioni"
},
"execute_script": {
"execute_script": "Esegui script",
"help_text": "È possibile eseguire semplici script sulle note abbinate.",
"example_1": "Ad esempio, per aggiungere una stringa al titolo di una nota, utilizzare questo piccolo script:"
"showJumpToNoteDialog": "mostra <a class=\"external\" href=\"https://triliumnext.github.io/Docs/Wiki/note-navigation.html#jump-to-note\">la finestra di dialogo \"Salta alla nota\"<a>"
}
}

View File

@@ -67,9 +67,7 @@
"switch_to_mobile_version": "モバイル版に切り替え",
"switch_to_desktop_version": "デスクトップ版に切り替え",
"configure_launchbar": "ランチャーバーの設定",
"show_shared_notes_subtree": "共有ノートのサブツリーを表示",
"new-version-available": "新しいアップデートが利用可能",
"download-update": "{{latestVersion}} をバージョンを入手"
"show_shared_notes_subtree": "共有ノートのサブツリーを表示"
},
"left_pane_toggle": {
"show_panel": "パネルを表示",
@@ -164,13 +162,7 @@
"min-days-in-first-week": "最初の週の最低日数",
"first-week-info": "最初の週は、その年の最初の木曜日を含む週を指し、<a href=\"https://en.wikipedia.org/wiki/ISO_week_date#First_week\">ISO 8601</a>規格に基づいています。",
"first-week-warning": "最初の週のオプションを変更すると、既存のウィークノートと重複する可能性があり、既存のウィークノートはそれに応じて更新されません。",
"formatting-locale": "日付と数値のフォーマット",
"formatting-locale-auto": "アプリケーションの言語に基づいて",
"tuesday": "火曜日",
"wednesday": "水曜日",
"thursday": "木曜日",
"friday": "金曜日",
"saturday": "土曜日"
"formatting-locale": "日付と数値のフォーマット"
},
"tab_row": {
"close_tab": "タブを閉じる",
@@ -282,8 +274,8 @@
"selectAllNotes": "現在のレベルのノートをすべて選択",
"selectNote": "ノートを選択",
"copyNotes": "アクティブなノート(または現在の選択範囲)をクリップボードにコピーする(<a class=\"external\" href=\"https://triliumnext.github.io/Docs/Wiki/cloning-notes.html#cloning-notes\">クローン</a>に使用)",
"cutNotes": "アクティブなノート(または現在の選択範囲)をクリップボードに切り取り(ノートの移動に使用)",
"pasteNotes": "ノートをサブノートとしてアクティブノートに貼り付ける(コピーされたか切り取りされたかに よって、移動またはクローンになる)",
"cutNotes": "アクティブなノート(または現在の選択範囲)をクリップボードにカットする(ノートの移動に使用)",
"pasteNotes": "ノートをサブノートとしてアクティブノートに貼り付ける(コピーされたかカットされたかに よって、移動またはクローンになる)",
"deleteNotes": "ノート/サブツリーを削除",
"editingNotes": "ノート編集",
"editNoteTitle": "押下するとツリーペインからタイトルの編集に移ります。タイトルの編集からEnterキーを押すと、本文の編集に移動します。<kbd>Ctrl+.</kbd> で本文の編集からツリーペインに戻ります。",
@@ -302,7 +294,7 @@
"showDevTools": "開発者ツールを表示",
"showSQLConsole": "SQLコンソールを表示",
"other": "その他",
"quickSearch": "クイック検索にフォーカス",
"quickSearch": "クイックサーチにフォーカス",
"inPageSearch": "ページ内検索",
"showJumpToNoteDialog": "<a class=\"external\" href=\"https://triliumnext.github.io/Docs/Wiki/note-navigation.html#jump-to-note\">「ジャンプ先」ダイアログ</a>を表示",
"moveNoteUpDown": "ノートリストでノートを上/下に移動",
@@ -405,7 +397,7 @@
"unprotect-subtree": "サブツリーの保護を解除",
"copy-clone": "コピー/クローン",
"clone-to": "クローン先...",
"cut": "切り取り",
"cut": "カット",
"move-to": "移動先...",
"paste-into": "貼り付け",
"paste-after": "後ろに貼り付け",
@@ -534,8 +526,7 @@
"table": "テーブル",
"geo-map": "ジオマップ",
"board": "ボード",
"include_archived_notes": "アーカイブされたノートを表示",
"presentation": "プレゼンテーション"
"include_archived_notes": "アーカイブされたノートを表示"
},
"note_types": {
"geo-map": "ジオマップ",
@@ -1189,7 +1180,7 @@
"options": "オプション"
},
"quick-search": {
"placeholder": "クイック検索",
"placeholder": "クイックサーチ",
"searching": "検索中...",
"no-results": "結果は見つかりませんでした",
"more-results": "... および {{number}} 件の他の結果。",
@@ -1245,7 +1236,7 @@
"duplicated": "ノート \"{{title}}\" は複製されました。"
},
"clipboard": {
"cut": "ノートはクリップボードに切り取りとられました。",
"cut": "ノートはクリップボードにカットされました。",
"copied": "ノートはクリップボードにコピーされました。",
"copy_failed": "権限の問題で、クリップボードにコピーできません。",
"copy_success": "クリップボードにコピーしました。"
@@ -1296,10 +1287,10 @@
},
"electron_context_menu": {
"add-term-to-dictionary": "辞書に \"{{term}}\" を追加",
"cut": "切り取り",
"cut": "カット",
"copy": "コピー",
"copy-link": "リンクをコピー",
"paste": "貼り付け",
"paste": "ペースト",
"paste-as-plain-text": "プレーンテキストで貼り付け",
"search_online": "{{searchEngine}} で \"{{term}}\" を検索"
},
@@ -1591,8 +1582,7 @@
"delete_this_note": "このノートを削除",
"error_unrecognized_command": "認識されないコマンド {{command}}",
"insert_child_note": "子ノートを挿入",
"error_cannot_get_branch_id": "ノートパス 「{{notePath}} のbranchIdを取得できません",
"note_revisions": "ノートの変更履歴"
"error_cannot_get_branch_id": "ノートパス 「{{notePath}} のbranchIdを取得できません"
},
"inherited_attribute_list": {
"title": "継承属性",
@@ -1882,9 +1872,7 @@
"window-on-top": "ウィンドウを最前面に維持"
},
"note_detail": {
"could_not_find_typewidget": "タイプ {{type}} の typeWidget が見つかりませんでした",
"printing": "印刷中です...",
"printing_pdf": "PDF へのエクスポート中です..."
"could_not_find_typewidget": "タイプ {{type}} の typeWidget が見つかりませんでした"
},
"watched_file_update_status": {
"ignore_this_change": "この変更を無視する",
@@ -2077,10 +2065,5 @@
"role_and_size": "ロール: {{role}},サイズ: {{size}}",
"link_copied": "添付ファイルのリンクをクリップボードにコピーしました。",
"unrecognized_role": "添付ファイルのロール「{{role}}」は認識されません。"
},
"presentation_view": {
"edit-slide": "このスライドを編集",
"start-presentation": "プレゼンテーションを開始",
"slide-overview": "スライドの概要を切り替え"
}
}

View File

@@ -49,11 +49,5 @@
"chosen_actions": "선택한 액션들",
"execute_bulk_actions": "대량 액션들 실행",
"bulk_actions_executed": "대량 액션들이 성공적으로 실행되었습니다."
},
"i18n": {
"saturday": "토요일",
"sunday": "일요일",
"first-week-of-the-year": "일년의 첫째 주",
"first-week-contains-first-day": "첫 번째 주에는 올해의 첫날이 포함됩니다"
}
}

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -289,8 +289,7 @@
"table": "Tabel",
"geo-map": "Hartă geografică",
"board": "Tablă Kanban",
"include_archived_notes": "Afișează notițele arhivate",
"presentation": "Prezentare"
"include_archived_notes": "Afișează notițele arhivate"
},
"bookmark_switch": {
"bookmark": "Semn de carte",
@@ -612,9 +611,7 @@
"zoom_in": "Mărește",
"zoom_out": "Micșorează",
"show-cheatsheet": "Afișează ghidul rapid",
"toggle-zen-mode": "Mod zen",
"new-version-available": "Actualizare nouă disponibilă",
"download-update": "Obțineți versiunea {{latestVersion}}"
"toggle-zen-mode": "Mod zen"
},
"heading_style": {
"markdown": "Stil Markdown",
@@ -704,13 +701,7 @@
"first-week-has-minimum-days": "Prima săptămână are numărul minim de zile",
"min-days-in-first-week": "Numărul minim de zile pentru prima săptămână",
"first-week-info": "Opțiunea de prima săptămână conține prima zi de joi din an este bazată pe standardul <a href=\"https://en.wikipedia.org/wiki/ISO_week_date#First_week\">ISO 8601</a>.",
"first-week-warning": "Schimbarea opțiunii primei săptămâni poate cauza duplicate cu notițele săptămânale existente deoarece acestea nu vor fi actualizate retroactiv.",
"tuesday": "Marți",
"wednesday": "Miercuri",
"thursday": "Joi",
"friday": "Vineri",
"saturday": "Sâmbătă",
"formatting-locale-auto": "În funcție de limba aplicației"
"first-week-warning": "Schimbarea opțiunii primei săptămâni poate cauza duplicate cu notițele săptămânale existente deoarece acestea nu vor fi actualizate retroactiv."
},
"image_properties": {
"copy_reference_to_clipboard": "Copiază referință în clipboard",
@@ -812,8 +803,7 @@
"delete_this_note": "Șterge această notiță",
"error_cannot_get_branch_id": "Nu s-a putut obține branchId-ul pentru calea „{{notePath}}”",
"error_unrecognized_command": "Comandă nerecunoscută „{{command}}”",
"insert_child_note": "Inserează subnotiță",
"note_revisions": "Revizuiri ale notițelor"
"insert_child_note": "Inserează subnotiță"
},
"move_note": {
"clone_note_new_parent": "clonează notița la noul părinte dacă notița are mai multe clone/ramuri (când nu este clar care ramură trebuie ștearsă)",
@@ -2079,10 +2069,5 @@
},
"collections": {
"rendering_error": "Nu a putut fi afișat conținutul din cauza unei erori."
},
"presentation_view": {
"edit-slide": "Editați acest slide",
"start-presentation": "Începeți prezentarea",
"slide-overview": "Afișați o imagine de ansamblu a slide-urilor"
}
}

View File

@@ -1,8 +0,0 @@
{
"about": {
"title": "Om Trilium Notes",
"homepage": "Hemsida:",
"app_version": "App version:",
"db_version": "DB version:"
}
}

View File

@@ -646,9 +646,7 @@
"about": "關於 TriliumNext 筆記",
"logout": "登出",
"show-cheatsheet": "顯示快捷鍵說明",
"toggle-zen-mode": "禪模式",
"new-version-available": "發現新更新",
"download-update": "取得版本 {{latestVersion}}"
"toggle-zen-mode": "禪模式"
},
"sync_status": {
"unknown": "<p>同步狀態將在下一次同步嘗試開始後顯示。</p><p>點擊以立即觸發同步。</p>",
@@ -735,8 +733,7 @@
"insert_child_note": "插入子筆記",
"delete_this_note": "刪除此筆記",
"error_cannot_get_branch_id": "無法獲取 notePath '{{notePath}}' 的 branchId",
"error_unrecognized_command": "無法識別的命令 {{command}}",
"note_revisions": "筆記歷史版本"
"error_unrecognized_command": "無法識別的命令 {{command}}"
},
"note_icon": {
"change_note_icon": "更改筆記圖標",
@@ -749,7 +746,7 @@
"editable": "可編輯",
"basic_properties": "基本屬性",
"language": "語言",
"configure_code_notes": "設定程式碼筆記…"
"configure_code_notes": "配寘代碼注釋..."
},
"book_properties": {
"view_type": "視圖類型",
@@ -765,8 +762,7 @@
"table": "表格",
"geo-map": "地理地圖",
"board": "看板",
"include_archived_notes": "顯示已封存筆記",
"presentation": "簡報"
"include_archived_notes": "顯示已封存筆記"
},
"edited_notes": {
"no_edited_notes_found": "今天還沒有編輯過的筆記...",
@@ -1254,13 +1250,7 @@
"min-days-in-first-week": "第一週的最少天數",
"first-week-info": "年度第一週包含第一個週四是基於 <a href=\"https://en.wikipedia.org/wiki/ISO_week_date#First_week\">ISO 8601</a> 標準。",
"first-week-warning": "變更第一週選項可能導致與現有的「週筆記」重複,現有的「週筆記」將不會相應更新。",
"formatting-locale": "日期和數字格式",
"tuesday": "週二",
"wednesday": "週三",
"thursday": "週四",
"friday": "週五",
"saturday": "週六",
"formatting-locale-auto": "根據應用程式的語言設定"
"formatting-locale": "日期和數字格式"
},
"backup": {
"automatic_backup": "自動備份",
@@ -1441,7 +1431,7 @@
"relation-map": "關聯圖",
"note-map": "筆記地圖",
"render-note": "渲染筆記",
"mermaid-diagram": "美人魚圖",
"mermaid-diagram": "美人魚圖Mermaid",
"canvas": "畫布",
"web-view": "網頁顯示",
"mind-map": "心智圖",
@@ -1517,9 +1507,7 @@
"window-on-top": "保持此視窗置頂"
},
"note_detail": {
"could_not_find_typewidget": "找不到類型為 '{{type}}' 的 typeWidget",
"printing": "正在列印…",
"printing_pdf": "正在匯出為 PDF…"
"could_not_find_typewidget": "找不到類型為 '{{type}}' 的 typeWidget"
},
"note_title": {
"placeholder": "請輸入筆記標題..."
@@ -1639,7 +1627,7 @@
"label": "格式工具欄",
"floating": {
"title": "浮動",
"description": "編輯工具出現在標附近"
"description": "編輯工具出現在標附近;"
},
"fixed": {
"title": "固定",
@@ -2077,10 +2065,5 @@
},
"collections": {
"rendering_error": "發現錯誤,無法顯示內容。"
},
"presentation_view": {
"edit-slide": "編輯此投影片",
"start-presentation": "開始簡報",
"slide-overview": "切換投影片概覽"
}
}

View File

@@ -4,10 +4,7 @@
"title": "Về Trilium Notes",
"app_version": "Phiên bản:",
"db_version": "Phiên bản DB:",
"sync_version": "Phiên bản liên kết:",
"build_date": "Ngày build:",
"build_revision": "Xây dựng bản sửa đổi:",
"data_directory": "Đường dẫn dữ liệu:"
"sync_version": "Phiên bản liên kết:"
},
"add_link": {
"add_link": "Thêm liên kết",
@@ -37,11 +34,7 @@
},
"toast": {
"critical-error": {
"title": "Lỗi nghiêm trọng",
"message": "Đã xảy ra lỗi nghiêm trọng ngăn ứng dụng client khởi động\n\n{{message}}\n\nĐiều này có khả năng bị gây ra bởi một script hoạt động không như mong đợi. Hãy thử khởi động ứng dụng ở chế độ an toàn và giải quyết vấn đề."
},
"widget-error": {
"title": "Khởi tạo widget thất bại"
"title": "Lỗi nghiêm trọng"
}
},
"import": {

View File

@@ -16,7 +16,7 @@ interface ElectronProcess {
interface CustomGlobals {
isDesktop: typeof utils.isDesktop;
isMobile: typeof utils.isMobile;
device: "mobile" | "desktop" | "print";
device: "mobile" | "desktop";
getComponentByEl: typeof appContext.getComponentByEl;
getHeaders: typeof server.getHeaders;
getReferenceLinkTitle: (href: string) => Promise<string>;
@@ -46,7 +46,6 @@ interface CustomGlobals {
platform?: typeof process.platform;
linter: typeof lint;
hasNativeTitleBar: boolean;
isRtl: boolean;
}
type RequireMethod = (moduleName: string) => any;
@@ -59,9 +58,6 @@ declare global {
process?: ElectronProcess;
glob?: CustomGlobals;
/** On the printing endpoint, set to true when the note has fully loaded and is ready to be printed/exported as PDF. */
_noteReady?: boolean;
EXCALIDRAW_ASSET_PATH?: string;
}

View File

@@ -1,45 +0,0 @@
export function readCssVar(element: HTMLElement, varName: string) {
return new CssVarReader(getComputedStyle(element).getPropertyValue("--" + varName));
}
export class CssVarReader {
protected value: string;
constructor(rawValue: string) {
this.value = rawValue;
}
asString(defaultValue?: string) {
return (this.value) ? this.value : defaultValue;
}
asNumber(defaultValue?: number) {
let number: Number = NaN;
if (this.value) {
number = parseFloat(this.value);
}
return (!isNaN(number.valueOf()) ? number.valueOf() : defaultValue)
}
asEnum<T>(enumType: T, defaultValue?: T[keyof T]): T[keyof T] | undefined {
let result: T[keyof T] | undefined;
result = enumType[this.value as keyof T];
if (result === undefined) {
result = defaultValue;
}
return result;
}
asArray(delimiter: string = " "): CssVarReader[] {
// Note: ignoring delimiters inside quotation marks is currently unsupported
let values = this.value.split(delimiter);
return values.map((v) => new CssVarReader(v));
}
}

View File

@@ -1,5 +1,3 @@
import options from "../services/options";
type DateTimeStyle = "full" | "long" | "medium" | "short" | "none" | undefined;
/**
@@ -10,7 +8,7 @@ export function formatDateTime(date: string | Date | number | null | undefined,
return "";
}
const locale = options.get("formattingLocale") || options.get("locale") || navigator.language;
const locale = navigator.language;
let parsedDate;
if (typeof date === "string" || typeof date === "number") {
@@ -26,7 +24,7 @@ export function formatDateTime(date: string | Date | number | null | undefined,
if (timeStyle !== "none" && dateStyle !== "none") {
// Format the date and time
const formatter = new Intl.DateTimeFormat(locale, { dateStyle, timeStyle });
const formatter = new Intl.DateTimeFormat(navigator.language, { dateStyle, timeStyle });
return formatter.format(parsedDate);
} else if (timeStyle === "none" && dateStyle !== "none") {
// Format only the date

View File

@@ -7,7 +7,7 @@
.show-floating-buttons {
position: absolute;
top: var(--floating-buttons-vert-offset, 10px);
inset-inline-end: var(--floating-buttons-horiz-offset, 10px);
right: var(--floating-buttons-horiz-offset, 10px);
display: flex;
flex-direction: row;
z-index: 100;
@@ -15,7 +15,8 @@
.note-split.rtl .floating-buttons-children,
.note-split.rtl .show-floating-buttons {
inset-inline-end: 10px;
right: unset;
left: 10px;
}
.note-split.rtl .close-floating-buttons {
@@ -73,7 +74,7 @@
.show-floating-buttons {
/* display: none;*/
margin-inline-start: 5px !important;
margin-left: 5px !important;
}
.show-floating-buttons-button {
@@ -96,7 +97,7 @@
/* #region Close floating buttons */
.close-floating-buttons {
margin-inline-start: 5px !important;
margin-left: 5px !important;
}
.close-floating-buttons:first-child {
@@ -139,7 +140,7 @@
z-index: 10;
position: absolute;
top: 50px;
inset-inline-end: 10px;
right: 10px;
width: 400px;
border-radius: 10px;
background-color: var(--accented-background-color);
@@ -149,8 +150,8 @@
}
.backlink-excerpt {
border-inline-start: 2px solid var(--main-border-color);
padding-inline-start: 10px;
border-left: 2px solid var(--main-border-color);
padding-left: 10px;
opacity: 80%;
font-size: 90%;
}

View File

@@ -23,6 +23,6 @@
color: var(--button-text-color);
position: absolute;
top: 10px;
inset-inline-end: 10px;
right: 10px;
cursor: pointer;
}

View File

@@ -30,7 +30,7 @@ const TPL = /*html*/`
}
.attachment-details {
margin-inline-start: 10px;
margin-left: 10px;
}
.attachment-content-wrapper {

View File

@@ -36,7 +36,7 @@ const TPL = /*html*/`
}
.related-notes-list {
padding-inline-start: 20px;
padding-left: 20px;
margin-top: 10px;
margin-bottom: 10px;
}
@@ -46,7 +46,7 @@ const TPL = /*html*/`
}
.attr-edit-table th {
text-align: start;
text-align: left;
}
.attr-edit-table td input[not(type="checkbox")] {
@@ -150,7 +150,7 @@ const TPL = /*html*/`
<th title="${t("attribute_detail.precision_title")}">${t("attribute_detail.precision")}</th>
<td>
<div class="input-group">
<input type="number" class="form-control attr-input-number-precision" style="text-align: end">
<input type="number" class="form-control attr-input-number-precision" style="text-align: right">
<span class="input-group-text">${t("attribute_detail.digits")}</span>
</div>
</td>
@@ -176,7 +176,7 @@ const TPL = /*html*/`
<div class="attr-save-delete-button-container">
<button class="btn btn-primary btn-sm attr-save-changes-and-close-button"
style="flex-grow: 1; margin-inline-end: 20px">
style="flex-grow: 1; margin-right: 20px">
${t("attribute_detail.save_and_close")}</button>
<button class="btn btn-secondary btn-sm attr-delete-button">

View File

@@ -76,7 +76,7 @@ export class TypedBasicWidget<T extends TypedComponent<any>> extends TypedCompon
/**
* Sets the CSS attribute of the given name to the given value.
*
* @param name the name of the CSS attribute to set (e.g. `padding-inline-start`).
* @param name the name of the CSS attribute to set (e.g. `padding-left`).
* @param value the value of the CSS attribute to set (e.g. `12px`).
* @returns self for chaining.
*/
@@ -89,7 +89,7 @@ export class TypedBasicWidget<T extends TypedComponent<any>> extends TypedCompon
* Sets the CSS attribute of the given name to the given value, but only if the condition provided is truthy.
*
* @param condition `true` in order to apply the CSS, `false` to ignore it.
* @param name the name of the CSS attribute to set (e.g. `padding-inline-start`).
* @param name the name of the CSS attribute to set (e.g. `padding-left`).
* @param value the value of the CSS attribute to set (e.g. `12px`).
* @returns self for chaining.
*/

View File

@@ -4,7 +4,7 @@ import AbstractBulkAction from "./abstract_bulk_action";
import HelpRemoveButtons from "../react/HelpRemoveButtons";
interface BulkActionProps {
label: string | ComponentChildren;
label: string | ComponentChildren;
children?: ComponentChildren;
helpText?: ComponentChildren;
bulkAction: AbstractBulkAction;
@@ -12,8 +12,8 @@ interface BulkActionProps {
// Define styles as constants to prevent recreation
const flexContainerStyle = { display: "flex", alignItems: "center" } as const;
const labelStyle = { marginInlineEnd: "10px" } as const;
const textStyle = { marginInlineEnd: "10px", marginInlineStart: "10px" } as const;
const labelStyle = { marginRight: "10px" } as const;
const textStyle = { marginRight: "10px", marginLeft: "10px" } as const;
const BulkAction = memo(({ label, children, helpText, bulkAction }: BulkActionProps) => {
return (
@@ -44,4 +44,4 @@ export const BulkActionText = memo(({ text }: { text: string }) => {
{text}
</div>
);
});
});

View File

@@ -1,6 +1,5 @@
import { Tooltip } from "bootstrap";
import NoteContextAwareWidget from "../note_context_aware_widget.js";
import { handleRightToLeftPlacement } from "../../services/utils.js";
const TPL = /*html*/`<button class="button-widget bx"
data-bs-toggle="tooltip"
@@ -27,14 +26,13 @@ export default class AbstractButtonWidget<SettingsT extends AbstractButtonWidget
doRender() {
this.$widget = $(TPL);
this.tooltip = new Tooltip(this.$widget[0], {
html: true,
// in case getTitle() returns null -> use empty string as fallback
title: () => this.getTitle() || "",
trigger: "hover",
placement: handleRightToLeftPlacement(this.settings.titlePlacement),
fallbackPlacements: [ handleRightToLeftPlacement(this.settings.titlePlacement) ]
placement: this.settings.titlePlacement,
fallbackPlacements: [this.settings.titlePlacement]
});
if (this.settings.onContextMenu) {

View File

@@ -28,7 +28,7 @@ const TPL = /*html*/`
position: relative;
top: 3px;
font-size: 120%;
margin-inline-end: 5px;
margin-right: 5px;
}
.attachment-actions .dropdown-item[disabled], .attachment-actions .dropdown-item[disabled]:hover {

View File

@@ -35,7 +35,7 @@ const DROPDOWN_TPL = `
}
.bookmark-folder-widget li .note-link {
padding-inline-start: 35px;
padding-left: 35px;
}
</style>

View File

@@ -8,15 +8,13 @@ import options from "../../services/options.js";
import { Dropdown } from "bootstrap";
import type { EventData } from "../../components/app_context.js";
import dayjs, { Dayjs } from "dayjs";
import isoWeek from "dayjs/plugin/isoWeek.js";
import utc from "dayjs/plugin/utc.js";
import isSameOrAfter from "dayjs/plugin/isSameOrAfter.js";
import "../../stylesheets/calendar.css";
import type { AttributeRow, OptionDefinitions } from "@triliumnext/commons";
import type { AttributeRow } from "@triliumnext/commons";
dayjs.extend(utc);
dayjs.extend(isSameOrAfter);
dayjs.extend(isoWeek);
const MONTHS = [
t("calendar.january"),
@@ -71,15 +69,7 @@ const DROPDOWN_TPL = `
<div class="calendar-body" data-calendar-area="month"></div>
</div>`;
const DAYS_OF_WEEK = [
t("calendar.sun"),
t("calendar.mon"),
t("calendar.tue"),
t("calendar.wed"),
t("calendar.thu"),
t("calendar.fri"),
t("calendar.sat")
];
const DAYS_OF_WEEK = [t("calendar.sun"), t("calendar.mon"), t("calendar.tue"), t("calendar.wed"), t("calendar.thu"), t("calendar.fri"), t("calendar.sat")];
interface DateNotesForMonth {
[date: string]: string;
@@ -100,8 +90,7 @@ export default class CalendarWidget extends RightDropdownButtonWidget {
private $nextYear!: JQuery<HTMLElement>;
private $previousYear!: JQuery<HTMLElement>;
private monthDropdown!: Dropdown;
// stored in ISO 17
private firstDayOfWeekISO!: number;
private firstDayOfWeek!: number;
private weekCalculationOptions!: WeekCalculationOptions;
private activeDate: Dayjs | null = null;
private todaysDate!: Dayjs;
@@ -137,7 +126,6 @@ export default class CalendarWidget extends RightDropdownButtonWidget {
this.createMonth();
}
});
this.$next = this.$dropdownContent.find('[data-calendar-toggle="next"]');
this.$next.on("click", () => {
this.date = this.date.add(1, 'month');
@@ -156,24 +144,23 @@ export default class CalendarWidget extends RightDropdownButtonWidget {
this.date = this.date.year(parseInt(target.value));
this.createMonth();
});
this.$nextYear = this.$dropdownContent.find('[data-calendar-toggle="nextYear"]');
this.$nextYear.on("click", () => {
this.date = this.date.add(1, 'year');
this.createMonth();
});
this.$previousYear = this.$dropdownContent.find('[data-calendar-toggle="previousYear"]');
this.$previousYear.on("click", () => {
this.date = this.date.subtract(1, 'year');
this.createMonth();
});
// Date click
this.$dropdownContent.on("click", ".calendar-date", async (ev) => {
const date = $(ev.target).closest(".calendar-date").attr("data-calendar-date");
if (date) {
const note = await dateNoteService.getDayNote(date);
if (note) {
appContext.tabManager.getActiveContext()?.setNote(note.noteId);
this.dropdown?.hide();
@@ -181,10 +168,10 @@ export default class CalendarWidget extends RightDropdownButtonWidget {
toastService.showError(t("calendar.cannot_find_day_note"));
}
}
ev.stopPropagation();
});
// Week click
this.$dropdownContent.on("click", ".calendar-week-number", async (ev) => {
if (!this.weekNoteEnable) {
return;
@@ -231,17 +218,23 @@ export default class CalendarWidget extends RightDropdownButtonWidget {
return;
}
const noteAttributes = await server.get<AttributeRow[]>(`notes/${noteId}/attributes`);
this.weekNoteEnable = noteAttributes.some(a => a.name === 'enableWeekNote');
for (const attribute of noteAttributes) {
if (attribute.name === 'enableWeekNote') {
this.weekNoteEnable = true;
return
}
}
this.weekNoteEnable = false;
}
// Store firstDayOfWeek as ISO (17)
manageFirstDayOfWeek() {
const rawFirstDayOfWeek = options.getInt("firstDayOfWeek") || 0;
this.firstDayOfWeekISO = rawFirstDayOfWeek === 0 ? 7 : rawFirstDayOfWeek;
this.firstDayOfWeek = options.getInt("firstDayOfWeek") || 0;
// Generate the list of days of the week taking into consideration the user's selected first day of week.
let localeDaysOfWeek = [...DAYS_OF_WEEK];
const shifted = localeDaysOfWeek.splice(0, rawFirstDayOfWeek);
localeDaysOfWeek = ['', ...localeDaysOfWeek, ...shifted];
const daysToBeAddedAtEnd = localeDaysOfWeek.splice(0, this.firstDayOfWeek);
localeDaysOfWeek = ['', ...localeDaysOfWeek, ...daysToBeAddedAtEnd];
this.$weekHeader.html(localeDaysOfWeek.map((el) => `<span>${el}</span>`).join(''));
}
@@ -252,15 +245,72 @@ export default class CalendarWidget extends RightDropdownButtonWidget {
};
}
getWeekStartDate(date: Dayjs): Dayjs {
const currentISO = date.isoWeekday();
const diff = (currentISO - this.firstDayOfWeekISO + 7) % 7;
return date.clone().subtract(diff, "day").startOf("day");
}
getWeekNumber(date: Dayjs): number {
const weekStart = this.getWeekStartDate(date);
return weekStart.isoWeek();
const year = date.year();
const dayOfWeek = (day: number) => (day - this.firstDayOfWeek + 7) % 7;
// Get first day of the year and adjust to first week start
const jan1 = date.clone().year(year).month(0).date(1);
const jan1Weekday = jan1.day();
const dayOffset = dayOfWeek(jan1Weekday);
let firstWeekStart = jan1.clone().subtract(dayOffset, 'day');
// Adjust based on week rule
switch (this.weekCalculationOptions.firstWeekType) {
case 1: { // ISO 8601: first week contains Thursday
const thursday = firstWeekStart.clone().add(3, 'day'); // Monday + 3 = Thursday
if (thursday.year() < year) {
firstWeekStart = firstWeekStart.add(7, 'day');
}
break;
}
case 2: { // minDaysInFirstWeek rule
const daysInFirstWeek = 7 - dayOffset;
if (daysInFirstWeek < this.weekCalculationOptions.minDaysInFirstWeek) {
firstWeekStart = firstWeekStart.add(7, 'day');
}
break;
}
// default case 0: week containing Jan 1 → already handled
}
const diffDays = date.startOf('day').diff(firstWeekStart.startOf('day'), 'day');
const weekNumber = Math.floor(diffDays / 7) + 1;
// Handle case when date is before first week start → belongs to last week of previous year
if (weekNumber <= 0) {
return this.getWeekNumber(date.subtract(1, 'day'));
}
// Handle case when date belongs to first week of next year
const nextYear = year + 1;
const jan1Next = date.clone().year(nextYear).month(0).date(1);
const jan1WeekdayNext = jan1Next.day();
const offsetNext = dayOfWeek(jan1WeekdayNext);
let nextYearWeekStart = jan1Next.clone().subtract(offsetNext, 'day');
switch (this.weekCalculationOptions.firstWeekType) {
case 1: {
const thursday = nextYearWeekStart.clone().add(3, 'day');
if (thursday.year() < nextYear) {
nextYearWeekStart = nextYearWeekStart.add(7, 'day');
}
break;
}
case 2: {
const daysInFirstWeek = 7 - offsetNext;
if (daysInFirstWeek < this.weekCalculationOptions.minDaysInFirstWeek) {
nextYearWeekStart = nextYearWeekStart.add(7, 'day');
}
break;
}
}
if (date.isSameOrAfter(nextYearWeekStart)) {
return 1;
}
return weekNumber;
}
async dropdownShown() {
@@ -270,25 +320,32 @@ export default class CalendarWidget extends RightDropdownButtonWidget {
}
init(activeDate: string | null) {
// attaching time fixes local timezone handling
this.activeDate = activeDate ? dayjs(`${activeDate}T12:00:00`) : null;
this.todaysDate = dayjs();
this.date = dayjs(this.activeDate || this.todaysDate).startOf('month');
this.createMonth();
}
createDay(dateNotesForMonth: DateNotesForMonth, num: number) {
const $newDay = $("<a>")
.addClass("calendar-date")
.attr("data-calendar-date", this.date.local().format('YYYY-MM-DD'));
const $newDay = $("<a>").addClass("calendar-date").attr("data-calendar-date", this.date.local().format('YYYY-MM-DD'));
const $date = $("<span>").html(String(num));
const dateNoteId = dateNotesForMonth[this.date.local().format('YYYY-MM-DD')];
if (dateNoteId) {
$newDay.addClass("calendar-date-exists").attr("data-href", `#root/${dateNoteId}`);
$newDay.addClass("calendar-date-exists");
$newDay.attr("data-href", `#root/${dateNoteId}`);
}
if (this.date.isSame(this.activeDate, 'day')) $newDay.addClass("calendar-date-active");
if (this.date.isSame(this.todaysDate, 'day')) $newDay.addClass("calendar-date-today");
if (this.date.isSame(this.activeDate, 'day')) {
$newDay.addClass("calendar-date-active");
}
if (this.date.isSame(this.todaysDate, 'day')) {
$newDay.addClass("calendar-date-today");
}
$newDay.append($date);
return $newDay;
@@ -296,26 +353,29 @@ export default class CalendarWidget extends RightDropdownButtonWidget {
createWeekNumber(weekNumber: number) {
const weekNoteId = this.date.local().format('YYYY-') + 'W' + String(weekNumber).padStart(2, '0');
let $newWeekNumber;
let $newWeekNumber;
if (this.weekNoteEnable) {
// Utilize the hover effect of calendar-date
$newWeekNumber = $("<a>").addClass("calendar-date");
if (this.weekNotes.includes(weekNoteId)) {
$newWeekNumber.addClass("calendar-date-exists").attr("data-href", `#root/${weekNoteId}`);
$newWeekNumber.addClass("calendar-date-exists");
$newWeekNumber.attr("data-href", `#root/${weekNoteId}`);
}
} else {
$newWeekNumber = $("<span>").addClass("calendar-week-number-disabled");
}
$newWeekNumber.addClass("calendar-week-number").attr("data-calendar-week-number", weekNoteId);
$newWeekNumber.append($("<span>").html(String(weekNumber)));
return $newWeekNumber;
}
// Use isoWeekday() consistently
private getPrevMonthDays(firstDayISO: number): { weekNumber: number, dates: Dayjs[] } {
private getPrevMonthDays(firstDayOfWeek: number): { weekNumber: number, dates: Dayjs[] } {
const prevMonthLastDay = this.date.subtract(1, 'month').endOf('month');
const daysToAdd = (firstDayISO - this.firstDayOfWeekISO + 7) % 7;
const daysToAdd = (firstDayOfWeek - this.firstDayOfWeek + 7) % 7;
const dates: Dayjs[] = [];
const firstDay = this.date.startOf('month');
@@ -329,16 +389,18 @@ export default class CalendarWidget extends RightDropdownButtonWidget {
return { weekNumber, dates };
}
private getNextMonthDays(lastDayISO: number): Dayjs[] {
private getNextMonthDays(lastDayOfWeek: number): Dayjs[] {
const nextMonthFirstDay = this.date.add(1, 'month').startOf('month');
const dates: Dayjs[] = [];
const lastDayOfUserWeek = ((this.firstDayOfWeekISO + 6 - 1) % 7) + 1; // ISO wrap
const daysToAdd = (lastDayOfUserWeek - lastDayISO + 7) % 7;
const lastDayOfUserWeek = (this.firstDayOfWeek + 6) % 7;
const daysToAdd = (lastDayOfUserWeek - lastDayOfWeek + 7) % 7;
// Get dates from next month
for (let i = 0; i < daysToAdd; i++) {
dates.push(nextMonthFirstDay.add(i, 'day'));
}
return dates;
}
@@ -349,11 +411,12 @@ export default class CalendarWidget extends RightDropdownButtonWidget {
this.$month.empty();
const firstDay = this.date.startOf('month');
const firstDayISO = firstDay.isoWeekday();
const firstDayOfWeek = firstDay.day();
// Add dates from previous month
if (firstDayOfWeek !== this.firstDayOfWeek) {
const { weekNumber, dates } = this.getPrevMonthDays(firstDayOfWeek);
// Previous month filler
if (firstDayISO !== this.firstDayOfWeekISO) {
const { weekNumber, dates } = this.getPrevMonthDays(firstDayISO);
const prevMonth = this.date.subtract(1, 'month').format('YYYY-MM');
const dateNotesForPrevMonth: DateNotesForMonth = await server.get(`special-notes/notes-for-month/${prevMonth}`);
@@ -372,16 +435,18 @@ export default class CalendarWidget extends RightDropdownButtonWidget {
const currentMonth = this.date.month();
// Main month
while (this.date.month() === currentMonth) {
const weekNumber = this.getWeekNumber(this.date);
if (this.date.isoWeekday() === this.firstDayOfWeekISO) {
// Add week number if it's first day of week
if (this.date.day() === this.firstDayOfWeek) {
const $weekNumber = this.createWeekNumber(weekNumber);
this.$month.append($weekNumber);
}
const $day = this.createDay(dateNotesForMonth, this.date.date());
this.$month.append($day);
this.date = this.date.add(1, 'day');
}
// while loop trips over and day is at 30/31, bring it back
@@ -389,11 +454,11 @@ export default class CalendarWidget extends RightDropdownButtonWidget {
// Add dates from next month
const lastDayOfMonth = this.date.endOf('month');
const lastDayISO = lastDayOfMonth.isoWeekday();
const lastDayOfUserWeek = ((this.firstDayOfWeekISO + 6 - 1) % 7) + 1;
const lastDayOfWeek = lastDayOfMonth.day();
const lastDayOfUserWeek = (this.firstDayOfWeek + 6) % 7;
if (lastDayOfWeek !== lastDayOfUserWeek) {
const dates = this.getNextMonthDays(lastDayOfWeek);
if (lastDayISO !== lastDayOfUserWeek) {
const dates = this.getNextMonthDays(lastDayISO);
const nextMonth = this.date.add(1, 'month').format('YYYY-MM');
const dateNotesForNextMonth: DateNotesForMonth = await server.get(`special-notes/notes-for-month/${nextMonth}`);
@@ -412,12 +477,9 @@ export default class CalendarWidget extends RightDropdownButtonWidget {
}
async entitiesReloadedEvent({ loadResults }: EventData<"entitiesReloaded">) {
const WEEK_OPTIONS: (keyof OptionDefinitions)[] = [
"firstDayOfWeek",
"firstWeekOfYear",
"minDaysInFirstWeek",
];
if (!WEEK_OPTIONS.some(opt => loadResults.getOptionNames().includes(opt))) {
if (!loadResults.getOptionNames().includes("firstDayOfWeek") &&
!loadResults.getOptionNames().includes("firstWeekOfYear") &&
!loadResults.getOptionNames().includes("minDaysInFirstWeek")) {
return;
}

View File

@@ -9,9 +9,6 @@
}
button.global-menu-button {
--update-badge-x-offset: 4%;
--update-badge-y-offset: -16%;
position: relative;
width: 100% !important;
height: 100% !important;
@@ -58,26 +55,13 @@ button.global-menu-button {
.global-menu-button-update-available {
position: absolute;
display: flex;
width: 16px;
height: 16px;
right: calc(0px - var(--update-badge-x-offset));
bottom: calc(0px - var(--update-badge-y-offset));
justify-content: center;
align-items: center;
border-radius: 50%;
background: var(--global-menu-update-available-badge-background-color, var(--admonition-tip-accent-color));
color: var(--global-menu-update-available-badge-color, var(--main-background-color));
font-size: 16px;
transition: transform 200ms ease-in-out;
right: -30px;
bottom: -30px;
width: 100%;
height: 100%;
pointer-events: none;
}
.global-menu-button.show .global-menu-button-update-available {
transform: scale(.75);
transform-origin: center;
}
.global-menu .zoom-container {
display: flex;
flex-direction: row;
@@ -85,7 +69,7 @@ button.global-menu-button {
}
.global-menu .zoom-buttons {
margin-inline-start: 2em;
margin-left: 2em;
}
.global-menu .zoom-buttons a {
@@ -95,7 +79,7 @@ button.global-menu-button {
color: var(--button-text-color);
background-color: var(--button-background-color);
padding: 3px;
margin-inline-start: 3px;
margin-left: 3px;
text-decoration: none;
}
@@ -104,17 +88,32 @@ button.global-menu-button {
}
.global-menu .zoom-state {
margin-inline-start: 5px;
margin-inline-end: 5px;
margin-left: 5px;
margin-right: 5px;
}
.global-menu .dropdown-item .bx {
position: relative;
top: 3px;
font-size: 120%;
margin-inline-end: 6px;
margin-right: 6px;
}
/* #region Update available */
.global-menu-button-update-available-button {
width: 21px !important;
height: 21px !important;
padding: 0 !important;
border-radius: var(--button-border-radius);
transform: scale(0.9);
border: none;
opacity: 0.8;
display: flex;
align-items: center;
justify-content: center;
}
.global-menu-button-wrapper:hover .global-menu-button-update-available-button {
opacity: 1;

View File

@@ -3,7 +3,7 @@ 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 { FormDropdownDivider, FormDropdownSubmenu, FormListItem } from "../react/FormList";
import { CommandNames } from "../../components/app_context";
import KeyboardShortcut from "../react/KeyboardShortcut";
import { KeyboardActionNames } from "@triliumnext/commons";
@@ -26,7 +26,7 @@ export default function GlobalMenu({ isHorizontalLayout }: { isHorizontalLayout:
const isVerticalLayout = !isHorizontalLayout;
const parentComponent = useContext(ParentComponent);
const { isUpdateAvailable, latestVersion } = useTriliumUpdateStatus();
return (
<Dropdown
className="global-menu"
@@ -34,7 +34,7 @@ export default function GlobalMenu({ isHorizontalLayout }: { isHorizontalLayout:
text={<>
{isVerticalLayout && <VerticalLayoutIcon />}
{isUpdateAvailable && <div class="global-menu-button-update-available">
<span className="bx bxs-down-arrow-alt global-menu-button-update-available-button" title={t("update_available.update_available")}></span>
<span className="bx bx-sync global-menu-button-update-available-button" title={t("update_available.update_available")}></span>
</div>}
</>}
noDropdownListStyle
@@ -58,14 +58,7 @@ export default function GlobalMenu({ isHorizontalLayout }: { isHorizontalLayout:
<KeyboardActionMenuItem command="showHelp" icon="bx bx-help-circle" text={t("global_menu.show_help")} />
<KeyboardActionMenuItem command="showCheatsheet" icon="bx bxs-keyboard" text={t("global_menu.show-cheatsheet")} />
<MenuItem command="openAboutDialog" icon="bx bx-info-circle" text={t("global_menu.about")} />
{isUpdateAvailable && <>
<FormListHeader text={t("global_menu.new-version-available")} />
<MenuItem command={() => window.open("https://github.com/TriliumNext/Trilium/releases/latest")}
icon="bx bx-download"
text={t("global_menu.download-update", {latestVersion})} />
</>}
{isUpdateAvailable && <MenuItem command={() => window.open("https://github.com/TriliumNext/Trilium/releases/latest")} icon="bx bx-sync" text={`Version ${latestVersion} is available, click to download.`} /> }
{!isElectron() && <BrowserOnlyOptions />}
</Dropdown>
)

View File

@@ -1,29 +0,0 @@
@keyframes left-pane-toggle-button-expand {
from {
rotate: 0deg;
} to {
rotate: 180deg;
}
}
@keyframes left-pane-toggle-button-collapse {
from {
rotate: 180deg;
} to {
rotate: 360deg;
}
}
.layout-vertical .left-pane-toggle-button::before {
display: block;
}
.layout-vertical .left-pane-toggle-button.action-collapse::before {
rotate: 360deg;
animation: left-pane-toggle-button-collapse 600ms ease-in-out;
}
.layout-vertical .left-pane-toggle-button.action-expand::before {
rotate: 180deg;
animation: left-pane-toggle-button-expand 600ms ease-in-out;
}

View File

@@ -1,4 +1,3 @@
import "./left_pane_toggle.css";
import { useEffect, useState } from "preact/hooks";
import ActionButton from "../react/ActionButton";
import options from "../../services/options";
@@ -19,10 +18,12 @@ export default function LeftPaneToggle({ isHorizontalLayout }: { isHorizontalLay
return (
<ActionButton
className={`${isHorizontalLayout ? "toggle-button" : "launcher-button"} left-pane-toggle-button ${currentLeftPaneVisible ? "action-collapse" : "action-expand"}`}
className={`${isHorizontalLayout ? "toggle-button" : "launcher-button"}`}
text={currentLeftPaneVisible ? t("left_pane_toggle.hide_panel") : t("left_pane_toggle.show_panel")}
triggerCommand={currentLeftPaneVisible ? "hideLeftPane" : "showLeftPane"}
icon={isHorizontalLayout ? "bx bx-sidebar" : "bx bx-chevrons-left"}
icon={isHorizontalLayout
? "bx bx-sidebar"
: (currentLeftPaneVisible ? "bx bx-chevrons-left" : "bx bx-chevrons-right" )}
/>
)
}

View File

@@ -1,4 +1,3 @@
import { handleRightToLeftPlacement } from "../../services/utils.js";
import BasicWidget from "../basic_widget.js";
import { Tooltip, Dropdown } from "bootstrap";
type PopoverPlacement = Tooltip.PopoverPlacement;
@@ -49,8 +48,8 @@ export default class RightDropdownButtonWidget extends BasicWidget {
this.$tooltip = this.$widget.find(".tooltip-trigger").attr("title", this.title);
this.tooltip = new Tooltip(this.$tooltip[0], {
placement: handleRightToLeftPlacement(this.settings.titlePlacement),
fallbackPlacements: [ handleRightToLeftPlacement(this.settings.titlePlacement) ]
placement: this.settings.titlePlacement,
fallbackPlacements: [this.settings.titlePlacement]
});
this.$widget

View File

@@ -11,7 +11,7 @@ body.zen .close-zen-container {
display: block;
position: fixed;
top: 2px;
inset-inline-end: 2px;
right: 2px;
z-index: 9999;
-webkit-app-region: no-drag;
}
@@ -21,6 +21,6 @@ body.zen.mobile .close-zen-container {
}
body.zen.electron:not(.platform-darwin):not(.native-titlebar) .close-zen-container {
inset-inline-start: calc(env(titlebar-area-width) - var(--zen-button-size) - 2px);
inset-inline-end: unset;
left: calc(env(titlebar-area-width) - var(--zen-button-size) - 2px);
right: unset;
}

View File

@@ -1,4 +1,4 @@
import { allViewTypes, ViewModeMedia, ViewModeProps, ViewTypeOptions } from "./interface";
import { allViewTypes, ViewModeProps, ViewTypeOptions } from "./interface";
import { useNoteContext, useNoteLabel, useNoteLabelBoolean, useTriliumEvent } from "../react/hooks";
import FNote from "../../entities/fnote";
import "./NoteList.css";
@@ -12,9 +12,8 @@ import BoardView from "./board";
import { subscribeToMessages, unsubscribeToMessage as unsubscribeFromMessage } from "../../services/ws";
import { WebSocketMessage } from "@triliumnext/commons";
import froca from "../../services/froca";
import PresentationView from "./presentation";
interface NoteListProps {
interface NoteListProps<T extends object> {
note: FNote | null | undefined;
notePath: string | null | undefined;
highlightedTokens?: string[] | null;
@@ -22,24 +21,22 @@ interface NoteListProps {
displayOnlyCollections?: boolean;
isEnabled: boolean;
ntxId: string | null | undefined;
media: ViewModeMedia;
onReady?: () => void;
}
export default function NoteList<T extends object>(props: Pick<NoteListProps, "displayOnlyCollections" | "media" | "onReady">) {
export default function NoteList<T extends object>(props: Pick<NoteListProps<T>, "displayOnlyCollections">) {
const { note, noteContext, notePath, ntxId } = useNoteContext();
const isEnabled = noteContext?.hasNoteList();
return <CustomNoteList note={note} isEnabled={!!isEnabled} notePath={notePath} ntxId={ntxId} {...props} />
}
export function SearchNoteList<T extends object>(props: Omit<NoteListProps, "isEnabled">) {
export function SearchNoteList<T extends object>(props: Omit<NoteListProps<T>, "isEnabled">) {
return <CustomNoteList {...props} isEnabled={true} />
}
export function CustomNoteList<T extends object>({ note, isEnabled: shouldEnable, notePath, highlightedTokens, displayOnlyCollections, ntxId, onReady, ...restProps }: NoteListProps) {
function CustomNoteList<T extends object>({ note, isEnabled: shouldEnable, notePath, highlightedTokens, displayOnlyCollections, ntxId }: NoteListProps<T>) {
const widgetRef = useRef<HTMLDivElement>(null);
const viewType = useNoteViewType(note);
const noteIds = useNoteIds(shouldEnable ? note : null, viewType, ntxId);
const noteIds = useNoteIds(note, viewType, ntxId);
const isFullHeight = (viewType && viewType !== "list" && viewType !== "grid");
const [ isIntersecting, setIsIntersecting ] = useState(false);
const shouldRender = (isFullHeight || isIntersecting || note?.type === "book");
@@ -78,14 +75,12 @@ export function CustomNoteList<T extends object>({ note, isEnabled: shouldEnable
note, noteIds, notePath,
highlightedTokens,
viewConfig: viewModeConfig[0],
saveConfig: viewModeConfig[1],
onReady: onReady ?? (() => {}),
...restProps
saveConfig: viewModeConfig[1]
}
}
return (
<div ref={widgetRef} className={`note-list-widget component ${isFullHeight && isEnabled ? "full-height" : ""}`}>
<div ref={widgetRef} className={`note-list-widget component ${isFullHeight ? "full-height" : ""}`}>
{props && isEnabled && (
<div className="note-list-widget-content">
{getComponentByViewType(viewType, props)}
@@ -109,8 +104,6 @@ function getComponentByViewType(viewType: ViewTypeOptions, props: ViewModeProps<
return <TableView {...props} />
case "board":
return <BoardView {...props} />
case "presentation":
return <PresentationView {...props} />
}
}
@@ -127,7 +120,7 @@ function useNoteViewType(note?: FNote | null): ViewTypeOptions | undefined {
}
}
export function useNoteIds(note: FNote | null | undefined, viewType: ViewTypeOptions | undefined, ntxId: string | null | undefined) {
function useNoteIds(note: FNote | null | undefined, viewType: ViewTypeOptions | undefined, ntxId: string | null | undefined) {
const [ noteIds, setNoteIds ] = useState<string[]>([]);
const [ includeArchived ] = useNoteLabelBoolean(note, "includeArchived");
@@ -140,7 +133,7 @@ export function useNoteIds(note: FNote | null | undefined, viewType: ViewTypeOpt
}
async function getNoteIds(note: FNote) {
if (viewType === "list" || viewType === "grid" || viewType === "table" || note.type === "search") {
if (viewType === "list" || viewType === "grid") {
return note.getChildNoteIds();
} else {
return await note.getSubtreeNoteIds(includeArchived);
@@ -191,7 +184,7 @@ export function useNoteIds(note: FNote | null | undefined, viewType: ViewTypeOpt
return noteIds;
}
export function useViewModeConfig<T extends object>(note: FNote | null | undefined, viewType: ViewTypeOptions | undefined) {
function useViewModeConfig<T extends object>(note: FNote | null | undefined, viewType: ViewTypeOptions | undefined) {
const [ viewConfig, setViewConfig ] = useState<[T | undefined, (data: T) => void]>();
useEffect(() => {

View File

@@ -66,7 +66,7 @@ async function recursiveGroupBy(branches: FBranch[], byColumn: ColumnMap, groupB
const note = await branch.getNote();
if (!note || (!includeArchived && note.isArchived)) continue;
if (note.type !== "search" && note.hasChildren()) {
if (note.hasChildren()) {
await recursiveGroupBy(note.getChildBranches(), byColumn, groupByColumn, includeArchived);
}

View File

@@ -23,6 +23,8 @@
flex-shrink: 0;
border: 2px solid transparent;
border-radius: 8px;
padding: 0.5em;
padding-bottom: 0;
background-color: var(--accented-background-color);
transition: border-color 0.2s ease;
overflow-y: auto;
@@ -93,7 +95,7 @@
.board-view-container .board-column .edit-icon {
opacity: 0;
margin-inline-start: 0.5em;
margin-left: 0.5em;
transition: opacity 0.2s ease;
color: var(--muted-text-color);
cursor: pointer;
@@ -102,7 +104,7 @@
.board-view-container .board-column > .board-column-content {
flex-grow: 1;
overflow: scroll;
padding: 0.5em;
padding-bottom: 0.5em;
}
.board-view-container .board-column h3:hover .edit-icon,
@@ -128,10 +130,6 @@
font-size: var(--card-font-size);
}
.board-view-container .board-note:first-of-type {
margin-top: 0;
}
.board-view-container :focus {
outline: 3px solid var(--input-focus-outline-color);
outline-offset: 0;
@@ -146,14 +144,14 @@
}
.board-view-container .board-note .icon {
margin-inline-end: 0.25em;
margin-right: 0.25em;
display: inline;
}
.board-view-container .board-note > .edit-icon {
position: absolute;
top: 8px;
inset-inline-end: 4px;
right: 4px;
padding: 2px;
background-color: var(--main-background-color);
}
@@ -165,10 +163,10 @@
.board-view-container .board-note:hover > .edit-icon {
position: absolute;
top: 8px;
inset-inline-end: 4px;
right: 4px;
color: var(--main-text-color);
background-color: var(--main-background-color);
padding-inline-start: 6px;
padding-left: 6px;
}
.board-view-container .board-note.fade-in {
@@ -269,7 +267,7 @@
}
.board-new-item .icon {
margin-inline-end: 0.25em;
margin-right: 0.25em;
}
.board-add-column {
@@ -296,7 +294,7 @@
}
.board-add-column .icon {
margin-inline-end: 0.5em;
margin-right: 0.5em;
font-size: 1.2em;
}

View File

@@ -13,8 +13,8 @@
.search-result-widget-content .calendar-view {
position: absolute;
top: 0;
inset-inline-start: 0;
inset-inline-end: 0;
left: 0;
right: 0;
bottom: 0;
}
@@ -67,10 +67,10 @@
}
body.desktop:not(.zen) .calendar-view .calendar-header {
padding-inline-end: 5em;
padding-right: 5em;
}
.search-result-widget-content .calendar-view .calendar-header {
padding-inline-end: unset !important;
padding-right: unset !important;
}
/* #endregion */

Some files were not shown because too many files have changed in this diff Show More