From ef13cb436550df32ea1adef4e0520172a4acb19c Mon Sep 17 00:00:00 2001 From: Aleksandr Vasilenko Date: Wed, 20 Nov 2024 17:01:10 -0600 Subject: [PATCH 1/5] New endpoint for Tauri v2 updates --- package-lock.json | 61 +++++++-------------------------------- package.json | 2 +- src-tauri/tauri.conf.json | 4 +-- 3 files changed, 13 insertions(+), 54 deletions(-) diff --git a/package-lock.json b/package-lock.json index bcd3365..b0d798a 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "flc", - "version": "6.0.0", + "version": "6.1.0", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "flc", - "version": "6.0.0", + "version": "6.1.0", "license": "MIT", "dependencies": { "@fontsource-variable/inter": "^5.1.0" @@ -34,7 +34,7 @@ "mode-watcher": "^0.5.0", "prettier": "^3.3.3", "prettier-plugin-svelte": "^3.2.8", - "svelte": "^5.2.5", + "svelte": "^5.2.7", "svelte-check": "^4.0.9", "svelte-sonner": "^0.3.28", "tailwind-merge": "^2.5.4", @@ -1801,19 +1801,6 @@ "node": ">= 8" } }, - "node_modules/anymatch/node_modules/picomatch": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", - "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=8.6" - }, - "funding": { - "url": "https://github.com/sponsors/jonschlinkert" - } - }, "node_modules/arg": { "version": "5.0.2", "resolved": "https://registry.npmjs.org/arg/-/arg-5.0.2.tgz", @@ -3178,19 +3165,6 @@ "node": ">=8.6" } }, - "node_modules/micromatch/node_modules/picomatch": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", - "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=8.6" - }, - "funding": { - "url": "https://github.com/sponsors/jonschlinkert" - } - }, "node_modules/minimatch": { "version": "3.1.2", "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", @@ -3458,15 +3432,13 @@ "license": "ISC" }, "node_modules/picomatch": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.2.tgz", - "integrity": "sha512-M7BAV6Rlcy5u+m6oPhAPFgJTzAioX/6B0DxyvDlo9l8+T3nLKbrczg2WLUyzd45L8RqfUMyGPzekbMvX2Ldkwg==", + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", + "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", "dev": true, "license": "MIT", - "optional": true, - "peer": true, "engines": { - "node": ">=12" + "node": ">=8.6" }, "funding": { "url": "https://github.com/sponsors/jonschlinkert" @@ -4160,9 +4132,9 @@ } }, "node_modules/svelte": { - "version": "5.2.5", - "resolved": "https://registry.npmjs.org/svelte/-/svelte-5.2.5.tgz", - "integrity": "sha512-D33RkKYF4AFIgM+HrItxFudmWrXOLaua8vW3Mq7bObn7UwRn6zJPZ58bEIlj8wEYfi08n8VVvTk8dCLVHNnikQ==", + "version": "5.2.7", + "resolved": "https://registry.npmjs.org/svelte/-/svelte-5.2.7.tgz", + "integrity": "sha512-cEhPGuLHiH2+Z8B1FwQgiZJgA39uUmJR4516TKrM5zrp0/cuwJkfhUfcTxhAkznanAF5fXUKzvYR4o+Ksx3ZCQ==", "dev": true, "license": "MIT", "dependencies": { @@ -4428,19 +4400,6 @@ "node": ">= 6" } }, - "node_modules/tailwindcss/node_modules/picomatch": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", - "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=8.6" - }, - "funding": { - "url": "https://github.com/sponsors/jonschlinkert" - } - }, "node_modules/tailwindcss/node_modules/postcss-load-config": { "version": "4.0.2", "resolved": "https://registry.npmjs.org/postcss-load-config/-/postcss-load-config-4.0.2.tgz", diff --git a/package.json b/package.json index 7983994..1afb47b 100644 --- a/package.json +++ b/package.json @@ -39,7 +39,7 @@ "mode-watcher": "^0.5.0", "prettier": "^3.3.3", "prettier-plugin-svelte": "^3.2.8", - "svelte": "^5.2.5", + "svelte": "^5.2.7", "svelte-check": "^4.0.9", "svelte-sonner": "^0.3.28", "tailwind-merge": "^2.5.4", diff --git a/src-tauri/tauri.conf.json b/src-tauri/tauri.conf.json index 6c264eb..7d352d6 100644 --- a/src-tauri/tauri.conf.json +++ b/src-tauri/tauri.conf.json @@ -34,7 +34,7 @@ "category": "RolePlayingGame", "copyright": "phenomen", "targets": ["msi", "app", "dmg", "appimage"], - "createUpdaterArtifacts": "v1Compatible", + "createUpdaterArtifacts": true, "icon": [ "icons/32x32.png", "icons/128x128.png", @@ -46,7 +46,7 @@ "plugins": { "updater": { "active": true, - "endpoints": ["https://flc.ruleplaying.com/flc.json"], + "endpoints": ["https://flc.ruleplaying.com/flc2.json"], "pubkey": "dW50cnVzdGVkIGNvbW1lbnQ6IG1pbmlzaWduIHB1YmxpYyBrZXk6IDVEM0E0Q0VBNDJGMDI2RTEKUldUaEp2QkM2a3c2WFNNTUpNbDJxVjJIZXdXUnh1MmhuOTdTNDM3Tk1DeFEza3JHRHJzVVlIb2QK", "windows": { "installMode": "basicUi" From 461a0e72436c669fb5a8c4ce1dcc991651b2443f Mon Sep 17 00:00:00 2001 From: Aleksandr Vasilenko Date: Wed, 20 Nov 2024 17:03:15 -0600 Subject: [PATCH 2/5] Simplified URL scheme --- src/lib/scripts/servers.svelte.ts | 14 +++++--------- 1 file changed, 5 insertions(+), 9 deletions(-) diff --git a/src/lib/scripts/servers.svelte.ts b/src/lib/scripts/servers.svelte.ts index ac0c322..1ff8300 100644 --- a/src/lib/scripts/servers.svelte.ts +++ b/src/lib/scripts/servers.svelte.ts @@ -2,18 +2,14 @@ import { LocalStorage } from "$scripts/storage.svelte.js"; import { nanoid } from "nanoid"; import * as v from "valibot"; -const URLSchema = v.union( - [ - v.pipe(v.string(), v.trim(), v.url(), v.startsWith("http://")), - v.pipe(v.string(), v.trim(), v.url(), v.startsWith("https://")) - ], - "Please enter a correct URL starting with either http:// or https://" -); - const ServerSchema = v.object({ id: v.string(), label: v.pipe(v.string(), v.trim(), v.minLength(1, "Please enter a server name")), - url: URLSchema, + url: v.pipe( + v.string(), + v.trim(), + v.regex(/^https?:\/\//, "Please enter a correct URL starting with either http:// or https://") + ), notes: v.optional(v.string()) }); From bb95a13ddf6aad3fea32dbf690026045ba578811 Mon Sep 17 00:00:00 2001 From: Aleksandr Vasilenko Date: Wed, 20 Nov 2024 17:04:07 -0600 Subject: [PATCH 3/5] Optimized fetch; Status icons --- src/lib/components/NodeserverCard.svelte | 19 ++++-- src/lib/components/ServerCard.svelte | 86 +++++++++++++++--------- 2 files changed, 68 insertions(+), 37 deletions(-) diff --git a/src/lib/components/NodeserverCard.svelte b/src/lib/components/NodeserverCard.svelte index 4702a05..f7925bb 100644 --- a/src/lib/components/NodeserverCard.svelte +++ b/src/lib/components/NodeserverCard.svelte @@ -90,13 +90,21 @@ -
+

{server.label}

@@ -191,6 +199,9 @@ class="w-full h-full bg-primary text-primary-foreground overflow-hidden max-w-16 hover:bg-primary/90 border-primary border" title="Load Server Settings" > - + diff --git a/src/lib/components/ServerCard.svelte b/src/lib/components/ServerCard.svelte index 9fc3022..8c76ac1 100644 --- a/src/lib/components/ServerCard.svelte +++ b/src/lib/components/ServerCard.svelte @@ -14,7 +14,11 @@ import Settings from "lucide-svelte/icons/settings"; import X from "lucide-svelte/icons/x"; import LogIn from "lucide-svelte/icons/log-in"; - import Dot from "lucide-svelte/icons/dot"; + import Smile from "lucide-svelte/icons/smile"; + import Zap from "lucide-svelte/icons/zap"; + import Dices from "lucide-svelte/icons/dices"; + import Hexagon from "lucide-svelte/icons/hexagon"; + import Globe from "lucide-svelte/icons/globe"; import { deleteServer, updateServer } from "$scripts/servers.svelte.js"; import { openWebview } from "$scripts/webview.svelte.js"; @@ -67,19 +71,6 @@ } } - async function checkOnline() { - online = false; - - const response = await fetch(url, { - method: "GET" - }); - - if (response.statusText === "OK" || response.status === 200) { - online = true; - await checkStatus(); - } - } - async function checkStatus() { const response = await fetch(`${url}${url.endsWith("/") ? "" : "/"}api/status`, { method: "GET", @@ -94,7 +85,7 @@ } onMount(async () => { - await checkOnline(); + await checkStatus(); }); @@ -102,13 +93,21 @@ -
- - - -
+
+

{server.label}

-
- {#if status}Online - V{status.version} - {#if status.users}{status.users} users{/if} - {#if status.system}{status.system.toUpperCase()}{/if} +
+ {#if status} + Online + {status.version} + {#if status.system}{status.system.toUpperCase()}{/if} + {#if status.users !== undefined}{status.users}{/if} {:else} - Offline{/if} + + Offline{/if}
@@ -184,6 +201,9 @@ class="w-full h-full bg-primary text-primary-foreground overflow-hidden max-w-16 hover:bg-primary/90 border-primary border" title="Join Server" > - + From dc8903b39eff3525eaa9e6fac6c23305ff8f4ba0 Mon Sep 17 00:00:00 2001 From: phenomen Date: Wed, 20 Nov 2024 18:56:30 -0600 Subject: [PATCH 4/5] Attempt to enable SharedArrayBuffer --- src-tauri/tauri.conf.json | 4 ++++ vite.config.js | 4 ++++ 2 files changed, 8 insertions(+) diff --git a/src-tauri/tauri.conf.json b/src-tauri/tauri.conf.json index 7d352d6..dd795ec 100644 --- a/src-tauri/tauri.conf.json +++ b/src-tauri/tauri.conf.json @@ -25,6 +25,10 @@ } ], "security": { + "headers": { + "Cross-Origin-Opener-Policy": "same-origin", + "Cross-Origin-Embedder-Policy": "require-corp" + }, "csp": null } }, diff --git a/vite.config.js b/vite.config.js index 5ae20b6..087ac83 100644 --- a/vite.config.js +++ b/vite.config.js @@ -14,6 +14,10 @@ export default defineConfig(async () => ({ clearScreen: false, // 2. tauri expects a fixed port, fail if that port is not available server: { + headers: { + "Cross-Origin-Opener-Policy": "same-origin", + "Cross-Origin-Embedder-Policy": "require-corp" + }, port: 1420, strictPort: true, host: host || false, From 9d98c550cd7f453ab4d3ffc39069a90819ee2baf Mon Sep 17 00:00:00 2001 From: Aleksandr Vasilenko Date: Thu, 21 Nov 2024 11:16:58 -0600 Subject: [PATCH 5/5] Fixed auto-updater; Replaced tray controls with global shortcuts --- CHANGELOG.md | 9 ++ package-lock.json | 39 +++--- package.json | 15 +-- src-tauri/Cargo.lock | 35 +++++- src-tauri/Cargo.toml | 5 +- src-tauri/capabilities/default.json | 11 +- src-tauri/gen/schemas/capabilities.json | 2 +- src-tauri/gen/schemas/desktop-schema.json | 55 +++++++++ src-tauri/gen/schemas/windows-schema.json | 55 +++++++++ src-tauri/src/lib.rs | 1 + src-tauri/tauri.conf.json | 6 +- src/app.html | 2 +- src/lib/components/FoundryControls.svelte | 73 ++++++------ src/lib/components/NodeserverGrid.svelte | 2 +- src/lib/components/ServerCard.svelte | 2 +- src/lib/components/ServerGrid.svelte | 2 +- src/lib/components/Updater.svelte | 61 ++++++++++ src/lib/scripts/shortcuts.svelte.ts | 23 ++++ src/lib/scripts/tray.svelte.ts | 137 ---------------------- src/lib/scripts/webview.svelte.ts | 7 +- src/routes/+layout.svelte | 10 +- 21 files changed, 337 insertions(+), 215 deletions(-) create mode 100644 src/lib/components/Updater.svelte create mode 100644 src/lib/scripts/shortcuts.svelte.ts delete mode 100644 src/lib/scripts/tray.svelte.ts diff --git a/CHANGELOG.md b/CHANGELOG.md index 6c75e8e..8bf0c8b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,14 @@ # CHANGELOG +## v6.2.0 + +> [!WARNING] +> Prior to 6.2.0 auto-updater was not working. Now it's fixed but you need to download and install this version manually. + +- Fixed Auto-Updater and added a new update controls. +- Replaced tray/buttons controls for Fullscreen and Zoom with Global Shortcuts (Ctrl + ...) and added Help button. +- Added icons to server status details. + ## v6.1.0 - Added detailed status of server, if available: version, system, users. diff --git a/package-lock.json b/package-lock.json index b0d798a..c2d45fd 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "flc", - "version": "6.1.0", + "version": "6.0.0", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "flc", - "version": "6.1.0", + "version": "6.0.0", "license": "MIT", "dependencies": { "@fontsource-variable/inter": "^5.1.0" @@ -17,11 +17,12 @@ "@sveltejs/vite-plugin-svelte": "^4.0.1", "@tauri-apps/api": "^2.1.1", "@tauri-apps/cli": "^2.1.0", - "@tauri-apps/plugin-dialog": "~2.0.1", - "@tauri-apps/plugin-http": "~2.0.1", - "@tauri-apps/plugin-os": "~2.0.0", - "@tauri-apps/plugin-shell": "~2.0.1", - "@tauri-apps/plugin-updater": "~2.0.0", + "@tauri-apps/plugin-dialog": "^2.0.1", + "@tauri-apps/plugin-global-shortcut": "^2.0.0", + "@tauri-apps/plugin-http": "^2.0.1", + "@tauri-apps/plugin-os": "^2.0.0", + "@tauri-apps/plugin-shell": "^2.0.1", + "@tauri-apps/plugin-updater": "^2.0.0", "@types/eslint": "^9.6.1", "autoprefixer": "^10.4.20", "bits-ui": "^1.0.0-next.63", @@ -33,7 +34,7 @@ "lucide-svelte": "^0.460.1", "mode-watcher": "^0.5.0", "prettier": "^3.3.3", - "prettier-plugin-svelte": "^3.2.8", + "prettier-plugin-svelte": "^3.3.0", "svelte": "^5.2.7", "svelte-check": "^4.0.9", "svelte-sonner": "^0.3.28", @@ -1405,6 +1406,16 @@ "@tauri-apps/api": "^2.0.0" } }, + "node_modules/@tauri-apps/plugin-global-shortcut": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/@tauri-apps/plugin-global-shortcut/-/plugin-global-shortcut-2.0.0.tgz", + "integrity": "sha512-pnB4CUwFVjg4twtBSxoLJ4uLFTYxsvOdC1zIbG581pYzhYatOl6mjB+ijD5SSXgiS/jNoqMcfkOF9PWAisurew==", + "dev": true, + "license": "MIT OR Apache-2.0", + "dependencies": { + "@tauri-apps/api": "^2.0.0" + } + }, "node_modules/@tauri-apps/plugin-http": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/@tauri-apps/plugin-http/-/plugin-http-2.0.1.tgz", @@ -1996,9 +2007,9 @@ } }, "node_modules/caniuse-lite": { - "version": "1.0.30001680", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001680.tgz", - "integrity": "sha512-rPQy70G6AGUMnbwS1z6Xg+RkHYPAi18ihs47GH0jcxIG7wArmPgY3XbS2sRdBbxJljp3thdT8BIqv9ccCypiPA==", + "version": "1.0.30001683", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001683.tgz", + "integrity": "sha512-iqmNnThZ0n70mNwvxpEC2nBJ037ZHZUoBI5Gorh1Mw6IlEAZujEoU1tXA628iZfzm7R9FvFzxbfdgml82a3k8Q==", "dev": true, "funding": [ { @@ -3679,9 +3690,9 @@ } }, "node_modules/prettier-plugin-svelte": { - "version": "3.2.8", - "resolved": "https://registry.npmjs.org/prettier-plugin-svelte/-/prettier-plugin-svelte-3.2.8.tgz", - "integrity": "sha512-PAHmmU5cGZdnhW4mWhmvxuG2PVbbHIxUuPOdUKvfE+d4Qt2d29iU5VWrPdsaW5YqVEE0nqhlvN4eoKmVMpIF3Q==", + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/prettier-plugin-svelte/-/prettier-plugin-svelte-3.3.0.tgz", + "integrity": "sha512-iNoYiQUx4zwqbQDW/bk0WR75w+QiY4fHJQpGQ5v8Yr7X5m7YoSvs2buUnhoYFXNAL32ULVmrjPSc0vVOHJsO0Q==", "dev": true, "license": "MIT", "peerDependencies": { diff --git a/package.json b/package.json index 1afb47b..ac34c08 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "flc", - "version": "6.1.0", + "version": "6.2.0", "description": "Foundry Lightweight Client", "type": "module", "scripts": { @@ -22,11 +22,12 @@ "@sveltejs/vite-plugin-svelte": "^4.0.1", "@tauri-apps/api": "^2.1.1", "@tauri-apps/cli": "^2.1.0", - "@tauri-apps/plugin-dialog": "~2.0.1", - "@tauri-apps/plugin-http": "~2.0.1", - "@tauri-apps/plugin-os": "~2.0.0", - "@tauri-apps/plugin-shell": "~2.0.1", - "@tauri-apps/plugin-updater": "~2.0.0", + "@tauri-apps/plugin-dialog": "^2.0.1", + "@tauri-apps/plugin-global-shortcut": "^2.0.0", + "@tauri-apps/plugin-http": "^2.0.1", + "@tauri-apps/plugin-os": "^2.0.0", + "@tauri-apps/plugin-shell": "^2.0.1", + "@tauri-apps/plugin-updater": "^2.0.0", "@types/eslint": "^9.6.1", "autoprefixer": "^10.4.20", "bits-ui": "^1.0.0-next.63", @@ -38,7 +39,7 @@ "lucide-svelte": "^0.460.1", "mode-watcher": "^0.5.0", "prettier": "^3.3.3", - "prettier-plugin-svelte": "^3.2.8", + "prettier-plugin-svelte": "^3.3.0", "svelte": "^5.2.7", "svelte-check": "^4.0.9", "svelte-sonner": "^0.3.28", diff --git a/src-tauri/Cargo.lock b/src-tauri/Cargo.lock index 0228218..63689b4 100644 --- a/src-tauri/Cargo.lock +++ b/src-tauri/Cargo.lock @@ -975,13 +975,14 @@ dependencies = [ [[package]] name = "flc" -version = "6.1.0" +version = "6.0.0" dependencies = [ "serde", "serde_json", "tauri", "tauri-build", "tauri-plugin-dialog", + "tauri-plugin-global-shortcut", "tauri-plugin-http", "tauri-plugin-os", "tauri-plugin-shell", @@ -1355,6 +1356,23 @@ version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d2fabcfbdc87f4758337ca535fb41a6d701b65693ce38287d856d1674551ec9b" +[[package]] +name = "global-hotkey" +version = "0.6.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b00d88f1be7bf4cd2e61623ce08e84be2dfa4eab458e5d632d3dab95f16c1f64" +dependencies = [ + "crossbeam-channel", + "keyboard-types", + "objc2", + "objc2-app-kit", + "once_cell", + "serde", + "thiserror 1.0.69", + "windows-sys 0.59.0", + "x11-dl", +] + [[package]] name = "gobject-sys" version = "0.18.0" @@ -3993,6 +4011,21 @@ dependencies = [ "uuid", ] +[[package]] +name = "tauri-plugin-global-shortcut" +version = "2.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2c15fb7f5e4c80a73ce97217dcff27e423f496178cbcb87e13b4efe99eebb550" +dependencies = [ + "global-hotkey", + "log", + "serde", + "serde_json", + "tauri", + "tauri-plugin", + "thiserror 1.0.69", +] + [[package]] name = "tauri-plugin-http" version = "2.0.3" diff --git a/src-tauri/Cargo.toml b/src-tauri/Cargo.toml index a985174..a60aa93 100644 --- a/src-tauri/Cargo.toml +++ b/src-tauri/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "flc" -version = "6.1.0" +version = "6.2.0" description = "Foundry Lightweight Client" authors = ["phenomen"] license = "MIT" @@ -29,7 +29,7 @@ crate-type = ["staticlib", "cdylib", "rlib"] tauri-build = { version = "2", features = [] } [dependencies] -tauri = { version = "2", features = ["tray-icon", "devtools"] } +tauri = { version = "2", features = ["devtools"] } tauri-plugin-shell = "2" serde = { version = "1", features = ["derive"] } serde_json = "1" @@ -38,4 +38,5 @@ tauri-plugin-http = "2" tauri-plugin-os = "2" [target.'cfg(not(any(target_os = "android", target_os = "ios")))'.dependencies] +tauri-plugin-global-shortcut = "2" tauri-plugin-updater = "2" diff --git a/src-tauri/capabilities/default.json b/src-tauri/capabilities/default.json index cf77492..2633e89 100644 --- a/src-tauri/capabilities/default.json +++ b/src-tauri/capabilities/default.json @@ -21,7 +21,12 @@ "shell:allow-open", "shell:allow-spawn", "shell:allow-kill", - "updater:default", + "updater:default", + "updater:allow-check", + "updater:allow-download", + "updater:allow-install", + "updater:allow-download-and-install", + "global-shortcut:allow-register", "core:app:allow-default-window-icon", "core:app:allow-set-app-theme", "core:webview:allow-create-webview-window", @@ -32,6 +37,7 @@ "core:window:allow-close", "core:window:allow-create", "core:window:allow-is-fullscreen", + "core:window:allow-is-focused", "core:window:allow-set-focus", "core:window:allow-set-fullscreen", { @@ -55,6 +61,7 @@ } ], "sidecar": false - } + }, + "global-shortcut:default" ] } \ No newline at end of file diff --git a/src-tauri/gen/schemas/capabilities.json b/src-tauri/gen/schemas/capabilities.json index 2bbd301..d388593 100644 --- a/src-tauri/gen/schemas/capabilities.json +++ b/src-tauri/gen/schemas/capabilities.json @@ -1 +1 @@ -{"default":{"identifier":"default","description":"Capability for the main window","local":true,"windows":["main"],"permissions":["core:default","core:window:default","core:webview:default","dialog:default","http:default","os:default","shell:default","shell:allow-open","shell:allow-spawn","shell:allow-kill","updater:default","core:app:allow-default-window-icon","core:app:allow-set-app-theme","core:webview:allow-create-webview-window","core:webview:allow-create-webview","core:webview:allow-set-webview-focus","core:webview:allow-set-webview-size","core:webview:allow-set-webview-zoom","core:window:allow-close","core:window:allow-create","core:window:allow-is-fullscreen","core:window:allow-set-focus","core:window:allow-set-fullscreen",{"identifier":"http:default","allow":[{"url":"https://*:*"},{"url":"http://*:*"}]},{"identifier":"shell:allow-spawn","allow":[{"args":true,"cmd":"node","name":"node"}]}],"platforms":["macOS","windows","linux"]}} \ No newline at end of file +{"default":{"identifier":"default","description":"Capability for the main window","local":true,"windows":["main"],"permissions":["core:default","core:window:default","core:webview:default","dialog:default","http:default","os:default","shell:default","shell:allow-open","shell:allow-spawn","shell:allow-kill","updater:default","updater:allow-check","updater:allow-download","updater:allow-install","updater:allow-download-and-install","global-shortcut:allow-register","core:app:allow-default-window-icon","core:app:allow-set-app-theme","core:webview:allow-create-webview-window","core:webview:allow-create-webview","core:webview:allow-set-webview-focus","core:webview:allow-set-webview-size","core:webview:allow-set-webview-zoom","core:window:allow-close","core:window:allow-create","core:window:allow-is-fullscreen","core:window:allow-is-focused","core:window:allow-set-focus","core:window:allow-set-fullscreen",{"identifier":"http:default","allow":[{"url":"https://*:*"},{"url":"http://*:*"}]},{"identifier":"shell:allow-spawn","allow":[{"args":true,"cmd":"node","name":"node"}]},"global-shortcut:default"],"platforms":["macOS","windows","linux"]}} \ No newline at end of file diff --git a/src-tauri/gen/schemas/desktop-schema.json b/src-tauri/gen/schemas/desktop-schema.json index 3dac512..46d8b98 100644 --- a/src-tauri/gen/schemas/desktop-schema.json +++ b/src-tauri/gen/schemas/desktop-schema.json @@ -2027,6 +2027,61 @@ "type": "string", "const": "dialog:deny-save" }, + { + "description": "No features are enabled by default, as we believe\nthe shortcuts can be inherently dangerous and it is\napplication specific if specific shortcuts should be\nregistered or unregistered.\n", + "type": "string", + "const": "global-shortcut:default" + }, + { + "description": "Enables the is_registered command without any pre-configured scope.", + "type": "string", + "const": "global-shortcut:allow-is-registered" + }, + { + "description": "Enables the register command without any pre-configured scope.", + "type": "string", + "const": "global-shortcut:allow-register" + }, + { + "description": "Enables the register_all command without any pre-configured scope.", + "type": "string", + "const": "global-shortcut:allow-register-all" + }, + { + "description": "Enables the unregister command without any pre-configured scope.", + "type": "string", + "const": "global-shortcut:allow-unregister" + }, + { + "description": "Enables the unregister_all command without any pre-configured scope.", + "type": "string", + "const": "global-shortcut:allow-unregister-all" + }, + { + "description": "Denies the is_registered command without any pre-configured scope.", + "type": "string", + "const": "global-shortcut:deny-is-registered" + }, + { + "description": "Denies the register command without any pre-configured scope.", + "type": "string", + "const": "global-shortcut:deny-register" + }, + { + "description": "Denies the register_all command without any pre-configured scope.", + "type": "string", + "const": "global-shortcut:deny-register-all" + }, + { + "description": "Denies the unregister command without any pre-configured scope.", + "type": "string", + "const": "global-shortcut:deny-unregister" + }, + { + "description": "Denies the unregister_all command without any pre-configured scope.", + "type": "string", + "const": "global-shortcut:deny-unregister-all" + }, { "description": "This permission set configures what kind of\nfetch operations are available from the http plugin.\n\nThis enables all fetch operations but does not\nallow explicitly any origins to be fetched. This needs to\nbe manually configured before usage.\n\n#### Granted Permissions\n\nAll fetch operations are enabled.\n\n", "type": "string", diff --git a/src-tauri/gen/schemas/windows-schema.json b/src-tauri/gen/schemas/windows-schema.json index 3dac512..46d8b98 100644 --- a/src-tauri/gen/schemas/windows-schema.json +++ b/src-tauri/gen/schemas/windows-schema.json @@ -2027,6 +2027,61 @@ "type": "string", "const": "dialog:deny-save" }, + { + "description": "No features are enabled by default, as we believe\nthe shortcuts can be inherently dangerous and it is\napplication specific if specific shortcuts should be\nregistered or unregistered.\n", + "type": "string", + "const": "global-shortcut:default" + }, + { + "description": "Enables the is_registered command without any pre-configured scope.", + "type": "string", + "const": "global-shortcut:allow-is-registered" + }, + { + "description": "Enables the register command without any pre-configured scope.", + "type": "string", + "const": "global-shortcut:allow-register" + }, + { + "description": "Enables the register_all command without any pre-configured scope.", + "type": "string", + "const": "global-shortcut:allow-register-all" + }, + { + "description": "Enables the unregister command without any pre-configured scope.", + "type": "string", + "const": "global-shortcut:allow-unregister" + }, + { + "description": "Enables the unregister_all command without any pre-configured scope.", + "type": "string", + "const": "global-shortcut:allow-unregister-all" + }, + { + "description": "Denies the is_registered command without any pre-configured scope.", + "type": "string", + "const": "global-shortcut:deny-is-registered" + }, + { + "description": "Denies the register command without any pre-configured scope.", + "type": "string", + "const": "global-shortcut:deny-register" + }, + { + "description": "Denies the register_all command without any pre-configured scope.", + "type": "string", + "const": "global-shortcut:deny-register-all" + }, + { + "description": "Denies the unregister command without any pre-configured scope.", + "type": "string", + "const": "global-shortcut:deny-unregister" + }, + { + "description": "Denies the unregister_all command without any pre-configured scope.", + "type": "string", + "const": "global-shortcut:deny-unregister-all" + }, { "description": "This permission set configures what kind of\nfetch operations are available from the http plugin.\n\nThis enables all fetch operations but does not\nallow explicitly any origins to be fetched. This needs to\nbe manually configured before usage.\n\n#### Granted Permissions\n\nAll fetch operations are enabled.\n\n", "type": "string", diff --git a/src-tauri/src/lib.rs b/src-tauri/src/lib.rs index be37d2f..efbdf7a 100644 --- a/src-tauri/src/lib.rs +++ b/src-tauri/src/lib.rs @@ -7,6 +7,7 @@ fn greet(name: &str) -> String { #[cfg_attr(mobile, tauri::mobile_entry_point)] pub fn run() { tauri::Builder::default() + .plugin(tauri_plugin_global_shortcut::Builder::new().build()) .plugin(tauri_plugin_os::init()) .plugin(tauri_plugin_http::init()) .plugin(tauri_plugin_dialog::init()) diff --git a/src-tauri/tauri.conf.json b/src-tauri/tauri.conf.json index dd795ec..3eb6eb7 100644 --- a/src-tauri/tauri.conf.json +++ b/src-tauri/tauri.conf.json @@ -1,7 +1,7 @@ { "$schema": "https://schema.tauri.app/config/2", "productName": "FLC", - "version": "6.1.0", + "version": "6.2.0", "identifier": "com.phenomen.flc", "build": { "beforeDevCommand": "npm run dev", @@ -36,7 +36,7 @@ "active": true, "longDescription": "Foundry Lightweight Client", "category": "RolePlayingGame", - "copyright": "phenomen", + "copyright": "ruleplaying.com", "targets": ["msi", "app", "dmg", "appimage"], "createUpdaterArtifacts": true, "icon": [ @@ -50,7 +50,7 @@ "plugins": { "updater": { "active": true, - "endpoints": ["https://flc.ruleplaying.com/flc2.json"], + "endpoints": ["https://flc.ruleplaying.com/flc.json"], "pubkey": "dW50cnVzdGVkIGNvbW1lbnQ6IG1pbmlzaWduIHB1YmxpYyBrZXk6IDVEM0E0Q0VBNDJGMDI2RTEKUldUaEp2QkM2a3c2WFNNTUpNbDJxVjJIZXdXUnh1MmhuOTdTNDM3Tk1DeFEza3JHRHJzVVlIb2QK", "windows": { "installMode": "basicUi" diff --git a/src/app.html b/src/app.html index fcd24d9..d857ce6 100644 --- a/src/app.html +++ b/src/app.html @@ -20,6 +20,6 @@ data-sveltekit-preload-data="hover" class="h-full bg-muted" > -
%sveltekit.body%
+
%sveltekit.body%
diff --git a/src/lib/components/FoundryControls.svelte b/src/lib/components/FoundryControls.svelte index 4af43e0..3d45ca5 100644 --- a/src/lib/components/FoundryControls.svelte +++ b/src/lib/components/FoundryControls.svelte @@ -1,38 +1,45 @@ -
- - - + + +
+ +
+
+ +
+
+ Ctrl/⌘ F11Toggle Fullscreen +
+ +
+ Ctrl/⌘ +Zoom In +
+ +
+ Ctrl/⌘ -Zoom Out +
+ +
+ Ctrl/⌘ 0Reset Zoom +
+
+
+
- -
+ diff --git a/src/lib/components/NodeserverGrid.svelte b/src/lib/components/NodeserverGrid.svelte index ce30081..282aa96 100644 --- a/src/lib/components/NodeserverGrid.svelte +++ b/src/lib/components/NodeserverGrid.svelte @@ -5,7 +5,7 @@ import { nodeservers } from "$scripts/nodeservers.svelte.js"; -
+
{#if nodeservers.current.length} {#each nodeservers.current as server (server.id)}
diff --git a/src/lib/components/ServerCard.svelte b/src/lib/components/ServerCard.svelte index 8c76ac1..dc1fe35 100644 --- a/src/lib/components/ServerCard.svelte +++ b/src/lib/components/ServerCard.svelte @@ -197,7 +197,7 @@
+ {/if} +
+ +{/if} diff --git a/src/lib/scripts/shortcuts.svelte.ts b/src/lib/scripts/shortcuts.svelte.ts new file mode 100644 index 0000000..9fbf093 --- /dev/null +++ b/src/lib/scripts/shortcuts.svelte.ts @@ -0,0 +1,23 @@ +import { getAllWindows } from "@tauri-apps/api/window"; +import { register } from "@tauri-apps/plugin-global-shortcut"; + +export async function toggleFullscreen() { + const windows = await getAllWindows(); + const foundryWindows = windows.filter((window) => window.label.includes("foundry")); + + for (const window of foundryWindows) { + const focused = await window.isFocused(); + if (focused) { + const fullscreen = await window.isFullscreen(); + await window.setFullscreen(!fullscreen); + } + } +} + +export async function registerShortcuts() { + await register("CommandOrControl+F11", async (event) => { + if (event.state === "Pressed") { + await toggleFullscreen(); + } + }); +} diff --git a/src/lib/scripts/tray.svelte.ts b/src/lib/scripts/tray.svelte.ts deleted file mode 100644 index eb752d5..0000000 --- a/src/lib/scripts/tray.svelte.ts +++ /dev/null @@ -1,137 +0,0 @@ -import { defaultWindowIcon } from "@tauri-apps/api/app"; -import { getCurrentWindow, getAllWindows } from "@tauri-apps/api/window"; -import { Menu, Submenu } from "@tauri-apps/api/menu"; -import { TrayIcon } from "@tauri-apps/api/tray"; -import { getAllWebviews } from "@tauri-apps/api/webview"; -import { toast } from "svelte-sonner"; - -let zoom = $state(1.0); - -export async function toggleFullscreen() { - const windows = await getAllWindows(); - const foundryWindow = windows.find((window) => window.label === "foundry"); - if (foundryWindow) { - const fullscreen = await foundryWindow.isFullscreen(); - await foundryWindow.setFullscreen(!fullscreen); - } else { - return toast("Open a Foundry VTT window to toggle fullscreen."); - } -} - -export async function setZoomFactor(factor: number) { - const webviews = await getAllWebviews(); - const foundryWebview = webviews.find((webview) => webview.label === "foundry"); - if (foundryWebview) { - await foundryWebview.setZoom(factor); - return toast(`Zoom level is x${factor.toPrecision(2)}`); - } else { - return toast("Open a Foundry VTT window to set zoom level."); - } -} - -export async function zoomIn() { - const webviews = await getAllWebviews(); - const foundryWebview = webviews.find((webview) => webview.label === "foundry"); - - if (foundryWebview) { - if (zoom > 1.8) { - return toast("Zoom is already at maximum level."); - } else { - zoom = zoom + 0.1; - } - } - await setZoomFactor(zoom); -} - -export async function zoomOut() { - const webviews = await getAllWebviews(); - const foundryWebview = webviews.find((webview) => webview.label === "foundry"); - - if (foundryWebview) { - if (zoom < 0.8) { - return toast("Zoom is already at minimum level."); - } else { - zoom = zoom - 0.1; - } - } - await setZoomFactor(zoom); -} - -export async function registerTray() { - const currentMenu = await TrayIcon.getById("flc"); - - if (currentMenu) { - return; - } - - const submenu = await Submenu.new({ - id: "zoom", - text: "Zoom", - items: [ - { - id: "zoom120", - text: "120%", - action: async () => { - await setZoomFactor(1.2); - } - }, - { - id: "zoom110", - text: "110%", - action: async () => { - await setZoomFactor(1.1); - } - }, - { - id: "zoom100", - text: "100%", - action: async () => { - await setZoomFactor(1.0); - } - }, - { - id: "zoom90", - text: "90%", - action: async () => { - await setZoomFactor(0.9); - } - }, - { - id: "zoom80", - text: "80%", - action: async () => { - await setZoomFactor(0.8); - } - } - ] - }); - - const menu = await Menu.new({ - items: [ - { - id: "fullscreen", - text: "Toggle Fullscreen", - action: async () => { - await toggleFullscreen(); - } - }, - submenu, - { - id: "exit", - text: "Exit", - action: async () => { - await getCurrentWindow().close(); - } - } - ] - }); - - const options = { - id: "flc", - menu, - menuOnLeftClick: true, - icon: await defaultWindowIcon() - }; - - await TrayIcon.new(options); -} diff --git a/src/lib/scripts/webview.svelte.ts b/src/lib/scripts/webview.svelte.ts index 07d672e..5913295 100644 --- a/src/lib/scripts/webview.svelte.ts +++ b/src/lib/scripts/webview.svelte.ts @@ -1,8 +1,8 @@ import { WebviewWindow } from "@tauri-apps/api/webviewWindow"; import { toast } from "svelte-sonner"; -export async function openWebview(url: string, title?: string) { - const webview = new WebviewWindow("foundry", { +export async function openWebview(url: string, id: string, title: string) { + const webview = new WebviewWindow(`foundry-${id}`, { title: `Foundry VTT - ${title}`, url, x: 0, @@ -22,8 +22,5 @@ export async function openWebview(url: string, title?: string) { webview.once("tauri://error", function (e) { console.log(e); - if (e.payload === "a webview with label `foundry` already exists") { - toast("Foundry VTT window is already open."); - } }); } diff --git a/src/routes/+layout.svelte b/src/routes/+layout.svelte index da63e2d..5a968c2 100644 --- a/src/routes/+layout.svelte +++ b/src/routes/+layout.svelte @@ -4,18 +4,16 @@ import { ModeWatcher } from "mode-watcher"; - import { Toaster } from "$ui/sonner/index.js"; - import Header from "$components/Header.svelte"; - import { registerTray } from "$scripts/tray.svelte.js"; + import Updater from "$components/Updater.svelte"; + import { registerShortcuts } from "$scripts/shortcuts.svelte.js"; let { children } = $props(); - registerTray(); + registerShortcuts(); -
- {@render children?.()} +