Skip to content

Commit 8c08706

Browse files
CopilotGZTimeWalker
andcommitted
Fix views to use new scope-centric data models (Instance, string-based pages, LogEntry)
Co-authored-by: GZTimeWalker <[email protected]>
1 parent 686f1bc commit 8c08706

File tree

3 files changed

+79
-127
lines changed

3 files changed

+79
-127
lines changed

crates/wsrx-desktop-gpui/src/models/events.rs

Lines changed: 14 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -2,28 +2,25 @@
22

33
#![allow(dead_code)] // Events defined for future use
44

5-
use super::{Connection, LogEntry, Tunnel};
5+
use super::{Instance, LogEntry, Scope};
66

77
/// Events that can occur in the application
88
#[derive(Clone, Debug)]
99
pub enum AppEvent {
1010
/// Page navigation event
11-
NavigateToPage(super::app_state::Page),
12-
13-
/// Tunnel-related events
14-
TunnelCreated(Tunnel),
15-
TunnelUpdated(Tunnel),
16-
TunnelDeleted(String), // tunnel_id
17-
TunnelEnabled(String),
18-
TunnelDisabled(String),
19-
20-
/// Connection-related events
21-
ConnectionEstablished(Connection),
22-
ConnectionClosed(String), // connection_id
23-
ConnectionError {
24-
connection_id: String,
25-
error: String,
26-
},
11+
NavigateToPage(super::app_state::PageId),
12+
13+
/// Instance (tunnel) related events
14+
InstanceCreated(Instance),
15+
InstanceUpdated(Instance),
16+
InstanceDeleted(String), // local address
17+
18+
/// Scope-related events
19+
ScopeAdded(Scope),
20+
ScopeUpdated(Scope),
21+
ScopeRemoved(String), // host
22+
ScopeAllowed(String), // host
23+
ScopeDeclined(String), // host
2724

2825
/// Daemon-related events
2926
DaemonStarted,

crates/wsrx-desktop-gpui/src/views/connections.rs

Lines changed: 54 additions & 80 deletions
Original file line numberDiff line numberDiff line change
@@ -1,66 +1,51 @@
1-
// Connections view - Manage tunnels and connections
2-
use std::net::SocketAddr;
3-
1+
// Connections view - Manage instances (tunnels) and connections
42
use gpui::{Context, Render, SharedString, Window, div, prelude::*, px};
53

6-
use crate::{models::Tunnel, styles::colors};
4+
use crate::{models::Instance, styles::colors};
75

86
pub struct ConnectionsView {
9-
tunnels: Vec<Tunnel>,
7+
instances: Vec<Instance>,
108
show_add_modal: bool,
11-
new_tunnel_name: String,
12-
new_tunnel_local: String,
13-
new_tunnel_remote: String,
9+
new_instance_label: String,
10+
new_instance_local: String,
11+
new_instance_remote: String,
1412
}
1513

1614
impl ConnectionsView {
1715
pub fn new(_window: &mut Window, _cx: &mut Context<Self>) -> Self {
1816
Self {
19-
tunnels: Vec::new(),
17+
instances: Vec::new(),
2018
show_add_modal: false,
21-
new_tunnel_name: String::new(),
22-
new_tunnel_local: String::from("127.0.0.1:8080"),
23-
new_tunnel_remote: String::from("ws://example.com"),
19+
new_instance_label: String::new(),
20+
new_instance_local: String::from("127.0.0.1:8080"),
21+
new_instance_remote: String::from("ws://example.com"),
2422
}
2523
}
2624

27-
fn add_tunnel(&mut self, cx: &mut Context<Self>) {
28-
// Parse addresses
29-
let local_addr: Result<SocketAddr, _> = self.new_tunnel_local.parse();
30-
let remote_addr: Result<SocketAddr, _> = self.new_tunnel_remote.parse();
31-
32-
if let (Ok(local), Ok(remote)) = (local_addr, remote_addr) {
33-
let tunnel = Tunnel {
34-
id: format!("tunnel-{}", self.tunnels.len()),
35-
name: if self.new_tunnel_name.is_empty() {
36-
format!("Tunnel {}", self.tunnels.len() + 1)
37-
} else {
38-
self.new_tunnel_name.clone()
39-
},
40-
local_addr: local,
41-
remote_addr: remote,
42-
enabled: true,
43-
};
44-
45-
self.tunnels.push(tunnel);
46-
self.show_add_modal = false;
47-
self.new_tunnel_name.clear();
48-
self.new_tunnel_local = String::from("127.0.0.1:8080");
49-
self.new_tunnel_remote = String::from("ws://example.com");
50-
cx.notify();
51-
}
52-
}
25+
fn add_instance(&mut self, cx: &mut Context<Self>) {
26+
let instance = Instance {
27+
label: if self.new_instance_label.is_empty() {
28+
format!("Instance {}", self.instances.len() + 1)
29+
} else {
30+
self.new_instance_label.clone()
31+
},
32+
local: self.new_instance_local.clone(),
33+
remote: self.new_instance_remote.clone(),
34+
latency: -1, // Not connected yet
35+
scope_host: "default-scope".to_string(),
36+
};
5337

54-
fn remove_tunnel(&mut self, index: usize, cx: &mut Context<Self>) {
55-
if index < self.tunnels.len() {
56-
self.tunnels.remove(index);
57-
cx.notify();
58-
}
38+
self.instances.push(instance);
39+
self.show_add_modal = false;
40+
self.new_instance_label.clear();
41+
self.new_instance_local = String::from("127.0.0.1:8080");
42+
self.new_instance_remote = String::from("ws://example.com");
43+
cx.notify();
5944
}
6045

61-
fn toggle_tunnel(&mut self, index: usize, cx: &mut Context<Self>) {
62-
if let Some(tunnel) = self.tunnels.get_mut(index) {
63-
tunnel.enabled = !tunnel.enabled;
46+
fn remove_instance(&mut self, index: usize, cx: &mut Context<Self>) {
47+
if index < self.instances.len() {
48+
self.instances.remove(index);
6449
cx.notify();
6550
}
6651
}
@@ -77,12 +62,12 @@ impl ConnectionsView {
7762
div()
7863
.text_xl()
7964
.text_color(gpui::rgba(0xAAAAAAFF))
80-
.child("No tunnels configured"),
65+
.child("No instances configured"),
8166
)
8267
.child(
8368
div()
8469
.text_color(gpui::rgba(0x888888FF))
85-
.child("Click the + button to create your first tunnel"),
70+
.child("Click the + button to create your first instance"),
8671
)
8772
}
8873
}
@@ -120,23 +105,28 @@ impl Render for ConnectionsView {
120105
this.show_add_modal = true;
121106
cx.notify();
122107
}))
123-
.child("+ Add Tunnel"),
108+
.child("+ Add Instance"),
124109
),
125110
)
126-
.child(if self.tunnels.is_empty() {
111+
.child(if self.instances.is_empty() {
127112
self.render_empty_state().into_any_element()
128113
} else {
129114
div()
130115
.flex()
131116
.flex_col()
132117
.gap_2()
133118
.children(
134-
self.tunnels
119+
self.instances
135120
.iter()
136121
.enumerate()
137-
.map(|(index, tunnel)| {
138-
let id = SharedString::from(format!("tunnel-{}", index));
139-
let status_color = if tunnel.enabled {
122+
.map(|(index, instance)| {
123+
let id = SharedString::from(format!("instance-{}", index));
124+
let latency_text = if instance.latency >= 0 {
125+
format!("{} ms", instance.latency)
126+
} else {
127+
"--".to_string()
128+
};
129+
let status_color = if instance.latency >= 0 {
140130
colors::success()
141131
} else {
142132
gpui::rgba(0x888888FF)
@@ -167,15 +157,15 @@ impl Render for ConnectionsView {
167157
.child(
168158
div()
169159
.text_color(colors::foreground())
170-
.child(tunnel.name.clone()),
160+
.child(instance.label.clone()),
171161
)
172162
.child(
173163
div()
174164
.text_sm()
175165
.text_color(gpui::rgba(0xAAAAAAFF))
176166
.child(format!(
177167
"{} → {}",
178-
tunnel.local_addr, tunnel.remote_addr
168+
instance.local, instance.remote
179169
)),
180170
),
181171
),
@@ -186,28 +176,12 @@ impl Render for ConnectionsView {
186176
.gap_2()
187177
.child(
188178
div()
189-
.id(SharedString::from(format!("toggle-{}", index)))
190179
.px_3()
191180
.py_1()
192181
.rounded_md()
193182
.text_sm()
194-
.cursor_pointer()
195-
.bg(if tunnel.enabled {
196-
gpui::rgba(0x28A745FF)
197-
} else {
198-
gpui::rgba(0x555555FF)
199-
})
200-
.hover(|div| {
201-
div.bg(if tunnel.enabled {
202-
gpui::rgba(0x218838FF)
203-
} else {
204-
gpui::rgba(0x666666FF)
205-
})
206-
})
207-
.on_click(cx.listener(move |this, _event, _window, cx| {
208-
this.toggle_tunnel(index, cx);
209-
}))
210-
.child(if tunnel.enabled { "Enabled" } else { "Disabled" }),
183+
.text_color(status_color)
184+
.child(latency_text),
211185
)
212186
.child(
213187
div()
@@ -220,7 +194,7 @@ impl Render for ConnectionsView {
220194
.bg(colors::error())
221195
.hover(|div| div.bg(gpui::rgba(0xFF6655FF)))
222196
.on_click(cx.listener(move |this, _event, _window, cx| {
223-
this.remove_tunnel(index, cx);
197+
this.remove_instance(index, cx);
224198
}))
225199
.child("Delete"),
226200
),
@@ -261,7 +235,7 @@ impl ConnectionsView {
261235
div()
262236
.text_xl()
263237
.text_color(colors::foreground())
264-
.child("Add New Tunnel"),
238+
.child("Add New Instance"),
265239
)
266240
.child(
267241
div()
@@ -281,7 +255,7 @@ impl ConnectionsView {
281255
.rounded_md()
282256
.bg(gpui::rgba(0x2A2A2AFF))
283257
.text_color(colors::foreground())
284-
.child("Tunnel 1"),
258+
.child(self.new_instance_label.clone()),
285259
),
286260
)
287261
.child(
@@ -302,7 +276,7 @@ impl ConnectionsView {
302276
.rounded_md()
303277
.bg(gpui::rgba(0x2A2A2AFF))
304278
.text_color(colors::foreground())
305-
.child(self.new_tunnel_local.clone()),
279+
.child(self.new_instance_local.clone()),
306280
),
307281
)
308282
.child(
@@ -323,7 +297,7 @@ impl ConnectionsView {
323297
.rounded_md()
324298
.bg(gpui::rgba(0x2A2A2AFF))
325299
.text_color(colors::foreground())
326-
.child(self.new_tunnel_remote.clone()),
300+
.child(self.new_instance_remote.clone()),
327301
),
328302
)
329303
.child(
@@ -356,7 +330,7 @@ impl ConnectionsView {
356330
.cursor_pointer()
357331
.hover(|div| div.bg(gpui::rgba(0x0088DDFF)))
358332
.on_click(cx.listener(|this, _event, _window, cx| {
359-
this.add_tunnel(cx);
333+
this.add_instance(cx);
360334
}))
361335
.child("Add"),
362336
),

crates/wsrx-desktop-gpui/src/views/network_logs.rs

Lines changed: 11 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -3,10 +3,7 @@ use std::collections::VecDeque;
33

44
use gpui::{Context, Render, SharedString, Window, div, prelude::*};
55

6-
use crate::{
7-
models::{LogEntry, LogLevel},
8-
styles::colors,
9-
};
6+
use crate::{models::LogEntry, styles::colors};
107

118
pub struct NetworkLogsView {
129
logs: VecDeque<LogEntry>,
@@ -19,64 +16,47 @@ impl NetworkLogsView {
1916

2017
logs.push_back(LogEntry {
2118
timestamp: "2025-11-10 15:00:01".to_string(),
22-
level: LogLevel::Info,
19+
level: "INFO".to_string(),
2320
target: "wsrx::daemon".to_string(),
2421
message: "Daemon started successfully".to_string(),
2522
});
2623

2724
logs.push_back(LogEntry {
2825
timestamp: "2025-11-10 15:00:05".to_string(),
29-
level: LogLevel::Debug,
26+
level: "DEBUG".to_string(),
3027
target: "wsrx::tunnel".to_string(),
3128
message: "Initializing WebSocket connection to ws://example.com".to_string(),
3229
});
3330

3431
logs.push_back(LogEntry {
3532
timestamp: "2025-11-10 15:00:10".to_string(),
36-
level: LogLevel::Info,
33+
level: "INFO".to_string(),
3734
target: "wsrx::tunnel".to_string(),
3835
message: "Connection established: 127.0.0.1:8080 → ws://example.com".to_string(),
3936
});
4037

4138
logs.push_back(LogEntry {
4239
timestamp: "2025-11-10 15:00:15".to_string(),
43-
level: LogLevel::Warn,
40+
level: "WARN".to_string(),
4441
target: "wsrx::proxy".to_string(),
4542
message: "High latency detected: 250ms".to_string(),
4643
});
4744

4845
logs.push_back(LogEntry {
4946
timestamp: "2025-11-10 15:00:20".to_string(),
50-
level: LogLevel::Error,
47+
level: "ERROR".to_string(),
5148
target: "wsrx::tunnel".to_string(),
5249
message: "Connection failed: Connection refused".to_string(),
5350
});
5451

5552
Self { logs }
5653
}
5754

58-
fn log_level_color(&self, level: LogLevel) -> gpui::Rgba {
59-
match level {
60-
LogLevel::Debug => gpui::rgba(0x888888FF),
61-
LogLevel::Info => colors::foreground(),
62-
LogLevel::Warn => colors::warning(),
63-
LogLevel::Error => colors::error(),
64-
}
65-
}
66-
67-
fn log_level_text(&self, level: LogLevel) -> &'static str {
68-
match level {
69-
LogLevel::Debug => "DEBUG",
70-
LogLevel::Info => "INFO",
71-
LogLevel::Warn => "WARN",
72-
LogLevel::Error => "ERROR",
73-
}
74-
}
75-
7655
fn render_log_entry(&self, entry: &LogEntry, index: usize) -> impl IntoElement {
7756
let id = SharedString::from(format!("log-entry-{}", index));
78-
let level_color = self.log_level_color(entry.level);
79-
let level_text = self.log_level_text(entry.level);
57+
let level_color = entry.level_color();
58+
let level_text = &entry.level;
59+
let opacity = entry.opacity();
8060

8161
div()
8262
.id(id)
@@ -101,7 +81,7 @@ impl NetworkLogsView {
10181
.text_sm()
10282
.text_color(level_color)
10383
.min_w_16()
104-
.child(level_text),
84+
.child(level_text.clone()),
10585
)
10686
.child(
10787
div()
@@ -115,6 +95,7 @@ impl NetworkLogsView {
11595
.flex_1()
11696
.text_sm()
11797
.text_color(colors::foreground())
98+
.opacity(opacity)
11899
.child(entry.message.clone()),
119100
)
120101
}

0 commit comments

Comments
 (0)