Skip to content

Commit

Permalink
Merge pull request #270 from andymandias/broadcast-sent-time
Browse files Browse the repository at this point in the history
  • Loading branch information
casperstorm authored Mar 25, 2024
2 parents cefbe00 + bb7c29e commit d65b906
Show file tree
Hide file tree
Showing 7 changed files with 147 additions and 34 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
Fixed:

- Accept '@' in usernames to support bouncers that use the user@identifier/network convention
- Prevent rare scenario where broadcast messages' timestamp would not match time the messages are received

# 2024.5 (2024-03-21)

Expand Down
6 changes: 6 additions & 0 deletions data/src/client.rs
Original file line number Diff line number Diff line change
Expand Up @@ -45,17 +45,20 @@ pub enum Broadcast {
user: User,
comment: Option<String>,
channels: Vec<String>,
sent_time: DateTime<Utc>,
},
Nickname {
old_user: User,
new_nick: Nick,
ourself: bool,
channels: Vec<String>,
sent_time: DateTime<Utc>,
},
Invite {
inviter: User,
channel: String,
user_channels: Vec<String>,
sent_time: DateTime<Utc>,
},
}

Expand Down Expand Up @@ -400,6 +403,7 @@ impl Client {
inviter,
channel: channel.clone(),
user_channels,
sent_time: server_time(&message),
})]);
}
Command::NICK(nick) => {
Expand All @@ -425,6 +429,7 @@ impl Client {
new_nick,
ourself,
channels,
sent_time: server_time(&message)
})]);
}
Command::Numeric(ERR_NICKNAMEINUSE | ERR_ERRONEUSNICKNAME, _)
Expand Down Expand Up @@ -505,6 +510,7 @@ impl Client {
user,
comment: comment.clone(),
channels,
sent_time: server_time(&message)
})]);
}
Command::PART(channel, _) => {
Expand Down
26 changes: 18 additions & 8 deletions data/src/history/manager.rs
Original file line number Diff line number Diff line change
Expand Up @@ -262,7 +262,13 @@ impl Manager {
.unwrap_or_default()
}

pub fn broadcast(&mut self, server: &Server, broadcast: Broadcast, config: &Config) {
pub fn broadcast(
&mut self,
server: &Server,
broadcast: Broadcast,
config: &Config,
sent_time: DateTime<Utc>,
) {
let map = self.data.map.entry(server.clone()).or_default();

let channels = map
Expand All @@ -287,21 +293,23 @@ impl Manager {
.cloned();

let messages = match broadcast {
Broadcast::Connecting => message::broadcast::connecting(),
Broadcast::Connected => message::broadcast::connected(),
Broadcast::ConnectionFailed { error } => message::broadcast::connection_failed(error),
Broadcast::Connecting => message::broadcast::connecting(sent_time),
Broadcast::Connected => message::broadcast::connected(sent_time),
Broadcast::ConnectionFailed { error } => {
message::broadcast::connection_failed(error, sent_time)
}
Broadcast::Disconnected { error } => {
message::broadcast::disconnected(channels, queries, error)
message::broadcast::disconnected(channels, queries, error, sent_time)
}
Broadcast::Reconnected => message::broadcast::reconnected(channels, queries),
Broadcast::Reconnected => message::broadcast::reconnected(channels, queries, sent_time),
Broadcast::Quit {
user,
comment,
user_channels,
} => {
let user_query = queries.find(|nick| user.nickname() == *nick);

message::broadcast::quit(user_channels, user_query, &user, &comment, config)
message::broadcast::quit(user_channels, user_query, &user, &comment, config, sent_time)
}
Broadcast::Nickname {
old_nick,
Expand All @@ -317,6 +325,7 @@ impl Manager {
&old_nick,
&new_nick,
ourself,
sent_time,
)
} else {
// Otherwise just the query channel of the user w/ nick change
Expand All @@ -327,14 +336,15 @@ impl Manager {
&old_nick,
&new_nick,
ourself,
sent_time,
)
}
}
Broadcast::Invite {
inviter,
channel,
user_channels,
} => message::broadcast::invite(inviter, channel, user_channels),
} => message::broadcast::invite(inviter, channel, user_channels, sent_time),
};

messages.into_iter().for_each(|message| {
Expand Down
50 changes: 40 additions & 10 deletions data/src/message/broadcast.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
//! Generate messages that can be broadcast into every buffer
use chrono::Utc;
use chrono::{DateTime, Utc};

use super::{source, Direction, Message, Source, Target};
use crate::time::Posix;
Expand All @@ -17,11 +17,12 @@ fn expand(
include_server: bool,
cause: Cause,
text: String,
sent_time: DateTime<Utc>,
) -> Vec<Message> {
let message = |target, text| -> Message {
Message {
received_at: Posix::now(),
server_time: Utc::now(),
server_time: sent_time,
direction: Direction::Received,
target,
text,
Expand Down Expand Up @@ -64,25 +65,47 @@ fn expand(
.collect()
}

pub fn connecting() -> Vec<Message> {
pub fn connecting(sent_time: DateTime<Utc>) -> Vec<Message> {
let text = " ∙ connecting to server...".into();
expand([], [], true, Cause::Status(source::Status::Success), text)
expand(
[],
[],
true,
Cause::Status(source::Status::Success),
text,
sent_time,
)
}

pub fn connected() -> Vec<Message> {
pub fn connected(sent_time: DateTime<Utc>) -> Vec<Message> {
let text = " ∙ connected".into();
expand([], [], true, Cause::Status(source::Status::Success), text)
expand(
[],
[],
true,
Cause::Status(source::Status::Success),
text,
sent_time,
)
}

pub fn connection_failed(error: String) -> Vec<Message> {
pub fn connection_failed(error: String, sent_time: DateTime<Utc>) -> Vec<Message> {
let text = format!(" ∙ connection to server failed ({error})");
expand([], [], true, Cause::Status(source::Status::Error), text)
expand(
[],
[],
true,
Cause::Status(source::Status::Error),
text,
sent_time,
)
}

pub fn disconnected(
channels: impl IntoIterator<Item = String>,
queries: impl IntoIterator<Item = Nick>,
error: Option<String>,
sent_time: DateTime<Utc>,
) -> Vec<Message> {
let error = error.map(|error| format!(" ({error})")).unwrap_or_default();
let text = format!(" ∙ connection to server lost{error}");
Expand All @@ -92,12 +115,14 @@ pub fn disconnected(
true,
Cause::Status(source::Status::Error),
text,
sent_time,
)
}

pub fn reconnected(
channels: impl IntoIterator<Item = String>,
queries: impl IntoIterator<Item = Nick>,
sent_time: DateTime<Utc>,
) -> Vec<Message> {
let text = " ∙ connection to server restored".into();
expand(
Expand All @@ -106,6 +131,7 @@ pub fn reconnected(
true,
Cause::Status(source::Status::Success),
text,
sent_time,
)
}

Expand All @@ -115,6 +141,7 @@ pub fn quit(
user: &User,
comment: &Option<String>,
config: &Config,
sent_time: DateTime<Utc>,
) -> Vec<Message> {
let comment = comment
.as_ref()
Expand All @@ -134,6 +161,7 @@ pub fn quit(
Some(user.nickname().to_owned()),
))),
text,
sent_time,
)
}

Expand All @@ -143,22 +171,24 @@ pub fn nickname(
old_nick: &Nick,
new_nick: &Nick,
ourself: bool,
sent_time: DateTime<Utc>,
) -> Vec<Message> {
let text = if ourself {
format!(" ∙ You're now known as {new_nick}")
} else {
format!(" ∙ {old_nick} is now known as {new_nick}")
};

expand(channels, queries, false, Cause::Server(None), text)
expand(channels, queries, false, Cause::Server(None), text, sent_time)
}

pub fn invite(
inviter: Nick,
channel: String,
channels: impl IntoIterator<Item = String>,
sent_time: DateTime<Utc>,
) -> Vec<Message> {
let text = format!(" ∙ {inviter} invited you to join {channel}");

expand(channels, [], false, Cause::Server(None), text)
expand(channels, [], false, Cause::Server(None), text, sent_time)
}
10 changes: 10 additions & 0 deletions data/src/stream.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
use chrono::{DateTime, Utc};
use std::time::Duration;

use futures::channel::mpsc;
Expand Down Expand Up @@ -25,15 +26,18 @@ pub enum Update {
server: Server,
client: Client,
is_initial: bool,
sent_time: DateTime<Utc>,
},
Disconnected {
server: Server,
is_initial: bool,
error: Option<String>,
sent_time: DateTime<Utc>,
},
ConnectionFailed {
server: Server,
error: String,
sent_time: DateTime<Utc>,
},
MessagesReceived(Server, Vec<message::Encoded>),
}
Expand Down Expand Up @@ -77,6 +81,7 @@ pub async fn run(server: server::Entry, mut sender: mpsc::Sender<Update>) -> Nev
server: server.clone(),
is_initial,
error: None,
sent_time: Utc::now(),
})
.await;

Expand All @@ -100,6 +105,7 @@ pub async fn run(server: server::Entry, mut sender: mpsc::Sender<Update>) -> Nev
server: server.clone(),
client,
is_initial,
sent_time: Utc::now(),
})
.await;

Expand All @@ -125,6 +131,7 @@ pub async fn run(server: server::Entry, mut sender: mpsc::Sender<Update>) -> Nev
.send(Update::ConnectionFailed {
server: server.clone(),
error,
sent_time: Utc::now(),
})
.await;

Expand Down Expand Up @@ -177,6 +184,7 @@ pub async fn run(server: server::Entry, mut sender: mpsc::Sender<Update>) -> Nev
server: server.clone(),
is_initial,
error: Some(error),
sent_time: Utc::now(),
})
.await;
state = State::Disconnected {
Expand All @@ -197,6 +205,7 @@ pub async fn run(server: server::Entry, mut sender: mpsc::Sender<Update>) -> Nev
server: server.clone(),
is_initial,
error: Some(e.to_string()),
sent_time: Utc::now(),
})
.await;
state = State::Disconnected {
Expand Down Expand Up @@ -228,6 +237,7 @@ pub async fn run(server: server::Entry, mut sender: mpsc::Sender<Update>) -> Nev
server: server.clone(),
is_initial,
error: Some("ping timeout".into()),
sent_time: Utc::now(),
})
.await;
state = State::Disconnected {
Expand Down
Loading

0 comments on commit d65b906

Please sign in to comment.