diff --git a/assets/main.css b/assets/main.css index e36dd16..7643919 100644 --- a/assets/main.css +++ b/assets/main.css @@ -57,8 +57,12 @@ header p { color: #1f2937; } +/* Input Group Layout */ .input-group { margin-bottom: 16px; + display: flex; + align-items: flex-end; + gap: 8px; } .input-group label { @@ -75,6 +79,7 @@ header p { border-radius: 6px; font-size: 14px; transition: border-color 0.2s; + flex: 1; } .input-group input:focus { @@ -93,6 +98,15 @@ button { transition: all 0.2s; } +button:disabled { + opacity: 0.5; + cursor: not-allowed; +} + +button:disabled:hover { + background-color: inherit; +} + .connect-btn { background-color: #2563eb; color: white; @@ -170,6 +184,7 @@ button { .status-item { display: flex; justify-content: space-between; + align-items: center; margin-bottom: 12px; padding: 8px 0; border-bottom: 1px solid #f3f4f6; @@ -202,3 +217,45 @@ button { grid-column: 1 / -1; } } + +/* Readonly Input */ +.readonly-input { + background-color: #f9fafb !important; + cursor: not-allowed; + color: #6b7280; +} + +/* Copy Button */ +.copy-btn { + margin-left: 8px; + padding: 8px 12px; + background-color: #6b7280; + color: white; + border: none; + border-radius: 4px; + cursor: pointer; + font-size: 16px; +} + +.copy-btn:hover { + background-color: #4b5563; +} + +/* Muted Button State */ +.muted { + background-color: #ef4444 !important; +} + +.muted:hover { + background-color: #dc2626 !important; +} + +/* Peer ID Display */ +.peer-id { + font-family: 'Courier New', monospace; + font-size: 12px; + background-color: #f3f4f6; + padding: 2px 6px; + border-radius: 4px; + color: #374151; +} diff --git a/src/main.rs b/src/main.rs index c10d5f1..fa8996c 100644 --- a/src/main.rs +++ b/src/main.rs @@ -26,6 +26,7 @@ fn App() -> Element { #[component] pub fn Content() ->Element { + // State for connection status and audio let mut connected = use_signal(|| false); // Status: Verbindung aufgebaut? let mut audio_enabled = use_signal(|| true); // Status: Mikro aktiviert? @@ -48,20 +49,38 @@ pub fn Content() ->Element { // Connection Panel ConnectionPanel { - connected, - on_connect: move |_| connected.set(true) + connected, + local_peer_id, + remote_peer_id, + on_connect: move |_| { + log::info!("Verbindung wird hergestellt..."); + connected.set(true); + } } // Call Controls - CallControls { - audio_enabled, - on_toggle_audio: move |_| audio_enabled.set(!audio_enabled()) + CallControls { + connected, + audio_enabled, + on_start_call: move |_| { + log::info!("Anruf wird gestartet mit Remote Peer: {}", remote_peer_id()); + }, + on_end_call: move |_| { + log::info!("Anruf wird beendet"); + connected.set(false); + }, + on_toggle_audio: move |_| { + audio_enabled.set(!audio_enabled()); + log::info!("Audio Status: {}", if audio_enabled() { "Aktiviert" } else { "Deaktiviert" }); + } } // Status Display StatusDisplay { - connected, - audio_enabled + connected, + audio_enabled, + local_peer_id, + remote_peer_id } } } @@ -70,7 +89,12 @@ pub fn Content() ->Element { // Komponente für Verbindungseinstellungen #[component] -fn ConnectionPanel(connected: Signal, on_connect: EventHandler) -> Element { +fn ConnectionPanel( + connected: Signal, + local_peer_id: Signal, + mut remote_peer_id: Signal, + on_connect: EventHandler +) -> Element { rsx! { div { class: "connection-panel", @@ -78,21 +102,36 @@ fn ConnectionPanel(connected: Signal, on_connect: EventHandler div { class: "input-group", - label { "for": "peer-id", "Peer ID:" } + label { "for": "local-peer-id", "Ihre Peer ID:" } input { - id: "peer-id", + id: "local-peer-id", + class: "readonly-input", r#type: "text", - placeholder: "Wird autmatisch generiert" + value: "{local_peer_id}", + readonly: true + } + button { + class:"copy-btn", + onclick: move |_| { + // Später: Implementierung für Copy-to-Clipboard + log::info!("Peer-ID kopiert: {}", local_peer_id()); + }, + "📋" } } div { class: "input-group", - label { "for": "remote-peer", "Remote Peer-ID:" } + label { "for": "remote-peer-id", "Remote Peer-ID:" } input { - id: "remote-peer", + id: "remote-peer-id", r#type: "text", - placeholder: "ID des anderen Teilnehmers eingeben" + placeholder: "ID des anderen Teilnehmers eingeben", + value: "{remote_peer_id()}", + oninput: move |event| { + remote_peer_id.set(event.value()); + log::info!("Remote Peer-ID eingegeben: {}", event.value()); + } } } @@ -113,7 +152,13 @@ fn ConnectionPanel(connected: Signal, on_connect: EventHandler // Komponente für Anruf-Steuerungen #[component] -fn CallControls(audio_enabled: Signal, on_toggle_audio: EventHandler) -> Element { +fn CallControls( + connected: Signal, + audio_enabled: Signal, + on_start_call: EventHandler, + on_end_call: EventHandler, + on_toggle_audio: EventHandler +) -> Element { rsx! { div { class: "call-controls", @@ -123,21 +168,30 @@ fn CallControls(audio_enabled: Signal, on_toggle_audio: EventHandler, on_toggle_audio: EventHandler, audio_enabled: Signal) -> Element { +fn StatusDisplay( + connected: Signal, + audio_enabled: Signal, + local_peer_id: Signal, + remote_peer_id: Signal +) -> Element { rsx! { div { class: "status-display", h2 { "Status" } - div { + div { class: "status-item", span { class: "status-label", @@ -210,10 +269,37 @@ fn StatusDisplay(connected: Signal, audio_enabled: Signal) -> Elemen } } } + + div { + class: "status-item", + span { + class: "status-label", + "Lokale Peer-ID:" + } + span { + class: "status-value peer-id", + "{local_peer_id()}" + } + } + + if !remote_peer_id().is_empty() { + div { + class: "status-item", + span { + class: "status-label", + "Remote Peer-ID:" + } + span { + class: "status-value peer-id", + "{remote_peer_id()}" + } + } + } } } } +// Funktion zum Generieren einer eindeutigen Peer-ID fn generate_peer_id() -> String { use std::sync::atomic::{AtomicU32, Ordering};