diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 529e685e9..be9306a02 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -23,6 +23,22 @@ jobs: with: name: trilium-mac-x64.zip path: dist/trilium-mac-x64*.zip + build_darwin-arm64: + name: Build macOS aarch64 + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + - name: Set up node & dependencies + uses: actions/setup-node@v4 + with: + node-version: 18 + cache: "npm" + - run: npm ci + - run: ./bin/build-mac-arm64.sh + - uses: actions/upload-artifact@v4 + with: + name: trilium-mac-arm64.zip + path: dist/trilium-mac-arm64*.zip build_linux-x64: name: Build Linux x86_64 runs-on: ubuntu-latest diff --git a/bin/better-sqlite3/mac-arm64-better_sqlite3.node b/bin/better-sqlite3/mac-arm64-better_sqlite3.node new file mode 100644 index 000000000..9709dcd23 Binary files /dev/null and b/bin/better-sqlite3/mac-arm64-better_sqlite3.node differ diff --git a/bin/better-sqlite3/mac-better_sqlite3.node b/bin/better-sqlite3/mac-x64-better_sqlite3.node similarity index 100% rename from bin/better-sqlite3/mac-better_sqlite3.node rename to bin/better-sqlite3/mac-x64-better_sqlite3.node diff --git a/bin/build-mac-arm64.sh b/bin/build-mac-arm64.sh new file mode 100755 index 000000000..8d1f595a6 --- /dev/null +++ b/bin/build-mac-arm64.sh @@ -0,0 +1,38 @@ +#!/usr/bin/env bash + +SRC_DIR=./dist/trilium-mac-arm64-src + +if [ "$1" != "DONTCOPY" ] +then + ./bin/copy-trilium.sh $SRC_DIR +fi + +echo "Copying required mac arm64 binaries" + +cp -r bin/better-sqlite3/mac-arm64-better_sqlite3.node $SRC_DIR/node_modules/better-sqlite3/build/Release/better_sqlite3.node + +rm -r $SRC_DIR/src/public/app-dist/*.mobile.* + +echo "Packaging mac arm64 electron build" + +./node_modules/.bin/electron-packager $SRC_DIR --asar --out=dist --executable-name=trilium --platform=darwin --arch=arm64 --overwrite --icon=images/app-icons/mac/icon.icns + +BUILD_DIR=./dist/trilium-mac-arm64 +rm -rf $BUILD_DIR + +# Mac build has by default useless directory level +mv "./dist/Trilium Notes-darwin-arm64" $BUILD_DIR + +cp bin/tpl/anonymize-database.sql $BUILD_DIR/ + +cp -r dump-db $BUILD_DIR/ +rm -rf $BUILD_DIR/dump-db/node_modules + +echo "Zipping mac arm64 electron distribution..." + +VERSION=`jq -r ".version" package.json` + +cd dist + +rm trilium-mac-arm64-${VERSION}.zip +zip -r9 --symlinks trilium-mac-arm64-${VERSION}.zip trilium-mac-arm64 diff --git a/bin/build-mac-x64.sh b/bin/build-mac-x64.sh index 0e63c7fb2..8e560ba41 100755 --- a/bin/build-mac-x64.sh +++ b/bin/build-mac-x64.sh @@ -7,9 +7,9 @@ then ./bin/copy-trilium.sh $SRC_DIR fi -echo "Copying required mac binaries" +echo "Copying required mac x64 binaries" -cp -r bin/better-sqlite3/mac-better_sqlite3.node $SRC_DIR/node_modules/better-sqlite3/build/Release/better_sqlite3.node +cp -r bin/better-sqlite3/mac-x64-better_sqlite3.node $SRC_DIR/node_modules/better-sqlite3/build/Release/better_sqlite3.node rm -r $SRC_DIR/src/public/app-dist/*.mobile.* diff --git a/bin/build.sh b/bin/build.sh index ff90c288d..6092b2011 100755 --- a/bin/build.sh +++ b/bin/build.sh @@ -13,11 +13,14 @@ cp -r $SRC_DIR ./dist/trilium-linux-x64-src cp -r $SRC_DIR ./dist/trilium-linux-x64-server cp -r $SRC_DIR ./dist/trilium-windows-x64-src cp -r $SRC_DIR ./dist/trilium-mac-x64-src +cp -r $SRC_DIR ./dist/trilium-mac-arm64-src bin/build-win-x64.sh DONTCOPY bin/build-mac-x64.sh DONTCOPY +bin/build-mac-arm64.sh DONTCOPY + bin/build-linux-x64.sh DONTCOPY bin/build-server.sh DONTCOPY diff --git a/bin/release.sh b/bin/release.sh index 649a41437..65610c229 100755 --- a/bin/release.sh +++ b/bin/release.sh @@ -48,6 +48,7 @@ LINUX_X64_BUILD=trilium-linux-x64-$VERSION.tar.xz DEBIAN_X64_BUILD=trilium_${VERSION}_amd64.deb WINDOWS_X64_BUILD=trilium-windows-x64-$VERSION.zip MAC_X64_BUILD=trilium-mac-x64-$VERSION.zip +MAC_ARM64_BUILD=trilium-mac-arm64-$VERSION.zip SERVER_BUILD=trilium-linux-x64-server-$VERSION.tar.xz echo "Creating release in GitHub" @@ -68,4 +69,5 @@ gh release create "$TAG" \ "dist/$LINUX_X64_BUILD" \ "dist/$WINDOWS_X64_BUILD" \ "dist/$MAC_X64_BUILD" \ + "dist/$MAC_ARM64_BUILD" \ "dist/$SERVER_BUILD" diff --git a/package-lock.json b/package-lock.json index 2dd4a639d..c39403b79 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "trilium", - "version": "0.63.5", + "version": "0.63.6", "lockfileVersion": 2, "requires": true, "packages": { "": { "name": "trilium", - "version": "0.63.5", + "version": "0.63.6", "hasInstallScript": true, "license": "AGPL-3.0-only", "dependencies": { diff --git a/package.json b/package.json index e48bff6c2..4e37e4c7d 100644 --- a/package.json +++ b/package.json @@ -2,7 +2,7 @@ "name": "trilium", "productName": "Trilium Notes", "description": "Trilium Notes", - "version": "0.63.5", + "version": "0.63.7", "license": "AGPL-3.0-only", "main": "electron.js", "bin": { diff --git a/src/public/app/menus/tree_context_menu.js b/src/public/app/menus/tree_context_menu.js index feba6d69e..38c245251 100644 --- a/src/public/app/menus/tree_context_menu.js +++ b/src/public/app/menus/tree_context_menu.js @@ -50,10 +50,10 @@ export default class TreeContextMenu { { title: 'Open in a new tab Ctrl+Click', command: "openInTab", uiIcon: "bx bx-empty", enabled: noSelectedNotes }, { title: 'Open in a new split', command: "openNoteInSplit", uiIcon: "bx bx-dock-right", enabled: noSelectedNotes }, { title: 'Insert note after ', command: "insertNoteAfter", uiIcon: "bx bx-plus", - items: insertNoteAfterEnabled ? await noteTypesService.getNoteTypeItems("insertNoteAfter", {removeDeprecatedTypes: true}) : null, + items: insertNoteAfterEnabled ? await noteTypesService.getNoteTypeItems("insertNoteAfter") : null, enabled: insertNoteAfterEnabled && noSelectedNotes }, { title: 'Insert child note ', command: "insertChildNote", uiIcon: "bx bx-plus", - items: notSearch ? await noteTypesService.getNoteTypeItems("insertChildNote", {removeDeprecatedTypes: true}) : null, + items: notSearch ? await noteTypesService.getNoteTypeItems("insertChildNote") : null, enabled: notSearch && noSelectedNotes }, { title: 'Delete ', command: "deleteNotes", uiIcon: "bx bx-trash", enabled: isNotRoot && !isHoisted && parentNotSearch }, diff --git a/src/public/app/services/note_types.js b/src/public/app/services/note_types.js index 6a44e03b3..40bc4a88b 100644 --- a/src/public/app/services/note_types.js +++ b/src/public/app/services/note_types.js @@ -1,21 +1,19 @@ import server from "./server.js"; import froca from "./froca.js"; -async function getNoteTypeItems(command, opts = {}) { - const removeDeprecatedTypes = !!opts.removeDeprecatedTypes; - +async function getNoteTypeItems(command) { const items = [ { title: "Text", command: command, type: "text", uiIcon: "bx bx-note" }, { title: "Code", command: command, type: "code", uiIcon: "bx bx-code" }, { title: "Saved Search", command: command, type: "search", uiIcon: "bx bx-file-find" }, - { title: "Relation Map", command: command, type: "relationMap", uiIcon: "bx bx-map-alt", deprecated: true }, + { title: "Relation Map", command: command, type: "relationMap", uiIcon: "bx bx-map-alt" }, { title: "Note Map", command: command, type: "noteMap", uiIcon: "bx bx-map-alt" }, { title: "Render Note", command: command, type: "render", uiIcon: "bx bx-extension" }, { title: "Book", command: command, type: "book", uiIcon: "bx bx-book" }, { title: "Mermaid Diagram", command: command, type: "mermaid", uiIcon: "bx bx-selection" }, { title: "Canvas", command: command, type: "canvas", uiIcon: "bx bx-pen" }, { title: "Web View", command: command, type: "webView", uiIcon: "bx bx-globe-alt" }, - ].filter(item => !removeDeprecatedTypes || !item.deprecated); + ]; const templateNoteIds = await server.get("search-templates"); const templateNotes = await froca.getNotes(templateNoteIds); diff --git a/src/public/app/widgets/type_widgets/canvas.js b/src/public/app/widgets/type_widgets/canvas.js index b0be9f845..08f7128e3 100644 --- a/src/public/app/widgets/type_widgets/canvas.js +++ b/src/public/app/widgets/type_widgets/canvas.js @@ -2,7 +2,6 @@ import libraryLoader from '../../services/library_loader.js'; import TypeWidget from './type_widget.js'; import utils from '../../services/utils.js'; import linkService from '../../services/link.js'; -import debounce from '../../services/debounce.js'; const TPL = `
@@ -103,8 +102,6 @@ export default class ExcalidrawTypeWidget extends TypeWidget { this.SCENE_VERSION_INITIAL = -1; // -1 indicates that it is fresh. excalidraw scene version is always >0 this.SCENE_VERSION_ERROR = -2; // -2 indicates error - // config - this.DEBOUNCE_TIME_ONCHANGEHANDLER = 750; // ms // ensure that assets are loaded from trilium window.EXCALIDRAW_ASSET_PATH = `${window.location.origin}/node_modules/@excalidraw/excalidraw/dist/`; @@ -117,11 +114,6 @@ export default class ExcalidrawTypeWidget extends TypeWidget { this.$widget; this.reactHandlers; // used to control react state - // binds - this.createExcalidrawReactApp = this.createExcalidrawReactApp.bind(this); - this.onChangeHandler = this.onChangeHandler.bind(this); - this.isNewSceneVersion = this.isNewSceneVersion.bind(this); - this.libraryChanged = false; } @@ -153,7 +145,7 @@ export default class ExcalidrawTypeWidget extends TypeWidget { ReactDOM.unmountComponentAtNode(renderElement); const root = ReactDOM.createRoot(renderElement); - root.render(React.createElement(this.createExcalidrawReactApp)); + root.render(React.createElement(() => this.createExcalidrawReactApp())); }); return this.$widget; @@ -445,7 +437,7 @@ export default class ExcalidrawTypeWidget extends TypeWidget { this.saveData(); }, - onChange: debounce(this.onChangeHandler, this.DEBOUNCE_TIME_ONCHANGEHANDLER), + onChange: () => this.onChangeHandler(), viewModeEnabled: false, zenModeEnabled: false, gridModeEnabled: false, diff --git a/src/public/app/widgets/type_widgets/relation_map.js b/src/public/app/widgets/type_widgets/relation_map.js index 6fea5eb6a..beb16ff07 100644 --- a/src/public/app/widgets/type_widgets/relation_map.js +++ b/src/public/app/widgets/type_widgets/relation_map.js @@ -184,8 +184,6 @@ export default class RelationMapTypeWidget extends TypeWidget { } async loadMapData() { - toastService.showMessage("Relation Map has been deprecated since Trilium 0.63 and will be removed in a future version. Migrate your content to some other note type (e.g. canvas) as soon as possible.", 5000); - this.mapData = { notes: [], // it is important to have this exact value here so that initial transform is the same as this diff --git a/src/routes/api/files.ts b/src/routes/api/files.ts index df8f14b58..3bb269f7d 100644 --- a/src/routes/api/files.ts +++ b/src/routes/api/files.ts @@ -169,6 +169,8 @@ function saveAttachmentToTmpDir(req: Request) { return saveToTmpDir(fileName, content, 'attachments', attachment.attachmentId); } +const createdTemporaryFiles = new Set(); + function saveToTmpDir(fileName: string, content: string | Buffer, entityType: string, entityId: string) { const tmpObj = tmp.fileSync({ postfix: fileName }); @@ -180,6 +182,8 @@ function saveToTmpDir(fileName: string, content: string | Buffer, entityType: st fs.closeSync(tmpObj.fd); + createdTemporaryFiles.add(tmpObj.name); + log.info(`Saved temporary file ${tmpObj.name}`); if (utils.isElectron()) { @@ -203,6 +207,10 @@ function uploadModifiedFileToNote(req: Request) { const noteId = req.params.noteId; const {filePath} = req.body; + if (!createdTemporaryFiles.has(filePath)) { + throw new ValidationError(`File '${filePath}' is not a temporary file.`); + } + const note = becca.getNoteOrThrow(noteId); log.info(`Updating note '${noteId}' with content from '${filePath}'`); diff --git a/src/services/build.ts b/src/services/build.ts index b392adba0..a4c7df2d1 100644 --- a/src/services/build.ts +++ b/src/services/build.ts @@ -1 +1 @@ -export = { buildDate:"2024-03-28T07:11:39+01:00", buildRevision: "399458b52f250b22be22d980a78de0b3390d7521" }; +export = { buildDate:"2024-05-18T06:17:21+02:00", buildRevision: "c7f19e04fafc031910f6f9a45d2015387618e902" }; diff --git a/src/services/notes.ts b/src/services/notes.ts index a60799e80..2e099392e 100644 --- a/src/services/notes.ts +++ b/src/services/notes.ts @@ -446,13 +446,17 @@ function findIncludeNoteLinks(content: string, foundLinks: FoundLink[]) { } function findRelationMapLinks(content: string, foundLinks: FoundLink[]) { - const obj = JSON.parse(content); + try { + const obj = JSON.parse(content); - for (const note of obj.notes) { - foundLinks.push({ - name: 'relationMapLink', - value: note.noteId - }); + for (const note of obj.notes) { + foundLinks.push({ + name: 'relationMapLink', + value: note.noteId + }); + } + } catch (e: any) { + log.error("Could not scan for relation map links: " + e.message); } }