Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
74 changes: 53 additions & 21 deletions packages/core/core-shared/src/actor.rs
Original file line number Diff line number Diff line change
@@ -1,18 +1,18 @@
use std::{fmt, time::Duration};

use futures::{FutureExt, future::FusedFuture};
use rand::{SeedableRng, rngs::SmallRng};
#[cfg(not(feature = "web"))]
use std::time::Instant;
#[cfg(feature = "web")]
use web_time::Instant;

#[cfg(feature = "web")]
#[allow(unused_imports)]
use crate::dbg;
use crate::{
SendCommand,
database::Database,
response_channels::{CommandKey, CommandResponse, ResponseChannels},
response_channels::{CommandResponse, ResponseChannels},
state::{Channel, Message, OrbitError, Server, ServerEvent, User},
};
use anyhow::Context;
Expand Down Expand Up @@ -79,9 +79,24 @@ pub trait IrcConnection: fmt::Debug {
fn address(&self) -> &str;
}

pub(crate) struct RequestedHistory {
#[derive(Debug)]
pub(crate) struct RequestedBatch {
pub target: String,
pub label: Option<String>,
pub typ: BatchType,
}

#[derive(Debug, PartialEq, Eq)]
pub(crate) enum BatchType {
Join,
JoinHistory,
History,
}

#[derive(Debug, PartialEq, Eq)]
pub(crate) enum HistoryPurpose {
Join,
History,
}

#[derive(Debug)]
Expand All @@ -93,6 +108,7 @@ pub(crate) struct CurrentBatch {
#[derive(Debug)]
pub(crate) enum BatchData {
History {
purpose: HistoryPurpose,
label: Option<String>,
target: String,
messages: Vec<Message>,
Expand All @@ -101,13 +117,20 @@ pub(crate) enum BatchData {
target: String,
message: Message,
},
Join {
label: String,
target: String,
},
Unhandled,
}

impl CurrentBatch {
pub fn is_chathistory(&self) -> bool {
matches!(self.data, BatchData::History { .. })
}
pub fn is_join(&self) -> bool {
matches!(self.data, BatchData::Join { .. })
}
}

#[derive(Default, Clone)]
Expand All @@ -134,9 +157,8 @@ pub struct IrcActor<C: IrcConnection, DB: Database> {
pub(crate) disconnect_handlers: Vec<UnboundedSender<String>>,

pub(crate) current_batches: Vec<CurrentBatch>,
pub(crate) requested_history_batches: Vec<(RequestedHistory, Instant)>,
pub(crate) requested_batches: Vec<(RequestedBatch, Instant)>,
pub(crate) sasl_state: SaslState,
pub(crate) rng: SmallRng,
}

impl<C: IrcConnection, DB: Database> IrcActor<C, DB> {
Expand All @@ -162,21 +184,14 @@ impl<C: IrcConnection, DB: Database> IrcActor<C, DB> {
error_handlers: Default::default(),
disconnect_handlers: Default::default(),
current_batches: Default::default(),
requested_history_batches: Default::default(),
requested_batches: Default::default(),
sasl_state: Default::default(),
rng: SmallRng::from_seed([1; 32]),
};

let (tx, rx) = oneshot::channel();
actor
.response_channels
.register(CommandKey::RequestCaps, tx);
actor.request_caps().await?;
actor.init_cap_request().await?;

spawn(actor);

rx.await.unwrap();

Ok(cmd_tx)
}

Expand Down Expand Up @@ -220,7 +235,7 @@ impl<C: IrcConnection, DB: Database> IrcActor<C, DB> {


assert!(
self.requested_history_batches
self.requested_batches
.iter()
.all(|(_, creation)| creation.elapsed() < Duration::from_secs(5))
);
Expand Down Expand Up @@ -282,12 +297,17 @@ impl<C: IrcConnection, DB: Database> IrcActor<C, DB> {
}

#[tracing::instrument(err, skip(self))]
pub(crate) async fn request_caps(&mut self) -> Result<(), OrbitError> {
pub(crate) async fn init_cap_request(&mut self) -> Result<(), OrbitError> {
let irc_version = String::from("302");
self.cap_ls(irc_version)
.await
.context("Failed to send CAPS LS")?;
self.cap_req(&[

Ok(())
}
pub(crate) async fn request_caps(&mut self) -> Result<(), OrbitError> {
let mut enable = Vec::new();
for cap in [
"echo-message",
"labeled-response",
"message-tags",
Expand All @@ -298,11 +318,24 @@ impl<C: IrcConnection, DB: Database> IrcActor<C, DB> {
"draft/event-playback",
"draft/account-registration",
"draft/multiline",
"draft/extended-isupport",
"server-time",
"batch",
])
.await
.context("Failed to send CAP REQ")?;
"draft/webpush",
"extended-monitor",
"away-notify",
"draft/read-marker",
] {
if self.state.capabilities.cap_by_name(cap).has {
enable.push(cap);
}
}

if !enable.is_empty() {
self.cap_req(&enable)
.await
.context("Failed to send CAP REQ")?;
}

Ok(())
}
Expand All @@ -314,7 +347,6 @@ impl<C: IrcConnection, DB: Database> IrcActor<C, DB> {
username: String,
realname: String,
) -> Result<(), OrbitError> {
self.cap_end().await.context("Failed to send CAP END")?;
self.nick(nickname.clone())
.await
.context("Failed to send NICK")?;
Expand Down
Loading
Loading