diff --git a/tui/src/cache.rs b/tui/src/cache.rs index c5c7a03..6a1d86d 100644 --- a/tui/src/cache.rs +++ b/tui/src/cache.rs @@ -12,32 +12,36 @@ * */ -use crate::config::ServerMeta; use crate::api_types::{Channel, Message}; +use crate::net; use crate::command::Command; -use crate::config::ConfigFile; +use crate::config::{ConfigFile, ServerConfig}; use std::collections::HashMap; -use hyper::Request; + +type ChannelMeta = Channel; struct ChannelCache { - meta: Channel, - messages: Vec + pub meta: ChannelMeta, + pub messages: Vec } struct ServerCache { - meta: ServerMeta, + // container for the relevant user/serer meta data + // We use both parts in order to to maintain jwt's within the cache + meta: ServerConfig, channels: Vec } pub struct Cache { // url -> Cache servers: HashMap, - active_server: Option + active_server: Option, + active_text: Option } impl ServerCache { - pub fn from(meta: ServerMeta, channels: Vec) -> Self { + pub fn from(meta: ServerConfig, channels: Vec) -> Self { ServerCache { meta, channels } } } @@ -45,15 +49,16 @@ impl ServerCache { impl Cache { pub fn from(config: &ConfigFile) -> Cache { let mut servers = HashMap::new(); - for cfg in &config.servers { - let i_server_cache = ServerCache::from(cfg.server.clone(), Vec::new()); - let url = i_server_cache.meta.url.clone(); + for servercfg in &config.servers { + let i_server_cache = ServerCache::from(servercfg.clone(), Vec::new()); + let url = i_server_cache.meta.server.url.clone(); servers.insert(url, i_server_cache); } Cache { servers, - active_server: None + active_server: None, + active_text: None } } } @@ -67,23 +72,43 @@ impl Cache { } } pub async fn switch_server(&mut self, host: &str) -> Command { - if let Some(srv_cache) = self.servers.get(host) { - Command::Failure(format!("Not implemented yet!")) + // TODO: implement some better fuzzy finding for better ergonomics + // Reallt though the ux is still pretty bad here + // Also it greedily matches so if two servers are behind one domain we're kinda fucked + let mut found = false; + let mut err_msg = String::from("Nothing found"); + for (url, meta) in self.servers.iter_mut() { + if url.contains(host) { + let id = meta.meta.user.id; + let secret = &meta.meta.user.secret; + found = match net::login(url, id, secret).await { + Ok(jwt) => { + meta.meta.user.jwt = Some(jwt); + self.active_server = Some(meta.meta.clone()); + // Setup websocket to server or something idk + self.active_text = None; + true + }, + Err(e) => { // TODO: some kind of logging here + err_msg = format!("{}", e); + meta.meta.user.jwt = None; + false + } + }; + meta.meta.user.jwt = Some(String::from("asdf")); + break + } + } + + if found { + Command::Text(format!("logged in - /lc to list to list channels")) } else { - Command::Failure(format!("Host {{ {} }} not found", host)) + Command::Failure(err_msg) } } pub async fn send_message(&mut self, id: &str) -> Command { - use hyper::body::HttpBody as _; - use hyper::Client; - if let Some(server) = self.active_server.as_ref() { - let url = format!("{}/message/send", server.url); - let request = Request::builder() - .method("POST") - .uri(url).body(()).unwrap(); - Command::Failure(format!("Not implemented yet!")) } else { Command::Failure(format!("No active server+channel to send message to")) @@ -97,4 +122,26 @@ impl Cache { } Command::Text(hosts) } + + pub fn list_channels(&self) -> Command { + use crate::api_types; + if let Some(serv) = &self.active_server { + // Find the server we're whose channels we want + let (_, cache) = self.servers.iter() + .find(|(url, _)| url == &&serv.server.url).unwrap(); + + let mut buffer = String::from("! Channels "); + for (i, chan) in cache.channels.iter().enumerate() { + // NOTE only list out text channels for now + // another command will be provided for voice channels later + if chan.meta.r#type == api_types::TEXT_CHANNEL { + buffer.push_str(&format!("[{}] {}, ", i, chan.meta.r#type)); + } + } + + Command::Text(buffer) + } else { + Command::Failure(format!("No active server")) + } + } }