72 lines
1.9 KiB
Rust
72 lines
1.9 KiB
Rust
use uuid::Uuid;
|
|
|
|
use crate::cache::redis::AppRedis;
|
|
use crate::error::{AppError, AppResult};
|
|
use crate::service::im::util::{TYPING_PREFIX, TYPING_TTL_SECS};
|
|
use ::redis::Cmd;
|
|
|
|
pub fn set_typing(
|
|
redis: &AppRedis,
|
|
channel_id: Uuid,
|
|
thread_id: Option<Uuid>,
|
|
user_id: Uuid,
|
|
) -> AppResult<()> {
|
|
let key = typing_key(channel_id, thread_id, user_id);
|
|
let mut conn = redis.get_connection()?;
|
|
Cmd::new()
|
|
.arg("SETEX")
|
|
.arg(&key)
|
|
.arg(TYPING_TTL_SECS as u64)
|
|
.arg("1")
|
|
.query::<()>(&mut *conn.inner_mut())?;
|
|
Ok(())
|
|
}
|
|
|
|
pub fn clear_typing(
|
|
redis: &AppRedis,
|
|
channel_id: Uuid,
|
|
thread_id: Option<Uuid>,
|
|
user_id: Uuid,
|
|
) -> AppResult<()> {
|
|
let key = typing_key(channel_id, thread_id, user_id);
|
|
let mut conn = redis.get_connection()?;
|
|
Cmd::new()
|
|
.arg("DEL")
|
|
.arg(&key)
|
|
.query::<()>(&mut *conn.inner_mut())?;
|
|
Ok(())
|
|
}
|
|
|
|
pub fn get_typing_users(
|
|
redis: &AppRedis,
|
|
channel_id: Uuid,
|
|
thread_id: Option<Uuid>,
|
|
) -> AppResult<Vec<Uuid>> {
|
|
let pattern = match thread_id {
|
|
Some(tid) => format!("{TYPING_PREFIX}{channel_id}:{tid}:*"),
|
|
None => format!("{TYPING_PREFIX}{channel_id}:*"),
|
|
};
|
|
let mut conn = redis.get_connection()?;
|
|
let keys: Vec<String> = Cmd::new()
|
|
.arg("KEYS")
|
|
.arg(&pattern)
|
|
.query(&mut *conn.inner_mut())
|
|
.map_err(AppError::Redis)?;
|
|
let mut ids = Vec::with_capacity(keys.len());
|
|
for key in &keys {
|
|
if let Some(part) = key.rsplit(':').next()
|
|
&& let Ok(uid) = part.parse::<Uuid>()
|
|
{
|
|
ids.push(uid);
|
|
}
|
|
}
|
|
Ok(ids)
|
|
}
|
|
|
|
fn typing_key(channel_id: Uuid, thread_id: Option<Uuid>, user_id: Uuid) -> String {
|
|
match thread_id {
|
|
Some(tid) => format!("{TYPING_PREFIX}{channel_id}:{tid}:{user_id}"),
|
|
None => format!("{TYPING_PREFIX}{channel_id}:{user_id}"),
|
|
}
|
|
}
|