Skip to content

Commit 599023d

Browse files
authored
Do not accept connections when current session is running (#47)
- Show notification if a connection is attempted when during the current session - Do not resume listening immediately after the client disconnects (alllow history to be navigated).
1 parent a485b54 commit 599023d

File tree

9 files changed

+103
-41
lines changed

9 files changed

+103
-41
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ CHANGELOG
44
main
55
----
66

7+
- Do not accept connections while an existing session is running
78
- Filter properties with dot notation in context pane (`f`)
89
- Stack traversal - select stack and inspect stack frames in current mode.
910
- Fixed light theme.

src/app.rs

Lines changed: 48 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -175,12 +175,26 @@ pub enum SelectedView {
175175
Help,
176176
}
177177

178+
#[derive(PartialEq)]
179+
pub enum ListenStatus {
180+
Connected,
181+
Listening,
182+
Refusing,
183+
}
184+
185+
impl ListenStatus {
186+
pub fn is_connected(&self) -> bool {
187+
*self == ListenStatus::Connected
188+
}
189+
190+
}
191+
178192
pub struct App {
179193
receiver: Receiver<AppEvent>,
180194
quit: bool,
181195
sender: Sender<AppEvent>,
182196

183-
pub is_connected: bool,
197+
pub listening_status: ListenStatus,
184198
pub notification: Notification,
185199
pub config: Config,
186200

@@ -212,7 +226,7 @@ impl App {
212226
pub fn new(config: Config, receiver: Receiver<AppEvent>, sender: Sender<AppEvent>) -> App {
213227
let client = Arc::new(Mutex::new(DbgpClient::new(None)));
214228
App {
215-
is_connected: false,
229+
listening_status: ListenStatus::Listening,
216230
config,
217231
input_plurality: vec![],
218232
notification: Notification::none(),
@@ -346,7 +360,7 @@ impl App {
346360
AppEvent::HistoryNext => {
347361
for _ in 0..self.take_motion() {
348362
self.history.next();
349-
if self.history.is_current() && self.is_connected {
363+
if self.history.is_current() && (self.listening_status == ListenStatus::Connected) {
350364
self.sender
351365
.send(AppEvent::ChangeSessionViewMode(SessionViewMode::Current))
352366
.await?;
@@ -358,26 +372,36 @@ impl App {
358372
self.history.previous();
359373
}
360374
}
375+
AppEvent::Listen => {
376+
self.listening_status = ListenStatus::Listening;
377+
self.view_current = SelectedView::Listen;
378+
self.session_view.mode = SessionViewMode::Current;
379+
self.notification = Notification::info("listening for next connection".to_string())
380+
},
361381
AppEvent::ClientConnected(s) => {
362-
let filepath = {
363-
let mut client = self.client.lock().await;
364-
let response = client.deref_mut().connect(s).await?;
365-
for (feature, value) in [
366-
("max_depth", self.context_depth.to_string().as_str()),
367-
("extended_properties", "1"),
368-
] {
369-
info!("setting feature {} to {:?}", feature, value);
370-
client.feature_set(feature, value).await?;
371-
}
372-
response.fileuri.clone()
373-
};
374-
self.is_connected = true;
375-
self.reset();
376-
377-
let source = self.workspace.open(filepath.clone()).await;
378-
self.history = History::default();
379-
self.history
380-
.push(HistoryEntry::initial(filepath.clone(), source.text.clone()));
382+
if self.listening_status != ListenStatus::Listening {
383+
self.notification = Notification::warning("refused incoming connection".to_string());
384+
} else {
385+
let filepath = {
386+
let mut client = self.client.lock().await;
387+
let response = client.deref_mut().connect(s).await?;
388+
for (feature, value) in [
389+
("max_depth", self.context_depth.to_string().as_str()),
390+
("extended_properties", "1"),
391+
] {
392+
info!("setting feature {} to {:?}", feature, value);
393+
client.feature_set(feature, value).await?;
394+
}
395+
response.fileuri.clone()
396+
};
397+
self.listening_status = ListenStatus::Connected;
398+
self.reset();
399+
400+
let source = self.workspace.open(filepath.clone()).await;
401+
self.history = History::default();
402+
self.history
403+
.push(HistoryEntry::initial(filepath.clone(), source.text.clone()));
404+
}
381405
}
382406
AppEvent::Snapshot() => {
383407
self.snapshot().await?;
@@ -445,7 +469,7 @@ impl App {
445469
}
446470
AppEvent::Disconnect => {
447471
let _ = self.client.lock().await.deref_mut().disonnect().await;
448-
self.is_connected = false;
472+
self.listening_status = ListenStatus::Refusing;
449473
self.sender
450474
.send(AppEvent::ChangeSessionViewMode(SessionViewMode::History))
451475
.await?;
@@ -575,7 +599,7 @@ impl App {
575599
let line_no = frame.line;
576600
let context = {
577601
match (level as u16) < self.stack_max_context_fetch {
578-
true => Some(self.client.lock().await.deref_mut().context_get(level as u16).await.unwrap()),
602+
true => Some(self.client.lock().await.deref_mut().context_get(level as u16).await?),
579603
false => None,
580604
}
581605
};

src/event/input.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,7 @@ pub enum AppEvent {
4949
NextTheme,
5050
ContextFilterOpen,
5151
ContextSearchClose,
52+
Listen,
5253
}
5354

5455
pub type EventSender = Sender<AppEvent>;

src/notification.rs

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ pub enum NotificationLevel {
55
Error,
66
None,
77
Info,
8+
Warning,
89
}
910
pub struct Notification {
1011
pub message: String,
@@ -44,4 +45,15 @@ impl Notification {
4445
.unwrap(),
4546
}
4647
}
48+
49+
#[allow(dead_code)]
50+
pub(crate) fn warning(message: String) -> Notification {
51+
Notification {
52+
message,
53+
level: NotificationLevel::Warning,
54+
expires: SystemTime::now()
55+
.checked_add(Duration::from_secs(5))
56+
.unwrap(),
57+
}
58+
}
4759
}

src/theme.rs

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
12
use ratatui::style::Color;
23
use ratatui::style::Style;
34

@@ -47,6 +48,7 @@ impl Theme {
4748
syntax_brace: Style::default().fg(Solarized::Base01.to_color()),
4849
notification_info: Style::default().fg(Solarized::Green.to_color()),
4950
notification_error: Style::default().fg(Solarized::Red.to_color()),
51+
notification_warning: Style::default().fg(Color::Yellow),
5052
pane_border_active: Style::default().fg(Solarized::Base01.to_color()),
5153
pane_border_inactive: Style::default().fg(Solarized::Base02.to_color()),
5254
source_line: Style::default().fg(Solarized::Base1.to_color()),
@@ -73,7 +75,8 @@ impl Theme {
7375
syntax_brace: Style::default().fg(Color::White),
7476

7577
notification_info: Style::default().fg(Color::Black).bg(Color::Green),
76-
notification_error: Style::default().fg(Color::White).bg(Color::Red),
78+
notification_error: Style::default().fg(Color::Yellow),
79+
notification_warning: Style::default().fg(Color::White).bg(Color::Yellow),
7780

7881
pane_border_active: Style::default().fg(Color::Green),
7982
pane_border_inactive: Style::default().fg(Color::DarkGray),
@@ -108,6 +111,7 @@ pub struct Scheme {
108111

109112
pub notification_info: Style,
110113
pub notification_error: Style,
114+
pub notification_warning: Style,
111115

112116
pub pane_border_active: Style,
113117
pub pane_border_inactive: Style,

src/view/context.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -232,7 +232,7 @@ mod test {
232232
],
233233
&mut lines,
234234
0,
235-
&mut filter,
235+
filter,
236236
);
237237

238238
assert_eq!(vec![

src/view/help.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
use super::View;
2-
use crate::app::{App, SelectedView};
2+
use crate::app::{App, ListenStatus, SelectedView};
33
use crate::event::input::AppEvent;
44
use ratatui::layout::Rect;
55
use ratatui::widgets::Paragraph;
@@ -11,7 +11,7 @@ impl View for HelpView {
1111
fn handle(app: &mut App, event: AppEvent) -> Option<AppEvent> {
1212
match event {
1313
AppEvent::Input(_) => {
14-
if app.is_connected {
14+
if app.listening_status == ListenStatus::Connected{
1515
Some(AppEvent::ChangeView(SelectedView::Session))
1616
} else {
1717
Some(AppEvent::ChangeView(SelectedView::Listen))

src/view/layout.rs

Lines changed: 25 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ use super::session::SessionView;
44
use super::session::SessionViewMode;
55
use super::View;
66
use crate::app::App;
7+
use crate::app::ListenStatus;
78
use crate::app::SelectedView;
89
use crate::event::input::AppEvent;
910
use crate::notification::NotificationLevel;
@@ -48,13 +49,14 @@ fn status_widget(app: &App) -> Paragraph {
4849
Span::styled(
4950
format!(
5051
" 󱘖 {} ",
51-
if app.is_connected {
52-
"connected".to_string()
53-
} else {
54-
app.config.listen.to_string()
55-
}
52+
match app.listening_status {
53+
ListenStatus::Connected => "connected".to_string(),
54+
55+
ListenStatus::Listening => app.config.listen.to_string(),
56+
ListenStatus::Refusing => "refusing".to_string(),
57+
},
5658
),
57-
match app.is_connected {
59+
match app.listening_status.is_connected() {
5860
false => app.theme().widget_inactive,
5961
true => app.theme().widget_active,
6062
},
@@ -70,15 +72,25 @@ fn status_widget(app: &App) -> Paragraph {
7072
),
7173
Span::styled(
7274
(match app.session_view.mode {
73-
SessionViewMode::Current => match app.is_connected {
75+
SessionViewMode::Current => match app.listening_status.is_connected() {
7476
true => format!("  {} / ∞", app.history.offset + 1),
7577
false => "  0 / 0".to_string(),
7678
},
77-
SessionViewMode::History => format!(
78-
"  {} / {} history [p] to go back [n] to go forwards [b] to return",
79-
app.history.offset + 1,
80-
app.history.len()
81-
),
79+
SessionViewMode::History => {
80+
match app.listening_status {
81+
ListenStatus::Connected => format!(
82+
"  {} / {} history [p] to go back [n] to go forwards [b] to return",
83+
app.history.offset + 1,
84+
app.history.len()
85+
),
86+
ListenStatus::Refusing => format!(
87+
"  {} / {} terminated [p] to go back [n] to go forwards [b] to listen",
88+
app.history.offset + 1,
89+
app.history.len()
90+
),
91+
ListenStatus::Listening => String::new(),
92+
}
93+
}
8294
})
8395
.to_string(),
8496
match app.session_view.mode {
@@ -93,6 +105,7 @@ fn status_widget(app: &App) -> Paragraph {
93105
},
94106
match app.notification.level {
95107
NotificationLevel::Error => app.theme().notification_error,
108+
NotificationLevel::Warning => app.theme().notification_warning,
96109
NotificationLevel::Info => app.theme().notification_info,
97110
NotificationLevel::None => Style::default(),
98111
},

src/view/session.rs

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ use super::ComponentType;
55
use super::Pane;
66
use super::View;
77
use crate::app::App;
8+
use crate::app::ListenStatus;
89
use crate::app::SelectedView;
910
use crate::event::input::AppEvent;
1011
use crossterm::event::KeyCode;
@@ -68,7 +69,13 @@ impl View for SessionView {
6869
KeyCode::Char(c) => match c {
6970
'n' => Some(AppEvent::HistoryNext),
7071
'p' => Some(AppEvent::HistoryPrevious),
71-
'b' => Some(AppEvent::ChangeSessionViewMode(SessionViewMode::Current)),
72+
'b' => {
73+
if app.listening_status == ListenStatus::Refusing {
74+
Some(AppEvent::Listen)
75+
} else {
76+
Some(AppEvent::ChangeSessionViewMode(SessionViewMode::Current))
77+
}
78+
}
7279
_ => None,
7380
},
7481
_ => None,

0 commit comments

Comments
 (0)