2 Commits

Author SHA1 Message Date
restitux 286fa16710 gui: stricter validation in add and edit modals
Build Mumble Web 2 / macos_build (push) Successful in 1m1s
Build Mumble Web 2 / windows_build (push) Successful in 2m52s
Build Mumble Web 2 / linux_build (push) Successful in 1m26s
Build Mumble Web 2 / android_build (push) Successful in 4m47s
2026-05-05 06:12:02 +00:00
restitux 90f6f8ef95 gui: new login screen 2026-05-05 06:11:59 +00:00
+93 -83
View File
@@ -501,6 +501,98 @@ pub fn ServerView(overrides: Resource<ProxyOverrides>) -> Element {
)
}
#[component]
fn OverrideLoginView(overrides: Resource<ProxyOverrides>) -> Element {
let user_config = use_context::<ConfigSystem>();
let net: Coroutine<Command> = use_coroutine_handle();
let state = use_context::<SharedState>();
let version = option_env!("MUMBLE_WEB2_VERSION");
let proxy_url = overrides
.read()
.as_ref()
.and_then(|c| c.proxy_url.clone())
.unwrap_or_default();
let mut username = use_signal(|| {
user_config
.config_get::<String>("username")
.unwrap_or_default()
});
let is_connecting = matches!(&*state.status.read(), Connecting);
rsx!(
div {
class: "server-list-page",
h1 {
"Mumble Web"
match version {
Some(v) => rsx!(div { class: "login_version", "({v})" }),
None => rsx!(),
}
}
div {
class: "server-list",
div {
class: "server-card",
img {
class: "server-card__icon",
src: asset!("assets/earth-14-svgrepo-com.svg"),
alt: "Server icon",
}
div {
class: "server-card__info",
span { class: "server-card__name", "Server" }
span { class: "server-card__address", "{proxy_url}" }
}
}
div {
class: "override-username-row",
input {
class: "override-username-input",
r#type: "text",
placeholder: "Username",
value: "{username.read()}",
oninput: move |evt| username.set(evt.value().clone()),
}
button {
class: "server-card__action server-card__action--connect",
disabled: is_connecting || username.read().is_empty(),
onclick: {
let proxy_url = proxy_url.clone();
let user_config = user_config.clone();
move |_| {
user_config.config_set("username", &*username.read());
net.send(Connect {
target: ConnectTarget::Proxy(proxy_url.clone()),
username: username.read().clone(),
config: overrides.read().clone().unwrap_or_default(),
});
}
},
img {
src: asset!("assets/arrow-right-svgrepo-com.svg"),
alt: "Connect",
}
}
}
match &*state.status.read() {
Failed(msg) => rsx!(
div {
class: "login_error",
"Failed to connect:"
pre { "{msg}" }
}
),
_ => rsx!(),
}
}
}
)
}
#[component]
pub fn LoginView(overrides: Resource<ProxyOverrides>) -> Element {
let user_config = use_context::<ConfigSystem>();
@@ -521,89 +613,7 @@ pub fn LoginView(overrides: Resource<ProxyOverrides>) -> Element {
// --- Overrides mode: single preset server, username-only input ---
if is_override_mode {
let proxy_url = overrides
.read()
.as_ref()
.and_then(|c| c.proxy_url.clone())
.unwrap_or_default();
let mut username = use_signal(|| {
user_config
.config_get::<String>("username")
.unwrap_or_default()
});
let status = &state.status;
let is_connecting = matches!(&*status.read(), Connecting);
return rsx!(
div {
class: "server-list-page",
h1 {
"Mumble Web"
match version {
Some(v) => rsx!(div { class: "login_version", "({v})" }),
None => rsx!(),
}
}
div {
class: "server-list",
div {
class: "server-card",
img {
class: "server-card__icon",
src: asset!("assets/earth-14-svgrepo-com.svg"),
alt: "Server icon",
}
div {
class: "server-card__info",
span { class: "server-card__name", "Server" }
span { class: "server-card__address", "{proxy_url}" }
}
}
div {
class: "override-username-row",
input {
class: "override-username-input",
r#type: "text",
placeholder: "Username",
value: "{username.read()}",
oninput: move |evt| username.set(evt.value().clone()),
}
button {
class: "server-card__action server-card__action--connect",
disabled: is_connecting || username.read().is_empty(),
onclick: {
let proxy_url = proxy_url.clone();
let user_config = user_config.clone();
move |_| {
user_config.config_set("username", &*username.read());
net.send(Connect {
target: ConnectTarget::Proxy(proxy_url.clone()),
username: username.read().clone(),
config: overrides.read().clone().unwrap_or_default(),
});
}
},
img {
src: asset!("assets/arrow-right-svgrepo-com.svg"),
alt: "Connect",
}
}
}
match &*state.status.read() {
Failed(msg) => rsx!(
div {
class: "login_error",
"Failed to connect:"
pre { "{msg}" }
}
),
_ => rsx!(),
}
}
}
);
return rsx!(OverrideLoginView { overrides });
}
// --- Normal mode: editable server list ---