use indexmap::IndexMap;
use std::collections::HashMap;
use tokio::sync::mpsc;
pub mod buffer;
pub mod connection;
pub mod events;
pub mod sorting;
use buffer::Buffer;
use connection::Connection;
use connection::ConnectionStatus;
use crate::config::IgnoreEntry;
use crate::e2e::E2eManager;
use crate::irc::flood::FloodState;
use crate::irc::netsplit::NetsplitState;
use crate::scripting::engine::{BufferInfo, ConnectionInfo, NickInfo, ScriptStateSnapshot};
use crate::storage::LogRow;
#[derive(Debug, Clone)]
pub struct PendingE2eSend {
pub connection_id: String,
pub target: String,
pub notice_text: String,
}
#[derive(Debug, Clone, PartialEq, Eq)]
pub enum PendingUserhostAction {
E2eForget {
buffer_id: String,
target: String,
channel: Option<String>,
all: bool,
},
}
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct PendingUserhostRequest {
pub connection_id: String,
pub nick: String,
pub action: PendingUserhostAction,
}
pub struct AppState {
pub connections: HashMap<String, Connection>,
pub buffers: IndexMap<String, Buffer>,
pub active_buffer_id: Option<String>,
pub previous_buffer_id: Option<String>,
pub message_counter: u64,
pub flood_state: FloodState,
pub netsplit_state: NetsplitState,
pub flood_protection: bool,
pub ignores: Vec<IgnoreEntry>,
pub log_tx: Option<mpsc::Sender<LogRow>>,
pub log_exclude_types: Vec<String>,
pub scrollback_limit: usize,
pub pending_web_events: Vec<crate::web::protocol::WebEvent>,
pub pending_e2e_sends: Vec<PendingE2eSend>,
pub pending_userhost_requests: Vec<PendingUserhostRequest>,
pub nick_color_sat: f32,
pub nick_color_lit: f32,
pub e2e_manager: Option<std::sync::Arc<E2eManager>>,
}
impl AppState {
pub fn script_snapshot(&self) -> ScriptStateSnapshot {
let connections: Vec<ConnectionInfo> = self
.connections
.values()
.map(|c| ConnectionInfo {
id: c.id.clone(),
label: c.label.clone(),
nick: c.nick.clone(),
connected: c.status == ConnectionStatus::Connected,
user_modes: c.user_modes.clone(),
})
.collect();
let buffers: Vec<BufferInfo> = self
.buffers
.values()
.map(|b| {
let bt = match b.buffer_type {
buffer::BufferType::Mentions => "mentions",
buffer::BufferType::Server => "server",
buffer::BufferType::Channel => "channel",
buffer::BufferType::Query => "query",
buffer::BufferType::DccChat => "dcc_chat",
buffer::BufferType::Special => "special",
buffer::BufferType::Shell => "shell",
};
BufferInfo {
id: b.id.clone(),
connection_id: b.connection_id.clone(),
name: b.name.clone(),
buffer_type: bt.to_string(),
topic: b.topic.clone(),
unread_count: b.unread_count,
}
})
.collect();
let mut buffer_nicks: HashMap<String, Vec<NickInfo>> = HashMap::new();
for (buf_id, buf) in &self.buffers {
if !buf.users.is_empty() {
let nicks = buf
.users
.values()
.map(|e| NickInfo {
nick: e.nick.clone(),
prefix: e.prefix.clone(),
modes: e.modes.clone(),
away: e.away,
})
.collect();
buffer_nicks.insert(buf_id.clone(), nicks);
}
}
ScriptStateSnapshot {
active_buffer_id: self.active_buffer_id.clone(),
connections,
buffers,
buffer_nicks,
script_config: HashMap::new(),
app_config_toml: None,
}
}
}