Skip to content

Commit

Permalink
feat: initial user sync
Browse files Browse the repository at this point in the history
  • Loading branch information
casperstorm committed Mar 10, 2024
1 parent badd30b commit 7ecf031
Show file tree
Hide file tree
Showing 10 changed files with 101 additions and 37 deletions.
31 changes: 28 additions & 3 deletions data/src/client.rs
Original file line number Diff line number Diff line change
Expand Up @@ -701,7 +701,23 @@ impl Client {
self.chanmap.get(channel).map(|channel| &channel.topic)
}

fn users<'a>(&'a self, channel: &str) -> &'a [User] {
pub fn get_user_from_channel<'a>(
&'a self,
user: &User,
channel: Option<String>,
) -> Option<&'a User> {
let Some(channel) = channel else {
return None;
};

let Some(channel) = self.chanmap.get(&channel) else {
return None;
};

channel.users.get(user)
}

pub fn users<'a>(&'a self, channel: &str) -> &'a [User] {
self.users
.get(channel)
.map(Vec::as_slice)
Expand Down Expand Up @@ -825,8 +841,17 @@ impl Map {
}
}

pub fn nickname(&self, server: &Server) -> Option<NickRef> {
self.client(server).map(Client::nickname)
pub fn client_user(&self, server: &Server, channel: Option<String>) -> Option<User> {
let Some(client) = self.client(server) else {
return None;
};

let partial_user = User::from(Client::nickname(&client).to_owned());

match client.get_user_from_channel(&partial_user, channel) {
Some(user) => Some(user.clone()),
None => Some(partial_user),
}
}

pub fn receive(&mut self, server: &Server, message: message::Encoded) -> Vec<Event> {
Expand Down
6 changes: 3 additions & 3 deletions data/src/history/manager.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ use crate::config::buffer::Exclude;
use crate::history::{self, History};
use crate::message::{self, Limit};
use crate::time::Posix;
use crate::user::{Nick, NickRef};
use crate::user::Nick;
use crate::{server, Buffer, Config, Input, Server, User};

#[derive(Debug, Clone, PartialEq, Eq, Hash)]
Expand Down Expand Up @@ -167,8 +167,8 @@ impl Manager {
}
}

pub fn record_input(&mut self, input: Input, our_nick: NickRef) {
if let Some(message) = input.message(our_nick) {
pub fn record_input(&mut self, input: Input, user: User) {
if let Some(message) = input.message(user) {
self.record_message(input.server(), message);
}

Expand Down
7 changes: 3 additions & 4 deletions data/src/input.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@ use irc::proto;
use irc::proto::format;

use crate::time::Posix;
use crate::user::NickRef;
use crate::{command, message, Buffer, Command, Message, Server, User};

pub fn parse(buffer: Buffer, input: &str) -> Result<Input, Error> {
Expand Down Expand Up @@ -52,7 +51,7 @@ impl Input {
self.buffer.server()
}

pub fn message(&self, our_nick: NickRef) -> Option<Message> {
pub fn message(&self, user: User) -> Option<Message> {
let to_target = |target: String, source| {
if proto::is_channel(&target) {
Some(message::Target::Channel {
Expand All @@ -78,7 +77,7 @@ impl Input {
direction: message::Direction::Sent,
target: to_target(
target,
message::Source::User(User::from(our_nick.to_owned())),
message::Source::User(user),
)?,
text,
}),
Expand All @@ -87,7 +86,7 @@ impl Input {
server_time: Utc::now(),
direction: message::Direction::Sent,
target: to_target(target, message::Source::Action)?,
text: message::action_text(our_nick, &action),
text: message::action_text(user.nickname(), &action),
}),
_ => None,
}
Expand Down
55 changes: 48 additions & 7 deletions data/src/message.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ use irc::proto::Command;
use serde::{Deserialize, Serialize};

pub use self::source::Source;
use crate::client::Client;
use crate::time::{self, Posix};
use crate::user::{Nick, NickRef};
use crate::{Config, User};
Expand All @@ -25,6 +26,18 @@ impl Encoded {
_ => None,
}
}

pub fn channel(&self) -> Option<String> {
match &self.command {
Command::PRIVMSG(channel, _)
| Command::NOTICE(channel, _)
| Command::INVITE(_, channel)
| Command::PART(channel, _)
| Command::JOIN(channel, _)
| Command::TOPIC(channel, _) => Some(channel.clone()),
_ => None,
}
}
}

impl std::ops::Deref for Encoded {
Expand Down Expand Up @@ -91,10 +104,15 @@ impl Message {
&& matches!(self.target.source(), Source::User(_) | Source::Action)
}

pub fn received(encoded: Encoded, our_nick: Nick, config: &Config) -> Option<Message> {
pub fn received(
encoded: Encoded,
our_nick: Nick,
config: &Config,
client: Option<&Client>,
) -> Option<Message> {
let server_time = server_time(&encoded);
let text = text(&encoded, &our_nick, config)?;
let target = target(encoded, &our_nick)?;
let text = text(&encoded, &our_nick, config, client)?;
let target = target(encoded, &our_nick, client)?;

Some(Message {
received_at: Posix::now(),
Expand All @@ -110,10 +128,18 @@ impl Message {
}
}

fn target(message: Encoded, our_nick: &Nick) -> Option<Target> {
fn target(message: Encoded, our_nick: &Nick, client: Option<&Client>) -> Option<Target> {
use proto::command::Numeric::*;

let user = message.user();
let user = match message.user() {
Some(user) => match client {
Some(client) => client
.get_user_from_channel(&user, message.channel())
.cloned(),
None => Some(user),
},
None => None,
};

match message.0.command {
// Channel
Expand Down Expand Up @@ -167,6 +193,7 @@ fn target(message: Encoded, our_nick: &Nick) -> Option<Target> {
}
Command::PRIVMSG(target, text) => {
let is_action = is_action(&text);

let source = |user| {
if is_action {
Source::Action
Expand Down Expand Up @@ -274,10 +301,24 @@ pub fn server_time(message: &Encoded) -> DateTime<Utc> {
.unwrap_or_else(Utc::now)
}

fn text(message: &Encoded, our_nick: &Nick, config: &Config) -> Option<String> {
fn text(
message: &Encoded,
our_nick: &Nick,
config: &Config,
client: Option<&Client>,
) -> Option<String> {
use irc::proto::command::Numeric::*;

let user = message.user();
let user = match message.user() {
Some(user) => match client {
Some(client) => client
.get_user_from_channel(&user, message.channel())
.cloned(),
None => Some(user),
},
None => None,
};

match &message.command {
Command::TOPIC(_, topic) => {
let user = user?;
Expand Down
2 changes: 1 addition & 1 deletion data/src/user.rs
Original file line number Diff line number Diff line change
Expand Up @@ -203,7 +203,7 @@ impl From<proto::User> for User {

impl fmt::Display for User {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "{}", self.nickname())
write!(f, "{}{}", self.highest_access_level(), self.nickname())
}
}

Expand Down
16 changes: 6 additions & 10 deletions src/buffer/channel.rs
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ pub fn view<'a>(
) -> Element<'a, Message> {
let buffer = state.buffer();
let input_history = history.input_history(&buffer);
let our_nick = clients.nickname(&state.server);
let client_user = clients.client_user(&state.server, buffer.target());

let messages = container(
scroll_view::view(
Expand All @@ -53,17 +53,17 @@ pub fn view<'a>(
selectable_text(config.buffer.nickname.brackets.format(user)).style(
theme::Text::Nickname(
user.color_seed(&config.buffer.nickname.color),
false,
user.is_away(),
),
),
user.clone(),
)
.map(scroll_view::Message::UserContext);
let row_style = match our_nick {
Some(nick)
let row_style = match &client_user {
Some(client_user)
if message::reference_user(
user.nickname(),
nick,
client_user.nickname(),
&message.text,
) =>
{
Expand Down Expand Up @@ -277,11 +277,7 @@ mod nick_list {

pub fn view<'a>(users: &[User], config: &'a Config) -> Element<'a, Message> {
let column = column(users.iter().map(|user| {
let content = text(format!(
"{}{}",
user.highest_access_level(),
user.nickname()
))
let content = text(user)
.style(theme::Text::Nickname(
user.color_seed(&config.buffer.channel.users.color),
user.is_away(),
Expand Down
4 changes: 2 additions & 2 deletions src/buffer/input_view.rs
Original file line number Diff line number Diff line change
Expand Up @@ -76,8 +76,8 @@ impl State {
clients.send(input.buffer(), encoded);
}

if let Some(nick) = clients.nickname(input.server()) {
history.record_input(input, nick);
if let Some(user) = clients.client_user(input.server(), input.buffer().target()) {
history.record_input(input, user);
}

(Command::none(), Some(Event::InputSent))
Expand Down
9 changes: 6 additions & 3 deletions src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -319,17 +319,20 @@ impl Application for Halloy {

messages.into_iter().for_each(|message| {
for event in self.clients.receive(&server, message) {
let client = self.clients.client(&server);

match event {
data::client::Event::Single(encoded, our_nick) => {

if let Some(message) =
data::Message::received(encoded, our_nick, &self.config)
data::Message::received(encoded, our_nick, &self.config, client)
{
dashboard.record_message(&server, message);
}
}
data::client::Event::WithTarget(encoded, our_nick, target) => {
if let Some(message) =
data::Message::received(encoded, our_nick, &self.config)
data::Message::received(encoded, our_nick, &self.config, client)
{
dashboard
.record_message(&server, message.with_target(target));
Expand Down Expand Up @@ -388,7 +391,7 @@ impl Application for Halloy {
notification,
) => {
if let Some(message) =
data::Message::received(encoded, our_nick, &self.config)
data::Message::received(encoded, our_nick, &self.config, client)
{
dashboard.record_message(&server, message);
}
Expand Down
6 changes: 3 additions & 3 deletions src/screen/dashboard.rs
Original file line number Diff line number Diff line change
Expand Up @@ -115,15 +115,15 @@ impl Dashboard {
let command =
data::Command::Whois(None, user.nickname().to_string());

let input = data::Input::command(buffer, command);
let input = data::Input::command(buffer.clone(), command);

if let Some(encoded) = input.encoded() {
clients.send(input.buffer(), encoded);
}

if let Some(message) = clients
.nickname(input.server())
.and_then(|nick| input.message(nick))
.client_user(input.server(), buffer.target())
.and_then(|user| input.message(user))
{
self.history.record_message(input.server(), message);
}
Expand Down
2 changes: 1 addition & 1 deletion src/theme.rs
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,7 @@ impl rule::StyleSheet for Theme {
fill_mode: rule::FillMode::Full,
},
Rule::Unread => rule::Appearance {
color: self.colors().accent.base,
color: self.colors().background.light,
width: 1,
radius: 0.0.into(),
fill_mode: rule::FillMode::Full,
Expand Down

0 comments on commit 7ecf031

Please sign in to comment.