gitdataai/lib/channel/http/handler/pin.rs

102 lines
3.1 KiB
Rust

use chrono::Utc;
use uuid::Uuid;
use crate::event::{RoomInfo, UserInfo, pin};
use crate::{ChannelBus, ChannelResult};
use super::WsHandler;
use super::WsOutEvent;
impl WsHandler {
pub(super) async fn pin_add(
bus: &ChannelBus,
user_id: Uuid,
room: Uuid,
message: Uuid,
) -> ChannelResult<Option<WsOutEvent>> {
Self::ensure_room_access(bus, user_id, room).await?;
Self::ensure_message_in_room(bus, room, message).await?;
let seq = bus.inner.seq.seq(room).await?;
let result = db::sqlx::query(
"INSERT INTO room_pin (room, message, seq, pinned_by, created_at) \
VALUES ($1, $2, $3, $4, now()) \
ON CONFLICT DO NOTHING",
)
.bind(room)
.bind(message)
.bind(seq)
.bind(user_id)
.execute(bus.inner.db.writer())
.await?;
if result.rows_affected() == 0 {
return Ok(None);
}
db::sqlx::query("UPDATE room_message SET pinned = true, updated_at = now() WHERE id = $1")
.bind(message)
.execute(bus.inner.db.writer())
.await?;
let pa_room = bus
.lookup_room(room)
.await
.unwrap_or_else(|_| RoomInfo::unknown(room));
let pinned_by = bus
.lookup_user(user_id)
.await
.unwrap_or_else(|_| UserInfo::unknown(user_id));
let data = pin::PinAddedService {
room: pa_room,
message,
pinned_by,
pinned_at: Utc::now(),
};
bus.publish_room_event(room, "pin.added", &data).await?;
Ok(Some(WsOutEvent::PinAdded {
room: data.room.clone(),
data,
}))
}
pub(super) async fn pin_remove(
bus: &ChannelBus,
user_id: Uuid,
room: Uuid,
message: Uuid,
) -> ChannelResult<Option<WsOutEvent>> {
Self::ensure_room_access(bus, user_id, room).await?;
Self::ensure_message_in_room(bus, room, message).await?;
let result = db::sqlx::query(
"DELETE FROM room_pin WHERE room = $1 AND message = $2",
)
.bind(room)
.bind(message)
.execute(bus.inner.db.writer())
.await?;
if result.rows_affected() == 0 {
return Ok(None);
}
db::sqlx::query("UPDATE room_message SET pinned = false, updated_at = now() WHERE id = $1")
.bind(message)
.execute(bus.inner.db.writer())
.await?;
let pr_room = bus
.lookup_room(room)
.await
.unwrap_or_else(|_| RoomInfo::unknown(room));
let removed_by = bus
.lookup_user(user_id)
.await
.unwrap_or_else(|_| UserInfo::unknown(user_id));
let data = pin::PinRemovedService {
room: pr_room,
message,
removed_by,
removed_at: Utc::now(),
};
bus.publish_room_event(room, "pin.removed", &data).await?;
Ok(Some(WsOutEvent::PinRemoved {
room: data.room.clone(),
data,
}))
}
}