From 63dba0592cab1d05613425cbb3691cb3181a3480 Mon Sep 17 00:00:00 2001 From: Karim Date: Fri, 31 Jul 2026 17:03:23 +0200 Subject: [PATCH] =?UTF-8?q?Selbst-Update-Funktion=20erg=C3=A4nzt=20(Tauri?= =?UTF-8?q?=20Updater-Plugin)=20+=20App-Branding=20"dossier"=20statt=20"Do?= =?UTF-8?q?ssier".?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Prüft beim Start still gegen ein Gitea-Release-Manifest (latest.json), bietet im Settings-/About-Dialog einen manuellen Check sowie einen Versionsverlauf mit Rollback-Download (versions.json, eigener schlanker Index neben dem Updater-Manifest). Dafür: tauri-plugin-updater/process/ http/shell + zugehörige Capabilities, neue App-Icons (auch für die plattformspezifischen Bundle-Formate), sowie ein kleingeschriebener Produktname samt erweitertem nativen Info-Fenster (macOS-About). --- package-lock.json | 45 +- package.json | 4 + src-tauri/Cargo.lock | 780 +++++++++++++++++++++++++- src-tauri/Cargo.toml | 4 + src-tauri/capabilities/default.json | 13 +- src-tauri/icons/128x128.png | Bin 0 -> 2968 bytes src-tauri/icons/128x128@2x.png | Bin 0 -> 6021 bytes src-tauri/icons/32x32.png | Bin 0 -> 879 bytes src-tauri/icons/64x64.png | Bin 0 -> 1490 bytes src-tauri/icons/Square107x107Logo.png | Bin 0 -> 2554 bytes src-tauri/icons/Square142x142Logo.png | Bin 0 -> 3418 bytes src-tauri/icons/Square150x150Logo.png | Bin 0 -> 3534 bytes src-tauri/icons/Square284x284Logo.png | Bin 0 -> 6661 bytes src-tauri/icons/Square30x30Logo.png | Bin 0 -> 788 bytes src-tauri/icons/Square310x310Logo.png | Bin 0 -> 7306 bytes src-tauri/icons/Square44x44Logo.png | Bin 0 -> 1113 bytes src-tauri/icons/Square71x71Logo.png | Bin 0 -> 1761 bytes src-tauri/icons/Square89x89Logo.png | Bin 0 -> 2032 bytes src-tauri/icons/StoreLogo.png | Bin 0 -> 1180 bytes src-tauri/icons/icon.icns | Bin 0 -> 85316 bytes src-tauri/icons/icon.ico | Bin 0 -> 12572 bytes src-tauri/src/lib.rs | 12 + src-tauri/tauri.conf.json | 21 +- src/App.tsx | 8 + src/i18n/de.ts | 29 +- src/i18n/en.ts | 29 +- src/native/appMenu.ts | 19 +- src/native/contextImportWindow.ts | 2 +- src/native/drawingLevelsWindow.ts | 2 +- src/native/layerSettingsWindow.ts | 2 +- src/native/resourceWindow.ts | 2 +- src/native/settingsWindow.ts | 2 +- src/styles.css | 52 +- src/ui/SettingsDialog.tsx | 123 ++++ src/ui/TopBar.tsx | 44 +- src/update/checkForUpdate.ts | 81 +++ src/update/version.ts | 12 + src/update/versionHistory.ts | 48 ++ 38 files changed, 1299 insertions(+), 35 deletions(-) create mode 100644 src-tauri/icons/128x128.png create mode 100644 src-tauri/icons/128x128@2x.png create mode 100644 src-tauri/icons/32x32.png create mode 100644 src-tauri/icons/64x64.png create mode 100644 src-tauri/icons/Square107x107Logo.png create mode 100644 src-tauri/icons/Square142x142Logo.png create mode 100644 src-tauri/icons/Square150x150Logo.png create mode 100644 src-tauri/icons/Square284x284Logo.png create mode 100644 src-tauri/icons/Square30x30Logo.png create mode 100644 src-tauri/icons/Square310x310Logo.png create mode 100644 src-tauri/icons/Square44x44Logo.png create mode 100644 src-tauri/icons/Square71x71Logo.png create mode 100644 src-tauri/icons/Square89x89Logo.png create mode 100644 src-tauri/icons/StoreLogo.png create mode 100644 src-tauri/icons/icon.icns create mode 100644 src-tauri/icons/icon.ico create mode 100644 src/update/checkForUpdate.ts create mode 100644 src/update/version.ts create mode 100644 src/update/versionHistory.ts diff --git a/package-lock.json b/package-lock.json index 3e2892f..e5881b2 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,17 +1,22 @@ { - "name": "cad", + "name": "dossier", "version": "0.0.0", "lockfileVersion": 3, "requires": true, "packages": { "": { - "name": "cad", + "name": "dossier", "version": "0.0.0", + "license": "AGPL-3.0-or-later", "dependencies": { "@mlightcad/libredwg-web": "^0.7.7", "@tauri-apps/api": "^2.11.1", "@tauri-apps/plugin-dialog": "^2.7.1", "@tauri-apps/plugin-fs": "^2.5.1", + "@tauri-apps/plugin-http": "^2.5.9", + "@tauri-apps/plugin-process": "^2.3.1", + "@tauri-apps/plugin-shell": "^2.3.5", + "@tauri-apps/plugin-updater": "^2.10.1", "delaunator": "^5.1.0", "dxf-parser": "^1.1.2", "jspdf": "^4.2.1", @@ -1862,6 +1867,42 @@ "@tauri-apps/api": "^2.11.0" } }, + "node_modules/@tauri-apps/plugin-http": { + "version": "2.5.9", + "resolved": "https://registry.npmjs.org/@tauri-apps/plugin-http/-/plugin-http-2.5.9.tgz", + "integrity": "sha512-lCiY0+vs4HvIUSvZrBs8TC3TiCB0MOPRmiUjTq4prW7SlcJE2jdLeT6KBsJrT9Tlplufl7W1pY6SFAO3gCWxDA==", + "license": "MIT OR Apache-2.0", + "dependencies": { + "@tauri-apps/api": "^2.11.0" + } + }, + "node_modules/@tauri-apps/plugin-process": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/@tauri-apps/plugin-process/-/plugin-process-2.3.1.tgz", + "integrity": "sha512-nCa4fGVaDL/B9ai03VyPOjfAHRHSBz5v6F/ObsB73r/dA3MHHhZtldaDMIc0V/pnUw9ehzr2iEG+XkSEyC0JJA==", + "license": "MIT OR Apache-2.0", + "dependencies": { + "@tauri-apps/api": "^2.8.0" + } + }, + "node_modules/@tauri-apps/plugin-shell": { + "version": "2.3.5", + "resolved": "https://registry.npmjs.org/@tauri-apps/plugin-shell/-/plugin-shell-2.3.5.tgz", + "integrity": "sha512-jewtULhiQ7lI7+owCKAjc8tYLJr92U16bPOeAa472LHJdgaibLP83NcfAF2e+wkEcA53FxKQAZ7byDzs2eeizg==", + "license": "MIT OR Apache-2.0", + "dependencies": { + "@tauri-apps/api": "^2.10.1" + } + }, + "node_modules/@tauri-apps/plugin-updater": { + "version": "2.10.1", + "resolved": "https://registry.npmjs.org/@tauri-apps/plugin-updater/-/plugin-updater-2.10.1.tgz", + "integrity": "sha512-NFYMg+tWOZPJdzE/PpFj2qfqwAWwNS3kXrb1tm1gnBJ9mYzZ4WDRrwy8udzWoAnfGCHLuePNLY1WVCNHnh3eRA==", + "license": "MIT OR Apache-2.0", + "dependencies": { + "@tauri-apps/api": "^2.10.1" + } + }, "node_modules/@tweenjs/tween.js": { "version": "23.1.3", "resolved": "https://registry.npmjs.org/@tweenjs/tween.js/-/tween.js-23.1.3.tgz", diff --git a/package.json b/package.json index 9ef7e72..581e50d 100644 --- a/package.json +++ b/package.json @@ -29,6 +29,10 @@ "@tauri-apps/api": "^2.11.1", "@tauri-apps/plugin-dialog": "^2.7.1", "@tauri-apps/plugin-fs": "^2.5.1", + "@tauri-apps/plugin-http": "^2.5.9", + "@tauri-apps/plugin-process": "^2.3.1", + "@tauri-apps/plugin-shell": "^2.3.5", + "@tauri-apps/plugin-updater": "^2.10.1", "delaunator": "^5.1.0", "dxf-parser": "^1.1.2", "jspdf": "^4.2.1", diff --git a/src-tauri/Cargo.lock b/src-tauri/Cargo.lock index 59874da..4fcb92f 100644 --- a/src-tauri/Cargo.lock +++ b/src-tauri/Cargo.lock @@ -157,6 +157,15 @@ version = "1.0.103" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2a4385e2e34eb35d6b3efe798b9eb88096925d87726c0798709bf56d9ed84af3" +[[package]] +name = "arbitrary" +version = "1.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c3d036a3c4ab069c7b410a2ce876bd74808d2d0888a82667669f8e783a898bf1" +dependencies = [ + "derive_arbitrary", +] + [[package]] name = "arrayref" version = "0.3.9" @@ -395,6 +404,10 @@ dependencies = [ "tauri-build", "tauri-plugin-dialog", "tauri-plugin-fs", + "tauri-plugin-http", + "tauri-plugin-process", + "tauri-plugin-shell", + "tauri-plugin-updater", "wgpu", "winit", ] @@ -543,6 +556,17 @@ version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "613afe47fcd5fac7ccf1db93babcb082c5994d996f20b8b159f2ad1658eb5724" +[[package]] +name = "chacha20" +version = "0.10.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d524456ba66e72eb8b115ff89e01e497f8e6d11d78b70b1aa13c0fbd97540a81" +dependencies = [ + "cfg-if", + "cpufeatures 0.3.0", + "rand_core", +] + [[package]] name = "chrono" version = "0.4.45" @@ -607,10 +631,29 @@ version = "0.18.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4ddef33a339a91ea89fb53151bd0a4689cfce27055c291dfa69945475d22c747" dependencies = [ + "percent-encoding", "time", "version_check", ] +[[package]] +name = "cookie_store" +version = "0.22.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "15b2c103cf610ec6cae3da84a766285b42fd16aad564758459e6ecf128c75206" +dependencies = [ + "cookie", + "document-features", + "idna", + "log", + "publicsuffix", + "serde", + "serde_derive", + "serde_json", + "time", + "url", +] + [[package]] name = "core-foundation" version = "0.9.4" @@ -727,6 +770,15 @@ dependencies = [ "libc", ] +[[package]] +name = "cpufeatures" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8b2a41393f66f16b0823bb79094d54ac5fbd34ab292ddafb9a0456ac9f87d201" +dependencies = [ + "libc", +] + [[package]] name = "crc32fast" version = "1.5.0" @@ -846,6 +898,12 @@ dependencies = [ "syn 2.0.118", ] +[[package]] +name = "data-url" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "be1e0bca6c3637f992fc1cc7cbc52a78c1ef6db076dbf1059c4323d6a2048376" + [[package]] name = "dbus" version = "0.9.11" @@ -898,6 +956,17 @@ dependencies = [ "serde_core", ] +[[package]] +name = "derive_arbitrary" +version = "1.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1e567bd82dcff979e4b03460c307b3cdc9e96fde3d73bed1496d2bc75d9dd62a" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.118", +] + [[package]] name = "derive_more" version = "2.1.1" @@ -1112,6 +1181,15 @@ version = "1.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4ef6b89e5b37196644d8796de5268852ff179b44e96276cf4290264843743bb7" +[[package]] +name = "encoding_rs" +version = "0.8.35" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "75030f3c4f45dafd7586dd6780965a8c7e8e285a5ecb86713e63a79c5b2766f3" +dependencies = [ + "cfg-if", +] + [[package]] name = "env_filter" version = "2.0.0" @@ -1205,6 +1283,16 @@ dependencies = [ "rustc_version", ] +[[package]] +name = "filetime" +version = "0.2.29" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5c287a33c7f0a620c38e641e7f60827713987b3c0f26e8ddc9462cc69cf75759" +dependencies = [ + "cfg-if", + "libc", +] + [[package]] name = "find-msvc-tools" version = "0.1.9" @@ -1524,8 +1612,10 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ff2abc00be7fca6ebc474524697ae276ad847ad0a6b3faa4bcb027e9a4614ad0" dependencies = [ "cfg-if", + "js-sys", "libc", "wasi", + "wasm-bindgen", ] [[package]] @@ -1547,8 +1637,11 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "300e883d756b2e4ec94e02791f39b04b522276138852cfc41d9fb7e904106099" dependencies = [ "cfg-if", + "js-sys", "libc", "r-efi 6.0.0", + "rand_core", + "wasm-bindgen", ] [[package]] @@ -1778,6 +1871,25 @@ dependencies = [ "syn 2.0.118", ] +[[package]] +name = "h2" +version = "0.4.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6cb093c84e8bd9b188d4c4a8cb6579fc016968d14c99882163cd3ff402a4f155" +dependencies = [ + "atomic-waker", + "bytes", + "fnv", + "futures-core", + "futures-sink", + "http", + "indexmap 2.14.0", + "slab", + "tokio", + "tokio-util", + "tracing", +] + [[package]] name = "half" version = "2.7.1" @@ -1924,6 +2036,7 @@ dependencies = [ "bytes", "futures-channel", "futures-core", + "h2", "http", "http-body", "httparse", @@ -1934,6 +2047,22 @@ dependencies = [ "want", ] +[[package]] +name = "hyper-rustls" +version = "0.27.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "33ca68d021ef39cf6463ab54c1d0f5daf03377b70561305bb89a8f83aab66e0f" +dependencies = [ + "http", + "hyper", + "hyper-util", + "rustls", + "tokio", + "tokio-rustls", + "tower-service", + "webpki-roots", +] + [[package]] name = "hyper-util" version = "0.1.20" @@ -1952,9 +2081,11 @@ dependencies = [ "percent-encoding", "pin-project-lite", "socket2", + "system-configuration", "tokio", "tower-service", "tracing", + "windows-registry", ] [[package]] @@ -2151,6 +2282,25 @@ version = "2.12.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d98f6fed1fde3f8c21bc40a1abb88dd75e67924f9cffc3ef95607bad8017f8e2" +[[package]] +name = "is-docker" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "928bae27f42bc99b60d9ac7334e3a21d10ad8f1835a4e12ec3ec0464765ed1b3" +dependencies = [ + "once_cell", +] + +[[package]] +name = "is-wsl" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "173609498df190136aa7dea1a91db051746d339e18476eed5ca40521f02d7aa5" +dependencies = [ + "is-docker", + "once_cell", +] + [[package]] name = "is_terminal_polyfill" version = "1.70.2" @@ -2484,6 +2634,12 @@ version = "0.16.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7f66e8d5d03f609abc3a39e6f08e4164ebf1447a732906d39eb9b99b7919ef39" +[[package]] +name = "lru-slab" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "112b39cec0b298b6c1999fee3e31427f74f676e4cb9879ed1a121b43661a4154" + [[package]] name = "markup5ever" version = "0.38.0" @@ -2525,6 +2681,12 @@ version = "0.3.17" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6877bb514081ee2a7ff5ef9de3281f14a4dd4bceac4c09388074a6b5df8a139a" +[[package]] +name = "minisign-verify" +version = "0.2.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "22f9645cb765ea72b8111f36c522475d2daa0d22c957a9826437e97534bc4e9e" + [[package]] name = "miniz_oxide" version = "0.8.9" @@ -2957,6 +3119,18 @@ dependencies = [ "objc2-foundation 0.3.2", ] +[[package]] +name = "objc2-osa-kit" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f112d1746737b0da274ef79a23aac283376f335f4095a083a267a082f21db0c0" +dependencies = [ + "bitflags 2.13.0", + "objc2 0.6.4", + "objc2-app-kit 0.3.2", + "objc2-foundation 0.3.2", +] + [[package]] name = "objc2-quartz-core" version = "0.2.2" @@ -3095,6 +3269,23 @@ version = "1.70.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "384b8ab6d37215f3c5301a95a4accb5d64aa607f1fcb26a11b5303878451b4fe" +[[package]] +name = "open" +version = "5.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a0b3d059e795d52b8a72fef45658620edd4d9c359b338564aa14391ffa511ed5" +dependencies = [ + "dunce", + "is-wsl", + "libc", +] + +[[package]] +name = "openssl-probe" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7c87def4c32ab89d880effc9e097653c8da5d6ef28e6b539d313baaacfbafcbe" + [[package]] name = "option-ext" version = "0.2.0" @@ -3120,6 +3311,30 @@ dependencies = [ "num-traits", ] +[[package]] +name = "os_pipe" +version = "1.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7d8fae84b431384b68627d0f9b3b1245fcf9f46f6c0e3dc902e9dce64edd1967" +dependencies = [ + "libc", + "windows-sys 0.61.2", +] + +[[package]] +name = "osakit" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "732c71caeaa72c065bb69d7ea08717bd3f4863a4f451402fc9513e29dbd5261b" +dependencies = [ + "objc2 0.6.4", + "objc2-foundation 0.3.2", + "objc2-osa-kit", + "serde", + "serde_json", + "thiserror 2.0.18", +] + [[package]] name = "owned_ttf_parser" version = "0.25.1" @@ -3465,6 +3680,22 @@ version = "1.0.18" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3d595e54a326bc53c1c197b32d295e14b169e3cfeaa8dc82b529f947fba6bcf5" +[[package]] +name = "psl-types" +version = "2.0.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "33cb294fe86a74cbcf50d4445b37da762029549ebeea341421c7c70370f86cac" + +[[package]] +name = "publicsuffix" +version = "2.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6f42ea446cab60335f76979ec15e12619a2165b5ae2c12166bef27d283a9fadf" +dependencies = [ + "idna", + "psl-types", +] + [[package]] name = "pxfm" version = "0.1.29" @@ -3480,6 +3711,62 @@ dependencies = [ "memchr", ] +[[package]] +name = "quinn" +version = "0.11.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0c1a41e437b6bbd489372cd4971de128e85c855f56c57f283d20ff016cf7c0a8" +dependencies = [ + "bytes", + "cfg_aliases", + "pin-project-lite", + "quinn-proto", + "quinn-udp", + "rustc-hash 2.1.3", + "rustls", + "socket2", + "thiserror 2.0.18", + "tokio", + "tracing", + "web-time", +] + +[[package]] +name = "quinn-proto" +version = "0.11.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2f4bfc015262b9df63c8845072ce59068853ff5872180c2ce2f13038b970e560" +dependencies = [ + "bytes", + "getrandom 0.4.3", + "lru-slab", + "rand", + "rand_pcg", + "ring", + "rustc-hash 2.1.3", + "rustls", + "rustls-pki-types", + "slab", + "thiserror 2.0.18", + "tinyvec", + "tracing", + "web-time", +] + +[[package]] +name = "quinn-udp" +version = "0.5.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "35a133f956daabe89a61a685c2649f13d82d5aa4bd5d12d1277e1072a21c0694" +dependencies = [ + "cfg_aliases", + "libc", + "once_cell", + "socket2", + "tracing", + "windows-sys 0.61.2", +] + [[package]] name = "quote" version = "1.0.46" @@ -3501,6 +3788,32 @@ version = "6.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f8dcc9c7d52a811697d2151c701e0d08956f92b0e24136cf4cf27b57a6a0d9bf" +[[package]] +name = "rand" +version = "0.10.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c7f5fa3a058cd35567ef9bfa5e75732bee0f9e4c55fa90477bef2dfcdbc4be80" +dependencies = [ + "chacha20", + "getrandom 0.4.3", + "rand_core", +] + +[[package]] +name = "rand_core" +version = "0.10.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "63b8176103e19a2643978565ca18b50549f6101881c443590420e4dc998a3c69" + +[[package]] +name = "rand_pcg" +version = "0.10.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "caa0f4137e1c0a72f4c651489402276c8e8e1cf081f3b0ba156d2cbeef09e86a" +dependencies = [ + "rand_core", +] + [[package]] name = "range-alloc" version = "0.1.5" @@ -3685,6 +3998,49 @@ version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "19b30a45b0cd0bcca8037f3d0dc3421eaf95327a17cad11964fb8179b4fc4832" +[[package]] +name = "reqwest" +version = "0.12.28" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "eddd3ca559203180a307f12d114c268abf583f59b03cb906fd0b3ff8646c1147" +dependencies = [ + "base64 0.22.1", + "bytes", + "cookie", + "cookie_store", + "encoding_rs", + "futures-core", + "h2", + "http", + "http-body", + "http-body-util", + "hyper", + "hyper-rustls", + "hyper-util", + "js-sys", + "log", + "mime", + "percent-encoding", + "pin-project-lite", + "quinn", + "rustls", + "rustls-pki-types", + "serde", + "serde_json", + "serde_urlencoded", + "sync_wrapper", + "tokio", + "tokio-rustls", + "tower", + "tower-http", + "tower-service", + "url", + "wasm-bindgen", + "wasm-bindgen-futures", + "web-sys", + "webpki-roots", +] + [[package]] name = "reqwest" version = "0.13.4" @@ -3699,15 +4055,20 @@ dependencies = [ "http-body", "http-body-util", "hyper", + "hyper-rustls", "hyper-util", "js-sys", "log", "percent-encoding", "pin-project-lite", + "rustls", + "rustls-pki-types", + "rustls-platform-verifier", "serde", "serde_json", "sync_wrapper", "tokio", + "tokio-rustls", "tokio-util", "tower", "tower-http", @@ -3743,6 +4104,20 @@ dependencies = [ "windows-sys 0.60.2", ] +[[package]] +name = "ring" +version = "0.17.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a4689e6c2294d81e88dc6261c768b63bc4fcdb852be6d1352498b114f61383b7" +dependencies = [ + "cc", + "cfg-if", + "getrandom 0.2.17", + "libc", + "untrusted", + "windows-sys 0.52.0", +] + [[package]] name = "roxmltree" version = "0.20.0" @@ -3796,12 +4171,92 @@ dependencies = [ "windows-sys 0.61.2", ] +[[package]] +name = "rustls" +version = "0.23.43" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0283386ce02abc0151e1761d08802dfe86c173b0b494af5cbc086574e453da06" +dependencies = [ + "once_cell", + "ring", + "rustls-pki-types", + "rustls-webpki", + "subtle", + "zeroize", +] + +[[package]] +name = "rustls-native-certs" +version = "0.8.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dab5152771c58876a2146916e53e35057e1a4dfa2b9df0f0305b07f611fdea4d" +dependencies = [ + "openssl-probe", + "rustls-pki-types", + "schannel", + "security-framework", +] + +[[package]] +name = "rustls-pki-types" +version = "1.15.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2f4925028c7eb5d1fcdaf196971378ed9d2c1c4efc7dc5d011256f76c99c0a96" +dependencies = [ + "web-time", + "zeroize", +] + +[[package]] +name = "rustls-platform-verifier" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "26d1e2536ce4f35f4846aa13bff16bd0ff40157cdb14cc056c7b14ba41233ba0" +dependencies = [ + "core-foundation 0.10.1", + "core-foundation-sys", + "jni 0.22.4", + "log", + "once_cell", + "rustls", + "rustls-native-certs", + "rustls-platform-verifier-android", + "rustls-webpki", + "security-framework", + "security-framework-sys", + "webpki-root-certs", + "windows-sys 0.61.2", +] + +[[package]] +name = "rustls-platform-verifier-android" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f87165f0995f63a9fbeea62b64d10b4d9d8e78ec6d7d51fb2125fda7bb36788f" + +[[package]] +name = "rustls-webpki" +version = "0.103.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "61c429a8649f110dddef65e2a5ad240f747e85f7758a6bccc7e5777bd33f756e" +dependencies = [ + "ring", + "rustls-pki-types", + "untrusted", +] + [[package]] name = "rustversion" version = "1.0.22" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b39cdef0fa800fc44525c84ccb54a029961a8215f9619753635a9c0d2538d46d" +[[package]] +name = "ryu" +version = "1.0.23" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9774ba4a74de5f7b1c1451ed6cd5285a32eddb5cccb8cc655a4e50009e06477f" + [[package]] name = "same-file" version = "1.0.6" @@ -3811,6 +4266,15 @@ dependencies = [ "winapi-util", ] +[[package]] +name = "schannel" +version = "0.1.29" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "91c1b7e4904c873ef0710c1f407dde2e6287de2bebc1bbbf7d430bb7cbffd939" +dependencies = [ + "windows-sys 0.61.2", +] + [[package]] name = "schemars" version = "0.8.22" @@ -3887,6 +4351,29 @@ dependencies = [ "tiny-skia", ] +[[package]] +name = "security-framework" +version = "3.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b7f4bc775c73d9a02cde8bf7b2ec4c9d12743edf609006c7facc23998404cd1d" +dependencies = [ + "bitflags 2.13.0", + "core-foundation 0.10.1", + "core-foundation-sys", + "libc", + "security-framework-sys", +] + +[[package]] +name = "security-framework-sys" +version = "2.17.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6ce2691df843ecc5d231c0b14ece2acc3efb62c0a398c7e1d875f3983ce020e3" +dependencies = [ + "core-foundation-sys", + "libc", +] + [[package]] name = "selectors" version = "0.36.1" @@ -4017,6 +4504,18 @@ dependencies = [ "serde_core", ] +[[package]] +name = "serde_urlencoded" +version = "0.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d3491c14715ca2294c4d6a88f15e84739788c1d030eed8c110436aafdaa2f3fd" +dependencies = [ + "form_urlencoded", + "itoa", + "ryu", + "serde", +] + [[package]] name = "serde_with" version = "3.21.0" @@ -4087,16 +4586,58 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a7507d819769d01a365ab707794a4084392c824f54a7a6a7862f8c3d0892b283" dependencies = [ "cfg-if", - "cpufeatures", + "cpufeatures 0.2.17", "digest", ] +[[package]] +name = "shared_child" +version = "1.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1e362d9935bc50f019969e2f9ecd66786612daae13e8f277be7bfb66e8bed3f7" +dependencies = [ + "libc", + "sigchld", + "windows-sys 0.60.2", +] + [[package]] name = "shlex" version = "2.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f8fadd59c855ef2080decdef8ff161eb6661b86933c9d82e5ba29dc602a55aba" +[[package]] +name = "sigchld" +version = "0.2.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "47106eded3c154e70176fc83df9737335c94ce22f821c32d17ed1db1f83badb1" +dependencies = [ + "libc", + "os_pipe", + "signal-hook", +] + +[[package]] +name = "signal-hook" +version = "0.3.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d881a16cf4426aa584979d30bd82cb33429027e42122b169753d6ef1085ed6e2" +dependencies = [ + "libc", + "signal-hook-registry", +] + +[[package]] +name = "signal-hook-registry" +version = "1.4.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c4db69cba1110affc0e9f7bcd48bbf87b3f4fc7c61fc9155afd4c469eb3d6c1b" +dependencies = [ + "errno", + "libc", +] + [[package]] name = "simd-adler32" version = "0.3.9" @@ -4321,6 +4862,12 @@ version = "0.11.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7da8b5736845d9f2fcb837ea5d9e2628564b3b043a70948a3f0b778838c5fb4f" +[[package]] +name = "subtle" +version = "2.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "13c2bddecc57b384dee18652358fb23172facb8a2c51ccc10d74c157bdea3292" + [[package]] name = "swash" version = "0.2.9" @@ -4364,6 +4911,17 @@ dependencies = [ "unicode-ident", ] +[[package]] +name = "syn" +version = "3.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "53e9bae58849f64dfa4f5d5ae372c8341f7305f82a3868709269343628b659a3" +dependencies = [ + "proc-macro2", + "quote", + "unicode-ident", +] + [[package]] name = "sync_wrapper" version = "1.0.2" @@ -4393,6 +4951,27 @@ dependencies = [ "libc", ] +[[package]] +name = "system-configuration" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a13f3d0daba03132c0aa9767f98351b3488edc2c100cda2d2ec2b04f3d8d3c8b" +dependencies = [ + "bitflags 2.13.0", + "core-foundation 0.9.4", + "system-configuration-sys", +] + +[[package]] +name = "system-configuration-sys" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8e1d1b10ced5ca923a1fcb8d03e96b8d3268065d724548c0211415ff6ac6bac4" +dependencies = [ + "core-foundation-sys", + "libc", +] + [[package]] name = "system-deps" version = "6.2.2" @@ -4457,6 +5036,17 @@ dependencies = [ "syn 2.0.118", ] +[[package]] +name = "tar" +version = "0.4.46" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3f6221d9a6003c78398e3b239969f352578258df48c8eb051caadae0015bc840" +dependencies = [ + "filetime", + "libc", + "xattr", +] + [[package]] name = "target-lexicon" version = "0.12.16" @@ -4493,7 +5083,7 @@ dependencies = [ "percent-encoding", "plist", "raw-window-handle", - "reqwest", + "reqwest 0.13.4", "serde", "serde_json", "serde_repr", @@ -4634,6 +5224,94 @@ dependencies = [ "url", ] +[[package]] +name = "tauri-plugin-http" +version = "2.5.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b5bd512048e1985b7ec78f96d99083e2ddaf7e0d906b2b63c44ce5bb8b894067" +dependencies = [ + "bytes", + "cookie_store", + "data-url", + "http", + "regex", + "reqwest 0.12.28", + "schemars 0.8.22", + "serde", + "serde_json", + "tauri", + "tauri-plugin", + "tauri-plugin-fs", + "thiserror 2.0.18", + "tokio", + "url", + "urlpattern", +] + +[[package]] +name = "tauri-plugin-process" +version = "2.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d55511a7bf6cd70c8767b02c97bf8134fa434daf3926cfc1be0a0f94132d165a" +dependencies = [ + "tauri", + "tauri-plugin", +] + +[[package]] +name = "tauri-plugin-shell" +version = "2.3.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8457dbf9e2bab1edd8df22bb2c20857a59a9868e79cb3eac5ed639eec4d0c73b" +dependencies = [ + "encoding_rs", + "log", + "open", + "os_pipe", + "regex", + "schemars 0.8.22", + "serde", + "serde_json", + "shared_child", + "tauri", + "tauri-plugin", + "thiserror 2.0.18", + "tokio", +] + +[[package]] +name = "tauri-plugin-updater" +version = "2.10.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "806d9dac662c2e4594ff03c647a552f2c9bd544e7d0f683ec58f872f952ce4af" +dependencies = [ + "base64 0.22.1", + "dirs", + "flate2", + "futures-util", + "http", + "infer", + "log", + "minisign-verify", + "osakit", + "percent-encoding", + "reqwest 0.13.4", + "rustls", + "semver", + "serde", + "serde_json", + "tar", + "tauri", + "tauri-plugin", + "tempfile", + "thiserror 2.0.18", + "time", + "tokio", + "url", + "windows-sys 0.60.2", + "zip", +] + [[package]] name = "tauri-runtime" version = "2.11.3" @@ -4734,6 +5412,19 @@ dependencies = [ "toml 1.1.2+spec-1.1.0", ] +[[package]] +name = "tempfile" +version = "3.27.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "32497e9a4c7b38532efcdebeef879707aa9f794296a4f0244f6f69e9bc8574bd" +dependencies = [ + "fastrand", + "getrandom 0.4.3", + "once_cell", + "rustix 1.1.4", + "windows-sys 0.61.2", +] + [[package]] name = "tendril" version = "0.5.0" @@ -4884,9 +5575,31 @@ dependencies = [ "mio", "pin-project-lite", "socket2", + "tokio-macros", "windows-sys 0.61.2", ] +[[package]] +name = "tokio-macros" +version = "2.7.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "78773a2a397f451582ce068015985c33193cf6dea8b74d2a639fe457b2f07b0e" +dependencies = [ + "proc-macro2", + "quote", + "syn 3.0.3", +] + +[[package]] +name = "tokio-rustls" +version = "0.26.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1729aa945f29d91ba541258c8df89027d5792d85a8841fb65e8bf0f4ede4ef61" +dependencies = [ + "rustls", + "tokio", +] + [[package]] name = "tokio-util" version = "0.7.18" @@ -5210,6 +5923,12 @@ version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b4ac048d71ede7ee76d585517add45da530660ef4390e49b098733c6e897f254" +[[package]] +name = "untrusted" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8ecb6da28b8a351d773b68d5825ac39017e680750f980f3a1a85cd8dd28a47c1" + [[package]] name = "url" version = "2.5.8" @@ -5584,6 +6303,24 @@ dependencies = [ "system-deps", ] +[[package]] +name = "webpki-root-certs" +version = "1.0.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b96554aa2acc8ccdb7e1c9a58a7a68dd5d13bccc69cd124cb09406db612a1c9b" +dependencies = [ + "rustls-pki-types", +] + +[[package]] +name = "webpki-roots" +version = "1.0.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7dcd9d09a39985f5344844e66b0c530a33843579125f23e21e9f0f220850f22a" +dependencies = [ + "rustls-pki-types", +] + [[package]] name = "webview2-com" version = "0.38.2" @@ -5979,6 +6716,17 @@ dependencies = [ "windows-link 0.2.1", ] +[[package]] +name = "windows-registry" +version = "0.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "02752bf7fbdcce7f2a27a742f798510f3e5ad88dbe84871e5168e2120c3d5720" +dependencies = [ + "windows-link 0.2.1", + "windows-result 0.4.1", + "windows-strings 0.5.1", +] + [[package]] name = "windows-result" version = "0.3.4" @@ -6457,6 +7205,16 @@ version = "0.13.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ea6fc2961e4ef194dcbfe56bb845534d0dc8098940c7e5c012a258bfec6701bd" +[[package]] +name = "xattr" +version = "1.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "32e45ad4206f6d2479085147f02bc2ef834ac85886624a23575ae137c8aa8156" +dependencies = [ + "libc", + "rustix 1.1.4", +] + [[package]] name = "xcursor" version = "0.3.10" @@ -6564,6 +7322,12 @@ dependencies = [ "synstructure", ] +[[package]] +name = "zeroize" +version = "1.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e13c156562582aa81c60cb29407084cdb54c4164760106ab78e6c5b0858cf64e" + [[package]] name = "zerotrie" version = "0.2.4" @@ -6597,6 +7361,18 @@ dependencies = [ "syn 2.0.118", ] +[[package]] +name = "zip" +version = "4.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "caa8cd6af31c3b31c6631b8f483848b91589021b28fffe50adada48d4f4d2ed1" +dependencies = [ + "arbitrary", + "crc32fast", + "indexmap 2.14.0", + "memchr", +] + [[package]] name = "zmij" version = "1.0.21" diff --git a/src-tauri/Cargo.toml b/src-tauri/Cargo.toml index fc9d8c3..749fe60 100644 --- a/src-tauri/Cargo.toml +++ b/src-tauri/Cargo.toml @@ -39,6 +39,10 @@ tauri-build = { version = "2", features = [] } tauri = { version = "2", features = [] } tauri-plugin-dialog = "2" tauri-plugin-fs = "2" +tauri-plugin-updater = "2" +tauri-plugin-process = "2" +tauri-plugin-http = "2" +tauri-plugin-shell = "2" serde = { version = "1", features = ["derive"] } serde_json = "1" geometry = { path = "geometry" } diff --git a/src-tauri/capabilities/default.json b/src-tauri/capabilities/default.json index b403288..ee359b0 100644 --- a/src-tauri/capabilities/default.json +++ b/src-tauri/capabilities/default.json @@ -1,7 +1,7 @@ { "$schema": "../gen/schemas/desktop-schema.json", "identifier": "default", - "description": "Basis-Permissions + Fenstersteuerung fuer die randlose (decorations:false) Titelleiste: Minimieren/Maximieren/Schliessen + Ziehen der eigenen Titelleiste (data-tauri-drag-region). Menu: fuer die native macOS-Systemmenueleiste (src/native/appMenu.ts). Webview/Event: fuer die nativen Ressourcen-/Einstellungs-/Zeichnungsebenen-/Ebeneneinstellungs-Fenster + ihre Sync-Bruecken (src/native/*Window.ts) - gilt fuer alle Fensterlabels, da jedes Events senden/empfangen muss.", + "description": "Basis-Permissions + Fenstersteuerung fuer die randlose (decorations:false) Titelleiste: Minimieren/Maximieren/Schliessen + Ziehen der eigenen Titelleiste (data-tauri-drag-region). Menu: fuer die native macOS-Systemmenueleiste (src/native/appMenu.ts). Webview/Event: fuer die nativen Ressourcen-/Einstellungs-/Zeichnungsebenen-/Ebeneneinstellungs-Fenster + ihre Sync-Bruecken (src/native/*Window.ts) - gilt fuer alle Fensterlabels, da jedes Events senden/empfangen muss. Dialog/Fs: nativer Oeffnen- UND Speichern-Dialog fuer Projektdateien (.obp/.json) plus Lesen/Schreiben der gewaehlten Datei (io/projectFile.ts, io/saveFile.ts) - open+read fuer Projekt laden, save+write fuer Projekt/Export speichern. Updater/Process: Selbst-Update-Check beim Start (src/update/checkForUpdate.ts) + Neustart nach Installation. Http: Versionsverlauf (versions.json vom Gitea-Release) ohne Browser-CORS, Scope auf den eigenen Gitea-Host begrenzt. Shell:allow-open: oeffnet den DMG-Download einer aelteren Version im System-Browser (Rollback).", "windows": ["main", "resources", "settings", "drawing-levels", "layer-settings", "context-import"], "permissions": [ "core:default", @@ -16,7 +16,16 @@ "core:webview:allow-create-webview-window", "core:menu:default", "core:event:default", + "dialog:allow-open", "dialog:allow-save", - "fs:allow-write-text-file" + "fs:allow-read-text-file", + "fs:allow-write-text-file", + "updater:default", + "process:allow-restart", + { + "identifier": "http:default", + "allow": [{ "url": "https://git.openbureau.ch/*" }] + }, + "shell:allow-open" ] } diff --git a/src-tauri/icons/128x128.png b/src-tauri/icons/128x128.png new file mode 100644 index 0000000000000000000000000000000000000000..460af3fbe9bd8b5aa55d6360a47785e6e71a4a49 GIT binary patch literal 2968 zcmb7`X*3j!8pmgtVGv`_ma(UXK^k?*8Zi<=8oNqKXpGQcFxHe^LKMbUma_GFU;9|H zM8;UMFCoKg8w|!ew|mY#=bm%#r~91qJpXf^FVFMocYZG|&5gM^#W(=~05{6S(CT** z{?!n+-?LrkUM~Q^<$^NQx4})UJKgdUq>7$CdURIYE0WKd*M<$N2eHX7^yOLk8Xz}0 zMvriNd$Ul(Tjfsb_24JwwH7IZ*P-6eUKtkdS@nJ+nxrd-#|!wDSl-Of>jrXwZmXWQ zcV@Oszwg=N{qI(h1JUFwL7cg><9b{ zuKAZ5LS0>*$HiD1k%A^vRjC=PH^o|08geu>EUoaB%P+ zgxNpq>rI)Pu_e%1r0Sgx5qH=%oDcZHY@F9UqWw+Ry9+xBO9J@C8j!9my*96k<&AYcOX!;ES1>3Ne^4C28t@oF(8eFiy!UeE-GNzL z(L=}bg*l_q5EY19L4I>LoQ}*t*;>@o$)z5kQTpAb^%sWC4lBc7YvbQ#n0qjtr<@2y zRR^MCSl_GUs;}|DU`0DX!}D=cPaN(31+_9=NfhIAM+|rEN3Jh##1~rzSSn9qK@V0n z`fs`2(Po$Xo6SmKgO*cr>sr@kkc=Y2$JesJW2iNF7o=*jR*8Yx=53VvFlhI_7WXK| zc6$y~z<-oxP=L~QnLADXiUdCR@tUeaOj-(hD-yZ!kDFxOs)ZT!o2vU z6MsmVq^G0i1dyld;M)x>sR@hi5{*whJ*}@`X6VY1=5Yez)G-vaKVLImNb11e!C_=; zp=;!`Q$w10Tr|Mr8z)2)$y}xsG#i;*;#m6vaF=YK_!}ZNzO#9YH)ye&FM1nyABMSU zq|TnDkcLS0;!v2MWuM zCt9(4*U|3RM1Pb?o%Mx_+9ww(3%^H2T3|4kyX-s? zxSzgTAOwW*2)P}+zj08O(&Y~&4m%KHVq&Nf_MG^E-SE1zzX7Z#Altzd4}HS zAYG1&bWTc;eM_Bf3Lb?r`fSxvE_bhDK~j*u@q!u6^wEbo#4C)b+-?S;}{6ASm@dDJa3V6 z%s&Ryoa8PNY^<)Xjv3N!qU2{3)73bNXVMC#SA87fe9e*Y0eSlD)0cq9L#?v1vN`?HD$+vsUC|O%EL8$8RxYa6lVF-!TGN)*gj6q5 zlH&Q_rTTCJD&uqIk#VQC@WiHuhQ@@+NXy#lYVaQ*2bC`|ybt!URW+#9AXNBY?*`cv znDfw~p`o|Fth-VmAAk7`>$UO&?qc)`o1^H_;ZZ0kOmwaqWTrz|YWetNfPX2)?)vrX z$F!DYtXqzr$@dzamskw@hLNQ; zunr{c(&^<{-@HF%88rQt0@l6YchV2`q(${l`g9xK`y9%)LQ7AC{J}$DnnA2a3jlay zK);t!Ddl6x6DpZd&QqU4&fj2SE-EVLR@@qt8{o)C-aNy^qFes@Z?__j25w3PZye4W$Lq&v#hewZ$ zjPRf%E_8tG-d_*|SJU!C2ri3bgKO7!!uZ%27nPKe>3Sbtz@#pns0*;-DUIfQzxcjz z7U0>&Om?f|_kgE%hDR+Q#-Xgo13BDsjP~~SQ+H`C9PBl}_Q#v#O9+DMEu~l^i0vdb z6NuwV2^BtvekL-cE;2bQmJ9oRz)SbLNm>)@v9Ft=5~;zJmYbEGJvr{!qw!=WGv{ul z2IOgpU>8>?htYF%V13TK>;10#MQ?sN*)jl!E^ny$`sqfz@FSmsn?fpXJ4wZ$y>s zrtrF|^J&b2zKd>;OOVK|UF*aV6Kj;Hhx(?!XjaSE#DpeUAW{ literal 0 HcmV?d00001 diff --git a/src-tauri/icons/128x128@2x.png b/src-tauri/icons/128x128@2x.png new file mode 100644 index 0000000000000000000000000000000000000000..399326d7134dafbeb21be4cf62de96335034ec72 GIT binary patch literal 6021 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 F{{t literal 0 HcmV?d00001 diff --git a/src-tauri/icons/32x32.png b/src-tauri/icons/32x32.png new file mode 100644 index 0000000000000000000000000000000000000000..6b6020de0f00d957dc70d52ab3bf37cbcafe70ff GIT binary patch literal 879 zcmV-#1CacQP)OzQ69Wo%x zRf*G&CnqOHKA-QiDK(vThu23*&5fiZ|OwHG7Fs;#cB{-jY1 zWeeIO90AYni2L~S(78c&# z+}yC++grgoH^Ts+IM8NhW_UavXRTK2)5gZen_{u3l}aUZ1VEh+ET5a3``&K1`=l6a z`jkRo02|4$2+4j)p7^SCa;rNI4-bEl%U8&411IJGFnL<*34&zn{ zoYF*70f#e(+ubbh_xr5Z>p6C;`Nbv~W)g@e^Yio1@WcN8zGiG~ZK(}u1RMp7>1KU0 znM8y;S_%+!#&XTWQz8#`;CIT>SnVY3Slura;+U*g* zBLHpEH1v!12de{0F!CJvugbJ_&F4OF2H;nU$7(s7ot>3c52ZMjN=Y!dXc~=%EZIS; zp%Jtc!y*WU5&+0%v$o3!cSE&Wl~wZIN8sfFRa$WYg}jdK0QUCwRBf+;K!U?L34q{> ziwn=v3vfQlIe?NU|KOuuuZs~S!yQeW@Hbtnxrd-+v<5b$5r8vlxk91Plavf=Ac#Z0 zz617(I2#g4n*y)yr5y4Si3E&z59Lay6D|L^xVZTG`uZB@YFZx=6E;qPt3i3Q+5Akj z{FRNCk3SZO9ls#d??50C^`_g1r)uw3Wl%yVg^{ zRVtMqa62rgE|l{B^KoiruHfyU&S4ZI)iyUbO{>+`_7`X8M5gYn#R&ia002ovPDHLk FV1gqln+E^@ literal 0 HcmV?d00001 diff --git a/src-tauri/icons/64x64.png b/src-tauri/icons/64x64.png new file mode 100644 index 0000000000000000000000000000000000000000..0bcc96ac6e7466f76ad1db7a00a3c813417a7b7b GIT binary patch literal 1490 zcmV;@1ugoCP)(`GB@jqV- zMSvop^2IbwZE0yq@9OH(`~c$k_}H4Aoi%k`x9*ex0^ix$3E)O){F(8aHMh35jP31h zb8&Iebe#ZR+yH>0DYS8}Y_ zPnUBYtz37Xo14o3co%N=1UG*a3We@r^@ZhcZf-;}nLNVot5hoWbZTnqaA9FV$7+=d z3#}A*d4cuy_3yCxt)-6bD)6=wV zbxqXC0*6SowY3FdxbMfu$A2x97_~yKZzsHe0)aq;miMF8ON9i+uK^E14vyz~Nq&tQ7&M9uPb4#wLA$l9J29*Z2W=K22;x~pCw zuzu;pSace+%Ue$txG0M(4%}5DaNYZrJPU-Ywcz03pgtXEVU4!n;i9Uyd@?r&nL;l!^5mw%i~8!M`B=LKy-I^f3P-JlE5%R<`xGB2Lg3T z)uB+65GX|gf!I@1cAsGP_xA;w8n;}PB+xr}+->l}iz3I)$RF(!9NnMZ;RGsOo+K5D z;m@iod>0m0ZE;0_B0v$K2v7tl0u%v?07ZZzKoOt_Py{Ff{7t}J^!$Y1IzqDF=iF!8 ziw#q@(w%K|*&tycluURof~Qv{ zEAfE$UeyA0f0^*yjCo3GOAb;Qjg7^Millggg2L(PX{xSYan7dvw2n*tOjA=6G5ksJw&L9? zS_)HdZk&P47-dbL~v~x#0Y_N(1hM#$CczD<>`7A&sC7Gh+92c0kiq4xIb>WWof#xJ>n#z2-2FyS%g z>GlBslWj;npX*oj$qe=OBw}-Ovk#@}55PS~`KeRq<7ESd^E`|aXSQd;W6V3pUDY>3 zBIg?d?k_Jdw^4gb`6(5c6d~I3bWtlcDXs4KXzDH2*PQBH|7a>VBq%vA_u|5X&*nJQ s6?1u4p87tg4=3xg#8qu^MSy$Dzk17b2P_Rv?*IS*07*qoM6N<$g1Vd09RL6T literal 0 HcmV?d00001 diff --git a/src-tauri/icons/Square107x107Logo.png b/src-tauri/icons/Square107x107Logo.png new file mode 100644 index 0000000000000000000000000000000000000000..8a641dc450b5261797a5b6f89ac1d8ff6c4fd0b7 GIT binary patch literal 2554 zcmVpx^-|L*H5-A#qN)ZSw5rHMJL#Lram~e_6(vl@h zEWnx4aOOT^)Q`$(`3dRDl`C6gvDjOYNTk_uoDDcuTb5OWR|l`f&WjH)fnx;6T|CeA zcszb>*REaHQ=tK9Vm_du!RqPhiR{_4C&BZpSFhGjPELLZcpu>3=4H#4SsJEFBogi` zL4jBCQquR&Hj4);qkH}3%a?qamz_kV0}Zyz?$7P2&f!ZJ6~+uK_ejYbdRWD6g|SckX;QrQ&;T z!|Y6*34)^OgA?I`V(k%7o`j&Lp<(Yp!;bL6$&)8-Uo^|O=a(;EZbjqSH#Ifoq^P@y zcS+RL)I{Ls?}gKGA``dX%AlQcjvYHzy>{)|Kha<|O;1m=UlozE&)kuQLuR8L8$&&R z6~IQkwqKsqkRua(U9)D*LAvMAs+fSvT5LESF*GA}IPc;GGq#wsW*MzIckWz0+|a*Z z0vqYwi22K@FXo_3*_)n5`EJD!)sPqMvb|~*Kz)eXKu~c3mAhLHNO6>BB`W{NUbV|} zp~F@G4MQn!V8lFGjw2I(v|UgDn#8|RuAAXxOr~???R0%ArAN=9vafTjPeA3h?MedF zdX(#%UR-%QjR|z$=QIaL&&{B$NdCqVIp_;%P<*KGMdeE87G z8Wv|e_2~xvrB+b$MSf3h6o_V7GZPeQJ^z?F!JHfn43GQ)+xi-8Yaq@ACn^1|44gC! zdlHl`Je&*y`xj-qdH3$!%z`d#DEyH_h$uJrBuS(EWR?!+i7 z1!sA~gvQ^+QG>Rt8vl;x)MjyU3!w#J0S&CCrY5)M`%!@WPD0`o{OIVYdi3bgEVK}{ z%;7+T%Ex?G&^3>>-!E8v79Qx3DopXHRjXF1d-v{fM%S$*Oo zBG-v5UAk0l*|LRhvs+0Dd2q%q@qSEN4I?yuZsW#{Zd+N%z)BVt%_z;97ifH+4iwu; zYMS5Ps4BOO2`psHsj1tyZ_f(@F0sONj@u^Dc_4s=G=|p+i*VPiTc>W_x+Spk4T}ZL zrEl}W;{AU74}0nk5E2(>7MfO-yfoXV$+pBb-OuNQS0Ob6X~NWWKQ+wsb4Er+0*R4p zv?)wb+PRs)Jxt}IS&m5;h@6fic-_WiltG!nFhU50VF97l3}`%x1Zd-_N|Nz#Q%Zh} zyV_JZ0S5W??I<8`)zN8l|6v?rouR_XX>1T*dP9l$5-MCrzy4jNWT?o>!C1TM!2=1xv0riAVb#a)v;$aRebPjou z>^#6I#w6JZ{)*SSy1JaaP3!9fGSQBX4yJ3}&v~SvI>;rOrSO@r$9dF0jGD!A^iW%Nw9-i%Y+78%2l0fNE%Hc$?RIdU_(6 zfXZ02QnRcY^@WBVferqY(+@#7 z`ZEkg?Pacb)Se3Fh16MBljW>QJcoNuuXzgP^GU9tRIVC8o6Dgm9EslE-bT2j-MG1r znAw_>d(6X27heOkN>t;Vna6Vn3T!5d=Eww>3qX$3J*U@aM$|JkeR+d5*GuF%pl#48 z$lpVMY(0mlI3sI<;Fr?i2PY2AOfwG-%A%4!0FYC7&ZF$`&MlvuelK4)PP54QFLP5& z?8(g5xbZgJc(YFL+Q4L#x;7SjFn=112^^#NpYu^SP#FhcReo)0X&Kj_i?GA%wI3B2 ztc9SZ%9%4~YO$W98dCJ?rPoYMafWxUX`?1_tS^&3R4A}g+cV~hX9{x8(`4JIs^VBs zYIEX{&)M18narhK3I*0;ooZEL=?WK{iZ5DNBC>p1V2KDU5rHMJL<&s)2Xb@vK|%^^ Q$p8QV07*qoM6N<$f@?wA#{d8T literal 0 HcmV?d00001 diff --git a/src-tauri/icons/Square142x142Logo.png b/src-tauri/icons/Square142x142Logo.png new file mode 100644 index 0000000000000000000000000000000000000000..1f4f88c73d59e2c132ae9d91d18915f7b1ff3e6d GIT binary patch literal 3418 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 VFaj#`js8z#Fw!&CC1|5!{{sLd*Bt-= literal 0 HcmV?d00001 diff --git a/src-tauri/icons/Square284x284Logo.png b/src-tauri/icons/Square284x284Logo.png new file mode 100644 index 0000000000000000000000000000000000000000..154221ba76798df8ceddd3e6f753b44742ade621 GIT binary patch literal 6661 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 literal 0 HcmV?d00001 diff --git a/src-tauri/icons/Square44x44Logo.png b/src-tauri/icons/Square44x44Logo.png new file mode 100644 index 0000000000000000000000000000000000000000..925bd05fee0f54198faf7629a9b487858d57460e GIT binary patch literal 1113 zcmV-f1g86mP)vcJEt zgaMJwW=&O9O%%-Y{uQFPB1W>0BVoD#s!8=&^`}Fj5^7i&tv|24TYJ?#L7(tCjqhfq~TwGmU zo#DON)z#IbZqSNb2Ai9kI$_b%AF)`By>HplQA3t6jnTn7V=#2&^Jq+dZ2O=)G#DF=owMguyS z7g#*!2?lLjhYxTSRyF~h0?S)m|CC0xfaMIvI7>%^EDU;XuU64PKGPF~VGC_q&|bqL z?lZs=L4-;=88z3?MZ7jh$i>A)F*!LYbY1TX!h2ZH|Ig3Q#mUKuH7Y)!g?pmXp6SsR zfP|3O_Gnoam7Pf@lY$dZu~;0);-}}2fEO1R;`sRZUbCrGO3cm8SM0ic;a=C16kphhph7_AeSS0X5+k`rnqQ(PY=4Wl|oU(B*J7)fF zZf-np^Zjm#a4)y|ELNP1s@+%HB>yR5%AFw7E6hxXbj$g9c8P=Fn z)3&y@*ri=&5t*3tF>FsBefUOuVq${DZyOsM4YEDRtuga$%VMWqubCw0RPImLZM)EO}EO-_u=7T8sG)iF)=rYbSq^*%Mz9{f|Gtg<}&9_x2mq8(0K!s z$p{!3raX}xWCN=CZ*2824yjqb3!1%t47TSdgIq3Wr99D*k4((b8N>Kwz$6PDjGCnk z*4Ealoq_Lm+ fKIaQ~n0|i&mR`IE2Ahe200000NkvXXu0mjf0fiFq literal 0 HcmV?d00001 diff --git a/src-tauri/icons/Square71x71Logo.png b/src-tauri/icons/Square71x71Logo.png new file mode 100644 index 0000000000000000000000000000000000000000..194ca0040f79460507745ad4f099a814a7ed32a5 GIT binary patch literal 1761 zcmV<71|Io|P)qidtzz&$}BE_fwZK(D*& z=E}mL1|h%#2yX(+qx+tJTSb~?W_lhqOw*}OitYiXyX#lyoI0oLoDMOyW!ypvfr3+B zIHqZ8e(991>z0i36x^X`G^!5_4Cn_32iDZoRLXCoK0Q5cw6?ZttE;PKEEY2#1P)1v zJ~K0;xq&P#EmfydDWk5g&N@3gdvGZd*R86mG6x3-FWjIeCnqhED6?d6R#sL*bm1h2 z(PLTGM|3zq?F~9^)-=taV~h3=E-7?<(H{)jF|~iG{YpT79v&Y4+kOAi;J}`cXrh_R z%gX=}r8ZStTN|dov1BsINNRkeQifr$P$&f3!_LpoO&Y9OI*ttu4gKltOVI`ywuOtM zMbh#)LHL%SXqT6ljKnxe7uEcAL1K=MjuLc{ zuvQLhD+dtnJ3<2-rdz*L{kS4%57@MEwi;~TB1snKC$f&j)LK`DX*P_euWvM^E$3k$E&c{ZR*oOU4K zI3ABe$n_H)RZzpSXJcwY9ae&d$!;4(1C7-$SUfzrT+-$p$1jSTzWek#lT?@c-iC!jf@ubcV$D z7FaGS=lnlRxiFk9EiG(sZ;$Ql>=Z1CnYPNxN-JkLcrGGqgwS~|z8NFvbgJaEGidnS z)zxK3+nbx4QYDD&s#dmV$mt{ozawMFC@i`2cbWtkIi9yroZpYfyR<%J% zHqzyPz%JB{MvQH2Y}`>3fM{-RW<5PU_V3-DhZJ^nbg<*&j)J4$C^*b_3;h|FUc_2hsW;s(Ae;^BSxrq% zSc$v`foH8U$_{0vP5=p&6Nq?-?q0W|w0zdx-OYFk%)Rw4fWg9^%)|oUz!B?Dkc{5m zUe6Uzch&~h%&}$_h!xLFb_1P*lw?~gcdk_-sbF_^*Io)PwbXcJSxA!-jJ7igiQP?i zNh=+0djv__-rlyeEMz7TutKsd=ms?zV9hwcE2#080cVm_cMc!=`}<8#I7sb>YN7Ox;LdV~EEzDVNmB9?Qv08ckB`4_ z6x?~oRwx$bhA_rsm{7pfOXo9S6d(Hf`m~$_Pf$d?6|aeWiV8P6Q6eB

`mRZ}UBs z6a9{UW-9&8sf>|Q{eMJ-8w$BdfWnWs9wJTy9ifW7U#OJv19z!rL1m1niKG+G;lx5` zADfM#W(qJA0et8vy0Z!{op#nCq4bZu$uAKA@(lMBmm+2DEoKTPI6NLYnqTEt$;<^YT5i21ia7sR=>wI5Gq7@NP>L~py<}D+o z+{9a2;Q8kJf{&u%`1Rd6GT)&S$ofsD7WEXIvTm;cSR67!+aJPV00000NkvXXu0mjf DnYS?V literal 0 HcmV?d00001 diff --git a/src-tauri/icons/Square89x89Logo.png b/src-tauri/icons/Square89x89Logo.png new file mode 100644 index 0000000000000000000000000000000000000000..341696b9925b91633bb6b5dfd7a0f112444e7ef7 GIT binary patch literal 2032 zcmVG3p+koMdyeCb<9z-#pWV1|!zmYb$&k5o19y0MxTCSL@qK_jj<>JlbxT7- zgLm*rDL8hOPN&uK^75i(S$_ihB^>|xqeqYav-W%|4%ztJ!NI}o<;$1baP?2&06*Qj zb!$^5li@+~JGs^4b`#|~0M}-LktiC;lP6Eo*me%5akj6o?>6UEiEmCy@YKiVb$LlHyOr# zSRny>S8!xxSN=Y)~X@4>cFs8 z;2!%BL7fX@q;`-ff{h$~FkJ*Km^+Lr#!gsi#QCSUZ{PkQ4DJN1I7dEZxeMcW7)7AM zJBTD&(ZJ>E$bt(tj9|goKZ7Ww_weDve>3VJ@RBT<9St33-8Fs-Q`GlW=Fcl8F*r zF}D&~uP9TX`OvGCmtr`Fu$IQy#rH^wTA`neFdwWB+Ktj;2myIpwR!XA$bhij;O)zF zr9Sa$!rraQc>EN(mtcLky%byKo}M118`ZMwWu1hKF28#C@S$2-TJkPrH9-6M;y{oq z{X~QHM+JeF+tk#gm@V70XOEhkoa8e*&#Gfje8e0E1#&Hg7Qc&T+(mbHx9aHV@GLy; z=+mk3ShS!eayx+*0%#gOx}mPFE)P20N3~o>q979%eeBH4%!{coJRaJyV~6J+2)dY` z?(FPT$N_tG#bwbo4VhMGAm;<3MNUmkd6v3&?_S@=lh)1)!tdO@d)Iqz7l$?1yt^P6 zKVLmDG2wl_bLY;2pp9F>6OGsat0bf?{Te>g@tB^T_CWf%0%OgaHf>UIjsLI{oCWj3 zHpav2`CERE4PVfRMg|=E01px>N_3%QRHqbyERY4VAP~p`S&Bdw$O2i4Ko-bS1hPOD z$WjEdKo-bS1hPPuB9H~LKvv0`B%^{18Hj5voSkH_91+CP`WzutY)l2e$6;J?jlHmw z0JG3yhHJIAw-=qdz|T0sh%>n2Qj&3!AX!srR40dB?c29c?b@}=cT}et%Ec)TtVc$5 z763#jv{bdu_+&p{YpnReg9qMVav7#o05W0HTK)X-dXstxmcwhSIY}px?!q)!e!kkz zMG&x=oD(PD*dYfw@i1W*;c{UkM+-KypW+tva%w>IF0y%ibPI9J<0}htB|;u^J42aD zjgF2+J|mTDT5qiY4l-Htk)8rzMIHMR20=$1Pn$5Unt*XZ{|gP7>Z|(Y{Yq(Fuu9X3 zD7X52pw)y+E_72^?uCX-d0YK*9Jk;?rKE8Tkc6pCJ{KiYfDo2^TdfMQpaJk?vqkw4j=r`+NO&RtMHSiiia{hTXYpSufloVJECLcm%d z&JC3yqGqs;FwRqbmExd&mDFiTEi5dM&kx01MN!CMiB4|qKbF)oo+?;_=#7G+MOD7Kawy%VuuY>Uu7e( z(Hl8-!XW3+Knq4}{3b&-Hg=IJfvYtlsakUV1Xf?cPdn7K*9T+kI<1YM{LL_pQ3M+~ z`d}E?7yOWbsVQC2e`nzD=%cS+zy1p4Z2|W^Hj2#SG82Z9O`Iav4 zrE9U!a@kcb2X3U0^XtlBix&;gYBT O0000VPaSFUNX&d->tvp|!cW zX$2|N=;$byW6jLW7+(Ivy#Sb=o;Ed2v#Oh6G8^PsXRE8Mzj`{Vax)G2F zNCYGT5&?;TL_i`Sr5WOj10u6R*|Du}ZEY>tJfg%?(?GCoNA4ku3`nZFySwfD1lEy& z&d$zi2Z)-Jqd{2Y zbSHko?<9s+sR|fMIY_*hy8;2-B?i3kTb|k5+Y6;YC+D6Zf+QfT0Ekk41XDC6_zBOh z6-Md{nS=ti@Uy&#fKtgLJhKk`

J8nliM4NMV^s`JHZle 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

q5N@AdcP@M@g=%0Gon5UwkE&! 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 Bhw=ab literal 0 HcmV?d00001 diff --git a/src-tauri/icons/icon.ico b/src-tauri/icons/icon.ico new file mode 100644 index 0000000000000000000000000000000000000000..7ea8e8fa62d03cdf2ad4ca88821ade097682e429 GIT binary patch literal 12572 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 literal 0 HcmV?d00001 diff --git a/src-tauri/src/lib.rs b/src-tauri/src/lib.rs index 6599b5f..ecfe5be 100644 --- a/src-tauri/src/lib.rs +++ b/src-tauri/src/lib.rs @@ -72,6 +72,18 @@ pub fn run() { // im Tauri-Fenster einen echten Save-Dialog zeigen statt still zu laden. .plugin(tauri_plugin_dialog::init()) .plugin(tauri_plugin_fs::init()) + // Selbst-Update: prueft beim Start gegen `endpoints` aus tauri.conf.json + // (Gitea-Release-Asset `latest.json`), Installation via JS-Seite + // (@tauri-apps/plugin-updater). `tauri_plugin_process` liefert `relaunch()` + // fuer den Neustart nach der Installation. + .plugin(tauri_plugin_updater::Builder::new().build()) + .plugin(tauri_plugin_process::init()) + // HTTP-Requests aus der Webview (Versionsverlauf, versions.json vom + // selben Gitea-Release) ohne Browser-CORS-Einschraenkung; Shell: oeffnet + // den DMG-Download einer aelteren Version im System-Browser (Rollback, + // s. src/update/checkForUpdate.ts). + .plugin(tauri_plugin_http::init()) + .plugin(tauri_plugin_shell::init()) // Haelt die pro Instanz offen gelockten Projektdatei-Handles (lock.rs). .manage(lock::LockState::default()) .setup(|_app| { diff --git a/src-tauri/tauri.conf.json b/src-tauri/tauri.conf.json index d1308db..daeed46 100644 --- a/src-tauri/tauri.conf.json +++ b/src-tauri/tauri.conf.json @@ -1,6 +1,6 @@ { "$schema": "https://schema.tauri.app/config/2", - "productName": "Dossier", + "productName": "dossier", "version": "0.1.0", "identifier": "ch.dossier.cad", "build": { @@ -11,7 +11,7 @@ "windows": [ { "label": "main", - "title": "Dossier", + "title": "dossier", "width": 1400, "height": 900, "dragDropEnabled": false, @@ -27,6 +27,21 @@ "bundle": { "active": true, "targets": "all", - "icon": ["icons/icon.png"] + "createUpdaterArtifacts": true, + "icon": [ + "icons/32x32.png", + "icons/128x128.png", + "icons/128x128@2x.png", + "icons/icon.icns", + "icons/icon.ico" + ] + }, + "plugins": { + "updater": { + "pubkey": "dW50cnVzdGVkIGNvbW1lbnQ6IG1pbmlzaWduIHB1YmxpYyBrZXk6IEYyRDk3NkZGODQwRUJBNTQKUldSVXVnNkUvM2JaOHV2QWp0L05qZnpEUmt2TkN3ZWJBeFQwb1I0cExWNEpuZWU0UjZiazdQNU0K", + "endpoints": [ + "https://git.openbureau.ch/karim/DOSSIER-STANDALONE/releases/download/latest/latest.json" + ] + } } } diff --git a/src/App.tsx b/src/App.tsx index d343ec8..83df1f6 100644 --- a/src/App.tsx +++ b/src/App.tsx @@ -74,6 +74,7 @@ import { isTauriRuntime, } from "./io/projectFile"; import type { LockInfo } from "./io/projectFile"; +import { checkForUpdate } from "./update/checkForUpdate"; import type { PlanViewHandle, PlanSelection, @@ -541,6 +542,13 @@ export default function App() { return () => setDxfImportTrigger(null); }, []); + // Selbst-Update: einmalig beim Start prüfen (still — meldet sich nur bei + // einem gefundenen Update oder einem echten Fehler, s. checkForUpdate.ts). + // No-op ausserhalb von Tauri (Vite-Dev-Server im Browser). + useEffect(() => { + checkForUpdate(true); + }, []); + // Panel-Layout (Docks/Tabs/Größen) — aus dem Store-Slice (Init lädt aus // localStorage + reconcile). Bei jeder Änderung zurückspeichern. const layout = useStore((s) => s.layout); diff --git a/src/i18n/de.ts b/src/i18n/de.ts index aad961e..a7912bc 100644 --- a/src/i18n/de.ts +++ b/src/i18n/de.ts @@ -140,7 +140,7 @@ export const de = { "menu.native.view": "Ansicht", "menu.native.window": "Fenster", "menu.native.panels": "Panels", - "menu.native.about": "Über Dossier", + "menu.native.about": "Über dossier", "menu.native.quit": "Beenden", // ── Layout-Menü (Topbar) ───────────────────────────────────────────────── @@ -1318,12 +1318,22 @@ export const de = { "exportSave.fmt.stl": "STL (3D-Mesh)", "about.title": "Über dossier", "about.version": "Version", - "about.desc": "Open-Source-CAAD (Computer Aided Architecture Design) — schöne, normgerechte Pläne aus einem semantischen Gebäudemodell. Als Desktop-App (vollständige Fassung) und im Browser zugänglich.", + "about.desc": "Open Source Computer Aided Architecture Design — 2D-Vektordesign sowie normgerechte Pläne aus einem semantischen Gebäudemodell.", "about.copyright": "© 2026 Karim Gabriele Varano", "about.license": "Lizenz: AGPL-3.0-or-later", - "about.suite": "Teil der openbureau-Suite", + "about.suite": "Teil von openbureau", "about.licenses": "Open-Source-Lizenzen (Drittkomponenten)", "about.close": "Schließen", + "about.checkUpdate": "Nach Updates suchen", + "about.checkingUpdate": "Suche nach Updates …", + + "update.title": "Update", + "update.upToDate": "Du hast bereits die aktuellste Version.", + "update.availableBody": "Version {version} ist verfügbar. Jetzt herunterladen und installieren? Die App startet danach neu.", + "update.installNow": "Installieren", + "update.installLater": "Später", + "update.checkFailed": "Update-Prüfung fehlgeschlagen: {error}", + "update.installFailed": "Installation fehlgeschlagen: {error}", // ── Einstellungs-Fenster ────────────────────────────────────────────────── "topbar.settings": "Einstellungen", @@ -1344,6 +1354,19 @@ export const de = { "settings.referenceElevation": "Referenzhöhe EG (m ü. M.)", "settings.referenceElevation.hint": "Nur gespeichert — wird noch nicht verwendet. Folgt für Terrain-Draping/reale Höhen relativ zum Erdgeschoss.", + "settings.section.update": "Update", + "settings.update.autoCheck": "Automatisch nach Updates suchen", + "settings.update.snooze.active": "Aktiv", + "settings.update.snooze.1day": "1 Tag pausieren", + "settings.update.snooze.1week": "1 Woche pausieren", + "settings.update.snooze.1month": "1 Monat pausieren", + "settings.update.snoozedUntil": "Pausiert bis {date}. Manuelles Suchen funktioniert weiterhin.", + "settings.update.versionHistory": "Frühere Versionen", + "settings.update.versionHistory.hint": + "Öffnet den Download im Browser — Installation bleibt manuell (ersetzt die aktuelle Version, wie beim ersten Installieren).", + "settings.update.loadingHistory": "Lade Versionsliste …", + "settings.update.noHistory": "Keine früheren Versionen verfügbar.", + "settings.update.download": "Herunterladen", // ── Drag & Drop (App-weiter Datei-Drop) ────────────────────────────────── "drop.hint": "DXF/DWG-Datei hier ablegen", diff --git a/src/i18n/en.ts b/src/i18n/en.ts index 98ee5eb..4c0a476 100644 --- a/src/i18n/en.ts +++ b/src/i18n/en.ts @@ -138,7 +138,7 @@ export const en: Record = { "menu.native.view": "View", "menu.native.window": "Window", "menu.native.panels": "Panels", - "menu.native.about": "About Dossier", + "menu.native.about": "About dossier", "menu.native.quit": "Quit", // Layout menu. @@ -1305,12 +1305,22 @@ export const en: Record = { "exportSave.fmt.stl": "STL (3D mesh)", "about.title": "About dossier", "about.version": "Version", - "about.desc": "Open-source CAAD (Computer Aided Architecture Design) — beautiful, standard-compliant drawings from a semantic building model. Available as a desktop app (full version) and in the browser.", + "about.desc": "Open Source Computer Aided Architecture Design — 2D vector design plus standards-compliant drawings from a semantic building model.", "about.copyright": "© 2026 Karim Gabriele Varano", "about.license": "License: AGPL-3.0-or-later", - "about.suite": "Part of the openbureau suite", + "about.suite": "Part of openbureau", "about.licenses": "Open-source licenses (third-party)", "about.close": "Close", + "about.checkUpdate": "Check for updates", + "about.checkingUpdate": "Checking for updates …", + + "update.title": "Update", + "update.upToDate": "You already have the latest version.", + "update.availableBody": "Version {version} is available. Download and install now? The app will restart afterwards.", + "update.installNow": "Install", + "update.installLater": "Later", + "update.checkFailed": "Update check failed: {error}", + "update.installFailed": "Installation failed: {error}", // Settings dialog. "topbar.settings": "Settings", @@ -1331,6 +1341,19 @@ export const en: Record = { "settings.referenceElevation": "Ground floor reference elevation (m a.s.l.)", "settings.referenceElevation.hint": "Stored only — not used yet. Terrain draping / real-world elevations relative to the ground floor will follow.", + "settings.section.update": "Update", + "settings.update.autoCheck": "Check for updates automatically", + "settings.update.snooze.active": "Active", + "settings.update.snooze.1day": "Pause for 1 day", + "settings.update.snooze.1week": "Pause for 1 week", + "settings.update.snooze.1month": "Pause for 1 month", + "settings.update.snoozedUntil": "Paused until {date}. Manual checks still work.", + "settings.update.versionHistory": "Earlier versions", + "settings.update.versionHistory.hint": + "Opens the download in your browser — installation stays manual (replaces the current version, same as the first install).", + "settings.update.loadingHistory": "Loading version list …", + "settings.update.noHistory": "No earlier versions available.", + "settings.update.download": "Download", // Drag & drop (app-wide file drop). "drop.hint": "Drop a DXF/DWG file here", diff --git a/src/native/appMenu.ts b/src/native/appMenu.ts index ab68d0e..a0288e2 100644 --- a/src/native/appMenu.ts +++ b/src/native/appMenu.ts @@ -319,14 +319,27 @@ export function useNativeAppMenu( // macOS: der allererste Eintrag ist das App-Menü (Über/Beenden). Ohne ihn // rutscht „Datei" an die Stelle, an der macOS sonst den App-Namen zeigt. - // „Über Dossier" nutzt das NATIVE macOS-Info-Fenster (PredefinedMenuItem + // „Über dossier" nutzt das NATIVE macOS-Info-Fenster (PredefinedMenuItem // „About") statt des eigenen In-App-Dialogs (AboutDialog in TopBar.tsx) — // an dieser Stelle erwartet macOS exakt diesen Eintrag, kein Custom-Dialog. + // Metadaten spiegeln den In-App-Dialog: kleingeschriebener Name „dossier", + // Beschreibung + Lizenz/Suite als `credits` (macOS zeigt sie als Textblock + // unter der Version), Copyright unten. Das Icon zieht macOS aus dem Bundle + // (tauri.conf.json bundle.icon → icon.icns). Auf macOS NICHT unterstützt + // und daher weggelassen: authors/comments/license/website. const appMenu = await Submenu.new({ - text: "Dossier", + text: "dossier", items: [ await PredefinedMenuItem.new({ - item: { About: { name: "Dossier", version: APP_VERSION } }, + item: { + About: { + name: "dossier", + version: APP_VERSION, + shortVersion: APP_VERSION, + copyright: t("about.copyright"), + credits: `${t("about.desc")}\n\n${t("about.license")} · ${t("about.suite")}`, + }, + }, text: t("menu.native.about"), }), await PredefinedMenuItem.new({ item: "Separator" }), diff --git a/src/native/contextImportWindow.ts b/src/native/contextImportWindow.ts index 7b7627d..c051100 100644 --- a/src/native/contextImportWindow.ts +++ b/src/native/contextImportWindow.ts @@ -41,7 +41,7 @@ export async function openContextImportWindowNative(): Promise { } new WebviewWindow(CONTEXT_IMPORT_WINDOW_LABEL, { url: "index.html?window=context-import", - title: "Standort importieren — Dossier", + title: "Standort importieren — dossier", width: 480, height: 680, minWidth: 400, diff --git a/src/native/drawingLevelsWindow.ts b/src/native/drawingLevelsWindow.ts index 770a2c8..6438a32 100644 --- a/src/native/drawingLevelsWindow.ts +++ b/src/native/drawingLevelsWindow.ts @@ -51,7 +51,7 @@ export async function openDrawingLevelsWindowNative(): Promise { } new WebviewWindow(DRAWING_LEVELS_WINDOW_LABEL, { url: "index.html?window=drawing-levels", - title: "Zeichnungsebenen — Dossier", + title: "Zeichnungsebenen — dossier", width: 340, height: 560, minWidth: 260, diff --git a/src/native/layerSettingsWindow.ts b/src/native/layerSettingsWindow.ts index 5727ca2..4f3ca3b 100644 --- a/src/native/layerSettingsWindow.ts +++ b/src/native/layerSettingsWindow.ts @@ -54,7 +54,7 @@ export async function openLayerSettingsWindowNative(code: string): Promise } new WebviewWindow(LAYER_SETTINGS_WINDOW_LABEL, { url: `index.html?window=layer-settings&code=${encodeURIComponent(code)}`, - title: "Ebeneneinstellungen — Dossier", + title: "Ebeneneinstellungen — dossier", width: 360, height: 420, minWidth: 300, diff --git a/src/native/resourceWindow.ts b/src/native/resourceWindow.ts index 1c79bd6..40d6c0b 100644 --- a/src/native/resourceWindow.ts +++ b/src/native/resourceWindow.ts @@ -47,7 +47,7 @@ export async function openResourceWindowNative(initialTab?: TabId): Promise { } new WebviewWindow(SETTINGS_WINDOW_LABEL, { url: "index.html?window=settings", - title: "Einstellungen — Dossier", + title: "Einstellungen — dossier", width: 520, height: 640, minWidth: 420, diff --git a/src/styles.css b/src/styles.css index 0513f4f..f370816 100644 --- a/src/styles.css +++ b/src/styles.css @@ -630,9 +630,9 @@ body { border: 1px solid var(--border, #3a3f47); box-shadow: 0 12px 40px rgba(0, 0, 0, 0.5); color: var(--ink, #e6e8ea); - /* Der Dialog ist ein DOM-Kind der `.topbar` (white-space: nowrap) — ohne - dieses Reset liefe der mehrzeilige Beschreibungstext einzeilig aus dem - Dialog heraus. Hier wieder normalen Zeilenumbruch erzwingen. */ + /* Defensiv gesetzt (unabhängig davon, ob ein Vorfahre white-space: nowrap + setzt) — ohne dieses Reset liefe der mehrzeilige Beschreibungstext + einzeilig aus dem Dialog heraus. */ white-space: normal; } .about-brand { @@ -676,9 +676,15 @@ body { line-height: 1.6; color: var(--label, #c4c8cd); } -.about-close { - appearance: none; +.about-actions { + display: flex; + justify-content: flex-end; + gap: 8px; margin-top: 18px; +} +.about-close, +.about-check-update { + appearance: none; padding: 6px 14px; border-radius: 6px; border: 1px solid var(--border, #3a3f47); @@ -687,9 +693,14 @@ body { cursor: pointer; font-size: 12px; } -.about-close:hover { +.about-close:hover, +.about-check-update:hover:not(:disabled) { background: var(--accent-dim, #33383f); } +.about-check-update:disabled { + opacity: 0.6; + cursor: default; +} .tag { font-weight: 500; @@ -5392,6 +5403,35 @@ body { outline: none; box-shadow: 0 0 0 2px var(--accent-border); } +.settings-subsection { + display: flex; + flex-direction: column; + gap: 6px; + margin-top: 14px; + padding-top: 12px; + border-top: 1px solid var(--line); +} +.settings-select { + font-family: inherit; + font-size: 13px; + padding: 6px 9px; + border: none; + border-radius: 7px; + background: var(--field-bg); + color: var(--ink); +} +.settings-select:focus { + outline: none; + box-shadow: 0 0 0 2px var(--accent-border); +} +.settings-history-row { + display: flex; + align-items: center; + gap: 8px; +} +.settings-history-row .settings-select { + flex: 1; +} /* ── App-weites Drop-Feedback ────────────────────────────────────────────── Dezenter Rahmen + Hinweis, solange eine Datei über die App gezogen wird. */ diff --git a/src/ui/SettingsDialog.tsx b/src/ui/SettingsDialog.tsx index 028d459..06f531a 100644 --- a/src/ui/SettingsDialog.tsx +++ b/src/ui/SettingsDialog.tsx @@ -14,9 +14,25 @@ import { t } from "../i18n"; import { ACCENT_SWATCHES } from "../theme/accents"; import { ColorHexField } from "./ColorHexField"; import { LayoutMenu } from "./LayoutMenu"; +import { APP_VERSION } from "./TopBar"; import type { RendererMode } from "./StatusBar"; import type { LayoutState } from "../panels/types"; import type { ThemeMode } from "../theme/themeMode"; +import { checkForUpdate, getUpdateSnoozeUntil, setUpdateSnooze } from "../update/checkForUpdate"; +import { getRunningVersion } from "../update/version"; +import { + fetchVersionHistory, + openVersionDownload, + type VersionEntry, +} from "../update/versionHistory"; + +/** Pausier-Optionen fuer den stillen Start-Check (s. checkForUpdate.ts). */ +const SNOOZE_OPTIONS = [ + { id: "active", ms: null }, + { id: "1day", ms: 24 * 60 * 60 * 1000 }, + { id: "1week", ms: 7 * 24 * 60 * 60 * 1000 }, + { id: "1month", ms: 30 * 24 * 60 * 60 * 1000 }, +] as const; export interface SettingsDialogProps { /** Hell/Dunkel — Standard ist Hell (siehe theme/themeMode.ts). */ @@ -71,6 +87,22 @@ export function SettingsDialog({ onClose, windowed = false, }: SettingsDialogProps) { + const [checkingUpdate, setCheckingUpdate] = useState(false); + const [runningVersion, setRunningVersion] = useState(null); + const [snoozeUntil, setSnoozeUntilState] = useState(() => getUpdateSnoozeUntil()); + const [versionHistory, setVersionHistory] = useState(null); + const [selectedTag, setSelectedTag] = useState(""); + + useEffect(() => { + void getRunningVersion().then(setRunningVersion); + }, []); + useEffect(() => { + void fetchVersionHistory().then((entries) => { + setVersionHistory(entries); + if (entries.length > 0) setSelectedTag(entries[0].tag); + }); + }, []); + useEffect(() => { const onKey = (e: KeyboardEvent) => { if (e.key === "Escape") onClose(); @@ -208,6 +240,97 @@ export function SettingsDialog({ />

{t("settings.referenceElevation.hint")}
+ +
+
{t("settings.section.update")}
+
+ {t("about.version")} {runningVersion ?? APP_VERSION} +
+ + +
+ + + {snoozeUntil != null && ( +
+ {t("settings.update.snoozedUntil", { + date: new Date(snoozeUntil).toLocaleDateString(), + })} +
+ )} +
+ +
+ + {versionHistory == null ? ( +
{t("settings.update.loadingHistory")}
+ ) : versionHistory.length === 0 ? ( +
{t("settings.update.noHistory")}
+ ) : ( + <> +
+ + +
+
{t("settings.update.versionHistory.hint")}
+ + )} +
+
{!windowed && ( diff --git a/src/ui/TopBar.tsx b/src/ui/TopBar.tsx index a6957af..d7afb09 100644 --- a/src/ui/TopBar.tsx +++ b/src/ui/TopBar.tsx @@ -10,6 +10,8 @@ import type { Project } from "../model/types"; import { t } from "../i18n"; +import { checkForUpdate } from "../update/checkForUpdate"; +import { getRunningVersion } from "../update/version"; import { useEffect, useRef, useState } from "react"; import { createPortal } from "react-dom"; import { Dropdown } from "./Dropdown"; @@ -1020,6 +1022,11 @@ export const APP_VERSION = "0.1.0"; * Wortmarke. Klick ausserhalb / Esc schliesst. */ function AboutDialog({ onClose }: { onClose: () => void }) { + const [checkingUpdate, setCheckingUpdate] = useState(false); + const [runningVersion, setRunningVersion] = useState(null); + useEffect(() => { + void getRunningVersion().then(setRunningVersion); + }, []); useEffect(() => { const onKey = (e: KeyboardEvent) => { if (e.key === "Escape") onClose(); @@ -1028,7 +1035,14 @@ function AboutDialog({ onClose }: { onClose: () => void }) { return () => document.removeEventListener("keydown", onKey); }, [onClose]); - return ( + // Per Portal an document.body statt als DOM-Kind der .topbar rendern: die + // .topbar bildet (position:relative + z-index) einen eigenen Stacking- + // Context, der das hohe z-index:1000 von .about-overlay einsperrt — andere + // z-index:2-Elemente ausserhalb (z. B. das Lineal-Overlay im Grundriss) + // konnten dadurch trotzdem durch den abgedunkelten Hintergrund "durch- + // scheinen". Als Portal-Kind von body liegt der Dialog in keinem fremden + // Stacking-Context mehr. + return createPortal(
void }) { dossier.
- {t("about.version")} {APP_VERSION} + {t("about.version")} {runningVersion ?? APP_VERSION}

{t("about.desc")}

@@ -1059,11 +1073,29 @@ function AboutDialog({ onClose }: { onClose: () => void }) {
  • LibreDWG — GPL-3.0
  • acadrust — MPL-2.0
  • - +
    + + +
    -
    + , + document.body, ); } diff --git a/src/update/checkForUpdate.ts b/src/update/checkForUpdate.ts new file mode 100644 index 0000000..7716054 --- /dev/null +++ b/src/update/checkForUpdate.ts @@ -0,0 +1,81 @@ +// Selbst-Update: fragt `endpoints` aus tauri.conf.json ab (Gitea-Release-Asset +// `latest.json`, per `/releases/latest/download/` immer der aktuellste Release +// dieses Repos — die URL selbst muss bei neuen Versionen nicht angepasst +// werden). Nur unter Tauri aktiv; im reinen Browser/Vite-Dev-Server gibt es +// weder die Plugins noch etwas zu aktualisieren. +import { ask, message } from "@tauri-apps/plugin-dialog"; +import { t } from "../i18n"; +import { isTauriRuntime } from "../io/projectFile"; + +/** localStorage-Key fuer die Update-Pause (s. `getUpdateSnoozeUntil`). */ +const SNOOZE_KEY = "dossier.updateSnoozeUntil"; + +/** Ende der aktuellen Update-Pause (ms epoch), `null` wenn keine aktiv/abgelaufen. */ +export function getUpdateSnoozeUntil(): number | null { + const raw = localStorage.getItem(SNOOZE_KEY); + if (!raw) return null; + const n = Number(raw); + if (!Number.isFinite(n) || n <= Date.now()) return null; + return n; +} + +/** Pausiert den STILLEN Start-Check bis `untilMs` (epoch); `null` hebt die Pause auf. + * Der manuelle Check (Button in Settings/About) ignoriert die Pause immer — + * das ist eine explizite Nutzeraktion. */ +export function setUpdateSnooze(untilMs: number | null): void { + if (untilMs == null) localStorage.removeItem(SNOOZE_KEY); + else localStorage.setItem(SNOOZE_KEY, String(untilMs)); +} + +/** + * Prueft auf eine neue Version. `silent=true` (Start-Check) meldet sich nur + * bei einem GEFUNDENEN Update oder einem echten Fehler — nicht bei „aktuell", + * damit der App-Start nicht bei jedem Start einen Dialog zeigt. Respektiert + * ausserdem eine aktive Update-Pause (s. `setUpdateSnooze`). Der manuelle + * Aufruf (About-/Settings-Dialog, `silent=false`) meldet in jedem Fall ein + * Ergebnis und ignoriert die Pause. + */ +export async function checkForUpdate(silent: boolean): Promise { + if (!isTauriRuntime()) return; + if (silent && getUpdateSnoozeUntil() != null) return; + const { check } = await import("@tauri-apps/plugin-updater"); + let update: Awaited>; + try { + update = await check(); + } catch (err) { + if (!silent) { + await message(t("update.checkFailed", { error: String(err) }), { + title: t("update.title"), + kind: "error", + }); + } + return; + } + if (!update) { + if (!silent) { + await message(t("update.upToDate"), { + title: t("update.title"), + kind: "info", + }); + } + return; + } + const install = await ask(t("update.availableBody", { version: update.version }), { + title: t("update.title"), + kind: "info", + okLabel: t("update.installNow"), + cancelLabel: t("update.installLater"), + }); + if (!install) return; + try { + await update.downloadAndInstall(); + } catch (err) { + await message(t("update.installFailed", { error: String(err) }), { + title: t("update.title"), + kind: "error", + }); + return; + } + const { relaunch } = await import("@tauri-apps/plugin-process"); + await relaunch(); +} diff --git a/src/update/version.ts b/src/update/version.ts new file mode 100644 index 0000000..599d6cf --- /dev/null +++ b/src/update/version.ts @@ -0,0 +1,12 @@ +// Tatsaechlich laufende App-Version (aus Tauris eigenen Metadaten, NICHT der +// manuell gepflegte `APP_VERSION`-String in ui/TopBar.tsx) — vermeidet, dass +// die Anzeige von der echten Installation abweicht, falls jemand beim +// Versionsbump eine der beiden Stellen vergisst. +import { isTauriRuntime } from "../io/projectFile"; + +/** `null` ausserhalb von Tauri (Vite-Dev-Server im Browser, keine Installation). */ +export async function getRunningVersion(): Promise { + if (!isTauriRuntime()) return null; + const { getVersion } = await import("@tauri-apps/api/app"); + return getVersion(); +} diff --git a/src/update/versionHistory.ts b/src/update/versionHistory.ts new file mode 100644 index 0000000..f55afa4 --- /dev/null +++ b/src/update/versionHistory.ts @@ -0,0 +1,48 @@ +// Versionsverlauf fuer den manuellen Rollback (Settings → Update): Tauris +// Updater-Plugin kennt nur „neuere Version installieren", kein Downgrade- +// Manifest mit Auswahl. Statt das Plugin zu verbiegen, pflegen wir einen +// eigenen, schlanken Index `versions.json` (liegt auf demselben Gitea- +// Release „latest" wie `latest.json`, s. checkForUpdate.ts) und bieten pro +// Eintrag nur den DMG-Download im System-Browser an — Installation bleibt +// der gewohnte manuelle Schritt (DMG oeffnen, App in Applications ersetzen). +import { isTauriRuntime } from "../io/projectFile"; + +export interface VersionEntry { + version: string; + /** Git-Tag des Releases, z. B. "v0.1.0". */ + tag: string; + /** ISO-Datum. */ + pub_date: string; + notes: string; + /** Dateiname der DMG innerhalb dieses Release-Tags. */ + dmg: string; +} + +const VERSIONS_URL = + "https://git.openbureau.ch/karim/DOSSIER-STANDALONE/releases/download/latest/versions.json"; + +/** Leeres Array ausserhalb von Tauri oder bei Netzwerk-/Parsefehlern (keine + * Wurf-Semantik hier — der Aufrufer zeigt einfach eine leere Liste). */ +export async function fetchVersionHistory(): Promise { + if (!isTauriRuntime()) return []; + try { + const { fetch: tauriFetch } = await import("@tauri-apps/plugin-http"); + const res = await tauriFetch(VERSIONS_URL); + if (!res.ok) return []; + const data = (await res.json()) as VersionEntry[]; + return Array.isArray(data) ? data : []; + } catch { + return []; + } +} + +export function downloadUrlFor(entry: VersionEntry): string { + return `https://git.openbureau.ch/karim/DOSSIER-STANDALONE/releases/download/${entry.tag}/${entry.dmg}`; +} + +/** Oeffnet den DMG-Download im System-Standardbrowser (kein In-App-Download — + * Installation bleibt manuell). */ +export async function openVersionDownload(entry: VersionEntry): Promise { + const { open } = await import("@tauri-apps/plugin-shell"); + await open(downloadUrlFor(entry)); +}