multiverse/widgets/settings/
developer.rs

1use std::sync::Arc;
2
3use crossterm::event::{KeyCode, KeyEvent};
4use matrix_sdk::Client;
5use matrix_sdk_ui::sync_service::{self, SyncService};
6use ratatui::{
7    prelude::*,
8    widgets::{HighlightSpacing, *},
9};
10
11// TODO: This replicates a lot of the logic the details view has, we should make
12// a generic tab popout widget to share a bit of logic here.
13
14enum MenuEntries {
15    Sync = 0,
16    SendQueue = 1,
17}
18
19impl From<usize> for MenuEntries {
20    fn from(value: usize) -> Self {
21        match value {
22            0 => MenuEntries::Sync,
23            1 => MenuEntries::SendQueue,
24            _ => unreachable!("The developer settings view has only 2 options"),
25        }
26    }
27}
28
29pub struct DeveloperSettingsView {
30    client: Client,
31    sync_service: Arc<SyncService>,
32    state: ListState,
33}
34
35impl DeveloperSettingsView {
36    pub fn new(client: Client, sync_service: Arc<SyncService>) -> Self {
37        let state = ListState::default().with_selected(Some(0));
38        Self { client, sync_service, state }
39    }
40
41    pub async fn handle_key_press(&mut self, key: KeyEvent) {
42        use MenuEntries::*;
43
44        match key.code {
45            KeyCode::Char('j') | KeyCode::Down => {
46                self.state.select_next();
47            }
48            KeyCode::Char('k') | KeyCode::Up => {
49                self.state.select_previous();
50            }
51
52            KeyCode::Enter | KeyCode::Char(' ') => {
53                if let Some(selected) = self.state.selected() {
54                    match selected.into() {
55                        Sync => {
56                            let sync_service = &self.sync_service;
57
58                            match sync_service.state().get() {
59                                sync_service::State::Running => sync_service.stop().await,
60                                sync_service::State::Idle
61                                | sync_service::State::Terminated
62                                | sync_service::State::Error
63                                | sync_service::State::Offline => sync_service.start().await,
64                            }
65                        }
66                        SendQueue => {
67                            let send_queue = self.client.send_queue();
68                            let enabled = send_queue.is_enabled();
69                            send_queue.set_enabled(!enabled).await
70                        }
71                    }
72                }
73            }
74
75            _ => (),
76        }
77    }
78}
79
80impl Widget for &mut DeveloperSettingsView {
81    fn render(self, area: Rect, buf: &mut Buffer)
82    where
83        Self: Sized,
84    {
85        let sync_item = match self.sync_service.state().get() {
86            sync_service::State::Running => ListItem::new("Sync [x]"),
87            sync_service::State::Idle
88            | sync_service::State::Terminated
89            | sync_service::State::Error
90            | sync_service::State::Offline => ListItem::new("Sync [ ]"),
91        };
92
93        let send_queue_item = if self.client.send_queue().is_enabled() {
94            ListItem::new("Send Queue [x]")
95        } else {
96            ListItem::new("Send Queue [ ]")
97        };
98
99        let list = List::new(vec![sync_item, send_queue_item])
100            .highlight_symbol("> ")
101            .highlight_spacing(HighlightSpacing::Always);
102
103        StatefulWidget::render(list, area, buf, &mut self.state);
104    }
105}