use std::future::Future;
use std::time::Duration;
use grammers_mtsender::InvocationError;
use grammers_session::types::PeerRef;
use grammers_tl_types::{self as tl, enums::SendMessageAction};
use tokio::time::sleep;
use crate::Client;
const DEFAULT_REPEAT_DELAY: Duration = Duration::from_secs(4);
pub struct ActionSender {
client: Client,
peer: PeerRef,
topic_id: Option<i32>,
repeat_delay: Duration,
}
impl ActionSender {
pub fn new<C: Into<PeerRef>>(client: &Client, peer: C) -> Self {
Self {
client: client.clone(),
peer: peer.into(),
topic_id: None,
repeat_delay: DEFAULT_REPEAT_DELAY,
}
}
pub fn repeat_delay(mut self, repeat_delay: Duration) -> Self {
self.repeat_delay = repeat_delay;
self
}
pub fn topic_id(mut self, topic_id: i32) -> Self {
self.topic_id = Some(topic_id);
self
}
pub async fn cancel(&self) -> Result<(), InvocationError> {
self.oneshot(SendMessageAction::SendMessageCancelAction)
.await?;
Ok(())
}
pub async fn oneshot<A: Into<SendMessageAction>>(
&self,
action: A,
) -> Result<(), InvocationError> {
self.client
.invoke(&tl::functions::messages::SetTyping {
peer: self.peer.into(),
top_msg_id: self.topic_id,
action: action.into(),
})
.await?;
Ok(())
}
pub async fn repeat<A: Into<SendMessageAction>, T>(
&self,
action: impl Fn() -> A,
mut future: impl Future<Output = T> + Unpin,
) -> (T, Result<(), InvocationError>) {
let mut request_result = Ok(());
let future_output = loop {
if request_result.is_err() {
return (future.await, request_result);
}
let action = async {
request_result = self.oneshot(action().into()).await;
sleep(self.repeat_delay).await;
};
tokio::select! {
_ = action => continue,
output = &mut future => break output,
};
};
(future_output, request_result)
}
}