use tokio::sync::mpsc;
use crate::app::state::AppState;
use crate::messages::{NetworkCommand, NetworkResponse, RenderState, UiEvent};
pub struct AppActor {
state: AppState,
network_tx: mpsc::UnboundedSender<NetworkCommand>,
render_tx: mpsc::UnboundedSender<std::sync::Arc<RenderState>>,
}
impl AppActor {
pub fn new(
network_tx: mpsc::UnboundedSender<NetworkCommand>,
render_tx: mpsc::UnboundedSender<std::sync::Arc<RenderState>>,
) -> Self {
AppActor {
state: AppState::new(),
network_tx,
render_tx,
}
}
pub async fn run(
mut self,
mut ui_rx: mpsc::UnboundedReceiver<UiEvent>,
mut net_rx: mpsc::UnboundedReceiver<NetworkResponse>,
) {
let _ = self.render_tx.send(std::sync::Arc::new(self.state.to_render_state()));
loop {
tokio::select! {
Some(event) = ui_rx.recv() => {
if self.handle_ui_event(event) {
let _ = self.network_tx.send(NetworkCommand::Shutdown);
break;
}
let _ = self.render_tx.send(std::sync::Arc::new(self.state.to_render_state()));
}
Some(response) = net_rx.recv() => {
self.state.handle_response(response);
let _ = self.render_tx.send(std::sync::Arc::new(self.state.to_render_state()));
}
else => break,
}
}
}
fn handle_ui_event(&mut self, event: UiEvent) -> bool {
match event {
UiEvent::SwitchTab(tab) => self.state.switch_tab(tab),
UiEvent::NextPanel => self.state.next_panel(),
UiEvent::PrevPanel => self.state.prev_panel(),
UiEvent::FocusWorkspace => self.state.focus_workspace(),
UiEvent::ScrollUp => self.state.scroll_up(),
UiEvent::ScrollDown => self.state.scroll_down(),
UiEvent::StartEditing => self.state.start_editing(),
UiEvent::StopEditing => self.state.stop_editing(),
UiEvent::CharInput(c) => self.state.enter_char(c),
UiEvent::Backspace => self.state.delete_char(),
UiEvent::CursorLeft => self.state.move_cursor_left(),
UiEvent::CursorRight => self.state.move_cursor_right(),
UiEvent::CycleMethod => self.state.cycle_method(),
UiEvent::ToggleSslErrors => self.state.toggle_ssl_errors(),
UiEvent::SendRequest => {
if self.state.input_mode == crate::messages::ui_events::InputMode::Editing {
self.state.stop_editing();
}
if let Some(cmd) = self.state.prepare_streaming_request() {
let _ = self.network_tx.send(cmd);
}
}
UiEvent::CancelRequest => {
if let Some(cmd) = self.state.cancel_request() {
let _ = self.network_tx.send(cmd);
}
}
UiEvent::NextHeader => self.state.next_header(),
UiEvent::PrevHeader => self.state.prev_header(),
UiEvent::ToggleHeader => self.state.toggle_header(),
UiEvent::AddHeader => self.state.add_header(),
UiEvent::DeleteHeader => self.state.delete_header(),
UiEvent::CycleAuth => self.state.cycle_auth(),
UiEvent::NextAuthField => self.state.next_auth_field(),
UiEvent::HistoryPrev => self.state.history_prev(),
UiEvent::HistoryNext => self.state.history_next(),
UiEvent::OpenWorkspaceInput => self.state.open_workspace_input(),
UiEvent::WorkspacePathChar(c) => self.state.workspace_path_char(c),
UiEvent::WorkspacePathBackspace => self.state.workspace_path_backspace(),
UiEvent::WorkspacePathAutocomplete => self.state.workspace_path_autocomplete(),
UiEvent::LoadWorkspace => self.state.load_workspace(),
UiEvent::CancelWorkspaceInput => self.state.cancel_workspace_input(),
UiEvent::NextEndpoint => self.state.next_endpoint(),
UiEvent::PrevEndpoint => self.state.prev_endpoint(),
UiEvent::SelectEndpoint => self.state.select_endpoint(),
UiEvent::ShowCurlImport => self.state.show_curl_import(),
UiEvent::CurlImportChar(c) => self.state.curl_import_char(c),
UiEvent::CurlImportBackspace => self.state.curl_import_backspace(),
UiEvent::ImportCurl => self.state.import_curl(),
UiEvent::CancelCurlImport => self.state.cancel_curl_import(),
UiEvent::ExportCurl => self.state.export_curl(),
UiEvent::WsConnect => {
if let Some(cmd) = self.state.ws_connect() {
let _ = self.network_tx.send(cmd);
}
}
UiEvent::WsDisconnect => {
if let Some(cmd) = self.state.ws_disconnect() {
let _ = self.network_tx.send(cmd);
}
}
UiEvent::WsSend => {
if let Some(cmd) = self.state.ws_send() {
let _ = self.network_tx.send(cmd);
}
}
UiEvent::WsEditUrl => self.state.ws_start_url_edit(),
UiEvent::WsEditMessage => self.state.ws_start_input_edit(),
UiEvent::WsCharInput(c) => self.state.ws_char(c),
UiEvent::WsBackspace => self.state.ws_backspace(),
UiEvent::WsCursorLeft => self.state.ws_cursor_left(),
UiEvent::WsCursorRight => self.state.ws_cursor_right(),
UiEvent::GqlExecuteQuery => {
if self.state.input_mode == crate::messages::ui_events::InputMode::Editing {
self.state.stop_editing();
}
if let Some(cmd) = self.state.gql_execute_query() {
let _ = self.network_tx.send(cmd);
}
}
UiEvent::GqlEditEndpoint => self.state.gql_edit_endpoint(),
UiEvent::GqlEditQuery => self.state.gql_edit_query(),
UiEvent::GqlEditVariables => self.state.gql_edit_variables(),
UiEvent::GqlCharInput(c) => self.state.gql_char(c),
UiEvent::GqlBackspace => self.state.gql_backspace(),
UiEvent::GqlCursorLeft => self.state.gql_cursor_left(),
UiEvent::GqlCursorRight => self.state.gql_cursor_right(),
UiEvent::GqlNextField => self.state.gql_next_field(),
UiEvent::GqlScrollUp => self.state.gql_scroll_up(),
UiEvent::GqlScrollDown => self.state.gql_scroll_down(),
UiEvent::ToggleHelp => self.state.toggle_help(),
UiEvent::CloseHelp => self.state.close_help(),
UiEvent::Quit => return true,
}
false
}
}