Redesign login view with server card list, add/edit/delete modals,
and per-server ping status display. Rename ProxyOverrides to ClientConfig,
remove ConfigSystemInterface in favor of direct platform methods
(load_config, load_username, set_default_username, load_server_url),
remove SharedState threading in favor of global STATE, simplify
network_loop and audio setup, update proxy endpoint from /overrides
to /config, and clean up desktop launch configuration.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Add ServerEntry model, load_servers/save_servers/set_default_server
to PlatformInterface with implementations for desktop (etcetera config),
web (localStorage), mobile (stub), and stub platforms. Implement
mumble_udp_ping protocol on desktop for direct server status queries.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Puts the denoise bool into an AudioSettings struct in the model state, and persists changes to user state.
Co-authored-by: Sam Sartor <me@samsartor.com>
Co-committed-by: Sam Sartor <me@samsartor.com>
Previously the model state was in a `static STATE` to make it accessible to all the various subsystems. This moves it into an Arc and plumbs the reference around via function arguments. That allows us to do non-static initialization, eg based on user config. I also moved some things into dioxus context.
Co-authored-by: Sam Sartor <me@samsartor.com>
Co-committed-by: Sam Sartor <me@samsartor.com>
Some quick QAL changes I banged out this morning. The commit messages describe the individual changes in details.
## Changes
- Min window width on desktop.
- Removes white flash on desktop startup
- Removes right click menu on release builds (still exists on debug, and might come back in the future with new features).
Reviewed-on: #27
Reviewed-by: restitux <restitux@ohea.xyz>
This change migrates the config logic to a new generic key+value abstraction. This allows config parameters to be get and set with arbitrary string keys. Config value types can be anything that serde knows how to serialize / deserialize.
Implementations:
Desktop:
Uses a json file in a platform specific directory (pulled from etcetera). This is mostly the same as the existing code. Implemented in `native_config.rs`
Android:
Uses the same mechanism as desktop, with a different path selection that calls out to the android apis (via jni) to get the correct directory.
Web:
Uses browser local storage. Values are stored as strings instead of actual json objects to keep things simple for now. We might want to update this at some point.
Desktop support:

```
% cat ~/.config/mumble-web2/config.json
{
"username": "restitux-test",
"server_url": "voip.ohea.xyz"
}%
```
Web support:

Android support:

```
root@c053bdd1b4da:/# adb shell
tokay:/ $ run-as xyz.ohea.mumble_web_2
tokay:/data/user/0/xyz.ohea.mumble_web_2 $ ls
app_textures app_webview cache code_cache files no_backup shared_prefs
tokay:/data/user/0/xyz.ohea.mumble_web_2 $ ls files
config.json oat permission_manager.dex
tokay:/data/user/0/xyz.ohea.mumble_web_2 $ cat files/config.json
{
"server_url": "voip.ohea.xyz",
"username": "test"
}tokay:/data/user/0/xyz.ohea.mumble_web_2 $
```
Reviewed-on: #25
Reviewed-by: Sam Sartor <cap@samsartor.com>
This change adds CI to build the desktop client for MacOS. This builds the desktop client as a dmg and a .app and uploads them from the CI pipeline.
Reviewed-on: #26
Reviewed-by: Sam Sartor <cap@samsartor.com>