Added persistant settings on desktop
Build Mumble Web 2 / linux_build (push) Successful in 1m24s
Build Mumble Web 2 / windows_build (push) Successful in 2m17s

This commit is contained in:
2026-01-10 15:51:36 -07:00
parent 86e4753fbc
commit a7c307959c
5 changed files with 74 additions and 4 deletions
Generated
+21
View File
@@ -2270,6 +2270,17 @@ dependencies = [
"xxhash-rust", "xxhash-rust",
] ]
[[package]]
name = "etcetera"
version = "0.10.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "26c7b13d0780cb82722fd59f6f57f925e143427e4a75313a6c77243bf5326ae6"
dependencies = [
"cfg-if",
"home",
"windows-sys 0.59.0",
]
[[package]] [[package]]
name = "euclid" name = "euclid"
version = "0.22.11" version = "0.22.11"
@@ -3157,6 +3168,15 @@ version = "1.1.12"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ad6880c8d4a9ebf39c6e8b77007ce223f646a4d21ce29d99f70cb16420545425" checksum = "ad6880c8d4a9ebf39c6e8b77007ce223f646a4d21ce29d99f70cb16420545425"
[[package]]
name = "home"
version = "0.5.12"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "cc627f471c528ff0c4a49e1d5e60450c8f6461dd6d10ba9dcd3a61d3dff7728d"
dependencies = [
"windows-sys 0.61.2",
]
[[package]] [[package]]
name = "html-purifier" name = "html-purifier"
version = "0.3.0" version = "0.3.0"
@@ -4261,6 +4281,7 @@ dependencies = [
"dioxus", "dioxus",
"dioxus-asset-resolver", "dioxus-asset-resolver",
"dioxus-web", "dioxus-web",
"etcetera",
"futures", "futures",
"futures-channel", "futures-channel",
"gloo-timers", "gloo-timers",
+2
View File
@@ -63,6 +63,7 @@ tokio-rustls = { version = "^0.26.0", optional = true }
opus = { version = "0.3.0", optional = true } opus = { version = "0.3.0", optional = true }
cpal = { version = "0.15.3", optional = true } cpal = { version = "0.15.3", optional = true }
dasp_ring_buffer = { version = "0.11.0", optional = true } dasp_ring_buffer = { version = "0.11.0", optional = true }
etcetera = { version = "0.10.0", optional = true }
# Base Dependencies # Base Dependencies
# ================ # ================
@@ -130,4 +131,5 @@ desktop = [
"cpal", "cpal",
"dasp_ring_buffer", "dasp_ring_buffer",
"rfd/xdg-portal", "rfd/xdg-portal",
"etcetera",
] ]
+3
View File
@@ -575,6 +575,9 @@ pub fn LoginView(config: Resource<ClientConfig>) -> Element {
let do_connect = move |_| { let do_connect = move |_| {
//let _ = set_default_username(&username.read()); //let _ = set_default_username(&username.read());
let _ = imp::set_default_username(&username.read()); let _ = imp::set_default_username(&username.read());
if config.read().as_ref().is_some_and(|cfg| cfg.any_server) {
imp::set_default_server(&address.read());
}
net.send(Connect { net.send(Connect {
address: address.read().clone(), address: address.read().clone(),
username: username.read().clone(), username: username.read().clone(),
+44 -4
View File
@@ -1,11 +1,13 @@
use crate::app::Command; use crate::app::Command;
use crate::effects::{AudioProcessor, AudioProcessorSender}; use crate::effects::{AudioProcessor, AudioProcessorSender};
use color_eyre::eyre::{bail, eyre, Context, Error}; use color_eyre::eyre::{bail, eyre, Error};
use cpal::traits::{DeviceTrait, HostTrait, StreamTrait as _}; use cpal::traits::{DeviceTrait, HostTrait, StreamTrait as _};
use dioxus::hooks::UnboundedReceiver; use dioxus::hooks::UnboundedReceiver;
use etcetera::{choose_app_strategy, AppStrategy, AppStrategyArgs};
use futures::io::{AsyncRead, AsyncWrite}; use futures::io::{AsyncRead, AsyncWrite};
use mumble_protocol::control::ClientControlCodec; use mumble_protocol::control::ClientControlCodec;
use mumble_web2_common::{ClientConfig, ServerStatus}; use mumble_web2_common::{ClientConfig, ServerStatus};
use std::collections::HashMap;
use std::mem::replace; use std::mem::replace;
use std::net::ToSocketAddrs; use std::net::ToSocketAddrs;
use std::sync::Arc; use std::sync::Arc;
@@ -314,17 +316,55 @@ pub async fn network_connect(
crate::network_loop(username, event_rx, reader, writer).await crate::network_loop(username, event_rx, reader, writer).await
} }
fn get_config_path() -> std::path::PathBuf {
let strategy = choose_app_strategy(AppStrategyArgs {
top_level_domain: "com".to_string(),
author: "Ohea Corp".to_string(),
app_name: "Mumble Web2".to_string(),
})
.expect("failed to choose app strategy");
strategy.config_dir().join("config.json")
}
fn load_config_map() -> HashMap<String, String> {
let config_path = get_config_path();
match std::fs::read_to_string(&config_path) {
Ok(contents) => serde_json::from_str(&contents).unwrap_or_default(),
Err(_) => HashMap::new(),
}
}
fn save_config_map(config: &HashMap<String, String>) -> color_eyre::Result<()> {
let config_path = get_config_path();
if let Some(parent) = config_path.parent() {
std::fs::create_dir_all(parent)?;
}
let contents = serde_json::to_string_pretty(config)?;
std::fs::write(&config_path, contents)?;
Ok(())
}
pub fn set_default_username(username: &str) -> Option<()> { pub fn set_default_username(username: &str) -> Option<()> {
None let mut config = load_config_map();
config.insert("username".to_string(), username.to_string());
save_config_map(&config).ok()
}
pub fn set_default_server(server: &str) -> Option<()> {
let mut config = load_config_map();
config.insert("server".to_string(), server.to_string());
save_config_map(&config).ok()
} }
pub fn load_username() -> Option<String> { pub fn load_username() -> Option<String> {
return None; let config = load_config_map();
config.get("username").cloned()
} }
pub async fn load_config() -> color_eyre::Result<ClientConfig> { pub async fn load_config() -> color_eyre::Result<ClientConfig> {
let config = load_config_map();
Ok(ClientConfig { Ok(ClientConfig {
proxy_url: None, proxy_url: config.get("server").cloned(),
cert_hash: None, cert_hash: None,
any_server: true, any_server: true,
}) })
+4
View File
@@ -399,6 +399,10 @@ pub fn set_default_username(username: &str) -> Option<()> {
.ok() .ok()
} }
pub fn set_default_server(username: &str) -> Option<()> {
None
}
pub fn load_username() -> Option<String> { pub fn load_username() -> Option<String> {
web_sys::window() web_sys::window()
.unwrap() .unwrap()