1use std::time::{Duration, SystemTime};
2
3use stoat_database::events::server::ClientMessage;
4use tokio::{select, time::sleep};
5use ulid::Ulid;
6
7use crate::context::Events;
8
9pub fn created_at(id: &str) -> SystemTime {
10 Ulid::from_string(id).expect("Malformed ID").datetime()
11}
12
13pub async fn with_typing<Fut: Future<Output = R>, R>(
31 events: impl AsRef<Events>,
32 channel_id: String,
33 fut: Fut,
34) -> R {
35 let events = events.as_ref();
36
37 let bg = {
38 let events = events.clone();
39 let channel_id = channel_id.clone();
40
41 async move {
42 loop {
43 if let Err(e) = events.send_event(ClientMessage::BeginTyping {
44 channel: channel_id.clone(),
45 }) {
46 log::error!("Error occurred in with_typing: {e:?}");
47 };
48
49 sleep(Duration::from_secs(10)).await;
50 }
51 }
52 };
53
54 select! {
55 _ = bg => {
56 unreachable!()
57 },
58 r = fut => {
59 if let Err(e) = events.send_event(ClientMessage::EndTyping { channel: channel_id }) {
60 log::error!("Error occurred in with_typing: {e:?}");
61 };
62
63 r
64 }
65 }
66}