mirror of
https://github.com/zadam/trilium.git
synced 2025-12-10 09:24:23 +01:00
Merge remote-tracking branch 'origin/develop' into renovate/csrf-csrf-4.x
This commit is contained in:
commit
f38105ef05
6
.github/workflows/main-docker.yml
vendored
6
.github/workflows/main-docker.yml
vendored
@ -82,7 +82,7 @@ jobs:
|
|||||||
require-healthy: true
|
require-healthy: true
|
||||||
|
|
||||||
- name: Run Playwright tests
|
- name: Run Playwright tests
|
||||||
run: TRILIUM_DOCKER=1 TRILIUM_PORT=8082 pnpx nx run -t e2e
|
run: TRILIUM_DOCKER=1 TRILIUM_PORT=8082 pnpx nx run server-e2e:e2e
|
||||||
- uses: actions/upload-artifact@v4
|
- uses: actions/upload-artifact@v4
|
||||||
if: ${{ !cancelled() }}
|
if: ${{ !cancelled() }}
|
||||||
with:
|
with:
|
||||||
@ -129,7 +129,6 @@ jobs:
|
|||||||
- name: Set TEST_TAG to lowercase
|
- name: Set TEST_TAG to lowercase
|
||||||
run: echo "TEST_TAG=${TEST_TAG,,}" >> $GITHUB_ENV
|
run: echo "TEST_TAG=${TEST_TAG,,}" >> $GITHUB_ENV
|
||||||
|
|
||||||
|
|
||||||
- name: Checkout repository
|
- name: Checkout repository
|
||||||
uses: actions/checkout@v4
|
uses: actions/checkout@v4
|
||||||
- uses: pnpm/action-setup@v4
|
- uses: pnpm/action-setup@v4
|
||||||
@ -142,6 +141,9 @@ jobs:
|
|||||||
- name: Install dependencies
|
- name: Install dependencies
|
||||||
run: pnpm install --frozen-lockfile
|
run: pnpm install --frozen-lockfile
|
||||||
|
|
||||||
|
- name: Run the TypeScript build
|
||||||
|
run: pnpm run server:build
|
||||||
|
|
||||||
- name: Update build info
|
- name: Update build info
|
||||||
run: pnpm run chore:update-build-info
|
run: pnpm run chore:update-build-info
|
||||||
|
|
||||||
|
|||||||
@ -14,7 +14,7 @@ import { applySingleBlockSyntaxHighlight, applySyntaxHighlight } from "./syntax_
|
|||||||
import { loadElkIfNeeded, postprocessMermaidSvg } from "./mermaid.js";
|
import { loadElkIfNeeded, postprocessMermaidSvg } from "./mermaid.js";
|
||||||
import { normalizeMimeTypeForCKEditor } from "./mime_type_definitions.js";
|
import { normalizeMimeTypeForCKEditor } from "./mime_type_definitions.js";
|
||||||
import renderDoc from "./doc_renderer.js";
|
import renderDoc from "./doc_renderer.js";
|
||||||
import { t } from "i18next";
|
import { t } from "../services/i18n.js";
|
||||||
import WheelZoom from 'vanilla-js-wheel-zoom';
|
import WheelZoom from 'vanilla-js-wheel-zoom';
|
||||||
|
|
||||||
let idCounter = 1;
|
let idCounter = 1;
|
||||||
|
|||||||
@ -590,11 +590,6 @@ table.promoted-attributes-in-tooltip th {
|
|||||||
}
|
}
|
||||||
|
|
||||||
.tooltip-trigger {
|
.tooltip-trigger {
|
||||||
position: absolute;
|
|
||||||
top: 0;
|
|
||||||
left: 0;
|
|
||||||
width: 100%;
|
|
||||||
height: 100%;
|
|
||||||
background: transparent;
|
background: transparent;
|
||||||
pointer-events: none;
|
pointer-events: none;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -81,9 +81,6 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Checked list item */
|
/* Checked list item */
|
||||||
:root ul.ck.ck-list button.ck-button.ck-on:not(:hover) {
|
|
||||||
background: transparent !important;
|
|
||||||
}
|
|
||||||
|
|
||||||
:root ul.ck.ck-list button.ck-button:hover,
|
:root ul.ck.ck-list button.ck-button:hover,
|
||||||
:root ul.ck.ck-list button.ck-button.ck-on:hover {
|
:root ul.ck.ck-list button.ck-button.ck-on:hover {
|
||||||
|
|||||||
@ -1,7 +1,6 @@
|
|||||||
import { Dropdown } from "bootstrap";
|
import { Dropdown } from "bootstrap";
|
||||||
import NoteContextAwareWidget from "./note_context_aware_widget.js";
|
import NoteContextAwareWidget from "./note_context_aware_widget.js";
|
||||||
import { getAvailableLocales, getLocaleById } from "../services/i18n.js";
|
import { getAvailableLocales, getLocaleById, t } from "../services/i18n.js";
|
||||||
import { t } from "i18next";
|
|
||||||
import type { EventData } from "../components/app_context.js";
|
import type { EventData } from "../components/app_context.js";
|
||||||
import type FNote from "../entities/fnote.js";
|
import type FNote from "../entities/fnote.js";
|
||||||
import attributes from "../services/attributes.js";
|
import attributes from "../services/attributes.js";
|
||||||
|
|||||||
@ -72,7 +72,7 @@ export default class AbstractCodeTypeWidget extends TypeWidget {
|
|||||||
* @param the note that was changed.
|
* @param the note that was changed.
|
||||||
* @param new content of the note.
|
* @param new content of the note.
|
||||||
*/
|
*/
|
||||||
_update(note: FNote, content: string) {
|
_update(note: { mime: string }, content: string) {
|
||||||
this.codeEditor.setText(content);
|
this.codeEditor.setText(content);
|
||||||
this.codeEditor.setMimeType(note.mime);
|
this.codeEditor.setMimeType(note.mime);
|
||||||
this.codeEditor.clearHistory();
|
this.codeEditor.clearHistory();
|
||||||
|
|||||||
@ -1,6 +1,7 @@
|
|||||||
import server from "../../../services/server.js";
|
import server from "../../../services/server.js";
|
||||||
import AbstractCodeTypeWidget from "../abstract_code_type_widget.js";
|
import AbstractCodeTypeWidget from "../abstract_code_type_widget.js";
|
||||||
import type { EventData } from "../../../components/app_context.js";
|
import type { EventData } from "../../../components/app_context.js";
|
||||||
|
import type { EditorConfig } from "@triliumnext/codemirror";
|
||||||
|
|
||||||
const TPL = /*html*/`<div style="height: 100%; display: flex; flex-direction: column;">
|
const TPL = /*html*/`<div style="height: 100%; display: flex; flex-direction: column;">
|
||||||
<style>
|
<style>
|
||||||
@ -21,9 +22,9 @@ export default class BackendLogWidget extends AbstractCodeTypeWidget {
|
|||||||
private $refreshBackendLog!: JQuery<HTMLElement>;
|
private $refreshBackendLog!: JQuery<HTMLElement>;
|
||||||
|
|
||||||
doRender() {
|
doRender() {
|
||||||
super.doRender();
|
|
||||||
this.$widget = $(TPL);
|
this.$widget = $(TPL);
|
||||||
this.$editor = this.$widget.find(".backend-log-editor");
|
this.$editor = this.$widget.find(".backend-log-editor");
|
||||||
|
super.doRender();
|
||||||
}
|
}
|
||||||
|
|
||||||
async refresh() {
|
async refresh() {
|
||||||
@ -38,9 +39,10 @@ export default class BackendLogWidget extends AbstractCodeTypeWidget {
|
|||||||
this.refresh();
|
this.refresh();
|
||||||
}
|
}
|
||||||
|
|
||||||
getExtraOpts(): Partial<CodeMirrorOpts> {
|
getExtraOpts(): Partial<EditorConfig> {
|
||||||
return {
|
return {
|
||||||
readOnly: true
|
readOnly: true,
|
||||||
|
preferPerformance: true
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -40,7 +40,7 @@ import ShareSettingsOptions from "./options/other/share_settings.js";
|
|||||||
import AiSettingsOptions from "./options/ai_settings.js";
|
import AiSettingsOptions from "./options/ai_settings.js";
|
||||||
import type FNote from "../../entities/fnote.js";
|
import type FNote from "../../entities/fnote.js";
|
||||||
import type NoteContextAwareWidget from "../note_context_aware_widget.js";
|
import type NoteContextAwareWidget from "../note_context_aware_widget.js";
|
||||||
import { t } from "i18next";
|
import { t } from "../../services/i18n.js";
|
||||||
import LanguageOptions from "./options/i18n/language.js";
|
import LanguageOptions from "./options/i18n/language.js";
|
||||||
import type BasicWidget from "../basic_widget.js";
|
import type BasicWidget from "../basic_widget.js";
|
||||||
import CodeTheme from "./options/code_notes/code_theme.js";
|
import CodeTheme from "./options/code_notes/code_theme.js";
|
||||||
|
|||||||
@ -1,7 +1,7 @@
|
|||||||
import OptionsWidget from "../options_widget.js";
|
import OptionsWidget from "../options_widget.js";
|
||||||
import type { OptionMap } from "@triliumnext/commons";
|
import type { OptionMap } from "@triliumnext/commons";
|
||||||
import { getAvailableLocales } from "../../../../services/i18n.js";
|
import { getAvailableLocales } from "../../../../services/i18n.js";
|
||||||
import { t } from "i18next";
|
import { t } from "../../../../services/i18n.js";
|
||||||
|
|
||||||
const TPL = /*html*/`
|
const TPL = /*html*/`
|
||||||
<div class="options-section">
|
<div class="options-section">
|
||||||
|
|||||||
@ -18,7 +18,7 @@
|
|||||||
"@types/electron-squirrel-startup": "1.0.2",
|
"@types/electron-squirrel-startup": "1.0.2",
|
||||||
"@triliumnext/server": "workspace:*",
|
"@triliumnext/server": "workspace:*",
|
||||||
"copy-webpack-plugin": "13.0.0",
|
"copy-webpack-plugin": "13.0.0",
|
||||||
"electron": "36.2.0",
|
"electron": "36.2.1",
|
||||||
"@electron-forge/cli": "7.8.1",
|
"@electron-forge/cli": "7.8.1",
|
||||||
"@electron-forge/maker-deb": "7.8.1",
|
"@electron-forge/maker-deb": "7.8.1",
|
||||||
"@electron-forge/maker-dmg": "7.8.1",
|
"@electron-forge/maker-dmg": "7.8.1",
|
||||||
@ -57,7 +57,7 @@
|
|||||||
"command": "cross-env DEBUG=* tsx scripts/electron-rebuild.mts {projectRoot}/dist"
|
"command": "cross-env DEBUG=* tsx scripts/electron-rebuild.mts {projectRoot}/dist"
|
||||||
},
|
},
|
||||||
"nixos": {
|
"nixos": {
|
||||||
"command": "cross-env DEBUG=* tsx scripts/electron-rebuild.mts {projectRoot}/dist $(nix-shell -p electron_33 --run \"electron --version\")"
|
"command": "cross-env DEBUG=* tsx scripts/electron-rebuild.mts {projectRoot}/dist $(nix-shell -p electron_35 --run \"electron --version\")"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@ -73,7 +73,7 @@
|
|||||||
"cwd": "{projectRoot}/dist"
|
"cwd": "{projectRoot}/dist"
|
||||||
},
|
},
|
||||||
"nixos": {
|
"nixos": {
|
||||||
"command": "nix-shell -p electron_33 --run \"electron {projectRoot}/dist/main.js\"",
|
"command": "nix-shell -p electron_35 --run \"electron {projectRoot}/dist/main.js\"",
|
||||||
"cwd": ".",
|
"cwd": ".",
|
||||||
"forwardAllArgs": false
|
"forwardAllArgs": false
|
||||||
}
|
}
|
||||||
@ -91,7 +91,7 @@
|
|||||||
"cwd": "{projectRoot}/dist"
|
"cwd": "{projectRoot}/dist"
|
||||||
},
|
},
|
||||||
"nixos": {
|
"nixos": {
|
||||||
"command": "nix-shell -p electron_33 --run \"electron {projectRoot}/dist/main.js\"",
|
"command": "nix-shell -p electron_35 --run \"electron {projectRoot}/dist/main.js\"",
|
||||||
"cwd": ".",
|
"cwd": ".",
|
||||||
"forwardAllArgs": false
|
"forwardAllArgs": false
|
||||||
}
|
}
|
||||||
|
|||||||
@ -8,7 +8,7 @@
|
|||||||
"@triliumnext/desktop": "workspace:*",
|
"@triliumnext/desktop": "workspace:*",
|
||||||
"@types/fs-extra": "11.0.4",
|
"@types/fs-extra": "11.0.4",
|
||||||
"copy-webpack-plugin": "13.0.0",
|
"copy-webpack-plugin": "13.0.0",
|
||||||
"electron": "36.2.0",
|
"electron": "36.2.1",
|
||||||
"fs-extra": "11.3.0"
|
"fs-extra": "11.3.0"
|
||||||
},
|
},
|
||||||
"nx": {
|
"nx": {
|
||||||
|
|||||||
@ -1,4 +1,4 @@
|
|||||||
FROM node:22.15.0-bullseye-slim AS builder
|
FROM node:22.15.1-bullseye-slim AS builder
|
||||||
RUN corepack enable
|
RUN corepack enable
|
||||||
|
|
||||||
# Install native dependencies since we might be building cross-platform.
|
# Install native dependencies since we might be building cross-platform.
|
||||||
@ -7,7 +7,7 @@ FROM node:22.15.0-bullseye-slim AS builder
|
|||||||
# We have to use --no-frozen-lockfile due to CKEditor patches
|
# We have to use --no-frozen-lockfile due to CKEditor patches
|
||||||
RUN pnpm install --no-frozen-lockfile --prod && pnpm rebuild
|
RUN pnpm install --no-frozen-lockfile --prod && pnpm rebuild
|
||||||
|
|
||||||
FROM node:22.15.0-bullseye-slim
|
FROM node:22.15.1-bullseye-slim
|
||||||
# Install only runtime dependencies
|
# Install only runtime dependencies
|
||||||
RUN apt-get update && \
|
RUN apt-get update && \
|
||||||
apt-get install -y --no-install-recommends \
|
apt-get install -y --no-install-recommends \
|
||||||
|
|||||||
@ -1,4 +1,4 @@
|
|||||||
FROM node:22.15.0-alpine AS builder
|
FROM node:22.15.1-alpine AS builder
|
||||||
RUN corepack enable
|
RUN corepack enable
|
||||||
|
|
||||||
# Install native dependencies since we might be building cross-platform.
|
# Install native dependencies since we might be building cross-platform.
|
||||||
@ -7,7 +7,7 @@ FROM node:22.15.0-alpine AS builder
|
|||||||
# We have to use --no-frozen-lockfile due to CKEditor patches
|
# We have to use --no-frozen-lockfile due to CKEditor patches
|
||||||
RUN pnpm install --no-frozen-lockfile --prod && pnpm rebuild
|
RUN pnpm install --no-frozen-lockfile --prod && pnpm rebuild
|
||||||
|
|
||||||
FROM node:22.15.0-alpine
|
FROM node:22.15.1-alpine
|
||||||
# Install runtime dependencies
|
# Install runtime dependencies
|
||||||
RUN apk add --no-cache su-exec shadow
|
RUN apk add --no-cache su-exec shadow
|
||||||
|
|
||||||
|
|||||||
@ -48,7 +48,7 @@
|
|||||||
"jquery": "3.7.1",
|
"jquery": "3.7.1",
|
||||||
"katex": "0.16.22",
|
"katex": "0.16.22",
|
||||||
"normalize.css": "8.0.1",
|
"normalize.css": "8.0.1",
|
||||||
"@anthropic-ai/sdk": "0.50.4",
|
"@anthropic-ai/sdk": "0.51.0",
|
||||||
"@braintree/sanitize-url": "7.1.1",
|
"@braintree/sanitize-url": "7.1.1",
|
||||||
"@triliumnext/commons": "workspace:*",
|
"@triliumnext/commons": "workspace:*",
|
||||||
"@triliumnext/express-partial-content": "workspace:*",
|
"@triliumnext/express-partial-content": "workspace:*",
|
||||||
@ -68,7 +68,7 @@
|
|||||||
"debounce": "2.2.0",
|
"debounce": "2.2.0",
|
||||||
"debug": "4.4.1",
|
"debug": "4.4.1",
|
||||||
"ejs": "3.1.10",
|
"ejs": "3.1.10",
|
||||||
"electron": "36.2.0",
|
"electron": "36.2.1",
|
||||||
"electron-debug": "4.1.0",
|
"electron-debug": "4.1.0",
|
||||||
"electron-window-state": "5.0.3",
|
"electron-window-state": "5.0.3",
|
||||||
"escape-html": "1.0.3",
|
"escape-html": "1.0.3",
|
||||||
|
|||||||
@ -6,7 +6,6 @@ import attributeService from "./attributes.js";
|
|||||||
import cloningService from "./cloning.js";
|
import cloningService from "./cloning.js";
|
||||||
import dayjs from "dayjs";
|
import dayjs from "dayjs";
|
||||||
import hoistedNoteService from "./hoisted_note.js";
|
import hoistedNoteService from "./hoisted_note.js";
|
||||||
import i18next from "i18next";
|
|
||||||
import isSameOrAfter from "dayjs/plugin/isSameOrAfter.js";
|
import isSameOrAfter from "dayjs/plugin/isSameOrAfter.js";
|
||||||
import noteService from "./notes.js";
|
import noteService from "./notes.js";
|
||||||
import optionService from "./options.js";
|
import optionService from "./options.js";
|
||||||
@ -16,6 +15,7 @@ import searchContext from "../services/search/search_context.js";
|
|||||||
import searchService from "../services/search/services/search.js";
|
import searchService from "../services/search/services/search.js";
|
||||||
import sql from "./sql.js";
|
import sql from "./sql.js";
|
||||||
import { t } from "i18next";
|
import { t } from "i18next";
|
||||||
|
import { ordinal } from "./i18n.js";
|
||||||
|
|
||||||
dayjs.extend(isSameOrAfter);
|
dayjs.extend(isSameOrAfter);
|
||||||
dayjs.extend(quarterOfYear);
|
dayjs.extend(quarterOfYear);
|
||||||
@ -67,24 +67,7 @@ function getTimeUnitReplacements(timeUnit: TimeUnit): string[] {
|
|||||||
return units.slice(0, index + 1).flatMap(unit => baseReplacements[unit]);
|
return units.slice(0, index + 1).flatMap(unit => baseReplacements[unit]);
|
||||||
}
|
}
|
||||||
|
|
||||||
async function ordinal(date: Dayjs, lng: string) {
|
function getJournalNoteTitle(
|
||||||
const localeMap: Record<string, string> = {
|
|
||||||
cn: "zh-cn",
|
|
||||||
tw: "zh-tw"
|
|
||||||
};
|
|
||||||
|
|
||||||
const dayjsLocale = localeMap[lng] || lng;
|
|
||||||
|
|
||||||
try {
|
|
||||||
await import(`dayjs/locale/${dayjsLocale}.js`);
|
|
||||||
} catch (err) {
|
|
||||||
console.warn(`Could not load locale ${dayjsLocale}`, err);
|
|
||||||
}
|
|
||||||
|
|
||||||
return dayjs(date).locale(dayjsLocale).format("Do");
|
|
||||||
}
|
|
||||||
|
|
||||||
async function getJournalNoteTitle(
|
|
||||||
rootNote: BNote,
|
rootNote: BNote,
|
||||||
timeUnit: TimeUnit,
|
timeUnit: TimeUnit,
|
||||||
dateObj: Dayjs,
|
dateObj: Dayjs,
|
||||||
@ -102,7 +85,7 @@ async function getJournalNoteTitle(
|
|||||||
const monthName = t(MONTH_TRANSLATION_IDS[dateObj.month()]);
|
const monthName = t(MONTH_TRANSLATION_IDS[dateObj.month()]);
|
||||||
const weekDay = t(WEEKDAY_TRANSLATION_IDS[dateObj.day()]);
|
const weekDay = t(WEEKDAY_TRANSLATION_IDS[dateObj.day()]);
|
||||||
const numberStr = number.toString();
|
const numberStr = number.toString();
|
||||||
const ordinalStr = await ordinal(dateObj, i18next.language);
|
const ordinalStr = ordinal(dateObj);
|
||||||
|
|
||||||
const allReplacements: Record<string, string> = {
|
const allReplacements: Record<string, string> = {
|
||||||
// Common date formats
|
// Common date formats
|
||||||
@ -228,7 +211,7 @@ function getQuarterNumberStr(date: Dayjs) {
|
|||||||
return `${date.year()}-Q${date.quarter()}`;
|
return `${date.year()}-Q${date.quarter()}`;
|
||||||
}
|
}
|
||||||
|
|
||||||
async function getQuarterNote(quarterStr: string, _rootNote: BNote | null = null): Promise<BNote> {
|
function getQuarterNote(quarterStr: string, _rootNote: BNote | null = null): BNote {
|
||||||
const rootNote = _rootNote || getRootCalendarNote();
|
const rootNote = _rootNote || getRootCalendarNote();
|
||||||
|
|
||||||
quarterStr = quarterStr.trim().substring(0, 7);
|
quarterStr = quarterStr.trim().substring(0, 7);
|
||||||
@ -247,7 +230,7 @@ async function getQuarterNote(quarterStr: string, _rootNote: BNote | null = null
|
|||||||
const quarterStartDate = dayjs().year(parseInt(yearStr)).month(firstMonth).date(1);
|
const quarterStartDate = dayjs().year(parseInt(yearStr)).month(firstMonth).date(1);
|
||||||
|
|
||||||
const yearNote = getYearNote(yearStr, rootNote);
|
const yearNote = getYearNote(yearStr, rootNote);
|
||||||
const noteTitle = await getJournalNoteTitle(
|
const noteTitle = getJournalNoteTitle(
|
||||||
rootNote, "quarter", quarterStartDate, quarterNumber
|
rootNote, "quarter", quarterStartDate, quarterNumber
|
||||||
);
|
);
|
||||||
|
|
||||||
@ -269,7 +252,7 @@ async function getQuarterNote(quarterStr: string, _rootNote: BNote | null = null
|
|||||||
return quarterNote as unknown as BNote;
|
return quarterNote as unknown as BNote;
|
||||||
}
|
}
|
||||||
|
|
||||||
async function getMonthNote(dateStr: string, _rootNote: BNote | null = null): Promise<BNote> {
|
function getMonthNote(dateStr: string, _rootNote: BNote | null = null): BNote {
|
||||||
const rootNote = _rootNote || getRootCalendarNote();
|
const rootNote = _rootNote || getRootCalendarNote();
|
||||||
|
|
||||||
const monthStr = dateStr.substring(0, 7);
|
const monthStr = dateStr.substring(0, 7);
|
||||||
@ -286,12 +269,12 @@ async function getMonthNote(dateStr: string, _rootNote: BNote | null = null): Pr
|
|||||||
let monthParentNote;
|
let monthParentNote;
|
||||||
|
|
||||||
if (rootNote.hasLabel("enableQuarterNote")) {
|
if (rootNote.hasLabel("enableQuarterNote")) {
|
||||||
monthParentNote = await getQuarterNote(getQuarterNumberStr(dayjs(dateStr)), rootNote);
|
monthParentNote = getQuarterNote(getQuarterNumberStr(dayjs(dateStr)), rootNote);
|
||||||
} else {
|
} else {
|
||||||
monthParentNote = getYearNote(dateStr, rootNote);
|
monthParentNote = getYearNote(dateStr, rootNote);
|
||||||
}
|
}
|
||||||
|
|
||||||
const noteTitle = await getJournalNoteTitle(
|
const noteTitle = getJournalNoteTitle(
|
||||||
rootNote, "month", dayjs(dateStr), parseInt(monthNumber)
|
rootNote, "month", dayjs(dateStr), parseInt(monthNumber)
|
||||||
);
|
);
|
||||||
|
|
||||||
@ -408,7 +391,7 @@ function getWeekFirstDayNote(dateStr: string, rootNote: BNote | null = null) {
|
|||||||
* @param _rootNote a {@link BNote} representing the calendar root, or {@code null} or not specified to use the default root calendar note.
|
* @param _rootNote a {@link BNote} representing the calendar root, or {@code null} or not specified to use the default root calendar note.
|
||||||
* @returns a Promise that resolves to the {@link BNote} corresponding to the week note.
|
* @returns a Promise that resolves to the {@link BNote} corresponding to the week note.
|
||||||
*/
|
*/
|
||||||
async function getWeekNote(weekStr: string, _rootNote: BNote | null = null): Promise<BNote | null> {
|
function getWeekNote(weekStr: string, _rootNote: BNote | null = null): BNote | null {
|
||||||
const rootNote = _rootNote || getRootCalendarNote();
|
const rootNote = _rootNote || getRootCalendarNote();
|
||||||
if (!rootNote.hasLabel("enableWeekNote")) {
|
if (!rootNote.hasLabel("enableWeekNote")) {
|
||||||
return null;
|
return null;
|
||||||
@ -435,10 +418,10 @@ async function getWeekNote(weekStr: string, _rootNote: BNote | null = null): Pro
|
|||||||
const startMonth = startDate.month();
|
const startMonth = startDate.month();
|
||||||
const endMonth = endDate.month();
|
const endMonth = endDate.month();
|
||||||
|
|
||||||
const monthNote = await getMonthNote(startDate.format("YYYY-MM-DD"), rootNote);
|
const monthNote = getMonthNote(startDate.format("YYYY-MM-DD"), rootNote);
|
||||||
const noteTitle = await getJournalNoteTitle(rootNote, "week", startDate, weekNumber);
|
const noteTitle = getJournalNoteTitle(rootNote, "week", startDate, weekNumber);
|
||||||
|
|
||||||
sql.transactional(async () => {
|
sql.transactional(() => {
|
||||||
weekNote = createNote(monthNote, noteTitle);
|
weekNote = createNote(monthNote, noteTitle);
|
||||||
|
|
||||||
attributeService.createLabel(weekNote.noteId, WEEK_LABEL, weekStr);
|
attributeService.createLabel(weekNote.noteId, WEEK_LABEL, weekStr);
|
||||||
@ -452,7 +435,7 @@ async function getWeekNote(weekStr: string, _rootNote: BNote | null = null): Pro
|
|||||||
|
|
||||||
// If the week spans different months, clone the week note in the other month as well
|
// If the week spans different months, clone the week note in the other month as well
|
||||||
if (startMonth !== endMonth) {
|
if (startMonth !== endMonth) {
|
||||||
const secondMonthNote = await getMonthNote(endDate.format("YYYY-MM-DD"), rootNote);
|
const secondMonthNote = getMonthNote(endDate.format("YYYY-MM-DD"), rootNote);
|
||||||
cloningService.cloneNoteToParentNote(weekNote.noteId, secondMonthNote.noteId);
|
cloningService.cloneNoteToParentNote(weekNote.noteId, secondMonthNote.noteId);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
@ -460,7 +443,7 @@ async function getWeekNote(weekStr: string, _rootNote: BNote | null = null): Pro
|
|||||||
return weekNote as unknown as BNote;
|
return weekNote as unknown as BNote;
|
||||||
}
|
}
|
||||||
|
|
||||||
async function getDayNote(dateStr: string, _rootNote: BNote | null = null): Promise<BNote> {
|
function getDayNote(dateStr: string, _rootNote: BNote | null = null): BNote {
|
||||||
const rootNote = _rootNote || getRootCalendarNote();
|
const rootNote = _rootNote || getRootCalendarNote();
|
||||||
|
|
||||||
dateStr = dateStr.trim().substring(0, 10);
|
dateStr = dateStr.trim().substring(0, 10);
|
||||||
@ -476,13 +459,13 @@ async function getDayNote(dateStr: string, _rootNote: BNote | null = null): Prom
|
|||||||
let dateParentNote;
|
let dateParentNote;
|
||||||
|
|
||||||
if (rootNote.hasLabel("enableWeekNote")) {
|
if (rootNote.hasLabel("enableWeekNote")) {
|
||||||
dateParentNote = await getWeekNote(getWeekNumberStr(dayjs(dateStr)), rootNote);
|
dateParentNote = getWeekNote(getWeekNumberStr(dayjs(dateStr)), rootNote);
|
||||||
} else {
|
} else {
|
||||||
dateParentNote = await getMonthNote(dateStr, rootNote);
|
dateParentNote = getMonthNote(dateStr, rootNote);
|
||||||
}
|
}
|
||||||
|
|
||||||
const dayNumber = dateStr.substring(8, 10);
|
const dayNumber = dateStr.substring(8, 10);
|
||||||
const noteTitle = await getJournalNoteTitle(
|
const noteTitle = getJournalNoteTitle(
|
||||||
rootNote, "day", dayjs(dateStr), parseInt(dayNumber)
|
rootNote, "day", dayjs(dateStr), parseInt(dayNumber)
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|||||||
@ -5,20 +5,43 @@ import { join } from "path";
|
|||||||
import { getResourceDir } from "./utils.js";
|
import { getResourceDir } from "./utils.js";
|
||||||
import hidden_subtree from "./hidden_subtree.js";
|
import hidden_subtree from "./hidden_subtree.js";
|
||||||
import { LOCALES, type Locale } from "@triliumnext/commons";
|
import { LOCALES, type Locale } from "@triliumnext/commons";
|
||||||
|
import dayjs, { Dayjs } from "dayjs";
|
||||||
|
|
||||||
|
const DAYJS_LOCALE_MAP: Record<string, string> = {
|
||||||
|
cn: "zh-cn",
|
||||||
|
tw: "zh-tw"
|
||||||
|
};
|
||||||
|
|
||||||
|
let dayjsLocale: string;
|
||||||
|
|
||||||
export async function initializeTranslations() {
|
export async function initializeTranslations() {
|
||||||
const resourceDir = getResourceDir();
|
const resourceDir = getResourceDir();
|
||||||
const Backend = (await import("i18next-fs-backend")).default;
|
const Backend = (await import("i18next-fs-backend")).default;
|
||||||
|
const locale = getCurrentLanguage();
|
||||||
|
|
||||||
// Initialize translations
|
// Initialize translations
|
||||||
await i18next.use(Backend).init({
|
await i18next.use(Backend).init({
|
||||||
lng: getCurrentLanguage(),
|
lng: locale,
|
||||||
fallbackLng: "en",
|
fallbackLng: "en",
|
||||||
ns: "server",
|
ns: "server",
|
||||||
backend: {
|
backend: {
|
||||||
loadPath: join(resourceDir, "assets/translations/{{lng}}/{{ns}}.json")
|
loadPath: join(resourceDir, "assets/translations/{{lng}}/{{ns}}.json")
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// Initialize dayjs locale.
|
||||||
|
dayjsLocale = DAYJS_LOCALE_MAP[locale] ?? locale;
|
||||||
|
try {
|
||||||
|
await import(`dayjs/locale/${dayjsLocale}.js`);
|
||||||
|
} catch (err) {
|
||||||
|
console.warn(`Could not load locale ${dayjsLocale}`, err);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export function ordinal(date: Dayjs) {
|
||||||
|
return dayjs(date)
|
||||||
|
.locale(dayjsLocale)
|
||||||
|
.format("Do");
|
||||||
}
|
}
|
||||||
|
|
||||||
export function getLocales(): Locale[] {
|
export function getLocales(): Locale[] {
|
||||||
|
|||||||
@ -39,6 +39,7 @@
|
|||||||
* Slight organization in Appearance settings: code block themes are now in "Text Notes", added a "Related settings" section in Appearance.
|
* Slight organization in Appearance settings: code block themes are now in "Text Notes", added a "Related settings" section in Appearance.
|
||||||
* [Added support for opening and activating a note in a new tab using Ctrl+Shift+click on notes in the launcher pane, note tree, or note images](https://github.com/TriliumNext/Notes/pull/1854) by @SiriusXT
|
* [Added support for opening and activating a note in a new tab using Ctrl+Shift+click on notes in the launcher pane, note tree, or note images](https://github.com/TriliumNext/Notes/pull/1854) by @SiriusXT
|
||||||
* [Style and footnote improvements](https://github.com/TriliumNext/Notes/pull/1913) by @SiriusXT
|
* [Style and footnote improvements](https://github.com/TriliumNext/Notes/pull/1913) by @SiriusXT
|
||||||
|
* Backend log: disable some editor features in order to increase performance for large logs (syntax highlighting, folding, etc.).
|
||||||
|
|
||||||
## 📖 Documentation
|
## 📖 Documentation
|
||||||
|
|
||||||
|
|||||||
@ -20,6 +20,8 @@ export interface EditorConfig {
|
|||||||
lineWrapping?: boolean;
|
lineWrapping?: boolean;
|
||||||
vimKeybindings?: boolean;
|
vimKeybindings?: boolean;
|
||||||
readOnly?: boolean;
|
readOnly?: boolean;
|
||||||
|
/** Disables some of the nice-to-have features (bracket matching, syntax highlighting, indentation markers) in order to improve performance. */
|
||||||
|
preferPerformance?: boolean;
|
||||||
tabIndex?: number;
|
tabIndex?: number;
|
||||||
onContentChanged?: ContentChangedListener;
|
onContentChanged?: ContentChangedListener;
|
||||||
}
|
}
|
||||||
@ -51,19 +53,10 @@ export default class CodeMirror extends EditorView {
|
|||||||
...extensions,
|
...extensions,
|
||||||
languageCompartment.of([]),
|
languageCompartment.of([]),
|
||||||
lineWrappingCompartment.of(config.lineWrapping ? EditorView.lineWrapping : []),
|
lineWrappingCompartment.of(config.lineWrapping ? EditorView.lineWrapping : []),
|
||||||
themeCompartment.of([
|
|
||||||
syntaxHighlighting(defaultHighlightStyle, { fallback: true })
|
|
||||||
]),
|
|
||||||
|
|
||||||
searchMatchHighlightTheme,
|
searchMatchHighlightTheme,
|
||||||
searchHighlightCompartment.of([]),
|
searchHighlightCompartment.of([]),
|
||||||
|
|
||||||
highlightActiveLine(),
|
highlightActiveLine(),
|
||||||
highlightSelectionMatches(),
|
|
||||||
bracketMatching(),
|
|
||||||
lineNumbers(),
|
lineNumbers(),
|
||||||
foldGutter(),
|
|
||||||
indentationMarkers(),
|
|
||||||
indentUnit.of(" ".repeat(4)),
|
indentUnit.of(" ".repeat(4)),
|
||||||
keymap.of([
|
keymap.of([
|
||||||
...defaultKeymap,
|
...defaultKeymap,
|
||||||
@ -72,6 +65,19 @@ export default class CodeMirror extends EditorView {
|
|||||||
])
|
])
|
||||||
]
|
]
|
||||||
|
|
||||||
|
if (!config.preferPerformance) {
|
||||||
|
extensions = [
|
||||||
|
...extensions,
|
||||||
|
themeCompartment.of([
|
||||||
|
syntaxHighlighting(defaultHighlightStyle, { fallback: true })
|
||||||
|
]),
|
||||||
|
highlightSelectionMatches(),
|
||||||
|
bracketMatching(),
|
||||||
|
foldGutter(),
|
||||||
|
indentationMarkers(),
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
if (!config.readOnly) {
|
if (!config.readOnly) {
|
||||||
// Logic specific to editable notes
|
// Logic specific to editable notes
|
||||||
if (config.placeholder) {
|
if (config.placeholder) {
|
||||||
|
|||||||
471
pnpm-lock.yaml
generated
471
pnpm-lock.yaml
generated
File diff suppressed because it is too large
Load Diff
Loading…
x
Reference in New Issue
Block a user