diff --git a/.github/workflows/action.yml b/.github/workflows/action.yml
index 6288ad6..709d35b 100644
--- a/.github/workflows/action.yml
+++ b/.github/workflows/action.yml
@@ -23,6 +23,11 @@ jobs:
# Note: Required by vergen (https://crates.io/crates/vergen)
run: git config --global --add safe.directory $GITHUB_WORKSPACE
+ - name: install dependencies (desktop-app)
+ run: |
+ sudo apt-get update
+ sudo apt-get install -y libwebkit2gtk-4.0-dev libwebkit2gtk-4.1-dev libappindicator3-dev librsvg2-dev patchelf
+
- name: Install build dependencies - Rustup
run: |
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh -s -- --default-toolchain stable -y
@@ -92,3 +97,77 @@ jobs:
tag: ${{ github.ref }}
prerelease: ${{ !startsWith(github.ref, 'refs/tags/') }}
overwrite: true
+
+ build-tauri:
+ needs: quick-tests
+ permissions:
+ contents: write
+ strategy:
+ fail-fast: false
+ matrix:
+ include:
+ - platform: 'macos-latest'
+ args: '--target aarch64-apple-darwin'
+ label: 'Mac-M1'
+ - platform: 'macos-latest'
+ args: '--target x86_64-apple-darwin'
+ label: 'Mac-x86'
+ - platform: 'ubuntu-22.04'
+ args: ''
+ label: 'Linux'
+ - platform: 'windows-latest'
+ args: ''
+ label: 'Windows'
+
+ runs-on: ${{ matrix.platform }}
+ steps:
+ - uses: actions/checkout@v4
+
+ - name: install dependencies (ubuntu only)
+ if: matrix.platform == 'ubuntu-22.04' # This must match the platform value defined above.
+ run: |
+ sudo apt-get update
+ sudo apt-get install -y libwebkit2gtk-4.0-dev libwebkit2gtk-4.1-dev libappindicator3-dev librsvg2-dev patchelf
+ # webkitgtk 4.0 is for Tauri v1 - webkitgtk 4.1 is for Tauri v2.
+
+ - name: setup node
+ uses: actions/setup-node@v4
+ with:
+ node-version: lts/*
+
+ - name: Setup Bun
+ uses: oven-sh/setup-bun@v1
+ with:
+ bun-version: latest
+
+ - name: install Rust stable
+ uses: dtolnay/rust-toolchain@stable
+ with:
+ # Those targets are only used on macos runners so it's in an `if` to slightly speed up windows and linux builds.
+ targets: ${{ matrix.platform == 'macos-latest' && 'aarch64-apple-darwin,x86_64-apple-darwin' || '' }}
+
+ - name: Rust cache
+ uses: swatinem/rust-cache@v2
+ with:
+ workspaces: './src-tauri -> target'
+
+ - name: Install dependencies
+ run: |
+ cd ping-viewer-next-desktop
+ bun install
+
+ - name: Build the app
+ id: tauri-build
+ uses: tauri-apps/tauri-action@v0.5.13
+ env:
+ GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
+ with:
+ projectPath: './ping-viewer-next-desktop'
+ args: ${{ matrix.args }}
+
+ - name: Upload artifacts
+ uses: actions/upload-artifact@v4.4.0
+ with:
+ name: 'ping-viewer_${{steps.tauri-build.outputs.appVersion}}_${{ matrix.label }}'
+ path: "${{ join(fromJSON(steps.tauri-build.outputs.artifactPaths), '\n') }}"
+ retention-days: 5
\ No newline at end of file
diff --git a/Cargo.toml b/Cargo.toml
index 2de692f..e845313 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -34,6 +34,9 @@ validator = "0.18.1"
thiserror = "1.0.63"
shellexpand = "3.1"
+tauri = { version = "1.7.2", optional = true, features = ["shell-open"] }
+
+
[build-dependencies]
vergen-gix = { version = "1.0.1", default-features = false, features = ["build", "cargo"] }
@@ -44,3 +47,7 @@ path = "src/lib.rs"
[[bin]]
name = "ping-viewer-next"
path = "src/main.rs"
+
+[features]
+default = []
+desktop-app = ["tauri"]
diff --git a/ping-viewer-next-desktop/.gitignore b/ping-viewer-next-desktop/.gitignore
new file mode 100644
index 0000000..a547bf3
--- /dev/null
+++ b/ping-viewer-next-desktop/.gitignore
@@ -0,0 +1,24 @@
+# Logs
+logs
+*.log
+npm-debug.log*
+yarn-debug.log*
+yarn-error.log*
+pnpm-debug.log*
+lerna-debug.log*
+
+node_modules
+dist
+dist-ssr
+*.local
+
+# Editor directories and files
+.vscode/*
+!.vscode/extensions.json
+.idea
+.DS_Store
+*.suo
+*.ntvs*
+*.njsproj
+*.sln
+*.sw?
diff --git a/ping-viewer-next-desktop/README.md b/ping-viewer-next-desktop/README.md
new file mode 100644
index 0000000..4b0342d
--- /dev/null
+++ b/ping-viewer-next-desktop/README.md
@@ -0,0 +1,17 @@
+# Ping Viewer Next DesktopApp
+
+Ping Viewer Next Desktop is a standalone version of the **Ping Viewer Next** core server. This application allows you to interface with **ping devices** attached directly to your computer or connected to a remotely one.
+
+## Key Features
+
+- **Local and Remote Connections**: Connect to ping devices on your local network or to remote Ping Viewer Next servers.
+- **Cross-Platform Support**: Available for macOS, Linux, and Windows.
+- **Standalone App**: Just install and use directly on your favorite OS.
+
+### Download
+
+You can download the latest version from the [releases page](https://github.com/bluerobotics/ping-viewer-next/releases).
+
+## How It Works
+
+Ping Viewer Next Desktop integrates the core Ping Viewer Next server with an embedded GUI, using Tauri to create a native experience across platforms.
diff --git a/ping-viewer-next-desktop/bun.lockb b/ping-viewer-next-desktop/bun.lockb
new file mode 100755
index 0000000..14f3822
Binary files /dev/null and b/ping-viewer-next-desktop/bun.lockb differ
diff --git a/ping-viewer-next-desktop/index.html b/ping-viewer-next-desktop/index.html
new file mode 100644
index 0000000..99f203f
--- /dev/null
+++ b/ping-viewer-next-desktop/index.html
@@ -0,0 +1,14 @@
+
+
+
+
+
+
+ Tauri + Vue + Typescript App
+
+
+
+
+
+
+
diff --git a/ping-viewer-next-desktop/package.json b/ping-viewer-next-desktop/package.json
new file mode 100644
index 0000000..2891872
--- /dev/null
+++ b/ping-viewer-next-desktop/package.json
@@ -0,0 +1,23 @@
+{
+ "name": "ping-viewer-next-desktop",
+ "private": true,
+ "version": "0.1.0",
+ "type": "module",
+ "scripts": {
+ "dev": "vite",
+ "build": "vue-tsc --noEmit && vite build",
+ "preview": "vite preview",
+ "tauri": "tauri"
+ },
+ "dependencies": {
+ "vue": "^3.3.4",
+ "@tauri-apps/api": "^1"
+ },
+ "devDependencies": {
+ "@vitejs/plugin-vue": "^5.0.5",
+ "typescript": "^5.2.2",
+ "vite": "^5.3.1",
+ "vue-tsc": "^2.0.22",
+ "@tauri-apps/cli": "^1"
+ }
+}
diff --git a/ping-viewer-next-desktop/public/tauri.svg b/ping-viewer-next-desktop/public/tauri.svg
new file mode 100644
index 0000000..31b62c9
--- /dev/null
+++ b/ping-viewer-next-desktop/public/tauri.svg
@@ -0,0 +1,6 @@
+
diff --git a/ping-viewer-next-desktop/public/vite.svg b/ping-viewer-next-desktop/public/vite.svg
new file mode 100644
index 0000000..e7b8dfb
--- /dev/null
+++ b/ping-viewer-next-desktop/public/vite.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/ping-viewer-next-desktop/src-tauri/.gitignore b/ping-viewer-next-desktop/src-tauri/.gitignore
new file mode 100644
index 0000000..16936f9
--- /dev/null
+++ b/ping-viewer-next-desktop/src-tauri/.gitignore
@@ -0,0 +1,9 @@
+# Generated by Cargo
+# will have compiled files and executables
+/target/
+
+# Generated by Tauri
+# will have schema files for capabilities auto-completion
+/gen/schemas
+
+/Cargo.lock
diff --git a/ping-viewer-next-desktop/src-tauri/Cargo.toml b/ping-viewer-next-desktop/src-tauri/Cargo.toml
new file mode 100644
index 0000000..dcd3087
--- /dev/null
+++ b/ping-viewer-next-desktop/src-tauri/Cargo.toml
@@ -0,0 +1,23 @@
+[package]
+name = "ping-viewer-next-desktop"
+version = "0.1.0"
+description = "A Tauri App"
+authors = ["you"]
+edition = "2021"
+
+# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
+
+[build-dependencies]
+tauri-build = { version = "1.5.4", features = [] }
+
+[dependencies]
+tauri = { version = "1.7.2", features = ["shell-open"] }
+serde = { version = "1", features = ["derive"] }
+serde_json = "1"
+ping-viewer-next = { path = "./../../", features = ["desktop-app"] }
+tokio = { version = "1.40.0", features = ["full"] }
+actix-web = "4.6.0"
+
+[features]
+# This feature is used for production builds or when a dev server is not specified, DO NOT REMOVE!!
+custom-protocol = ["tauri/custom-protocol"]
diff --git a/ping-viewer-next-desktop/src-tauri/build.rs b/ping-viewer-next-desktop/src-tauri/build.rs
new file mode 100644
index 0000000..d860e1e
--- /dev/null
+++ b/ping-viewer-next-desktop/src-tauri/build.rs
@@ -0,0 +1,3 @@
+fn main() {
+ tauri_build::build()
+}
diff --git a/ping-viewer-next-desktop/src-tauri/icons/128x128.png b/ping-viewer-next-desktop/src-tauri/icons/128x128.png
new file mode 100644
index 0000000..6be5e50
Binary files /dev/null and b/ping-viewer-next-desktop/src-tauri/icons/128x128.png differ
diff --git a/ping-viewer-next-desktop/src-tauri/icons/128x128@2x.png b/ping-viewer-next-desktop/src-tauri/icons/128x128@2x.png
new file mode 100644
index 0000000..e81bece
Binary files /dev/null and b/ping-viewer-next-desktop/src-tauri/icons/128x128@2x.png differ
diff --git a/ping-viewer-next-desktop/src-tauri/icons/32x32.png b/ping-viewer-next-desktop/src-tauri/icons/32x32.png
new file mode 100644
index 0000000..a437dd5
Binary files /dev/null and b/ping-viewer-next-desktop/src-tauri/icons/32x32.png differ
diff --git a/ping-viewer-next-desktop/src-tauri/icons/Square107x107Logo.png b/ping-viewer-next-desktop/src-tauri/icons/Square107x107Logo.png
new file mode 100644
index 0000000..0ca4f27
Binary files /dev/null and b/ping-viewer-next-desktop/src-tauri/icons/Square107x107Logo.png differ
diff --git a/ping-viewer-next-desktop/src-tauri/icons/Square142x142Logo.png b/ping-viewer-next-desktop/src-tauri/icons/Square142x142Logo.png
new file mode 100644
index 0000000..b81f820
Binary files /dev/null and b/ping-viewer-next-desktop/src-tauri/icons/Square142x142Logo.png differ
diff --git a/ping-viewer-next-desktop/src-tauri/icons/Square150x150Logo.png b/ping-viewer-next-desktop/src-tauri/icons/Square150x150Logo.png
new file mode 100644
index 0000000..624c7bf
Binary files /dev/null and b/ping-viewer-next-desktop/src-tauri/icons/Square150x150Logo.png differ
diff --git a/ping-viewer-next-desktop/src-tauri/icons/Square284x284Logo.png b/ping-viewer-next-desktop/src-tauri/icons/Square284x284Logo.png
new file mode 100644
index 0000000..c021d2b
Binary files /dev/null and b/ping-viewer-next-desktop/src-tauri/icons/Square284x284Logo.png differ
diff --git a/ping-viewer-next-desktop/src-tauri/icons/Square30x30Logo.png b/ping-viewer-next-desktop/src-tauri/icons/Square30x30Logo.png
new file mode 100644
index 0000000..6219700
Binary files /dev/null and b/ping-viewer-next-desktop/src-tauri/icons/Square30x30Logo.png differ
diff --git a/ping-viewer-next-desktop/src-tauri/icons/Square310x310Logo.png b/ping-viewer-next-desktop/src-tauri/icons/Square310x310Logo.png
new file mode 100644
index 0000000..f9bc048
Binary files /dev/null and b/ping-viewer-next-desktop/src-tauri/icons/Square310x310Logo.png differ
diff --git a/ping-viewer-next-desktop/src-tauri/icons/Square44x44Logo.png b/ping-viewer-next-desktop/src-tauri/icons/Square44x44Logo.png
new file mode 100644
index 0000000..d5fbfb2
Binary files /dev/null and b/ping-viewer-next-desktop/src-tauri/icons/Square44x44Logo.png differ
diff --git a/ping-viewer-next-desktop/src-tauri/icons/Square71x71Logo.png b/ping-viewer-next-desktop/src-tauri/icons/Square71x71Logo.png
new file mode 100644
index 0000000..63440d7
Binary files /dev/null and b/ping-viewer-next-desktop/src-tauri/icons/Square71x71Logo.png differ
diff --git a/ping-viewer-next-desktop/src-tauri/icons/Square89x89Logo.png b/ping-viewer-next-desktop/src-tauri/icons/Square89x89Logo.png
new file mode 100644
index 0000000..f3f705a
Binary files /dev/null and b/ping-viewer-next-desktop/src-tauri/icons/Square89x89Logo.png differ
diff --git a/ping-viewer-next-desktop/src-tauri/icons/StoreLogo.png b/ping-viewer-next-desktop/src-tauri/icons/StoreLogo.png
new file mode 100644
index 0000000..4556388
Binary files /dev/null and b/ping-viewer-next-desktop/src-tauri/icons/StoreLogo.png differ
diff --git a/ping-viewer-next-desktop/src-tauri/icons/icon.icns b/ping-viewer-next-desktop/src-tauri/icons/icon.icns
new file mode 100644
index 0000000..12a5bce
Binary files /dev/null and b/ping-viewer-next-desktop/src-tauri/icons/icon.icns differ
diff --git a/ping-viewer-next-desktop/src-tauri/icons/icon.ico b/ping-viewer-next-desktop/src-tauri/icons/icon.ico
new file mode 100644
index 0000000..b3636e4
Binary files /dev/null and b/ping-viewer-next-desktop/src-tauri/icons/icon.ico differ
diff --git a/ping-viewer-next-desktop/src-tauri/icons/icon.png b/ping-viewer-next-desktop/src-tauri/icons/icon.png
new file mode 100644
index 0000000..e1cd261
Binary files /dev/null and b/ping-viewer-next-desktop/src-tauri/icons/icon.png differ
diff --git a/ping-viewer-next-desktop/src-tauri/src/main.rs b/ping-viewer-next-desktop/src-tauri/src/main.rs
new file mode 100644
index 0000000..fdd29d1
--- /dev/null
+++ b/ping-viewer-next-desktop/src-tauri/src/main.rs
@@ -0,0 +1,46 @@
+// Prevents additional console window on Windows in release, DO NOT REMOVE!!
+#![cfg_attr(not(debug_assertions), windows_subsystem = "windows")]
+
+use ping_viewer_next::{cli, device, logger, server};
+use tauri::Manager;
+
+#[tokio::main]
+async fn main() {
+ cli::manager::init();
+
+ logger::manager::init();
+
+ let (manager, handler) = device::manager::DeviceManager::new(10);
+
+ tokio::spawn(async move { manager.run().await });
+
+ run_tauri_app(handler).await;
+}
+
+async fn run_tauri_app(handler: device::manager::ManagerActorHandler) {
+ tauri::Builder::default()
+ .setup(|app: &mut tauri::App| {
+ let window = app.get_window("main").unwrap();
+
+ std::thread::spawn(move || {
+ run_from_tauri(&cli::manager::server_address(), handler).unwrap();
+ });
+
+ std::thread::spawn(move || {
+ std::thread::sleep(std::time::Duration::from_secs(6));
+ window.eval("window.location.replace('http://0.0.0.0:8080')").unwrap();
+ });
+
+ Ok(())
+ })
+ .run(tauri::generate_context!())
+ .expect("error while running tauri application");
+}
+
+#[actix_web::main]
+pub async fn run_from_tauri(
+ server_address: &str,
+ handler: device::manager::ManagerActorHandler,
+) -> std::io::Result<()> {
+ server::manager::run(server_address, handler).await
+}
diff --git a/ping-viewer-next-desktop/src-tauri/tauri.conf.json b/ping-viewer-next-desktop/src-tauri/tauri.conf.json
new file mode 100644
index 0000000..1fa0e4d
--- /dev/null
+++ b/ping-viewer-next-desktop/src-tauri/tauri.conf.json
@@ -0,0 +1,43 @@
+{
+ "build": {
+ "beforeDevCommand": "bun run dev",
+ "beforeBuildCommand": "bun run build",
+ "devPath": "http://localhost:1420",
+ "distDir": "../dist"
+ },
+ "package": {
+ "productName": "ping-viewer-next-desktop",
+ "version": "0.1.0"
+ },
+ "tauri": {
+ "allowlist": {
+ "all": false,
+ "shell": {
+ "all": false,
+ "open": true
+ }
+ },
+ "windows": [
+ {
+ "title": "ping-viewer-next-desktop",
+ "width": 800,
+ "height": 600
+ }
+ ],
+ "security": {
+ "csp": null
+ },
+ "bundle": {
+ "active": true,
+ "targets": "all",
+ "identifier": "com.ping-viewer-next-desktop.app",
+ "icon": [
+ "icons/32x32.png",
+ "icons/128x128.png",
+ "icons/128x128@2x.png",
+ "icons/icon.icns",
+ "icons/icon.ico"
+ ]
+ }
+ }
+}
diff --git a/ping-viewer-next-desktop/src/App.vue b/ping-viewer-next-desktop/src/App.vue
new file mode 100644
index 0000000..c3fe08c
--- /dev/null
+++ b/ping-viewer-next-desktop/src/App.vue
@@ -0,0 +1,57 @@
+
+
+
+
+
Ping Viewer Next
+
Creating a local server...
+
+
+
+
Ping Viewer Next
+
Server is ready!
+
+
+
+
diff --git a/ping-viewer-next-desktop/src/assets/vue.svg b/ping-viewer-next-desktop/src/assets/vue.svg
new file mode 100644
index 0000000..770e9d3
--- /dev/null
+++ b/ping-viewer-next-desktop/src/assets/vue.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/ping-viewer-next-desktop/src/components/Greet.vue b/ping-viewer-next-desktop/src/components/Greet.vue
new file mode 100644
index 0000000..5bee007
--- /dev/null
+++ b/ping-viewer-next-desktop/src/components/Greet.vue
@@ -0,0 +1,21 @@
+
+
+
+
+
+ {{ greetMsg }}
+
diff --git a/ping-viewer-next-desktop/src/main.ts b/ping-viewer-next-desktop/src/main.ts
new file mode 100644
index 0000000..b670de8
--- /dev/null
+++ b/ping-viewer-next-desktop/src/main.ts
@@ -0,0 +1,4 @@
+import { createApp } from "vue";
+import App from "./App.vue";
+
+createApp(App).mount("#app");
diff --git a/ping-viewer-next-desktop/src/vite-env.d.ts b/ping-viewer-next-desktop/src/vite-env.d.ts
new file mode 100644
index 0000000..fc81239
--- /dev/null
+++ b/ping-viewer-next-desktop/src/vite-env.d.ts
@@ -0,0 +1,7 @@
+///
+
+declare module "*.vue" {
+ import type { DefineComponent } from "vue";
+ const component: DefineComponent<{}, {}, any>;
+ export default component;
+}
diff --git a/ping-viewer-next-desktop/tsconfig.json b/ping-viewer-next-desktop/tsconfig.json
new file mode 100644
index 0000000..f82888f
--- /dev/null
+++ b/ping-viewer-next-desktop/tsconfig.json
@@ -0,0 +1,25 @@
+{
+ "compilerOptions": {
+ "target": "ES2020",
+ "useDefineForClassFields": true,
+ "module": "ESNext",
+ "lib": ["ES2020", "DOM", "DOM.Iterable"],
+ "skipLibCheck": true,
+
+ /* Bundler mode */
+ "moduleResolution": "bundler",
+ "allowImportingTsExtensions": true,
+ "resolveJsonModule": true,
+ "isolatedModules": true,
+ "noEmit": true,
+ "jsx": "preserve",
+
+ /* Linting */
+ "strict": true,
+ "noUnusedLocals": true,
+ "noUnusedParameters": true,
+ "noFallthroughCasesInSwitch": true
+ },
+ "include": ["src/**/*.ts", "src/**/*.d.ts", "src/**/*.tsx", "src/**/*.vue"],
+ "references": [{ "path": "./tsconfig.node.json" }]
+}
diff --git a/ping-viewer-next-desktop/tsconfig.node.json b/ping-viewer-next-desktop/tsconfig.node.json
new file mode 100644
index 0000000..42872c5
--- /dev/null
+++ b/ping-viewer-next-desktop/tsconfig.node.json
@@ -0,0 +1,10 @@
+{
+ "compilerOptions": {
+ "composite": true,
+ "skipLibCheck": true,
+ "module": "ESNext",
+ "moduleResolution": "bundler",
+ "allowSyntheticDefaultImports": true
+ },
+ "include": ["vite.config.ts"]
+}
diff --git a/ping-viewer-next-desktop/vite.config.ts b/ping-viewer-next-desktop/vite.config.ts
new file mode 100644
index 0000000..ce8e371
--- /dev/null
+++ b/ping-viewer-next-desktop/vite.config.ts
@@ -0,0 +1,21 @@
+import { defineConfig } from "vite";
+import vue from "@vitejs/plugin-vue";
+
+// https://vitejs.dev/config/
+export default defineConfig(async () => ({
+ plugins: [vue()],
+
+ // Vite options tailored for Tauri development and only applied in `tauri dev` or `tauri build`
+ //
+ // 1. prevent vite from obscuring rust errors
+ clearScreen: false,
+ // 2. tauri expects a fixed port, fail if that port is not available
+ server: {
+ port: 1420,
+ strictPort: true,
+ watch: {
+ // 3. tell vite to ignore watching `src-tauri`
+ ignored: ["**/src-tauri/**"],
+ },
+ },
+}));
diff --git a/src/logger/manager.rs b/src/logger/manager.rs
index 7a4db2d..dbeaf62 100644
--- a/src/logger/manager.rs
+++ b/src/logger/manager.rs
@@ -1,4 +1,4 @@
-use std::str::FromStr;
+use std::{path::PathBuf, str::FromStr};
use crate::cli;
@@ -39,13 +39,15 @@ pub fn init() {
EnvFilter::new(LevelFilter::DEBUG.to_string())
};
- let dir = cli::manager::log_path();
+ let dir = get_app_log_dir();
+
let file_appender = custom_rolling_appender(
dir,
tracing_appender::rolling::Rotation::HOURLY,
"ping-viewer",
"log",
);
+
let file_layer = fmt::Layer::new()
.with_writer(file_appender)
.with_ansi(false)
@@ -136,3 +138,41 @@ fn custom_rolling_appender>(
.build(dir)
.expect("failed to initialize rolling file appender")
}
+
+#[allow(unused)]
+#[cfg(feature = "desktop-app")]
+static APP_DIR: &str = "Ping-Viewer-Next";
+
+#[cfg(feature = "desktop-app")]
+pub fn get_app_home_dir() -> PathBuf {
+ #[cfg(target_os = "windows")]
+ if let Err(e) = std::env::current_dir() {
+ error!("Failed to get app home dir. Errmsg: {}", e);
+ std::process::exit(-1);
+ } else {
+ return std::env::current_dir().unwrap();
+ }
+
+ #[cfg(not(target_os = "windows"))]
+ match tauri::api::path::home_dir() {
+ None => {
+ error!("Failed to get app home dir");
+ std::process::exit(-1);
+ }
+ Some(path) => {
+ return path.join(APP_DIR);
+ }
+ }
+}
+
+pub fn get_app_log_dir() -> PathBuf {
+ #[cfg(feature = "desktop-app")]
+ {
+ get_app_home_dir().join("logs")
+ }
+
+ #[cfg(not(feature = "desktop-app"))]
+ {
+ PathBuf::from(cli::manager::log_path())
+ }
+}