Migrate to tauri logger (#1537)

Co-authored-by: lucas lelievre <loucass003@gmail.com>
This commit is contained in:
Uriel
2025-10-31 13:42:13 -03:00
committed by GitHub
parent 1d273ac651
commit 81716be512
25 changed files with 3484 additions and 2388 deletions

668
Cargo.lock generated

File diff suppressed because it is too large Load Diff

View File

@@ -9,7 +9,7 @@ members = ["gui/src-tauri"]
[workspace.package]
edition = "2021"
license = "MIT OR Apache-2.0"
rust-version = "1.75" # Tauri's MSRV
rust-version = "1.82" # Tauri's MSRV
repository = "https://github.com/SlimeVR/SlimeVR-Server"
[profile.release]

107
flake.lock generated
View File

@@ -43,11 +43,11 @@
]
},
"locked": {
"lastModified": 1750800495,
"narHash": "sha256-wBTGFNCx3Gr3BkNkEoFrKx9+d7otSdQesCDCPGDKZHk=",
"lastModified": 1757003908,
"narHash": "sha256-Op3cnPTav+ObcL4R4BGuWHEFxW6YS2A0aE3Av6sZN2g=",
"owner": "cachix",
"repo": "devenv",
"rev": "b33ab3610c084a7e3fabc5eefaeb437449f1efe7",
"rev": "ac8ebf17828c0e7d9be0270d359123fffcc6f066",
"type": "github"
},
"original": {
@@ -64,11 +64,11 @@
"rust-analyzer-src": "rust-analyzer-src"
},
"locked": {
"lastModified": 1750833544,
"narHash": "sha256-e5W27mfPGiM35qr0DjTUzLHP4ET2MbvRc4HJHScw/ko=",
"lastModified": 1756795219,
"narHash": "sha256-tKBQtz1JLKWrCJUxVkHKR+YKmVpm0KZdJdPWmR2slQ8=",
"owner": "nix-community",
"repo": "fenix",
"rev": "c3940d9ff4d37e965e5841149367234c2aad1ab6",
"rev": "80dbdab137f2809e3c823ed027e1665ce2502d74",
"type": "github"
},
"original": {
@@ -120,11 +120,11 @@
"nixpkgs-lib": "nixpkgs-lib"
},
"locked": {
"lastModified": 1749398372,
"narHash": "sha256-tYBdgS56eXYaWVW3fsnPQ/nFlgWi/Z2Ymhyu21zVM98=",
"lastModified": 1756770412,
"narHash": "sha256-+uWLQZccFHwqpGqr2Yt5VsW/PbeJVTn9Dk6SHWhNRPw=",
"owner": "hercules-ci",
"repo": "flake-parts",
"rev": "9305fe4e5c2a6fcf5ba6a3ff155720fbe4076569",
"rev": "4524271976b625a4a605beefd893f270620fd751",
"type": "github"
},
"original": {
@@ -133,12 +133,15 @@
}
},
"flake-utils": {
"inputs": {
"systems": "systems"
},
"locked": {
"lastModified": 1659877975,
"narHash": "sha256-zllb8aq3YO3h8B/U0/J1WBgAL8EX5yWf5pMj3G0NAmc=",
"lastModified": 1731533236,
"narHash": "sha256-l0KFg5HjrsfsO/JpG+r7fRrqm12kzFHyUHqHCVpMMbI=",
"owner": "numtide",
"repo": "flake-utils",
"rev": "c0e246b9b83f637f4681389ecabcb2681b4f3af0",
"rev": "11707dc2f618dd54ca8739b309ec4fc024de578b",
"type": "github"
},
"original": {
@@ -160,10 +163,11 @@
]
},
"locked": {
"lastModified": 1749636823,
"lastModified": 1750779888,
"narHash": "sha256-wibppH3g/E2lxU43ZQHC5yA/7kIKLGxVEnsnVK1BtRg=",
"owner": "cachix",
"repo": "git-hooks.nix",
"rev": "623c56286de5a3193aa38891a6991b28f9bab056",
"rev": "16ec914f6fb6f599ce988427d9d94efddf25fe6d",
"type": "github"
},
"original": {
@@ -182,6 +186,7 @@
},
"locked": {
"lastModified": 1709087332,
"narHash": "sha256-HG2cCnktfHsKV0s4XW83gU3F57gaTljL9KNSuG6bnQs=",
"owner": "hercules-ci",
"repo": "gitignore.nix",
"rev": "637db329424fd7e46cf4185293b9cc8c88c95394",
@@ -219,7 +224,10 @@
"devenv",
"git-hooks"
],
"nixpkgs": "nixpkgs",
"nixpkgs": [
"devenv",
"nixpkgs"
],
"nixpkgs-23-11": [
"devenv"
],
@@ -228,11 +236,11 @@
]
},
"locked": {
"lastModified": 1750117611,
"narHash": "sha256-LTwASICtyN3AjzlF9l2ZNAIVZqclio3yRcwwZy3QSJA=",
"lastModified": 1755029779,
"narHash": "sha256-3+GHIYGg4U9XKUN4rg473frIVNn8YD06bjwxKS1IPrU=",
"owner": "cachix",
"repo": "nix",
"rev": "9e4fc95c388e2223d47da865503dee20d179776a",
"rev": "b0972b0eee6726081d10b1199f54de6d2917f861",
"type": "github"
},
"original": {
@@ -249,11 +257,11 @@
]
},
"locked": {
"lastModified": 1749158376,
"narHash": "sha256-uirStFNxauh0lxzBowcp28X+Sq7JgsBIDnbwbAfZwf8=",
"lastModified": 1752002763,
"narHash": "sha256-JYAkdZvpdSx9GUoHPArctYMypSONob4DYKRkOubUWtY=",
"owner": "nlewo",
"repo": "nix2container",
"rev": "0f8974c58755dba441df03598eefd1e1cd50e341",
"rev": "4f2437f6a1844b843b380d483087ae6d461240ee",
"type": "github"
},
"original": {
@@ -270,11 +278,11 @@
]
},
"locked": {
"lastModified": 1713543440,
"narHash": "sha256-lnzZQYG0+EXl/6NkGpyIz+FEOc/DSEG57AP1VsdeNrM=",
"lastModified": 1752054764,
"narHash": "sha256-Ob/HuUhANoDs+nvYqyTKrkcPXf4ZgXoqMTQoCK0RFgQ=",
"owner": "guibou",
"repo": "nixGL",
"rev": "310f8e49a149e4c9ea52f1adf70cdc768ec53f8a",
"rev": "a8e1ce7d49a149ed70df676785b07f63288f53c5",
"type": "github"
},
"original": {
@@ -285,11 +293,11 @@
},
"nixpkgs": {
"locked": {
"lastModified": 1747179050,
"narHash": "sha256-qhFMmDkeJX9KJwr5H32f1r7Prs7XbQWtO0h3V0a0rFY=",
"lastModified": 1756787288,
"narHash": "sha256-rw/PHa1cqiePdBxhF66V7R+WAP8WekQ0mCDG4CFqT8Y=",
"owner": "NixOS",
"repo": "nixpkgs",
"rev": "adaa24fbf46737f3f1b5497bf64bae750f82942e",
"rev": "d0fc30899600b9b3466ddb260fd83deb486c32f1",
"type": "github"
},
"original": {
@@ -301,11 +309,11 @@
},
"nixpkgs-lib": {
"locked": {
"lastModified": 1748740939,
"narHash": "sha256-rQaysilft1aVMwF14xIdGS3sj1yHlI6oKQNBRTF40cc=",
"lastModified": 1754788789,
"narHash": "sha256-x2rJ+Ovzq0sCMpgfgGaaqgBSwY+LST+WbZ6TytnT9Rk=",
"owner": "nix-community",
"repo": "nixpkgs.lib",
"rev": "656a64127e9d791a334452c6b6606d17539476e2",
"rev": "a73b9c743612e4244d865a2fdee11865283c04e6",
"type": "github"
},
"original": {
@@ -314,22 +322,6 @@
"type": "github"
}
},
"nixpkgs_2": {
"locked": {
"lastModified": 1750741721,
"narHash": "sha256-Z0djmTa1YmnGMfE9jEe05oO4zggjDmxOGKwt844bUhE=",
"owner": "NixOS",
"repo": "nixpkgs",
"rev": "4b1164c3215f018c4442463a27689d973cffd750",
"type": "github"
},
"original": {
"owner": "NixOS",
"ref": "nixos-unstable",
"repo": "nixpkgs",
"type": "github"
}
},
"root": {
"inputs": {
"devenv": "devenv",
@@ -338,17 +330,17 @@
"mk-shell-bin": "mk-shell-bin",
"nix2container": "nix2container",
"nixgl": "nixgl",
"nixpkgs": "nixpkgs_2"
"nixpkgs": "nixpkgs"
}
},
"rust-analyzer-src": {
"flake": false,
"locked": {
"lastModified": 1750788942,
"narHash": "sha256-bBSdUlEw/7xh66rtMEDg39xQUNN2VaDJIbRPIwhpFYk=",
"lastModified": 1756597274,
"narHash": "sha256-wfaKRKsEVQDB7pQtAt04vRgFphkVscGRpSx3wG1l50E=",
"owner": "rust-lang",
"repo": "rust-analyzer",
"rev": "c68c8a81a7d2979778ae1e8ba024beacb4fff6b6",
"rev": "21614ed2d3279a9aa1f15c88d293e65a98991b30",
"type": "github"
},
"original": {
@@ -357,6 +349,21 @@
"repo": "rust-analyzer",
"type": "github"
}
},
"systems": {
"locked": {
"lastModified": 1681028828,
"narHash": "sha256-Vy1rq5AaRuLzOxct8nz4T6wlgyUR7zLU309k9mBC768=",
"owner": "nix-systems",
"repo": "default",
"rev": "da67096a3b9bf56a91d16901293e51ba5b49a27e",
"type": "github"
},
"original": {
"owner": "nix-systems",
"repo": "default",
"type": "github"
}
}
},
"root": "root",

View File

@@ -129,7 +129,7 @@
enable = true;
toolchain = fenixpkgs.fromToolchainName {
name = rust_toolchain.toolchain.channel;
sha256 = "sha256-yMuSb5eQPO/bHv+Bcf/US8LVMbf/G/0MSfiPwBhiPpk=";
sha256 = "sha256-+9FmLhAOezBZCOziO0Qct1NOrfpjNsXxc/8I0c7BdKE=";
};
components = rust_toolchain.toolchain.components;
};

View File

@@ -16,13 +16,15 @@
"@sentry/vite-plugin": "^2.22.7",
"@tailwindcss/typography": "^0.5.15",
"@tanstack/react-query": "^5.48.0",
"@tauri-apps/api": "^2.0.2",
"@tauri-apps/plugin-dialog": "^2.0.0",
"@tauri-apps/plugin-fs": "2.4.1",
"@tauri-apps/plugin-http": "^2.5.0",
"@tauri-apps/plugin-os": "^2.0.0",
"@tauri-apps/plugin-shell": "^2.0.0",
"@tauri-apps/plugin-store": "^2.0.0",
"@tauri-apps/api": "~2",
"@tauri-apps/plugin-dialog": "~2",
"@tauri-apps/plugin-fs": "~2",
"@tauri-apps/plugin-http": "~2",
"@tauri-apps/plugin-log": "~2",
"@tauri-apps/plugin-opener": "~2",
"@tauri-apps/plugin-os": "~2",
"@tauri-apps/plugin-shell": "~2",
"@tauri-apps/plugin-store": "~2",
"@tweenjs/tween.js": "^25.0.0",
"@twemoji/svg": "^15.0.0",
"browser-fs-access": "^0.35.0",
@@ -70,8 +72,9 @@
"@openapi-codegen/cli": "^2.0.2",
"@openapi-codegen/typescript": "^8.0.2",
"@tailwindcss/forms": "^0.5.9",
"@tauri-apps/cli": "^2.0.2",
"@tauri-apps/cli": "~2",
"@types/file-saver": "^2.0.7",
"@types/node": "^24.3.1",
"@types/react": "^18.3.11",
"@types/react-dom": "^18.3.0",
"@types/react-helmet": "^6.1.11",

View File

@@ -28,14 +28,15 @@ shadow-rs = "0.35"
[dependencies]
serde_json = "1"
serde = { version = "1", features = ["derive"] }
tauri = { version = "2.0", features = ["devtools", "tray-icon", "image-png", "rustls-tls"] }
tauri-runtime = "2.0"
tauri-plugin-dialog = "2.0"
tauri-plugin-fs = "2.4.1"
tauri-plugin-os = "2.0"
tauri-plugin-shell = "2.0"
tauri-plugin-store = "2.0"
flexi_logger = "0.29"
tauri = { version = "2", features = ["devtools", "tray-icon", "image-png", "rustls-tls"] }
tauri-runtime = "2"
tauri-plugin-dialog = "2"
tauri-plugin-fs = "2"
tauri-plugin-http = "2"
tauri-plugin-opener = "2"
tauri-plugin-os = "2"
tauri-plugin-shell = "2"
tauri-plugin-store = "2"
log-panics = { version = "2", features = ["with-backtrace"] }
log = "0.4"
clap = { version = "4.0.29", features = ["derive"] }
@@ -54,7 +55,7 @@ dirs-next = "2.0.0"
discord-sdk = "0.3.6"
tokio = { version = "1.37.0", features = ["time"] }
itertools = "0.13.0"
tauri-plugin-http = "2.5.0"
tauri-plugin-log = "2"
[target.'cfg(windows)'.dependencies]
win32job = "1"

View File

@@ -2,7 +2,9 @@
"identifier": "migrated",
"description": "permissions that were migrated from v1",
"local": true,
"windows": ["main"],
"windows": [
"main"
],
"permissions": [
"core:default",
"core:window:allow-close",
@@ -30,7 +32,14 @@
"fs:allow-exists",
{
"identifier": "fs:scope",
"allow": [{ "path": "$APPDATA" }, { "path": "$APPDATA/**" }]
"allow": [
{
"path": "$APPDATA"
},
{
"path": "$APPDATA/**"
}
]
},
{
"identifier": "http:default",
@@ -39,6 +48,8 @@
"url": "https://github.com/SlimeVR/SlimeVR-Tracker-ESP/releases/download/*"
}
]
}
},
"opener:default",
"log:default"
]
}
}

View File

@@ -17,6 +17,7 @@ use tauri::Emitter;
use tauri::WindowEvent;
use tauri::{Manager, RunEvent};
use tauri_plugin_shell::process::CommandChild;
use util::get_log_dir;
use crate::util::{
get_launch_path, show_error, valid_java_paths, Cli, JAVA_BIN, MINIMUM_JAVA_VERSION,
@@ -43,21 +44,6 @@ fn update_window_state(
Ok(())
}
#[tauri::command]
fn logging(msg: String) {
log::info!(target: "webview", "{}", msg)
}
#[tauri::command]
fn erroring(msg: String) {
log::error!(target: "webview", "{}", msg)
}
#[tauri::command]
fn warning(msg: String) {
log::warn!(target: "webview", "{}", msg)
}
#[tauri::command]
fn open_config_folder(app_handle: tauri::AppHandle) {
let path = app_handle
@@ -66,7 +52,7 @@ fn open_config_folder(app_handle: tauri::AppHandle) {
.unwrap_or_else(|_| Path::new(".").to_path_buf());
if let Err(err) = open::that(path) {
eprintln!("Failed to open config folder: {}", err);
log::error!("Failed to open config folder: {}", err);
}
}
@@ -81,7 +67,7 @@ fn open_logs_folder(app_handle: tauri::AppHandle) {
if let Err(err) =
open::that(path.unwrap_or_else(|_| Path::new("./logs/").to_path_buf()))
{
eprintln!("Failed to open logs folder: {}", err);
log::error!("Failed to open logs folder: {}", err);
}
}
@@ -97,9 +83,6 @@ fn main() -> Result<()> {
let cli = Cli::parse();
let tauri_context = tauri::generate_context!();
// Set up loggers and global handlers
let _logger = setup_logger(&tauri_context);
// Ensure child processes die when spawned on windows
// and then check for WebView2's existence
#[cfg(windows)]
@@ -125,37 +108,6 @@ fn main() -> Result<()> {
Ok(())
}
fn setup_logger(context: &tauri::Context) -> Result<flexi_logger::LoggerHandle> {
use flexi_logger::{
Age, Cleanup, Criterion, Duplicate, FileSpec, Logger, Naming, WriteMode,
};
use tauri::Error;
// Based on https://docs.rs/tauri/2.0.0-alpha.10/src/tauri/path/desktop.rs.html#238-256
#[cfg(target_os = "macos")]
let path = dirs_next::home_dir()
.ok_or(Error::UnknownPath)
.map(|dir| dir.join("Library/Logs").join(&context.config().identifier));
#[cfg(not(target_os = "macos"))]
let path = dirs_next::data_dir()
.ok_or(Error::UnknownPath)
.map(|dir| dir.join(&context.config().identifier).join("logs"));
Ok(Logger::try_with_env_or_str("info")?
.log_to_file(FileSpec::default().directory(path.expect("We need a log dir")))
.format_for_files(|w, now, record| util::logger_format(w, now, record, false))
.format_for_stderr(|w, now, record| util::logger_format(w, now, record, true))
.rotate(
Criterion::Age(Age::Day),
Naming::Timestamps,
Cleanup::KeepLogFiles(2),
)
.duplicate_to_stderr(Duplicate::All)
.write_mode(WriteMode::BufferAndFlush)
.start()?)
}
#[cfg(windows)]
fn setup_webview2() -> Result<()> {
use crate::util::webview2_exists;
@@ -249,6 +201,19 @@ fn setup_tauri(
) -> Result<tauri::App, tauri::Error> {
let exit_flag_terminated = exit_flag.clone();
tauri::Builder::default()
.plugin(
tauri_plugin_log::Builder::new()
.target(tauri_plugin_log::Target::new(
tauri_plugin_log::TargetKind::Folder {
path: get_log_dir(&context)?,
file_name: Some("slimevr".to_string()),
},
))
.max_file_size(30_000 /* bytes */)
.rotation_strategy(tauri_plugin_log::RotationStrategy::KeepSome(3))
.build(),
)
.plugin(tauri_plugin_opener::init())
.plugin(tauri_plugin_dialog::init())
.plugin(tauri_plugin_fs::init())
.plugin(tauri_plugin_os::init())
@@ -257,9 +222,6 @@ fn setup_tauri(
.plugin(tauri_plugin_http::init())
.invoke_handler(tauri::generate_handler![
update_window_state,
logging,
erroring,
warning,
open_config_folder,
open_logs_folder,
tray::update_translations,
@@ -271,6 +233,7 @@ fn setup_tauri(
presence::create_discord_client,
])
.setup(move |app| {
log::info!("SlimeVR started!");
let window_state =
WindowState::open_state(app.path().app_config_dir().unwrap())
.unwrap_or_default();

View File

@@ -10,8 +10,6 @@ use std::{
use clap::Parser;
use const_format::concatcp;
use flexi_logger::{style, DeferredNow};
use log::Record;
use shadow_rs::shadow;
use tempfile::Builder;
@@ -111,6 +109,21 @@ pub fn show_error(text: &str) -> bool {
== MessageDialogResult::Ok
}
pub fn get_log_dir(context: &tauri::Context) -> tauri::Result<PathBuf> {
use tauri::Error;
#[cfg(target_os = "macos")]
let path = dirs_next::home_dir()
.ok_or(Error::UnknownPath)
.map(|dir| dir.join("Library/Logs").join(&context.config().identifier))?;
#[cfg(not(target_os = "macos"))]
let path = dirs_next::data_dir()
.ok_or(Error::UnknownPath)
.map(|dir| dir.join(&context.config().identifier).join("logs"))?;
Ok(path)
}
#[cfg(mobile)]
pub fn show_error(text: &str) -> bool {
// needs to do native stuff on mobile
@@ -218,31 +231,3 @@ pub fn valid_java_paths() -> Vec<(OsString, i32)> {
})
.collect()
}
pub fn logger_format(
w: &mut dyn std::io::Write,
_now: &mut DeferredNow,
record: &Record,
ansi: bool,
) -> Result<(), std::io::Error> {
let level = record.level();
let module_path = record.module_path().unwrap_or("<unnamed>");
// Optionally print target
let target = if module_path.starts_with(record.target()) {
"".to_string()
} else {
format!(", {}", record.target())
};
// A toggle for ansi formatting, mainly disabled for file logs, but enabled for terminal logs.
if ansi {
write!(
w,
"{} [{}{target}] {}",
style(level).paint(level.to_string()),
module_path,
style(level).paint(record.args().to_string())
)
} else {
write!(w, "{} [{}{target}] {}", level, module_path, record.args())
}
}

View File

@@ -43,7 +43,7 @@ import { StatusProvider } from './components/providers/StatusSystemContext';
import { VersionUpdateModal } from './components/VersionUpdateModal';
import { CalibrationTutorialPage } from './components/onboarding/pages/CalibrationTutorial';
import { AssignmentTutorialPage } from './components/onboarding/pages/assignment-preparation/AssignmentTutorial';
import { open } from '@tauri-apps/plugin-shell';
import { openUrl } from '@tauri-apps/plugin-opener';
import semver from 'semver';
import { useBreakpoint, useIsTauri } from './hooks/breakpoint';
import { VRModePage } from './components/vr-mode/VRModePage';
@@ -283,7 +283,7 @@ export default function App() {
useEffect(() => {
function onKeyboard(ev: KeyboardEvent) {
if (ev.key === 'F1') {
return open(DOCS_SITE).catch(() => window.open(DOCS_SITE, '_blank'));
return openUrl(DOCS_SITE).catch(() => window.open(DOCS_SITE, '_blank'));
}
}

View File

@@ -9,7 +9,9 @@
grid-template:
't t t' var(--topbar-h)
's c w' calc(100% - var(--topbar-h))
/ var(--navbar-w) calc(100% - var(--navbar-w) - var(--widget-w)) var(--widget-w);
/ var(--navbar-w) calc(100% - var(--navbar-w) - var(--widget-w)) var(
--widget-w
);
}
@screen mobile {

View File

@@ -14,7 +14,7 @@ import { SlimeVRIcon } from './commons/icon/SimevrIcon';
import { ProgressBar } from './commons/ProgressBar';
import { Typography } from './commons/Typography';
import { DownloadIcon } from './commons/icon/DownloadIcon';
import { open } from '@tauri-apps/plugin-shell';
import { openUrl } from '@tauri-apps/plugin-opener';
import { DOCS_SITE, GH_REPO, VersionContext } from '@/App';
import classNames from 'classnames';
import { QuestionIcon } from './commons/icon/QuestionIcon';
@@ -47,7 +47,7 @@ export function VersionTag() {
)}
onClick={() => {
const url = `https://github.com/${GH_REPO}/releases`;
open(url).catch(() => window.open(url, '_blank'));
openUrl(url).catch(() => window.open(url, '_blank'));
}}
>
{(__VERSION_TAG__ || __COMMIT_HASH__) + (__GIT_CLEAN__ ? '' : '-dirty')}
@@ -203,7 +203,7 @@ export function TopBar({
const url = document.body.classList.contains('windows')
? 'https://slimevr.dev/download'
: `https://github.com/${GH_REPO}/releases/latest`;
open(url).catch(() => window.open(url, '_blank'));
openUrl(url).catch(() => window.open(url, '_blank'));
}}
>
<DownloadIcon></DownloadIcon>
@@ -266,7 +266,9 @@ export function TopBar({
'hover:bg-background-60 rounded-full w-7 h-7 cursor-pointer'
)}
onClick={() =>
open(DOCS_SITE).catch(() => window.open(DOCS_SITE, '_blank'))
openUrl(DOCS_SITE).catch(() =>
window.open(DOCS_SITE, '_blank')
)
}
>
<QuestionIcon></QuestionIcon>

View File

@@ -3,7 +3,7 @@ import { useContext, useState } from 'react';
import { BaseModal } from './commons/BaseModal';
import { Button } from './commons/Button';
import { Typography } from './commons/Typography';
import { open } from '@tauri-apps/plugin-shell';
import { openUrl } from '@tauri-apps/plugin-opener';
import semver from 'semver';
import { GH_REPO, VersionContext } from '@/App';
import { error } from '@/utils/logging';
@@ -54,7 +54,7 @@ export function VersionUpdateModal() {
const url = document.body.classList.contains('windows')
? 'https://slimevr.dev/download'
: `https://github.com/${GH_REPO}/releases/latest`;
await open(url).catch(() => window.open(url, '_blank'));
await openUrl(url).catch(() => window.open(url, '_blank'));
closeModal();
}}
>

View File

@@ -1,4 +1,4 @@
import { open } from '@tauri-apps/plugin-shell';
import { openUrl } from '@tauri-apps/plugin-opener';
import { ReactNode } from 'react';
export function A({ href, children }: { href?: string; children?: ReactNode }) {
@@ -6,7 +6,7 @@ export function A({ href, children }: { href?: string; children?: ReactNode }) {
<a
href="javascript:void(0)"
onClick={() =>
href && open(href).catch(() => window.open(href, '_blank'))
href && openUrl(href).catch(() => window.open(href, '_blank'))
}
className="underline"
>

View File

@@ -333,7 +333,7 @@ export function DrawerTooltip({
elem.classList.add(classNames('duration-500'));
touchTimeout.current = setTimeout(() => {
open();
}, TOOLTIP_DELAY);
}, TOOLTIP_DELAY) as unknown as number;
}
};

View File

@@ -118,7 +118,7 @@ export function ResetButton({
finishedTimeoutRef.current = setTimeout(() => {
setFinished(false);
finishedTimeoutRef.current = -1;
}, 2000);
}, 2000) as unknown as number;
if (onReseted) onReseted();
},
});

View File

@@ -12,9 +12,9 @@
grid-template:
's t' var(--connect-tracker-layout-top)
's c' calc(100% - var(--connect-tracker-layout-top))
/ calc(var(--connect-tracker-layout-sidebar)) calc(100% - var(
--connect-tracker-layout-sidebar
));
/ calc(var(--connect-tracker-layout-sidebar)) calc(
100% - var(--connect-tracker-layout-sidebar)
);
@screen mobile {
grid-template:

View File

@@ -7,9 +7,9 @@
grid-template:
't t t' var(--topbar-h)
'n s c' calc(100% - var(--topbar-h))
/ var(--navbar-w) var(--settings-sidebar-w) calc(100% - var(--navbar-w) - var(
--settings-sidebar-w
));
/ var(--navbar-w) var(--settings-sidebar-w) calc(
100% - var(--navbar-w) - var(--settings-sidebar-w)
);
@screen lg {
--settings-sidebar-w: 270px;

View File

@@ -1,6 +1,6 @@
import { Localized, useLocalization } from '@fluent/react';
import classNames from 'classnames';
import { IPv4 } from 'ip-num/IPNumber';
import { IPv4 } from 'ip-num';
import { useEffect, useMemo, useState } from 'react';
import { useForm } from 'react-hook-form';
import { useParams } from 'react-router-dom';

View File

@@ -1,6 +1,6 @@
import { useLocalization } from '@fluent/react';
import classNames from 'classnames';
import { IPv4 } from 'ip-num/IPNumber';
import { IPv4 } from 'ip-num';
import { MouseEventHandler, ReactNode, useMemo, useState } from 'react';
import {
TrackerDataT,

View File

@@ -1,15 +1,17 @@
import { isTauri } from '@tauri-apps/api/core';
import { createStore } from '@tauri-apps/plugin-store';
import { LazyStore } from '@tauri-apps/plugin-store';
interface CrossStorage {
set(key: string, value: string): Promise<void>;
get(key: string): Promise<string | null>;
set(key: string, value: unknown): Promise<void>;
get<T>(key: string): Promise<T | undefined>;
delete(key: string): Promise<boolean>;
}
const localStore: CrossStorage = {
get: async (key) => localStorage.getItem(`slimevr-cache/${key}`),
set: async (key, value) => localStorage.setItem(`slimevr-cache/${key}`, value),
get: async <T>(key: string) =>
(localStorage.getItem(`slimevr-cache/${key}`) as T) ?? undefined,
set: async (key, value) =>
localStorage.setItem(`slimevr-cache/${key}`, value as string),
delete: async (key) => {
localStorage.removeItem(`slimevr-cache/${key}`);
return true;
@@ -17,11 +19,11 @@ const localStore: CrossStorage = {
};
const store: CrossStorage = isTauri()
? await createStore('gui-cache.dat', { autoSave: 100 as never })
? new LazyStore('gui-cache.dat', { autoSave: 100, defaults: {} })
: localStore;
export async function cacheGet(key: string): Promise<string | null> {
const itemStr = await store.get(key);
const itemStr = await store.get<string>(key);
if (!itemStr) {
return null;

View File

@@ -5,7 +5,7 @@ import {
} from '@/components/widgets/DeveloperModeWidget';
import { error } from '@/utils/logging';
import { useDebouncedEffect } from './timeout';
import { createStore, Store } from '@tauri-apps/plugin-store';
import { load, Store } from '@tauri-apps/plugin-store';
import { useIsTauri } from './breakpoint';
import { waitUntil } from '@/utils/a11y';
import { isTauri } from '@tauri-apps/api/core';
@@ -78,17 +78,17 @@ export const defaultConfig: Config = {
};
interface CrossStorage {
set(key: string, value: string): Promise<void>;
get(key: string): Promise<string | null>;
set(key: string, value: unknown): Promise<void>;
get<T>(key: string): Promise<T | undefined>;
}
const localStore: CrossStorage = {
get: async (key) => localStorage.getItem(key),
set: async (key, value) => localStorage.setItem(key, value),
get: async <T>(key: string) => (localStorage.getItem(key) as T) ?? undefined,
set: async (key, value) => localStorage.setItem(key, value as string),
};
const store: CrossStorage = isTauri()
? await createStore('gui-settings.dat', { autoSave: 100 as never })
? await load('gui-settings.dat', { autoSave: 100, defaults: {} })
: localStore;
function fallbackToDefaults(loadedConfig: any): Config {
@@ -99,7 +99,7 @@ function fallbackToDefaults(loadedConfig: any): Config {
// allows to load everything before the first render
export const loadConfig = async () => {
try {
const migrated = await store.get('configMigratedToTauri');
const migrated = await store.get<string>('configMigratedToTauri');
if (!migrated) {
const oldConfig = localStorage.getItem('config.json');
@@ -108,7 +108,7 @@ export const loadConfig = async () => {
store.set('configMigratedToTauri', 'true');
}
const json = await store.get('config.json');
const json = await store.get<string>('config.json');
if (!json) throw new Error('Config has ceased existing for some reason');

View File

@@ -1,16 +1,17 @@
import { invoke, isTauri } from '@tauri-apps/api/core';
import { isTauri } from '@tauri-apps/api/core';
import { warn as tauriWarn, error as tauriError, info } from '@tauri-apps/plugin-log';
export function log(...msgs: any[]) {
console.log(...msgs);
if (isTauri()) invoke('logging', { msg: msgs.join() });
if (isTauri()) info(msgs.join());
}
export function error(...msgs: any[]) {
console.error(...msgs);
if (isTauri()) invoke('erroring', { msg: msgs.join() });
if (isTauri()) tauriError(msgs.join());
}
export function warn(...msgs: any[]) {
console.warn(...msgs);
if (isTauri()) invoke('warning', { msg: msgs.join() });
if (isTauri()) tauriWarn(msgs.join());
}

4831
pnpm-lock.yaml generated

File diff suppressed because it is too large Load Diff

View File

@@ -1,4 +1,4 @@
[toolchain]
channel = "1.82"
channel = "1.89"
profile = "default"
components = ["rustc", "cargo", "clippy", "rustfmt", "rust-analyzer", "rust-src"]