Skip to content

Commit

Permalink
Changes based on PR conversation
Browse files Browse the repository at this point in the history
- Removed ignore and notifier configs from `Tab`
- Use proper YAML for `Chan` config
- Reverted formatting changes
  • Loading branch information
trevarj committed Dec 15, 2022
1 parent c0c0e73 commit 7a4a09e
Show file tree
Hide file tree
Showing 14 changed files with 317 additions and 332 deletions.
26 changes: 26 additions & 0 deletions crates/libtiny_common/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -164,6 +164,25 @@ pub enum MsgTarget<'a> {
CurrentTab,
}

impl<'a> MsgTarget<'a> {
pub fn serv_name(&self) -> Option<&str> {
match self {
MsgTarget::Server { serv }
| MsgTarget::Chan { serv, .. }
| MsgTarget::User { serv, .. }
| MsgTarget::AllServTabs { serv } => Some(serv),
_ => None,
}
}

pub fn chan_name(&self) -> Option<&ChanNameRef> {
match self {
MsgTarget::Chan { chan, .. } => Some(chan),
_ => None,
}
}
}

/// Source of a message from the user.
#[derive(Debug, Clone, PartialEq, Eq)]
pub enum MsgSource {
Expand All @@ -186,6 +205,13 @@ impl MsgSource {
}
}

pub fn chan_name(&self) -> Option<&ChanNameRef> {
match self {
MsgSource::Chan { chan, .. } => Some(chan),
_ => None,
}
}

pub fn to_target(&self) -> MsgTarget {
match self {
MsgSource::Serv { serv } => MsgTarget::Server { serv },
Expand Down
126 changes: 79 additions & 47 deletions crates/libtiny_tui/src/config.rs
Original file line number Diff line number Diff line change
@@ -1,15 +1,15 @@
// To see how color numbers map to actual colors in your terminal run
// `cargo run --example colors`. Use tab to swap fg/bg colors.

use libtiny_common::{ChanName, ChanNameRef};
use serde::de::{self, Deserializer, MapAccess, Visitor};
use serde::Deserialize;
use std::collections::HashMap;
use std::fs::File;
use std::io::Read;
use std::path::Path;
use std::str::FromStr;

use libtiny_common::{ChanName, ChanNameRef};
use serde::de::{self, Deserializer, MapAccess, Visitor};
use serde::Deserialize;
pub use termbox_simple::*;

use crate::key_map::KeyMap;
Expand Down Expand Up @@ -55,43 +55,43 @@ impl Default for Defaults {
Defaults {
tab_config: TabConfig {
ignore: Some(false),
notifier: Some(Notifier::default()),
notify: Some(Notifier::default()),
},
}
}
}

#[derive(Clone, Debug, PartialEq, Eq)]
pub struct Chan {
pub name: ChanName,
pub config: TabConfig,
#[derive(Clone, Deserialize, Debug, PartialEq, Eq)]
#[serde(untagged)]
pub enum Chan {
#[serde(deserialize_with = "deser_chan_name")]
Name(ChanName),
WithConfig {
#[serde(deserialize_with = "deser_chan_name")]
name: ChanName,
#[serde(flatten)]
config: TabConfig,
},
}

impl<'de> Deserialize<'de> for Chan {
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
where
D: serde::Deserializer<'de>,
{
struct ChanVisitor;

impl<'de> Visitor<'de> for ChanVisitor {
type Value = Chan;

fn expecting(&self, formatter: &mut std::fmt::Formatter) -> std::fmt::Result {
write!(formatter, "a channel name with arguments")
}

fn visit_str<E>(self, v: &str) -> Result<Self::Value, E>
where
E: de::Error,
{
Chan::from_str(v).map_err(de::Error::custom)
}
impl Chan {
pub fn name(&self) -> &ChanNameRef {
match self {
Chan::Name(name) => name,
Chan::WithConfig { name, .. } => name,
}
deserializer.deserialize_str(ChanVisitor)
.as_ref()
}
}

fn deser_chan_name<'de, D>(d: D) -> Result<ChanName, D::Error>
where
D: Deserializer<'de>,
{
let name: String = serde::de::Deserialize::deserialize(d)?;
Ok(ChanName::new(name))
}

impl FromStr for Chan {
type Err = String;

Expand All @@ -107,16 +107,13 @@ impl FromStr for Chan {
// with args
Some((name, args)) => {
let config = TabConfig::from_str(args)?;
Ok(Chan {
Ok(Chan::WithConfig {
name: ChanName::new(name.to_string()),
config,
})
}
// chan name only
None => Ok(Chan {
name: ChanName::new(s),
config: TabConfig::default(),
}),
None => Ok(Chan::Name(ChanName::new(s))),
}
}
}
Expand All @@ -126,14 +123,44 @@ impl FromStr for Chan {
pub(crate) struct TabConfigs(HashMap<String, TabConfig>);

impl TabConfigs {
pub(crate) fn serv_conf(&self, serv_name: &str) -> Option<TabConfig> {
self.0.get(serv_name).cloned()
pub(crate) fn get(
&self,
serv_name: &str,
chan_name: Option<&ChanNameRef>,
) -> Option<TabConfig> {
let key = if let Some(chan) = chan_name {
format!("{}_{}", serv_name, chan.display())
} else {
serv_name.to_string()
};
self.0.get(&key).cloned()
}

pub(crate) fn chan_conf(&self, serv_name: &str, chan: &ChanNameRef) -> Option<TabConfig> {
self.0
.get(&format!("{}_{}", serv_name, chan.display()))
.cloned()
pub(crate) fn get_mut(
&mut self,
serv_name: &str,
chan_name: Option<&ChanNameRef>,
) -> Option<&mut TabConfig> {
let key = if let Some(chan) = chan_name {
format!("{}_{}", serv_name, chan.display())
} else {
serv_name.to_string()
};
self.0.get_mut(&key)
}

pub(crate) fn set(
&mut self,
serv_name: &str,
chan_name: Option<&ChanNameRef>,
config: TabConfig,
) {
let key = if let Some(chan) = chan_name {
format!("{}_{}", serv_name, chan.display())
} else {
serv_name.to_string()
};
self.0.insert(key, config);
}
}

Expand All @@ -144,10 +171,14 @@ impl From<&Config> for TabConfigs {
let serv_tc = server.config.or_use(&config.defaults.tab_config);
tab_configs.insert(server.addr.clone(), serv_tc);
for chan in &server.join {
let tc = chan.config.or_use(&serv_tc);
tab_configs.insert(format!("{}_{}", server.addr, chan.name.display()), tc);
let (name, tc) = match chan {
Chan::Name(name) => (name, serv_tc),
Chan::WithConfig { name, config } => (name, config.or_use(&serv_tc)),
};
tab_configs.insert(format!("{}_{}", server.addr, name.display()), tc);
}
}
tab_configs.insert("_defaults".to_string(), config.defaults.tab_config);
debug!("new {tab_configs:?}");
Self(tab_configs)
}
Expand All @@ -160,21 +191,21 @@ pub struct TabConfig {
pub ignore: Option<bool>,
/// Notification setting for tab
#[serde(default)]
pub notifier: Option<Notifier>,
pub notify: Option<Notifier>,
}

impl TabConfig {
pub fn user_tab_config() -> TabConfig {
pub fn user_tab_defaults() -> TabConfig {
TabConfig {
ignore: Some(false),
notifier: Some(Notifier::Messages),
notify: Some(Notifier::Messages),
}
}

pub(crate) fn or_use(&self, config: &TabConfig) -> TabConfig {
TabConfig {
ignore: self.ignore.or(config.ignore),
notifier: self.notifier.or(config.notifier),
notify: self.notify.or(config.notify),
}
}
}
Expand All @@ -195,7 +226,7 @@ impl FromStr for TabConfig {
arg => match arg.split_once(' ') {
// arg with parameter
Some(("notify", val)) => {
tc.notifier = Some(Notifier::from_str(val)?);
tc.notify = Some(Notifier::from_str(val)?);
Ok(tc)
}
_ => Err(format!("Unexpected argument: {:?}", arg)),
Expand Down Expand Up @@ -317,6 +348,7 @@ impl Default for Colors {
}
}

//
// Parsing
//

Expand Down
37 changes: 27 additions & 10 deletions crates/libtiny_tui/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -23,13 +23,16 @@ mod widget;
#[cfg(test)]
mod tests;

use crate::tui::{CmdResult, TUIRet};
use config::TabConfig;
use libtiny_common::{ChanNameRef, Event, MsgSource, MsgTarget, TabStyle};
pub use notifier::Notifier;
use term_input::Input;

use std::cell::RefCell;
use std::path::PathBuf;
use std::rc::{Rc, Weak};

use libtiny_common::{ChanNameRef, Event, MsgSource, MsgTarget, TabStyle};
pub use notifier::Notifier;
use term_input::Input;
use time::Tm;
use tokio::select;
use tokio::signal::unix::{signal, SignalKind};
Expand All @@ -38,9 +41,6 @@ use tokio::task::spawn_local;
use tokio_stream::wrappers::{ReceiverStream, SignalStream};
use tokio_stream::{Stream, StreamExt};

use crate::config::TabConfig;
use crate::tui::{CmdResult, TUIRet};

#[macro_use]
extern crate log;

Expand Down Expand Up @@ -69,9 +69,8 @@ impl TUI {
(TUI { inner }, rcv_ev)
}

/// Create a test instance that doesn't render to the terminal, just updates
/// the termbox buffer. Useful for testing. See also
/// [`get_front_buffer`](TUI::get_front_buffer).
/// Create a test instance that doesn't render to the terminal, just updates the termbox
/// buffer. Useful for testing. See also [`get_front_buffer`](TUI::get_front_buffer).
pub fn run_test<S>(width: u16, height: u16, input_stream: S) -> (TUI, mpsc::Receiver<Event>)
where
S: Stream<Item = std::io::Result<term_input::Event>> + Unpin + 'static,
Expand Down Expand Up @@ -258,7 +257,25 @@ impl TUI {
chan_name: &ChanNameRef,
));
delegate!(set_tab_style(style: TabStyle, target: &MsgTarget,));
delegate!(set_tab_config(config: TabConfig, target: &MsgTarget,));

pub fn get_tab_config(&self, serv_name: &str, chan_name: Option<&ChanNameRef>) -> TabConfig {
self.inner
.upgrade()
.map(|tui| tui.borrow().get_tab_config(serv_name, chan_name))
.unwrap_or_default()
}

pub fn set_tab_config(
&self,
serv_name: &str,
chan_name: Option<&ChanNameRef>,
config: TabConfig,
) {
if let Some(tui) = self.inner.upgrade() {
tui.borrow_mut()
.set_tab_config(serv_name, chan_name, config);
}
}

pub fn user_tab_exists(&self, serv_name: &str, nick: &str) -> bool {
match self.inner.upgrade() {
Expand Down
28 changes: 4 additions & 24 deletions crates/libtiny_tui/src/messaging.rs
Original file line number Diff line number Diff line change
Expand Up @@ -27,9 +27,6 @@ pub(crate) struct MessagingUI {
width: i32,
height: i32,

// Option to disable status messages ( join/part )
show_status: bool,

// All nicks in the channel. Need to keep this up-to-date to be able to
// properly highlight mentions.
nicks: Trie,
Expand Down Expand Up @@ -91,7 +88,6 @@ impl MessagingUI {
pub(crate) fn new(
width: i32,
height: i32,
status: bool,
scrollback: usize,
msg_layout: Layout,
) -> MessagingUI {
Expand All @@ -101,7 +97,6 @@ impl MessagingUI {
exit_dialogue: None,
width,
height,
show_status: status,
nicks: Trie::new(),
last_activity_line: None,
last_activity_ts: None,
Expand Down Expand Up @@ -385,8 +380,8 @@ impl MessagingUI {
self.nicks.clear();
}

pub(crate) fn join(&mut self, nick: &str, ts: Option<Timestamp>) {
if self.show_status {
pub(crate) fn join(&mut self, nick: &str, ts: Option<Timestamp>, ignore: bool) {
if !ignore {
if let Some(ts) = ts {
let line_idx = self.get_activity_line_idx(ts);
self.msg_area.modify_line(line_idx, |line| {
Expand All @@ -399,10 +394,10 @@ impl MessagingUI {
self.nicks.insert(nick);
}

pub(crate) fn part(&mut self, nick: &str, ts: Option<Timestamp>) {
pub(crate) fn part(&mut self, nick: &str, ts: Option<Timestamp>, ignore: bool) {
self.nicks.remove(nick);

if self.show_status {
if !ignore {
if let Some(ts) = ts {
let line_idx = self.get_activity_line_idx(ts);
self.msg_area.modify_line(line_idx, |line| {
Expand All @@ -413,21 +408,6 @@ impl MessagingUI {
}
}

/// `state` == `None` means toggle
/// `state` == `Some(state)` means set it to `state`
pub(crate) fn set_or_toggle_status(&mut self, state: Option<bool>) {
self.show_status = state.unwrap_or(!self.show_status);
if self.show_status {
self.add_client_notify_msg("Ignore disabled");
} else {
self.add_client_notify_msg("Ignore enabled");
}
}

pub(crate) fn is_showing_status(&self) -> bool {
self.show_status
}

pub(crate) fn nick(&mut self, old_nick: &str, new_nick: &str, ts: Timestamp) {
self.nicks.remove(old_nick);
self.nicks.insert(new_nick);
Expand Down
Loading

0 comments on commit 7a4a09e

Please sign in to comment.