add /config endpoint, add docker proxy setup, and style chat box

This commit is contained in:
2025-07-13 19:33:55 -06:00
parent 74fe399cdc
commit 1793504467
12 changed files with 561 additions and 94 deletions
Generated
+252 -40
View File
@@ -306,6 +306,15 @@ dependencies = [
"syn 2.0.87",
]
[[package]]
name = "async_cell"
version = "0.2.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "447ab28afbb345f5408b120702a44e5529ebf90b1796ec76e9528df8e288e6c2"
dependencies = [
"loom",
]
[[package]]
name = "asynchronous-codec"
version = "0.6.2"
@@ -2160,6 +2169,20 @@ dependencies = [
"tracing",
]
[[package]]
name = "generator"
version = "0.8.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d18470a76cb7f8ff746cf1f7470914f900252ec36bbc40b569d74b1258446827"
dependencies = [
"cc",
"cfg-if",
"libc",
"log",
"rustversion",
"windows 0.61.3",
]
[[package]]
name = "generic-array"
version = "0.14.7"
@@ -2631,9 +2654,9 @@ checksum = "df3b46402a9d5adb4c86a0cf463f42e19994e3ee891101b1841f30a545cb49a9"
[[package]]
name = "hyper"
version = "1.5.0"
version = "1.6.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bbbff0a806a4728c99295b254c8838933b5b082d75e3cb70c8dab21fdfbcfa9a"
checksum = "cc2b571658e38e0c01b1fdca3bbbe93c00d3d71693ff2770043f8c29bc7d6f80"
dependencies = [
"bytes",
"futures-channel",
@@ -2687,21 +2710,28 @@ dependencies = [
[[package]]
name = "hyper-util"
version = "0.1.10"
version = "0.1.15"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "df2dcfbe0677734ab2f3ffa7fa7bfd4706bfdc1ef393f2ee30184aed67e631b4"
checksum = "7f66d5bd4c6f02bf0542fad85d626775bab9258cf795a4256dcaf3161114d1df"
dependencies = [
"base64 0.22.1",
"bytes",
"futures-channel",
"futures-core",
"futures-util",
"http",
"http-body",
"hyper",
"ipnet",
"libc",
"percent-encoding",
"pin-project-lite",
"socket2",
"system-configuration",
"tokio",
"tower-service",
"tracing",
"windows-registry",
]
[[package]]
@@ -2908,6 +2938,16 @@ version = "2.10.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ddc24109865250148c2e0f3d25d4f0f479571723792d3802153c60922a4fb708"
[[package]]
name = "iri-string"
version = "0.7.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "dbc5ebe9c3a1a7a5127f920a418f7585e9e758e911d0466ed004f393b0e380b2"
dependencies = [
"memchr",
"serde",
]
[[package]]
name = "itertools"
version = "0.12.1"
@@ -2985,10 +3025,11 @@ dependencies = [
[[package]]
name = "js-sys"
version = "0.3.72"
version = "0.3.77"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6a88f1bda2bd75b0452a14784937d796722fdebfe50df998aeb3f0b7603019a9"
checksum = "1cfaf33c695fc6e08064efbc1f72ec937429614f25eef83af942d0e227c3a28f"
dependencies = [
"once_cell",
"wasm-bindgen",
]
@@ -3075,9 +3116,9 @@ dependencies = [
[[package]]
name = "libc"
version = "0.2.162"
version = "0.2.174"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "18d287de67fe55fd7e1581fe933d965a5a9477b38e949cfa9f8574ef01506398"
checksum = "1171693293099992e19cddea4e8b849964e9846f4acee11b3948bcc337be8776"
[[package]]
name = "libloading"
@@ -3207,6 +3248,19 @@ version = "0.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b3bd0dd2cd90571056fdb71f6275fada10131182f84899f4b2a916e565d81d86"
[[package]]
name = "loom"
version = "0.7.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "419e0dc8046cb947daa77eb95ae174acfbddb7673b4151f56d1eed8e93fbfaca"
dependencies = [
"cfg-if",
"generator",
"scoped-tls",
"tracing",
"tracing-subscriber",
]
[[package]]
name = "mac"
version = "0.1.1"
@@ -3489,6 +3543,7 @@ dependencies = [
name = "mumble-web2-gui"
version = "0.1.0"
dependencies = [
"async_cell",
"asynchronous-codec",
"base64 0.22.1",
"byteorder",
@@ -3514,6 +3569,7 @@ dependencies = [
"once_cell",
"opus",
"ordermap",
"reqwest",
"rfd 0.15.2",
"serde",
"serde-wasm-bindgen 0.6.5",
@@ -3750,7 +3806,7 @@ version = "0.7.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "af1844ef2428cc3e1cb900be36181049ef3d3193c63e43026cfe202983b27a56"
dependencies = [
"proc-macro-crate 2.0.0",
"proc-macro-crate 3.2.0",
"proc-macro2",
"quote",
"syn 2.0.87",
@@ -4711,9 +4767,9 @@ checksum = "2b15c43186be67a4fd63bee50d0303afffcef381492ebe2c5d87f324e1b8815c"
[[package]]
name = "reqwest"
version = "0.12.9"
version = "0.12.22"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a77c62af46e79de0a562e1a9849205ffcb7fc1238876e9bd743357570e04046f"
checksum = "cbc931937e6ca3a06e3b6c0aa7841849b160a90351d6ab467a8b9b9959767531"
dependencies = [
"base64 0.22.1",
"bytes",
@@ -4728,31 +4784,29 @@ dependencies = [
"hyper-rustls",
"hyper-tls",
"hyper-util",
"ipnet",
"js-sys",
"log",
"mime",
"mime_guess",
"native-tls",
"once_cell",
"percent-encoding",
"pin-project-lite",
"rustls-pemfile",
"rustls-pki-types",
"serde",
"serde_json",
"serde_urlencoded",
"sync_wrapper 1.0.1",
"system-configuration",
"sync_wrapper",
"tokio",
"tokio-native-tls",
"tokio-util",
"tower",
"tower-http",
"tower-service",
"url",
"wasm-bindgen",
"wasm-bindgen-futures",
"wasm-streams",
"web-sys",
"windows-registry",
]
[[package]]
@@ -4982,6 +5036,8 @@ version = "0.74.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7a941a79d92a35187603ddb3ee6010649e687341a943666224642bf9c1c6b4f8"
dependencies = [
"salvo-cors",
"salvo-craft",
"salvo-jwt-auth",
"salvo-proxy",
"salvo-serve-static",
@@ -4989,6 +5045,39 @@ dependencies = [
"salvo_extra",
]
[[package]]
name = "salvo-cors"
version = "0.74.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "76ad895197577cca6e7b35f5ec0810a84a42aa229c501985153e3b7cdce27136"
dependencies = [
"bytes",
"salvo_core",
"tracing",
]
[[package]]
name = "salvo-craft"
version = "0.74.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ef9718312065c4762a3a8c697e1937fe5ffee615f2cf4e7986414de82088d1e0"
dependencies = [
"salvo-craft-macros",
]
[[package]]
name = "salvo-craft-macros"
version = "0.74.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2fa3960c9ae2af644d0561a1ff24e43bcd4b7e32175584c663196868406963af"
dependencies = [
"proc-macro-crate 3.2.0",
"proc-macro2",
"quote",
"regex",
"syn 2.0.87",
]
[[package]]
name = "salvo-http3"
version = "0.3.1"
@@ -5115,7 +5204,7 @@ dependencies = [
"serde",
"serde-xml-rs",
"serde_json",
"sync_wrapper 1.0.1",
"sync_wrapper",
"tempfile",
"thiserror 2.0.3",
"tokio",
@@ -5152,7 +5241,7 @@ version = "0.74.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ddf066ba183548285f7dc8db26a35767e94ac2fc95f397913c98d5b63b45bed4"
dependencies = [
"proc-macro-crate 2.0.0",
"proc-macro-crate 3.2.0",
"proc-macro2",
"quote",
"regex",
@@ -5606,9 +5695,9 @@ checksum = "3c5e1a9a646d36c3599cd173a41282daf47c44583ad367b8e6837255952e5c67"
[[package]]
name = "socket2"
version = "0.5.7"
version = "0.5.10"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ce305eb0b4296696835b71df73eb912e0f1ffd2556a501fcede6e0c50349191c"
checksum = "e22376abed350d73dd1cd119b57ffccad95b4e585a7cda43e286245ce23c0678"
dependencies = [
"libc",
"windows-sys 0.52.0",
@@ -5718,12 +5807,6 @@ dependencies = [
"unicode-ident",
]
[[package]]
name = "sync_wrapper"
version = "0.1.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2047c6ded9c721764247e62cd3b03c09ffc529b2ba5b10ec482ae507a4a70160"
[[package]]
name = "sync_wrapper"
version = "1.0.1"
@@ -6106,14 +6189,14 @@ dependencies = [
[[package]]
name = "tower"
version = "0.5.1"
version = "0.5.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2873938d487c3cfb9aed7546dc9f2711d867c9f90c46b889989a2cb84eba6b4f"
checksum = "d039ad9159c98b70ecfd540b2573b97f7f52c3e8d9f8ad57a24b916a536975f9"
dependencies = [
"futures-core",
"futures-util",
"pin-project-lite",
"sync_wrapper 0.1.2",
"sync_wrapper",
"tokio",
"tokio-util",
"tower-layer",
@@ -6121,6 +6204,24 @@ dependencies = [
"tracing",
]
[[package]]
name = "tower-http"
version = "0.6.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "adc82fd73de2a9722ac5da747f12383d2bfdb93591ee6c58486e0097890f05f2"
dependencies = [
"bitflags 2.6.0",
"bytes",
"futures-util",
"http",
"http-body",
"iri-string",
"pin-project-lite",
"tower",
"tower-layer",
"tower-service",
]
[[package]]
name = "tower-layer"
version = "0.3.3"
@@ -6707,8 +6808,8 @@ dependencies = [
"webview2-com-sys",
"windows 0.58.0",
"windows-core 0.58.0",
"windows-implement",
"windows-interface",
"windows-implement 0.58.0",
"windows-interface 0.58.0",
]
[[package]]
@@ -6796,6 +6897,28 @@ dependencies = [
"windows-targets 0.52.6",
]
[[package]]
name = "windows"
version = "0.61.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9babd3a767a4c1aef6900409f85f5d53ce2544ccdfaa86dad48c91782c6d6893"
dependencies = [
"windows-collections",
"windows-core 0.61.2",
"windows-future",
"windows-link",
"windows-numerics",
]
[[package]]
name = "windows-collections"
version = "0.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3beeceb5e5cfd9eb1d76b381630e82c4241ccd0d27f1a39ed41b2760b255c5e8"
dependencies = [
"windows-core 0.61.2",
]
[[package]]
name = "windows-core"
version = "0.54.0"
@@ -6812,13 +6935,37 @@ version = "0.58.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6ba6d44ec8c2591c134257ce647b7ea6b20335bf6379a27dac5f1641fcf59f99"
dependencies = [
"windows-implement",
"windows-interface",
"windows-implement 0.58.0",
"windows-interface 0.58.0",
"windows-result 0.2.0",
"windows-strings",
"windows-strings 0.1.0",
"windows-targets 0.52.6",
]
[[package]]
name = "windows-core"
version = "0.61.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c0fdd3ddb90610c7638aa2b3a3ab2904fb9e5cdbecc643ddb3647212781c4ae3"
dependencies = [
"windows-implement 0.60.0",
"windows-interface 0.59.1",
"windows-link",
"windows-result 0.3.4",
"windows-strings 0.4.2",
]
[[package]]
name = "windows-future"
version = "0.2.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "fc6a41e98427b19fe4b73c550f060b59fa592d7d686537eebf9385621bfbad8e"
dependencies = [
"windows-core 0.61.2",
"windows-link",
"windows-threading",
]
[[package]]
name = "windows-implement"
version = "0.58.0"
@@ -6830,6 +6977,17 @@ dependencies = [
"syn 2.0.87",
]
[[package]]
name = "windows-implement"
version = "0.60.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a47fddd13af08290e67f4acabf4b459f647552718f683a7b415d290ac744a836"
dependencies = [
"proc-macro2",
"quote",
"syn 2.0.87",
]
[[package]]
name = "windows-interface"
version = "0.58.0"
@@ -6842,14 +7000,41 @@ dependencies = [
]
[[package]]
name = "windows-registry"
name = "windows-interface"
version = "0.59.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bd9211b69f8dcdfa817bfd14bf1c97c9188afa36f4750130fcdf3f400eca9fa8"
dependencies = [
"proc-macro2",
"quote",
"syn 2.0.87",
]
[[package]]
name = "windows-link"
version = "0.1.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5e6ad25900d524eaabdbbb96d20b4311e1e7ae1699af4fb28c17ae66c80d798a"
[[package]]
name = "windows-numerics"
version = "0.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e400001bb720a623c1c69032f8e3e4cf09984deec740f007dd2b03ec864804b0"
checksum = "9150af68066c4c5c07ddc0ce30421554771e528bde427614c61038bc2c92c2b1"
dependencies = [
"windows-result 0.2.0",
"windows-strings",
"windows-targets 0.52.6",
"windows-core 0.61.2",
"windows-link",
]
[[package]]
name = "windows-registry"
version = "0.5.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5b8a9ed28765efc97bbc954883f4e6796c33a06546ebafacbabee9696967499e"
dependencies = [
"windows-link",
"windows-result 0.3.4",
"windows-strings 0.4.2",
]
[[package]]
@@ -6870,6 +7055,15 @@ dependencies = [
"windows-targets 0.52.6",
]
[[package]]
name = "windows-result"
version = "0.3.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "56f42bd332cc6c8eac5af113fc0c1fd6a8fd2aa08a0119358686e5160d0586c6"
dependencies = [
"windows-link",
]
[[package]]
name = "windows-strings"
version = "0.1.0"
@@ -6880,6 +7074,15 @@ dependencies = [
"windows-targets 0.52.6",
]
[[package]]
name = "windows-strings"
version = "0.4.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "56e6c93f3a0c3b36176cb1327a4958a0353d5d166c2a35cb268ace15e91d3b57"
dependencies = [
"windows-link",
]
[[package]]
name = "windows-sys"
version = "0.45.0"
@@ -6962,6 +7165,15 @@ dependencies = [
"windows_x86_64_msvc 0.52.6",
]
[[package]]
name = "windows-threading"
version = "0.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b66463ad2e0ea3bbf808b7f1d371311c80e115c0b71d60efc142cafbcfb057a6"
dependencies = [
"windows-link",
]
[[package]]
name = "windows-version"
version = "0.1.1"
+10
View File
@@ -0,0 +1,10 @@
localhost:64444 {
tls internal
# Proxy /config path to mumble-web2-proxy
reverse_proxy /config http://127.0.0.1:4400
# Proxy root path to dx-serve
reverse_proxy http://127.0.0.1:8080
}
+22
View File
@@ -0,0 +1,22 @@
FROM rust:1-bookworm AS base
# Install cargo-binstall for faster CLI installation
#RUN curl -L --proto '=https' --tlsv1.2 -sSf https://raw.githubusercontent.com/cargo-bins/cargo-binstall/main/install-from-binstall-release.sh | bash
RUN apt-get update && apt-get install -y screen
# Install dioxus-cli version 0.6.3 specifically
RUN cargo install dioxus-cli --version 0.6.3
# Set working directory
WORKDIR /app
# Add wasm32 target for web development
RUN rustup target add wasm32-unknown-unknown
# Set environment variables
ENV PATH="/root/.cargo/bin:$PATH"
# Default command (can be overridden in docker-compose)
CMD ["dx", "--help"]
+60
View File
@@ -0,0 +1,60 @@
services:
caddy:
image: caddy:latest
ports:
- "64444:64444/tcp"
- "64444:64444/udp"
volumes:
- ./Caddyfile:/etc/caddy/Caddyfile
#- caddy_data:/data
#- caddy_config:/config
depends_on:
#- dx-serve
- mumble-web2-proxy
network_mode: host
#dx-serve:
# build:
# dockerfile: ./dioxus.Dockerfile
# working_dir: /app
# volumes:
# - ..:/app
# environment:
# - MUMBLE_WEB2_GUI_CONFIG_URL=https://localhost:64444/config
# stdin_open: true
# tty: true
# command: >
# bash -c "
# screen -dmS serve bash -c 'dx serve -p mumble-web2-gui --platform web' &&
# tail -f /dev/null
# "
# networks:
# - app-network
mumble-web2-proxy:
image: rust:latest
working_dir: /app
volumes:
- ..:/app
- ./proxy-config.toml:/app/config.toml
ports:
- "4433:4433/tcp"
- "4433:4433/udp"
command: ["cargo", "run", "-p", "mumble-web2-proxy"]
network_mode: host
mumble-server:
image: mumblevoip/mumble-server:latest
ports:
- "64738:64738/tcp"
- "64738:64738/udp"
environment:
- MUMBLE_CONFIG_WELCOMETEXT=Welcome to the Mumble server
network_mode: host
#volumes:
# caddy_data:
# caddy_config:
#
#networks:
# app-network:
# driver: bridge
+12
View File
@@ -0,0 +1,12 @@
https_listen_address = "127.0.0.1:4433"
http_listen_address = "127.0.0.1:4400"
#cert_path = "./cert.pem"
#key_path = "./key.pem"
#mumble_server_url = "voip.ohea.xyz:64738"
mumble_server_url = "127.0.0.1:64738"
#gui_path = "./target/dx/mumble-web2-gui/release/web/public"
gui_path = "./target/dx/mumble-web2-gui/debug/web/public"
[gui]
force_proxy = true
proxy_url = "https://127.0.0.1:4433/proxy"
+2
View File
@@ -95,6 +95,8 @@ lol_html = "2.2.0"
rfd = "0.15.2"
base64 = "0.22"
mime_guess = "2.0.5"
async_cell = "0.2.3"
reqwest = { version = "0.12.22", features = ["json"] }
[features]
web = [
+129 -37
View File
@@ -3,9 +3,11 @@
use base64::{display::Base64Display, prelude::BASE64_URL_SAFE};
use dioxus::prelude::*;
use mime_guess::Mime;
use mumble_web2_common::GuiConfig;
use ordermap::OrderSet;
use sir::{css, global_css};
use std::collections::HashMap;
use tracing::error;
use crate::{imp, CONFIG};
@@ -279,6 +281,13 @@ pub fn ChatView() -> Element {
let server = STATE.server.read();
let mut draft = use_signal(|| "".to_string());
let chat_panel = css!(
"
display: flex;
flex-direction: column;
"
);
let chat_history = css!(
"
overflow-y: auto;
@@ -296,18 +305,44 @@ pub fn ChatView() -> Element {
"
);
let chat_box_wrapper = css!(
"
padding: 16px;
border-top: solid var(--line-color) var(--line-width);
"
);
let chat_box = css!(
"
display: flex;
flex-direction: row;
padding: 16px;
gap: 8px;
border-top: solid var(--line-color) var(--line-width);
gap: 16px;
background-color: var(--light-bg-color);
padding-top: 16px;
padding-bottom: 16px;
padding-left: 8px;
padding-right: 16px;
border-radius: 8px;
input {
color: white;
background-color: var(--light-bg-color);
font-size: larger;
flex-grow: 1;
padding: 8px;
border: none;
}
input:focus {
outline: none;
}
"
);
@@ -322,49 +357,88 @@ pub fn ChatView() -> Element {
rsx!(
div {
class: "{chat_history}",
for chat in server.chat.iter() {
div {
class: "{chat_message}",
if let Some(sender) = chat.sender.and_then(|u| server.users.get(&u)) {
UserPill {
name: sender.name.clone(),
icon: UserIcon::None,
isself: false,
class: "{chat_panel}",
div {
class: "{chat_history}",
for chat in server.chat.iter() {
div {
class: "{chat_message}",
if let Some(sender) = chat.sender.and_then(|u| server.users.get(&u)) {
UserPill {
name: sender.name.clone(),
icon: UserIcon::None,
isself: false,
}
}
span {
dangerous_inner_html: "{chat.dangerous_html}",
}
}
span {
dangerous_inner_html: "{chat.dangerous_html}",
}
}
}
}
div {
class: "{chat_box}",
input {
placeholder: "say something",
value: "{draft.read()}",
oninput: move |evt| draft.set(evt.value().clone()),
onkeypress: move |evt: Event<KeyboardData>| {
if evt.code() == Code::Enter && evt.modifiers().is_empty() {
do_send();
div {
class: "{chat_box_wrapper}",
div {
class: "{chat_box}",
input {
placeholder: "say something",
value: "{draft.read()}",
oninput: move |evt| draft.set(evt.value().clone()),
onkeypress: move |evt: Event<KeyboardData>| {
if evt.code() == Code::Enter && evt.modifiers().is_empty() {
do_send();
}
}
}
div {
span {
onclick: move |_| pick_and_send_file(&net),
class: "material-symbols-outlined",
style: "color: rgba(255, 255, 255, 0.5); font-variation-settings: 'FILL' 1, 'wght' 700, 'GRAD' 0, 'opsz' 48; vertical-align: middle; font-size: 35px; user-select: none;",
"attach_file",
}
}
div {
span {
onclick: move |_| do_send(),
class: "material-symbols-outlined",
style: "color: rgba(255, 255, 255, 0.5); font-variation-settings: 'FILL' 1, 'wght' 700, 'GRAD' 0, 'opsz' 48; vertical-align: middle; font-size: 35px; user-select: none;",
"send",
}
}
}
}
button {
onclick: move |_| pick_and_send_file(&net),
"File"
}
button {
onclick: move |_| do_send(),
"Send"
//button {
// onclick: move |_| do_send(),
// "Send"
//}
}
}
)
}
// true => rsx!(span { class: "material-symbols-outlined", style: "{button_style}", "mic_off"}),
//Connecting => rsx! {
// div {
// class: "{connecting_status}",
// span {
// class: "material-symbols-outlined",
// style: "vertical-align: middle; font-size: 30px;",
// "signal_cellular_alt_2_bar"
// }
// span {
// style: "width: 5px; display: inline-block;"
// }
// span {
// style: "vertical-align: middle; font-size: 30px;",
// "Connecting"
// }
// }
//},
#[component]
pub fn ControlView() -> Element {
let config_future = use_resource(|| CONFIG.get());
let net: Coroutine<Command> = use_coroutine_handle();
let status = &STATE.status;
let server = STATE.server.read();
@@ -382,7 +456,12 @@ pub fn ControlView() -> Element {
};
let current_channel_name = server.channels[&channel].name.clone();
let Some(proxy_url) = &CONFIG.proxy_url else {
let Some(proxy_url) = config_future
.read_unchecked()
.as_ref()
.and_then(|gui_config| gui_config.proxy_url.clone())
else {
return rsx!();
};
@@ -675,7 +754,7 @@ pub fn ServerView() -> Element {
let chat_box = css!(
"
display: flex;
flex-direction: column;
flex-direction: row;
grid-area: chat;
border-left: solid var(--line-color) var(--line-width);
@@ -727,7 +806,15 @@ pub fn ServerView() -> Element {
#[component]
pub fn LoginView() -> Element {
let net: Coroutine<Command> = use_coroutine_handle();
let default_address = CONFIG.proxy_url.as_deref().unwrap_or("");
let config_future = use_resource(|| CONFIG.get());
let default_address = &*config_future
.read_unchecked()
.as_ref()
.and_then(|gui_config| gui_config.proxy_url.clone())
.unwrap_or("".to_string());
let mut address = use_signal(|| default_address.to_string());
let previous_username = imp::load_username();
@@ -840,6 +927,11 @@ pub fn LoginView() -> Element {
pub fn app() -> Element {
use_coroutine(|rx: UnboundedReceiver<Command>| super::network_entrypoint(rx));
use_future(|| async move {
if let Err(err) = imp::load_config().await {
error!("{}", err)
}
});
global_css!(
"
+4 -2
View File
@@ -224,8 +224,10 @@ pub fn load_username() -> Option<String> {
return None;
}
pub fn load_config() -> Option<GuiConfig> {
None
pub async fn load_config() -> color_eyre::Result<GuiConfig> {
color_eyre::eyre::bail!(
"there is no config on desktop because desktops cannot be configured as they are tables"
)
}
pub fn init_logging() {
+15 -3
View File
@@ -320,7 +320,8 @@ pub async fn network_connect(
)
.ey()?;
if let Some(server_hash) = &CONFIG.cert_hash {
if let Some(server_hash) = &CONFIG.try_get().and_then(|cfg| cfg.cert_hash) {
error!("{:?}", server_hash);
let hash = web_sys::js_sys::Uint8Array::from(server_hash.as_slice());
web_sys::js_sys::Reflect::set(&object, &"value".into(), &hash).ey()?;
}
@@ -394,8 +395,19 @@ fn load_config_from_env() -> Option<GuiConfig> {
serde_json::from_str(option_env!("MUMBLE_WEB2_GUI_CONFIG")?).ok()?
}
pub fn load_config() -> Option<GuiConfig> {
load_config_from_window().or_else(load_config_from_env)
pub async fn load_config() -> color_eyre::Result<()> {
let config_url = option_env!("MUMBLE_WEB2_GUI_CONFIG_URL").ok_or(eyre!("foo"))?;
let config = reqwest::get(config_url)
.await
.unwrap()
.json::<GuiConfig>()
.await
.unwrap();
crate::CONFIG.set(config);
Ok(())
}
pub fn init_logging() {
+2 -1
View File
@@ -33,7 +33,8 @@ pub mod app;
pub mod imp;
mod msghtml;
pub static CONFIG: Lazy<GuiConfig> = Lazy::new(|| imp::load_config().unwrap_or_default());
//pub static CONFIG: Lazy<GuiConfig> = Lazy::new(|| imp::load_config().unwrap_or_default());
pub static CONFIG: async_cell::sync::AsyncCell<GuiConfig> = async_cell::sync::AsyncCell::new();
pub async fn network_entrypoint(mut event_rx: UnboundedReceiver<Command>) {
loop {
+9 -1
View File
@@ -13,7 +13,15 @@ toml = "0.8.19"
tracing = { version = "0.1.40", features = ["async-await"] }
tracing-subscriber = { version = "0.3.18", features = ["env-filter"] }
mumble-web2-common = { workspace = true }
salvo = { version = "0.74.2", features = ["quinn", "eyre", "rustls", "serve-static", "logging"] }
salvo = { version = "0.74.2", features = [
"quinn",
"eyre",
"rustls",
"serve-static",
"logging",
"craft",
"cors",
] }
once_cell = "1.20.2"
rustls = { version = "^0.23", features = ["aws_lc_rs"] }
rcgen = "0.13.2"
+44 -10
View File
@@ -4,10 +4,11 @@ use mumble_web2_common::GuiConfig;
use once_cell::sync::OnceCell;
use rcgen::date_time_ymd;
use salvo::conn::rustls::{Keycert, RustlsConfig};
use salvo::cors::{AllowOrigin, Cors};
use salvo::logging::Logger;
use salvo::prelude::*;
use salvo::proto::quic::BidiStream;
use serde::Deserialize;
use serde::{Deserialize, Serialize};
use std::net::{SocketAddr, ToSocketAddrs};
use std::path::PathBuf;
use std::sync::{Arc, Mutex};
@@ -106,13 +107,6 @@ async fn main() -> Result<()> {
info!("config\n{}", toml::to_string_pretty(&config.gui)?);
info!("gui config\n{}", serde_json::to_string_pretty(&config.gui)?);
// Server routing
let router = Router::new()
.get(serve_gui_index_html)
.push(Router::with_path("/proxy").goal(connect_proxy))
.push(Router::with_path("/<*+rest>").get(StaticDir::new(config.gui_path.clone())))
.hoop(Logger::new());
rustls::crypto::aws_lc_rs::default_provider()
.install_default()
.map_err(|e| anyhow!("could not install crypto provider {e:?}"))?;
@@ -155,6 +149,26 @@ async fn main() -> Result<()> {
};
let rustls_config = RustlsConfig::new(Keycert::new().cert(cert.as_slice()).key(key.as_slice()));
let config_craft = ConfigCraft {
client_config: MumbleClientConfig {
force_proxy: true,
proxy_url: "https://localhost:4433".to_string(),
cert_hash: config.gui.lock().unwrap().cert_hash.clone().unwrap(),
},
};
// Server routing
let router = Router::new()
.get(serve_gui_index_html)
.push(Router::with_path("/proxy").goal(connect_proxy))
.push(Router::with_path("/config").get(config_craft.get_config()))
.push(Router::with_path("/<*+rest>").get(StaticDir::new(config.gui_path.clone())))
.hoop(Logger::new());
let cors = Cors::new().allow_origin(AllowOrigin::any()).into_handler();
let service = Service::new(router).hoop(cors);
// Create http listeners
let http_listener = config.http_listen_address.map(TcpListener::new);
let https_listener =
@@ -165,17 +179,37 @@ async fn main() -> Result<()> {
match (http_listener, https_listener, http3_listener) {
(Some(a), b, c) => {
let accepter = a.join(b).join(c).bind().await;
Server::new(accepter).serve(router).await;
Server::new(accepter).serve(service).await;
}
(None, b, c) => {
let accepter = b.join(c).bind().await;
Server::new(accepter).serve(router).await;
Server::new(accepter).serve(service).await;
}
}
Ok(())
}
#[derive(Serialize, Clone)]
struct MumbleClientConfig {
force_proxy: bool,
proxy_url: String,
cert_hash: Vec<u8>,
}
#[derive(Clone)]
pub struct ConfigCraft {
client_config: MumbleClientConfig,
}
#[craft]
impl ConfigCraft {
#[craft(handler)]
async fn get_config(&self) -> Json<MumbleClientConfig> {
Json(self.client_config.clone())
}
}
#[handler]
#[instrument]
async fn connect_proxy(req: &mut Request, res: &mut Response) {