diff --git a/.dockerignore b/.dockerignore index 2ceb847c9..1ca391a43 100644 --- a/.dockerignore +++ b/.dockerignore @@ -34,10 +34,11 @@ npm-debug.log # exceptions !/bin/copy-dist.ts -!/bin/electron-forge/sign-windows.cjs +!/bin/cleanupNodeModules.ts # temporary exception to make copy-dist inside Docker build not fail -# TriliumNextTODO: make copy-dist *not* requiring to copy this file for builds other than electron-forge +# TriliumNextTODO: make copy-dist *not* requiring to copy these file for builds other than electron-forge !forge.config.cjs !/bin/tpl -!/bin/electron-forge/desktop.ejs \ No newline at end of file +!/bin/electron-forge/desktop.ejs +!/bin/electron-forge/sign-windows.cjs \ No newline at end of file diff --git a/.dprint.json b/.dprint.json new file mode 100644 index 000000000..21e6f8585 --- /dev/null +++ b/.dprint.json @@ -0,0 +1,44 @@ +{ + "typescript": { + "indentWidth": 4, + "quoteStyle": "preferDouble", + "semiColons": "prefer", + "quoteProps": "asNeeded", + "newLineKind": "lf", + "lineWidth": 200, + "trailingCommas": "never", + "arrayPattern.spaceAround": true, + "arrayExpression.spaceAround": true + }, + "json": { + }, + "markdown": { + }, + "dockerfile": { + }, + "malva": { + }, + "markup": { + }, + "yaml": { + }, + "excludes": [ + "**/node_modules", + "**/*-lock.json", + "*.html", + "*.md", + "*.yml", + "libraries/*", + "docs/*", + "src/public/app/doc_notes" + ], + "plugins": [ + "https://plugins.dprint.dev/typescript-0.94.0.wasm", + "https://plugins.dprint.dev/json-0.20.0.wasm", + "https://plugins.dprint.dev/markdown-0.18.0.wasm", + "https://plugins.dprint.dev/dockerfile-0.3.2.wasm", + "https://plugins.dprint.dev/g-plane/malva-v0.11.1.wasm", + "https://plugins.dprint.dev/g-plane/markup_fmt-v0.19.0.wasm", + "https://plugins.dprint.dev/g-plane/pretty_yaml-v0.5.0.wasm" + ] +} diff --git a/.github/actions/build-electron/action.yml b/.github/actions/build-electron/action.yml index 6c1b6d819..ccd7f93ff 100644 --- a/.github/actions/build-electron/action.yml +++ b/.github/actions/build-electron/action.yml @@ -81,7 +81,7 @@ runs: APPLE_ID: ${{ env.APPLE_ID }} APPLE_ID_PASSWORD: ${{ env.APPLE_ID_PASSWORD }} WINDOWS_SIGN_EXECUTABLE: ${{ env.WINDOWS_SIGN_EXECUTABLE }} - TRILIUM_ARTIFACT_NAME_HINT: TriliumNextNotes ${{ inputs.os }} ${{ inputs.arch }} + TRILIUM_ARTIFACT_NAME_HINT: TriliumNextNotes-${{ github.ref_name }}-${{ inputs.os }}-${{ inputs.arch }} run: | npm run electron-forge:make -- \ --arch=${{ inputs.arch }} \ diff --git a/.prettierignore b/.prettierignore deleted file mode 100644 index 5e1d8fad5..000000000 --- a/.prettierignore +++ /dev/null @@ -1,6 +0,0 @@ -*.html -*.md -*.yml -libraries/* -docs/* -src/public/app/doc_notes/**/* \ No newline at end of file diff --git a/.prettierrc b/.prettierrc deleted file mode 100644 index 036c81de1..000000000 --- a/.prettierrc +++ /dev/null @@ -1,22 +0,0 @@ -{ - "printWidth": 200, - "tabWidth": 4, - "useTabs": false, - "semi": true, - "singleQuote": false, - "quoteProps": "as-needed", - "trailingComma": "none", - "bracketSpacing": true, - "arrowParens": "always", - "proseWrap": "preserve", - "htmlWhitespaceSensitivity": "css", - "endOfLine": "lf", - "overrides": [ - { - "files": ["*.json"], - "options": { - "tabWidth": 2 - } - } - ] -} diff --git a/Dockerfile b/Dockerfile index 4aac3160f..635a44d3b 100644 --- a/Dockerfile +++ b/Dockerfile @@ -39,8 +39,11 @@ COPY --from=builder /usr/src/app ./ RUN sed -i "/electron/d" package.json && \ npm ci --omit=dev && \ + node --experimental-strip-types ./bin/cleanupNodeModules.ts . --skip-prune-dev-deps && \ npm cache clean --force && \ - rm -rf /tmp/node-compile-cache + rm -rf \ + /tmp/node-compile-cache \ + /usr/src/app/bin/cleanupNodeModules.ts # Configure container EXPOSE 8080 diff --git a/Dockerfile.alpine b/Dockerfile.alpine index f83789399..88a450723 100644 --- a/Dockerfile.alpine +++ b/Dockerfile.alpine @@ -34,8 +34,11 @@ COPY --from=builder /usr/src/app ./ RUN sed -i "/electron/d" package.json && \ npm ci --omit=dev && \ + node --experimental-strip-types ./bin/cleanupNodeModules.ts . --skip-prune-dev-deps && \ npm cache clean --force && \ - rm -rf /tmp/node-compile-cache + rm -rf \ + /tmp/node-compile-cache \ + /usr/src/app/bin/cleanupNodeModules.ts # Add application user RUN adduser -s /bin/false node; exit 0 diff --git a/README.md b/README.md index fb08bdec2..265e10543 100644 --- a/README.md +++ b/README.md @@ -80,10 +80,11 @@ xattr -c "/path/to/Trilium Next.app" ### Mobile -To use TriliumNext on a mobile device: +To use TriliumNext on a mobile device, you can use a mobile web browser to access the mobile interface of a server installation (see below). -* Use a mobile web browser to access the mobile interface of a server installation (see below) -* Use of a mobile app is not yet supported ([see here](https://github.com/TriliumNext/Notes/issues/72)) to track mobile improvements. +If you prefer a native Android app, you can use [TriliumDroid](https://apt.izzysoft.de/fdroid/index/apk/eu.fliegendewurst.triliumdroid). Report bugs and missing features at [their repository](https://github.com/FliegendeWurst/TriliumDroid). + +See issue https://github.com/TriliumNext/Notes/issues/72 for more information on mobile app support. ### Server @@ -108,7 +109,8 @@ npm run server:start ### Documentation -Head on over to our [Docs repo](https://github.com/TriliumNext/Docs) +We are currently transitioning to a new documentation mechanism. +Meanwhile you can still view the [archived Docs repository](https://github.com/TriliumNext/Docs). ## 👏 Shoutouts diff --git a/bin/build-server.sh b/bin/build-server.sh index 052a8131b..e89c72d5a 100755 --- a/bin/build-server.sh +++ b/bin/build-server.sh @@ -25,8 +25,16 @@ NODE_VERSION=22.14.0 BUILD_DIR="./build" DIST_DIR="./dist" +CLEANUP_SCRIPT="./bin/cleanupNodeModules.ts" -./bin/copy-trilium.sh + +# Trigger the build +echo "Build start" +npm run build:prepare-dist +echo "Build finished" + +# pruning of unnecessary files and devDeps in node_modules +node --experimental-strip-types $CLEANUP_SCRIPT $BUILD_DIR NODE_FILENAME=node-v${NODE_VERSION}-linux-${ARCH} @@ -37,7 +45,9 @@ mv $NODE_FILENAME node cd .. -rm -r $BUILD_DIR/node/lib/node_modules/npm \ +rm -r $BUILD_DIR/node/lib/node_modules/{npm,corepack} \ + $BUILD_DIR/node/bin/{npm,npx,corepack} \ + $BUILD_DIR/node/CHANGELOG.md \ $BUILD_DIR/node/include/node \ $BUILD_DIR/node_modules/electron* \ $BUILD_DIR/electron*.{js,map} diff --git a/bin/cleanupNodeModules.ts b/bin/cleanupNodeModules.ts new file mode 100644 index 000000000..bb3e90331 --- /dev/null +++ b/bin/cleanupNodeModules.ts @@ -0,0 +1,109 @@ +import fs from "fs-extra"; +import path from "path"; +import type { Dirent } from "fs-extra"; +import { execSync } from "node:child_process"; + +/** + * Example usage with node >= v22: + * node --experimental-strip-types bin/cleanupNodeModules.ts /path/to/build/folder [--skip-prune-dev-deps] + * Example usage with tsx: + * tsx bin/cleanupNodeModules.ts /path/to/build/folder [--skip-prune-dev-deps] + */ +function main() { + + if (process.argv.length > 4 || process.argv.length < 3) { + console.error("Usage: cleanupNodeModules.ts [path-to-build-folder] [--skip-prune-dev-deps]"); + process.exit(1); + } + + const basePath = process.argv[2]; + const pruneDevDeps = process.argv[3] !== "--skip-prune-dev-deps"; + + if (!fs.existsSync(basePath)) { + console.error(`Supplied path '${basePath}' does not exist. Aborting.`); + process.exit(1); + } + + console.log(`Starting pruning of node_modules ${!pruneDevDeps ? '(skipping npm pruning)' : ''} in '${basePath}'...`); + cleanupNodeModules(basePath, pruneDevDeps); + console.log("Successfully pruned node_modules."); +} + +function cleanupNodeModules(basePath: string, pruneDevDeps: boolean = true) { + + // This needs to run for the server and Docker build, + // but needs to be skipped for electron-forge: its + // built-in pruning takes care of it already + if (pruneDevDeps) { + execSync(`npm ci --omit=dev --prefix ${basePath}`); + } + + const nodeModulesDirPath = path.join(basePath, "node_modules"); + const nodeModulesContent = fs.readdirSync(nodeModulesDirPath, { recursive: true, withFileTypes: true }); + //const libDir = fs.readdirSync(path.join(basePath, "./libraries"), { recursive: true, withFileTypes: true }); + + /** + * Delete unnecessary folders + */ + const filterableDirs = new Set([ + "demo", + "demos", + "doc", + "docs", + "example", + "examples", + "test", + "tests" + ]); + + nodeModulesContent + .filter(el => el.isDirectory() && filterableDirs.has(el.name)) + .forEach(dir => removeDirent(dir)); + + /** + * Delete unnecessary files based on file extension + * TODO filter out useless (README).md files + */ + const filterableFileExt = new Set([ + "ts", + "map" + ]); + + nodeModulesContent + // TriliumNextTODO: check if we can improve this naive file ext matching, without introducing any additional dependency + .filter(el => el.isFile() && filterableFileExt.has(el.name.split(".").at(-1) || "")) + .forEach(dir => removeDirent(dir)); + + + /** + * Delete specific unnecessary folders + * TODO: check if we want removeSync to throw an error, if path does not exist anymore -> currently it will silently fail + */ + const extraFoldersDelete = new Set([ + path.join(nodeModulesDirPath, ".bin"), + path.join(nodeModulesDirPath, "@excalidraw", "excalidraw", "dist", "dev"), + path.join(nodeModulesDirPath, "boxicons", "svg"), + path.join(nodeModulesDirPath, "boxicons", "node_modules"), + path.join(nodeModulesDirPath, "boxicons", "src"), + path.join(nodeModulesDirPath, "boxicons", "iconjar"), + path.join(nodeModulesDirPath, "@jimp", "plugin-print", "fonts"), + path.join(nodeModulesDirPath, "jimp", "dist", "browser") // missing "@" in front of jimp is not a typo here + ]); + + nodeModulesContent + .filter(el => el.isDirectory() && extraFoldersDelete.has(path.join(el.parentPath, el.name))) + .forEach(dir => removeDirent(dir)) +} + + +function removeDirent(el: Dirent) { + const elementToDelete = path.join(el.parentPath, el.name); + fs.removeSync(elementToDelete); + + if (process.env.VERBOSE) { + console.log(`Deleted ${elementToDelete}`); + } + +} + +main() \ No newline at end of file diff --git a/bin/copy-dist.ts b/bin/copy-dist.ts index eaa79808e..404cf0991 100644 --- a/bin/copy-dist.ts +++ b/bin/copy-dist.ts @@ -11,16 +11,10 @@ function log(...args: any[]) { } } -function copyNodeModuleFileOrFolder(source: string) { - const destination = path.join(DEST_DIR, source); - log(`Copying ${source} to ${destination}`); - fs.ensureDirSync(path.dirname(destination)); - fs.copySync(source, destination); -} - try { const assetsToCopy = new Set([ + // copy node_module, to avoid downloading packages a 2nd time during pruning "./node_modules", "./images", "./libraries", @@ -33,6 +27,7 @@ try { "./README.md", "./forge.config.cjs", "./bin/tpl/", + "./bin/cleanupNodeModules.ts", "./bin/electron-forge/desktop.ejs", "./bin/electron-forge/sign-windows.cjs", "./src/views/", @@ -61,50 +56,10 @@ try { fs.copySync(dir, path.join(PUBLIC_DIR, path.basename(dir))); } - const nodeModulesFile = new Set([ - "node_modules/react/umd/react.production.min.js", - "node_modules/react/umd/react.development.js", - "node_modules/react-dom/umd/react-dom.production.min.js", - "node_modules/react-dom/umd/react-dom.development.js", - "node_modules/katex/dist/katex.min.js", - "node_modules/katex/dist/contrib/mhchem.min.js", - "node_modules/katex/dist/contrib/auto-render.min.js", - "node_modules/@highlightjs/cdn-assets/highlight.min.js", - ]); - - const nodeModulesFolder = new Set([ - "node_modules/@excalidraw/excalidraw/dist/prod/fonts/", - "node_modules/katex/dist/", - "node_modules/dayjs/", - "node_modules/boxicons/css/", - "node_modules/boxicons/fonts/", - "node_modules/jquery/dist/", - "node_modules/jquery-hotkeys/", - "node_modules/split.js/dist/", - "node_modules/i18next/", - "node_modules/i18next-http-backend/", - "node_modules/vanilla-js-wheel-zoom/dist/", - "node_modules/mark.js/dist/", - "node_modules/normalize.css/", - "node_modules/jquery.fancytree/dist/", - "node_modules/autocomplete.js/dist/", - "node_modules/codemirror/lib/", - "node_modules/codemirror/addon/", - "node_modules/codemirror/mode/", - "node_modules/codemirror/keymap/", - "node_modules/@highlightjs/cdn-assets/languages", - "node_modules/@highlightjs/cdn-assets/styles", - "node_modules/leaflet/dist" - ]); - - - - for (const nodeModuleItem of [...nodeModulesFile, ...nodeModulesFolder]) { - copyNodeModuleFileOrFolder(nodeModuleItem); - } console.log("Copying complete!") } catch(err) { console.error("Error during copy:", err) process.exit(1) } + diff --git a/bin/copy-trilium.sh b/bin/copy-trilium.sh deleted file mode 100755 index 55c5cf6de..000000000 --- a/bin/copy-trilium.sh +++ /dev/null @@ -1,44 +0,0 @@ -#!/usr/bin/env bash - -set -e # Fail on any command error -shopt -s globstar - -BUILD_DIR="./build" - -if ! [[ $(which npm) ]]; then - echo "Missing npm" - exit 1 -fi - -# Trigger the build -echo Build start -npm run build:prepare-dist -echo Build finished - -# Patch package.json main -sed -i 's|./dist/electron-main.js|electron-main.js|g' "$BUILD_DIR/package.json" - -# run in subshell (so we return to original dir) -(cd $BUILD_DIR && npm ci --omit=dev) - -if [[ -d "$BUILD_DIR"/node_modules ]]; then - # cleanup of useless files in dependencies - for d in 'image-q/demo' \ - '@excalidraw/excalidraw/dist/excalidraw-assets-dev' '@excalidraw/excalidraw/dist/excalidraw.development.js' '@excalidraw/excalidraw/dist/excalidraw-with-preact.development.js' \ - 'mermaid/dist/mermaid.js' \ - 'boxicons/svg' 'boxicons/node_modules/react'/* \ - '@jimp/plugin-print/fonts' 'jimp/browser' 'jimp/fonts'; do - [[ -e "$BUILD_DIR"/node_modules/"$d" ]] && rm -r "$BUILD_DIR"/node_modules/"$d" - done - - # delete all tests (there are often large images as test file for jimp etc.) - for d in 'test' 'docs' 'demo' 'example'; do - find "$BUILD_DIR"/node_modules -name "$d" -exec rm -rf {} + - done -fi - -find $BUILD_DIR/libraries -name "*.map" -type f -delete -find $BUILD_DIR/node_modules -name "*.map" -type f -delete -find $BUILD_DIR -name "*.ts" -type f -delete - -unset f d BUILD_DIR diff --git a/forge.config.cjs b/forge.config.cjs index ba3d8c3ff..8d5b5d22e 100644 --- a/forge.config.cjs +++ b/forge.config.cjs @@ -1,5 +1,6 @@ const path = require("path"); const fs = require("fs-extra"); +const { execSync } = require("child_process"); const APP_NAME = "TriliumNext Notes"; const BIN_PATH = path.normalize("./bin/electron-forge"); @@ -39,6 +40,22 @@ module.exports = { "translations/", "node_modules/@highlightjs/cdn-assets/styles" ], + afterPrune: [ + (buildPath, _electronVersion, _platform, _arch, callback) => { + // buildPath is a temporary directory that electron-packager creates - it's in the form of + // /tmp/electron-packager/tmp-SjJl0s/resources/app + try { + const cleanupNodeModulesScript = path.join(buildPath, "bin", "cleanupNodeModules.ts"); + // we don't have access to any devDeps like 'tsx' here, so use the built-in '--experimental-strip-types' flag instead + const command = `node --experimental-strip-types ${cleanupNodeModulesScript} "${buildPath}" --skip-prune-dev-deps`; + // execSync throws, if above returns any non-zero exit code + execSync(command); + callback() + } catch(err) { + callback(err) + } + } + ], afterComplete: [ (buildPath, _electronVersion, platform, _arch, callback) => { // Only move resources on non-macOS platforms diff --git a/package-lock.json b/package-lock.json index ae0ea852a..f1ac53b70 100644 --- a/package-lock.json +++ b/package-lock.json @@ -166,6 +166,7 @@ "bootstrap": "5.3.3", "cross-env": "7.0.3", "css-loader": "7.1.2", + "dprint": "0.49.1", "electron": "35.0.3", "eslint": "9.23.0", "esm": "3.2.25", @@ -177,10 +178,8 @@ "lorem-ipsum": "2.0.8", "mind-elixir": "4.4.3", "mini-css-extract-plugin": "2.9.2", - "node-abi": "4.2.0", "nodemon": "3.1.9", "postcss-loader": "8.1.1", - "prettier": "3.5.3", "rcedit": "4.0.1", "rimraf": "6.0.1", "sass": "1.86.0", @@ -570,6 +569,132 @@ "node": ">=14.17.0" } }, + "node_modules/@dprint/darwin-arm64": { + "version": "0.49.1", + "resolved": "https://registry.npmjs.org/@dprint/darwin-arm64/-/darwin-arm64-0.49.1.tgz", + "integrity": "sha512-ib6KcJWo/M5RJWXOQKhP664FG1hAvG7nrbkh+j8n+oXdzmbyDdXTP+zW+aM3/sIQUkGaZky1xy1j2VeScMEEHQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ] + }, + "node_modules/@dprint/darwin-x64": { + "version": "0.49.1", + "resolved": "https://registry.npmjs.org/@dprint/darwin-x64/-/darwin-x64-0.49.1.tgz", + "integrity": "sha512-vIVgnYxV7YYa1d6Uyz707RbgB9rwefGPam+rzaueFNPQjdOxPOTQDuMEJDS+Z3BlI00MfeoupIfIUGsXoM4dpQ==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ] + }, + "node_modules/@dprint/linux-arm64-glibc": { + "version": "0.49.1", + "resolved": "https://registry.npmjs.org/@dprint/linux-arm64-glibc/-/linux-arm64-glibc-0.49.1.tgz", + "integrity": "sha512-ZeIh6qMPWLBBifDtU0XadpK36b4WoaTqCOt0rWKfoTjq1RAt78EgqETWp43Dbr6et/HvTgYdoWF0ZNEu2FJFFA==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@dprint/linux-arm64-musl": { + "version": "0.49.1", + "resolved": "https://registry.npmjs.org/@dprint/linux-arm64-musl/-/linux-arm64-musl-0.49.1.tgz", + "integrity": "sha512-/nuRyx+TykN6MqhlSCRs/t3o1XXlikiwTc9emWdzMeLGllYvJrcht9gRJ1/q1SqwCFhzgnD9H7roxxfji1tc+Q==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@dprint/linux-riscv64-glibc": { + "version": "0.49.1", + "resolved": "https://registry.npmjs.org/@dprint/linux-riscv64-glibc/-/linux-riscv64-glibc-0.49.1.tgz", + "integrity": "sha512-RHBqrnvGO+xW4Oh0QuToBqWtkXMcfjqa1TqbBFF03yopFzZA2oRKX83PhjTWgd/IglaOns0BgmaLJy/JBSxOfQ==", + "cpu": [ + "riscv64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@dprint/linux-x64-glibc": { + "version": "0.49.1", + "resolved": "https://registry.npmjs.org/@dprint/linux-x64-glibc/-/linux-x64-glibc-0.49.1.tgz", + "integrity": "sha512-MjFE894mIQXOKBencuakKyzAI4KcDe/p0Y9lRp9YSw/FneR4QWH9VBH90h8fRxcIlWMArjFFJJAtsBnn5qgxeg==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@dprint/linux-x64-musl": { + "version": "0.49.1", + "resolved": "https://registry.npmjs.org/@dprint/linux-x64-musl/-/linux-x64-musl-0.49.1.tgz", + "integrity": "sha512-CvGBWOksHgrL1uzYqtPFvZz0+E82BzgoCIEHJeuYaveEn37qWZS5jqoCm/vz6BfoivE1dVuyyOT78Begj9KxkQ==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@dprint/win32-arm64": { + "version": "0.49.1", + "resolved": "https://registry.npmjs.org/@dprint/win32-arm64/-/win32-arm64-0.49.1.tgz", + "integrity": "sha512-gQa4s82lMcXjfdxjWBQun6IJlXdPZZaIj2/2cqXWVEOYPKxAZ/JvGzt2pPG+i73h9KHjNLIV8M9ckqEH3oHufg==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@dprint/win32-x64": { + "version": "0.49.1", + "resolved": "https://registry.npmjs.org/@dprint/win32-x64/-/win32-x64-0.49.1.tgz", + "integrity": "sha512-nPU6+hoVze5JJlgET7woYWElBw0IUaB/9XKTaglknQuUUfsmD75D9pkgJTxdIxl9Bg/i5O7c9wb3Nj4XNiTIfw==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ] + }, "node_modules/@electron-forge/cli": { "version": "7.8.0", "resolved": "https://registry.npmjs.org/@electron-forge/cli/-/cli-7.8.0.tgz", @@ -9203,6 +9328,28 @@ "url": "https://github.com/fb55/domutils?sponsor=1" } }, + "node_modules/dprint": { + "version": "0.49.1", + "resolved": "https://registry.npmjs.org/dprint/-/dprint-0.49.1.tgz", + "integrity": "sha512-pO9XH79SyXybj2Vhc9ITZMEI8cJkdlQQRoD8oEfPH6Jjpp/7WX5kIgECVd3DBOjjAdCSiW6R47v3gJBx/qZVkw==", + "dev": true, + "hasInstallScript": true, + "license": "MIT", + "bin": { + "dprint": "bin.js" + }, + "optionalDependencies": { + "@dprint/darwin-arm64": "0.49.1", + "@dprint/darwin-x64": "0.49.1", + "@dprint/linux-arm64-glibc": "0.49.1", + "@dprint/linux-arm64-musl": "0.49.1", + "@dprint/linux-riscv64-glibc": "0.49.1", + "@dprint/linux-x64-glibc": "0.49.1", + "@dprint/linux-x64-musl": "0.49.1", + "@dprint/win32-arm64": "0.49.1", + "@dprint/win32-x64": "0.49.1" + } + }, "node_modules/draggabilly": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/draggabilly/-/draggabilly-3.0.0.tgz", @@ -14980,19 +15127,6 @@ "dev": true, "license": "MIT" }, - "node_modules/node-abi": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/node-abi/-/node-abi-4.2.0.tgz", - "integrity": "sha512-admQxilhDcmFJbUl4LQzGu+QyEijW9rctKRH2P7LNavAvln1bdK9OcujM3yi2KysKI41dxTrDtp6QfGEZeCbkg==", - "dev": true, - "license": "MIT", - "dependencies": { - "semver": "^7.6.3" - }, - "engines": { - "node": ">=22.12.0" - } - }, "node_modules/node-addon-api": { "version": "7.1.1", "resolved": "https://registry.npmjs.org/node-addon-api/-/node-addon-api-7.1.1.tgz", @@ -16436,22 +16570,6 @@ "node": ">= 0.8.0" } }, - "node_modules/prettier": { - "version": "3.5.3", - "resolved": "https://registry.npmjs.org/prettier/-/prettier-3.5.3.tgz", - "integrity": "sha512-QQtaxnoDJeAkDvDKWCLiwIXkTgRhwYDEQCghU9Z6q03iyek/rxRh/2lC3HB7P8sWT2xC/y5JDctPLBIGzHKbhw==", - "dev": true, - "license": "MIT", - "bin": { - "prettier": "bin/prettier.cjs" - }, - "engines": { - "node": ">=14" - }, - "funding": { - "url": "https://github.com/prettier/prettier?sponsor=1" - } - }, "node_modules/proc-log": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/proc-log/-/proc-log-2.0.1.tgz", diff --git a/package.json b/package.json index 17961500f..bb48ad553 100644 --- a/package.json +++ b/package.json @@ -38,10 +38,9 @@ "electron:switch": "electron-rebuild", "docs:edit": "cross-env NODE_OPTIONS=\"--import tsx\" TRILIUM_DATA_DIR=./data-docs TRILIUM_ENV=dev TRILIUM_PORT=37741 electron ./electron-docs-main.ts .", "docs:edit-nix": "electron-rebuild --version 33.3.1 && cross-env NODE_OPTIONS=\"--import tsx\" TRILIUM_DATA_DIR=./data-docs TRILIUM_PORT=37741 TRILIUM_ENV=dev nix-shell -p electron_33 --run \"electron ./electron-docs-main.ts .\"", - "electron-forge:prepare": "npm run build:prepare-dist", - "electron-forge:start": "npm run electron-forge:prepare && cd ./build && electron-forge start", - "electron-forge:make": "npm run electron-forge:prepare && cross-env DEBUG=electron-windows-installer:* electron-forge make ./build", - "electron-forge:package": "npm run electron-forge:prepare && cd ./build && electron-forge package", + "electron-forge:start": "npm run build:prepare-dist && cd ./build && electron-forge start", + "electron-forge:make": "npm run build:prepare-dist && cross-env DEBUG=electron-windows-installer:* electron-forge make ./build", + "electron-forge:package": "npm run build:prepare-dist && cd ./build && electron-forge package", "docs:build-backend": "rimraf ./docs/backend_api && typedoc ./docs/backend_api src/becca/entities/*.ts src/services/backend_script_api.ts src/services/sql.ts", "docs:build-frontend": "rimraf ./docs/frontend_api && jsdoc -c jsdoc-conf.json -d ./docs/frontend_api src/public/app/entities/*.js src/public/app/services/frontend_script_api.js src/public/app/widgets/basic_widget.js src/public/app/widgets/note_context_aware_widget.js src/public/app/widgets/right_panel_widget.js", "docs:build": "npm run docs:build-backend && npm run docs:build-frontend", @@ -59,8 +58,8 @@ "test:integration-mem-db": "cross-env TRILIUM_INTEGRATION_TEST=memory TRILIUM_PORT=8082 TRILIUM_DATA_DIR=./integration-tests/db nodemon src/main.ts", "test:integration-mem-db-dev": "cross-env TRILIUM_INTEGRATION_TEST=memory TRILIUM_PORT=8082 TRILIUM_ENV=dev TRILIUM_DATA_DIR=./integration-tests/db nodemon src/main.ts", "dev:watch-dist": "tsx ./bin/watch-dist.ts", - "dev:prettier-check": "prettier . --check", - "dev:prettier-fix": "prettier . --write", + "dev:format-check": "dprint check", + "dev:format-fix": "dprint fmt", "dev:linter-check": "eslint .", "dev:linter-fix": "eslint . --fix", "chore:update-build-info": "tsx bin/update-build-info.ts", @@ -223,6 +222,7 @@ "bootstrap": "5.3.3", "cross-env": "7.0.3", "css-loader": "7.1.2", + "dprint": "0.49.1", "electron": "35.0.3", "eslint": "9.23.0", "esm": "3.2.25", @@ -234,10 +234,8 @@ "lorem-ipsum": "2.0.8", "mind-elixir": "4.4.3", "mini-css-extract-plugin": "2.9.2", - "node-abi": "4.2.0", "nodemon": "3.1.9", "postcss-loader": "8.1.1", - "prettier": "3.5.3", "rcedit": "4.0.1", "rimraf": "6.0.1", "sass": "1.86.0", diff --git a/src/public/stylesheets/style.css b/src/public/stylesheets/style.css index 1cfcd6c90..c6ae45c3a 100644 --- a/src/public/stylesheets/style.css +++ b/src/public/stylesheets/style.css @@ -307,6 +307,7 @@ button kbd { background-color: var(--menu-background-color) !important; user-select: none; -webkit-user-select: none; + --bs-dropdown-zindex: 999; } body.desktop .dropdown-menu { diff --git a/src/public/stylesheets/theme-next-dark.css b/src/public/stylesheets/theme-next-dark.css index 84a0e0eb9..2dbeb525c 100644 --- a/src/public/stylesheets/theme-next-dark.css +++ b/src/public/stylesheets/theme-next-dark.css @@ -191,9 +191,9 @@ --right-pane-item-hover-color: white; --scrollbar-thumb-color: #fdfdfd5c; - --scrollbar-thumb-color-hover: #ffffff7d; + --scrollbar-thumb-hover-color: #ffffff7d; + --scrollbar-background-color: transparent; --scrollbar-border-color: unset; /* Deprecated */ - --scrollbar-background-color: unset; /* Deprecated */ --link-color: lightskyblue; diff --git a/src/public/stylesheets/theme-next-light.css b/src/public/stylesheets/theme-next-light.css index 781a34a2b..46c116e39 100644 --- a/src/public/stylesheets/theme-next-light.css +++ b/src/public/stylesheets/theme-next-light.css @@ -190,9 +190,9 @@ --right-pane-item-hover-color: inherit; --scrollbar-thumb-color: #0000005c; - --scrollbar-thumb-color-hover: #00000066; + --scrollbar-thumb-hover-color: #00000066; + --scrollbar-background-color: transparent; --scrollbar-border-color: unset; /* Deprecated */ - --scrollbar-background-color: unset; /* Deprecated */ --link-color: blue; diff --git a/src/public/stylesheets/theme-next/base.css b/src/public/stylesheets/theme-next/base.css index 888b83ca9..aced7ab5d 100644 --- a/src/public/stylesheets/theme-next/base.css +++ b/src/public/stylesheets/theme-next/base.css @@ -95,8 +95,8 @@ font-size: 0.9rem !important; } -.dropdown-menu::-webkit-scrollbar-track { - background: var(--menu-background-color); +.dropdown-menu { + --scrollbar-background-color: var(--menu-background-color); } body.mobile .dropdown-menu { diff --git a/src/public/stylesheets/theme-next/forms.css b/src/public/stylesheets/theme-next/forms.css index 1c3945154..30e8eec22 100644 --- a/src/public/stylesheets/theme-next/forms.css +++ b/src/public/stylesheets/theme-next/forms.css @@ -674,6 +674,10 @@ input[type="range"] { /* Scrollbar's body */ +::-webkit-scrollbar-track { + background-color: var(--scrollbar-background-color); +} + ::-webkit-scrollbar:vertical { width: var(--scrollbar-thickness) !important; } @@ -707,10 +711,12 @@ input[type="range"] { ::-webkit-scrollbar-thumb:hover { --s-thumb-thickness: var(--scrollbar-thumb-hover-thickness); - --s-thumb-color: var(--scrollbar-thumb-color-hover); + --s-thumb-color: var(--scrollbar-thumb-hover-color); } -/* Scrollbar's increment/decrement buttons (repurposed as a scrollbar start/end gap) */ +/* Scrollbar's increment/decrement buttons (repurposed as a scrollbar start/end gap). + * This gap is useful also to avoid breaking the rounded corners of a container when a + * custom scrollbar background color is used. */ ::-webkit-scrollbar-button:vertical { height: var(--scrollbar-start-end-gap); @@ -724,7 +730,7 @@ input[type="range"] { * Firefox scrollbars * * Unsupported features: --scrollbar-thumb-thickness, --scrollbar-thumb-hover-thickness, - * --scrollbar-start-end-gap, --scrollbar-thumb-color-hover. + * --scrollbar-start-end-gap, --scrollbar-thumb-hover-color. */ :root { diff --git a/src/public/stylesheets/theme-next/notes/text.css b/src/public/stylesheets/theme-next/notes/text.css index cf8aa4760..9d1c20e88 100644 --- a/src/public/stylesheets/theme-next/notes/text.css +++ b/src/public/stylesheets/theme-next/notes/text.css @@ -42,14 +42,9 @@ html .note-detail-editable-text :not(figure, .include-note, hr):first-child { overflow: auto; } -.ck-content pre code::-webkit-scrollbar { - height: 6px; -} - -.ck-content pre code::-webkit-scrollbar-thumb { - height: 4px; - border: none !important; - background: gray !important; +.ck-content pre code { + --scrollbar-thumb-color: gray; + --scrollbar-thumb-hover-color: gray; } .ck-content pre code::-webkit-scrollbar-track, diff --git a/src/public/stylesheets/theme-next/shell.css b/src/public/stylesheets/theme-next/shell.css index 11958d494..5552e482d 100644 --- a/src/public/stylesheets/theme-next/shell.css +++ b/src/public/stylesheets/theme-next/shell.css @@ -46,7 +46,7 @@ body.background-effects.platform-win32 { } @media (prefers-color-scheme: dark) { - body.background-effects.platform-win32 #launcher-pane { + body.background-effects.platform-win32 { --launcher-pane-horiz-border-color: rgba(0, 0, 0, 0.5); --launcher-pane-horiz-background-color: rgba(255, 255, 255, 0.09); } @@ -897,6 +897,21 @@ body.layout-horizontal .tab-row-container { padding-top: calc((var(--tab-bar-height) - var(--tab-height))); } +/* Define extra drag areas for Electron windows */ +body.layout-horizontal .tab-row-container, +body.layout-vertical .tab-row-widget, +body.layout-vertical #left-pane .quick-search { + -webkit-app-region: drag; +} + +/* Limit the drag area for the previous elements to include just to the element itself + and not its descendants also */ +body.layout-horizontal .tab-row-container > *, +body.layout-vertical .tab-row-widget > *, +body.layout-vertical #left-pane .quick-search > * { + -webkit-app-region: no-drag; +} + body.layout-horizontal .tab-row-widget-container { margin-top: 0; position: relative;