mirror of
https://github.com/zadam/trilium.git
synced 2026-05-06 14:47:07 +02:00
chore(standalone): reintegrate changes from main lost in the merge
This commit is contained in:
@@ -9,7 +9,7 @@ import NodejsZipProvider from "../src/zip_provider.js";
|
||||
import ServerPlatformProvider from "../src/platform_provider.js";
|
||||
import BetterSqlite3Provider from "../src/sql_provider.js";
|
||||
import NodejsInAppHelpProvider from "../src/in_app_help_provider.js";
|
||||
import { initializeTranslations } from "../src/services/i18n.js";
|
||||
import { initializeTranslationsWithParams } from "../src/services/i18n.js";
|
||||
|
||||
// Initialize environment variables.
|
||||
process.env.TRILIUM_DATA_DIR = join(__dirname, "db");
|
||||
@@ -41,7 +41,7 @@ beforeAll(async () => {
|
||||
executionContext: new ClsHookedExecutionContext(),
|
||||
schema: readFileSync(require.resolve("@triliumnext/core/src/assets/schema.sql"), "utf-8"),
|
||||
platform: new ServerPlatformProvider(),
|
||||
translations: initializeTranslations,
|
||||
translations: initializeTranslationsWithParams,
|
||||
inAppHelp: new NodejsInAppHelpProvider()
|
||||
});
|
||||
});
|
||||
|
||||
@@ -71,7 +71,7 @@ async function startApplication() {
|
||||
messaging: new WebSocketMessagingProvider(),
|
||||
schema: loadCoreSchema(),
|
||||
platform: new ServerPlatformProvider(),
|
||||
translations: (await import("./services/i18n.js")).initializeTranslations,
|
||||
translations: (await import("./services/i18n.js")).initializeTranslationsWithParams,
|
||||
// demo.zip is a server-owned asset; src/assets is copied to dist/assets
|
||||
// by the build script, so the same RESOURCE_DIR-relative path works in
|
||||
// both source and bundled-production modes.
|
||||
|
||||
@@ -1,10 +1,17 @@
|
||||
import { LOCALE_IDS, setDayjsLocale } from "@triliumnext/commons";
|
||||
import type i18next from "i18next";
|
||||
import { dayjs, LOCALES, LOCALE_IDS, setDayjsLocale, type Dayjs } from "@triliumnext/commons";
|
||||
import i18next from "i18next";
|
||||
import { join } from "path";
|
||||
|
||||
import { getResourceDir } from "./utils";
|
||||
import options from "./options.js";
|
||||
import sql_init from "./sql_init.js";
|
||||
import hidden_subtree from "./hidden_subtree.js";
|
||||
|
||||
export async function initializeTranslations(i18nextInstance: typeof i18next, locale: LOCALE_IDS) {
|
||||
/**
|
||||
* Initialize translations with explicit i18next instance and locale.
|
||||
* Used as a TranslationProvider callback for initializeCore().
|
||||
*/
|
||||
export async function initializeTranslationsWithParams(i18nextInstance: typeof i18next, locale: LOCALE_IDS) {
|
||||
const resourceDir = getResourceDir();
|
||||
const Backend = (await import("i18next-fs-backend/cjs")).default;
|
||||
|
||||
@@ -21,3 +28,42 @@ export async function initializeTranslations(i18nextInstance: typeof i18next, lo
|
||||
// Initialize dayjs locale.
|
||||
await setDayjsLocale(locale);
|
||||
}
|
||||
|
||||
/**
|
||||
* Initialize translations using the global i18next instance and locale from options.
|
||||
* Convenience function for scripts that don't use initializeCore().
|
||||
*/
|
||||
export async function initializeTranslations() {
|
||||
const locale = getCurrentLanguage();
|
||||
await initializeTranslationsWithParams(i18next, locale);
|
||||
}
|
||||
|
||||
export function ordinal(date: Dayjs) {
|
||||
return dayjs(date).format("Do");
|
||||
}
|
||||
|
||||
function getCurrentLanguage(): LOCALE_IDS {
|
||||
let language: string | null = null;
|
||||
if (sql_init.isDbInitialized()) {
|
||||
language = options.getOptionOrNull("locale");
|
||||
}
|
||||
|
||||
if (!language) {
|
||||
console.info("Language option not found, falling back to en.");
|
||||
language = "en";
|
||||
}
|
||||
|
||||
return language as LOCALE_IDS;
|
||||
}
|
||||
|
||||
export async function changeLanguage(locale: string) {
|
||||
await i18next.changeLanguage(locale);
|
||||
hidden_subtree.checkHiddenSubtree(true, { restoreNames: true });
|
||||
}
|
||||
|
||||
export function getCurrentLocale() {
|
||||
const localeId = options.getOptionOrNull("locale") ?? "en";
|
||||
const currentLocale = LOCALES.find(l => l.id === localeId);
|
||||
if (!currentLocale) return LOCALES.find(l => l.id === "en")!;
|
||||
return currentLocale;
|
||||
}
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
import { type AttributeRow, dayjs, formatLogMessage } from "@triliumnext/commons";
|
||||
import AbstractBeccaEntity from "../becca/entities/abstract_becca_entity";
|
||||
import Becca from "../becca/becca-interface";
|
||||
import axios from "axios";
|
||||
import * as cheerio from "cheerio";
|
||||
import * as htmlParser from "node-html-parser";
|
||||
import xml2js from "xml2js";
|
||||
|
||||
@@ -67,14 +67,49 @@ export async function initNotSyncedOptions(initialized: boolean, opts: NotSynced
|
||||
optionService.createOption("textNoteEditorType", "ckeditor-classic", true);
|
||||
|
||||
optionService.createOption("syncServerHost", opts.syncServerHost || "", false);
|
||||
optionService.createOption("syncServerTimeout", "120000", false);
|
||||
optionService.createOption("syncServerTimeout", "120", false); // 120 seconds (2 minutes)
|
||||
optionService.createOption("syncProxy", opts.syncProxy || "", false);
|
||||
}
|
||||
|
||||
/**
|
||||
* Migrates a sync timeout value from milliseconds to seconds.
|
||||
* Values >= 1000 are assumed to be in milliseconds (since 1000+ seconds = 16+ minutes is unlikely).
|
||||
* TimeSelector stores values in seconds; the scale is only used for display.
|
||||
*
|
||||
* @returns The value in seconds and preferred display scale, or null if no migration is needed.
|
||||
*/
|
||||
export function migrateSyncTimeoutFromMilliseconds(milliseconds: number): { value: number; scale: number } | null {
|
||||
if (isNaN(milliseconds) || milliseconds < 1000) {
|
||||
return null;
|
||||
}
|
||||
|
||||
const seconds = Math.round(milliseconds / 1000);
|
||||
|
||||
// Value is always stored in seconds; scale determines display unit
|
||||
if (seconds >= 60 && seconds % 60 === 0) {
|
||||
return { value: seconds, scale: 60 }; // display as minutes
|
||||
}
|
||||
return { value: seconds, scale: 1 }; // display as seconds
|
||||
}
|
||||
|
||||
/**
|
||||
* Contains all the default options that must be initialized on new and existing databases (at startup). The value can also be determined based on other options, provided they have already been initialized.
|
||||
*/
|
||||
const defaultOptions: DefaultOption[] = [
|
||||
{
|
||||
name: "syncServerTimeoutTimeScale",
|
||||
value: (optionsMap) => {
|
||||
const timeout = parseInt(optionsMap.syncServerTimeout || "120", 10);
|
||||
const migrated = migrateSyncTimeoutFromMilliseconds(timeout);
|
||||
if (migrated) {
|
||||
optionService.setOption("syncServerTimeout", String(migrated.value));
|
||||
getLog().info(`Migrated syncServerTimeout from ${timeout}ms to ${migrated.value}s`);
|
||||
return String(migrated.scale);
|
||||
}
|
||||
return "60"; // default to minutes
|
||||
},
|
||||
isSynced: false
|
||||
},
|
||||
{ name: "revisionSnapshotTimeInterval", value: "600", isSynced: true },
|
||||
{ name: "revisionSnapshotTimeIntervalTimeScale", value: "60", isSynced: true }, // default to Minutes
|
||||
{ name: "revisionSnapshotNumberLimit", value: "-1", isSynced: true },
|
||||
@@ -189,6 +224,7 @@ const defaultOptions: DefaultOption[] = [
|
||||
{ name: "textNoteEmojiCompletionEnabled", value: "true", isSynced: true },
|
||||
{ name: "textNoteCompletionEnabled", value: "true", isSynced: true },
|
||||
{ name: "textNoteSlashCommandsEnabled", value: "true", isSynced: true },
|
||||
{ name: "includeNoteDefaultBoxSize", value: "medium", isSynced: true },
|
||||
|
||||
// HTML import configuration
|
||||
{ name: "layoutOrientation", value: "vertical", isSynced: false },
|
||||
|
||||
Reference in New Issue
Block a user