From 9f6557bb922e293a8cfba52ad8aebe92bd924e7c Mon Sep 17 00:00:00 2001 From: restitux Date: Tue, 17 Feb 2026 22:53:16 -0700 Subject: [PATCH] change login screen ui --- gui/assets/arrow-right-svgrepo-com.svg | 4 + gui/assets/earth-14-svgrepo-com.svg | 135 +++++++++++++++++++++++++ gui/assets/main.scss | 125 +++++++++++++++++++++++ gui/src/app.rs | 120 ++++++++++------------ gui/src/imp/desktop.rs | 4 +- 5 files changed, 321 insertions(+), 67 deletions(-) create mode 100644 gui/assets/arrow-right-svgrepo-com.svg create mode 100644 gui/assets/earth-14-svgrepo-com.svg diff --git a/gui/assets/arrow-right-svgrepo-com.svg b/gui/assets/arrow-right-svgrepo-com.svg new file mode 100644 index 0000000..4ae7291 --- /dev/null +++ b/gui/assets/arrow-right-svgrepo-com.svg @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/gui/assets/earth-14-svgrepo-com.svg b/gui/assets/earth-14-svgrepo-com.svg new file mode 100644 index 0000000..0512760 --- /dev/null +++ b/gui/assets/earth-14-svgrepo-com.svg @@ -0,0 +1,135 @@ + + + + + + + + + + + + \ No newline at end of file diff --git a/gui/assets/main.scss b/gui/assets/main.scss index f6054ab..f93216b 100644 --- a/gui/assets/main.scss +++ b/gui/assets/main.scss @@ -431,3 +431,128 @@ a:visited { } } } + +.server-list-page { + display: flex; + flex-direction: column; + padding: 1.5rem; + gap: 1rem; +} + +.server-list-page h1 { + text-align: center; +} + +.login_version { + font-size: 0.55em; + font-weight: 400; + color: rgba(255, 255, 255, 0.4); + vertical-align: middle; +} + +.server-list { + display: flex; + flex-direction: column; + gap: 0.75rem; + width: 500px; + margin: 0 auto; +} + +/* Rounded card */ +.server-card { + display: flex; + align-items: center; + gap: 1rem; + padding: 1rem 1.25rem; + border-radius: 12px; + background: rgba(255, 255, 255, 0.05); + border: 1px solid rgba(255, 255, 255, 0.1); +} + +.server-card__icon { + width: 32px; + height: 32px; + opacity: 0.65; + filter: brightness(0) invert(0.8); /* light gray */ + flex-shrink: 0; +} + +.server-card__info { + display: flex; + flex-direction: column; + gap: 0.15rem; + flex: 1; /* pushes the connect button to the far right */ + min-width: 0; /* prevents text overflow from breaking flex layout */ +} + +.server-card__name { + font-weight: 600; + font-size: 0.95rem; + white-space: nowrap; + overflow: hidden; + text-overflow: ellipsis; +} + +.server-card__address { + font-size: 0.78rem; + opacity: 0.55; +} + + +.server-card__connect { + flex-shrink: 0; + display: flex; + align-items: center; + justify-content: center; + width: 38px; + height: 38px; + padding: 0; + line-height: 0; + border-radius: 8px; + border: 1px solid rgba(255, 255, 255, 0.15); + background: rgba(255, 255, 255, 0.07); + cursor: pointer; + transition: background 0.15s, border-color 0.15s, transform 0.1s; +} + +.server-card__connect img { + width: 20px; + height: 20px; + filter: brightness(0) invert(0.8); /* light gray */ + opacity: 0.75; + transition: opacity 0.15s; +} + +.server-card__connect:hover { + background: rgba(255, 255, 255, 0.15); + border-color: rgba(255, 255, 255, 0.35); + transform: scale(1.08); +} + +.server-card__connect:hover img { + opacity: 1.0; +} + +.server-card__connect:active { + transform: scale(0.95); +} + +/* Add server — dashed outline style to distinguish from real cards */ +.add-server-btn { + width: 100%; + padding: 0.85rem; + border-radius: 12px; + border: 2px dashed rgba(255, 255, 255, 0.2); + background: transparent; + color: rgba(255, 255, 255, 0.45); + font-size: 0.9rem; + cursor: pointer; + transition: border-color 0.15s, color 0.15s; + width: 500px; + margin: 0 auto; +} + +.add-server-btn:hover { + border-color: rgba(255, 255, 255, 0.4); + color: rgba(255, 255, 255, 0.7); +} diff --git a/gui/src/app.rs b/gui/src/app.rs index a56e647..7534c23 100644 --- a/gui/src/app.rs +++ b/gui/src/app.rs @@ -752,83 +752,73 @@ pub fn LoginView(config: Resource) -> Element { ), Connected => unreachable!(), }; + + struct Server { + name: String, + username: String, + address: String, + } + + let servers: [Server; 3] = [ + Server { + name: "name0".to_string(), + username: "username0".to_string(), + address: "address0".to_string(), + }, + Server { + name: "name1".to_string(), + username: "username1".to_string(), + address: "address1".to_string(), + }, + Server { + name: "name2".to_string(), + username: "username2".to_string(), + address: "address2".to_string(), + }, + ]; + let version = option_env!("MUMBLE_WEB2_VERSION"); rsx!( div { - class: "login", + class: "server-list-page", h1 { "Mumble Web" match version { - Some(v) => rsx!(" " span { class: "login_version", "({v})" }), + Some(v) => rsx!(div { class: "login_version", "({v})" }), None => rsx!(), } } - if config.read().as_ref().is_some_and(|cfg| cfg.any_server) { - div { - label { - for: "address-entry", - "Server Address:" - } - input { - id: "address-entry", - placeholder: "address", - value: "{address.read()}", - autofocus: "true", - oninput: move |evt| address_input.set(Some(evt.value().clone())), + div { + class: "server-list", + for server in servers { + div { + key: "{server.address}", // use the most unique field + 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.name}" } + span { class: "server-card__address", "{server.address}" } + } + button { + class: "server-card__connect", + onclick: move |_| { /* TODO: initiate connection */ }, + img { + src: asset!("assets/arrow-right-svgrepo-com.svg"), + alt: "Connect", + } + } } } } - div { - label { - for: "username-entry", - "Username:" - //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;", - } - input { - id: "username-entry", - placeholder: "username", - value: "{username.read()}", - autofocus: "true", - oninput: move |evt| username.set(evt.value().clone()), - } - } - div { - match &*last_status.read() { - None => rsx!(div { - class: "login_status", - span {"···"} - }), - Some(Ok(ServerStatus { success: false, .. })) => rsx!(div { - class: "login_status is_error", - span { - "Could not reach server" - } - }), - Some(Ok(status)) => rsx!(div { - class: "login_status", - if let (Some(users), Some(max_users)) = (status.users, status.max_users) { - span {"{users}/{max_users} Online"} - } else { - span {"Unknown Online"} - } - span {"-"} - if let Some((maj, min, pat)) = status.version { - span {"Version: {maj}.{min}.{pat}"} - } else { - span {"Unknown Version"} - } - }), - Some(Err(_)) => rsx!(div { - class: "login_status is_error", - span { - "Could not reach proxy server" - } - }), - } - div { - {bottom} - } - + button { + class: "add-server-btn", + onclick: move |_| {}, + "+ Add Server" } } ) diff --git a/gui/src/imp/desktop.rs b/gui/src/imp/desktop.rs index 34a59f8..00c2404 100644 --- a/gui/src/imp/desktop.rs +++ b/gui/src/imp/desktop.rs @@ -81,8 +81,8 @@ impl super::PlatformInterface for DesktopPlatform { fn get_config_path() -> std::path::PathBuf { let strategy = choose_app_strategy(AppStrategyArgs { - top_level_domain: "com".to_string(), - author: "Ohea Corp".to_string(), + top_level_domain: "xyz".to_string(), + author: "ohea".to_string(), app_name: "Mumble Web2".to_string(), }) .expect("failed to choose app strategy");