87 lines
2.8 KiB
Rust
87 lines
2.8 KiB
Rust
use uuid::Uuid;
|
|
|
|
use crate::event::{RoomInfo, forward};
|
|
use crate::{ChannelBus, ChannelResult};
|
|
|
|
use super::WsHandler;
|
|
use super::WsOutEvent;
|
|
|
|
impl WsHandler {
|
|
pub(super) async fn message_forward(
|
|
bus: &ChannelBus,
|
|
user_id: Uuid,
|
|
source_message_id: Uuid,
|
|
target_room: Uuid,
|
|
) -> ChannelResult<Option<WsOutEvent>> {
|
|
let source = Self::load_message(bus, source_message_id).await?;
|
|
|
|
Self::ensure_room_access(bus, user_id, source.room).await?;
|
|
Self::ensure_room_access(bus, user_id, target_room).await?;
|
|
|
|
let seq = bus.inner.seq.seq(target_room).await?;
|
|
let sender = bus.lookup_user(user_id).await?;
|
|
|
|
let source_room_info = bus
|
|
.lookup_room(source.room)
|
|
.await
|
|
.unwrap_or_else(|_| RoomInfo::unknown(source.room));
|
|
let forward_content = format!(
|
|
"> Forwarded from {}:\n\n{}",
|
|
source_room_info.name, source.content
|
|
);
|
|
|
|
let metadata = serde_json::json!({
|
|
"source_room_id": source.room,
|
|
"source_message_id": source.id,
|
|
"source_room_name": source_room_info.name,
|
|
"forwarded_by": user_id,
|
|
});
|
|
|
|
let row = db::sqlx::query_as::<_, model::room::RoomMessageModel>(
|
|
"INSERT INTO room_message \
|
|
(room, seq, thread, parent, author, content, content_type, system_type, metadata) \
|
|
VALUES ($1, $2, NULL, NULL, $3, $4, 'forward', NULL, $5) \
|
|
RETURNING id, room, seq, thread, parent, author, content, content_type, pinned, \
|
|
system_type, metadata, edited_at, created_at, updated_at, deleted_at",
|
|
)
|
|
.bind(target_room)
|
|
.bind(seq)
|
|
.bind(user_id)
|
|
.bind(&forward_content)
|
|
.bind(&metadata)
|
|
.fetch_one(bus.inner.db.writer())
|
|
.await?;
|
|
|
|
let target_room_info = bus
|
|
.lookup_room(target_room)
|
|
.await
|
|
.unwrap_or_else(|_| RoomInfo::unknown(target_room));
|
|
|
|
let fwd_id = row.id;
|
|
let fwd_seq = row.seq;
|
|
let fwd_content = row.content.clone();
|
|
let fwd_content_type = row.content_type.clone();
|
|
let fwd_created_at = row.created_at;
|
|
|
|
bus.publish_room_message(row, Some(bus.lookup_user(user_id).await?))
|
|
.await?;
|
|
|
|
let data = forward::MessageForwardedService {
|
|
id: fwd_id,
|
|
seq: fwd_seq,
|
|
room: target_room_info.clone(),
|
|
sender,
|
|
content: fwd_content,
|
|
content_type: fwd_content_type,
|
|
source_room: source_room_info,
|
|
source_message_id: source.id,
|
|
forwarded_at: fwd_created_at,
|
|
};
|
|
|
|
Ok(Some(WsOutEvent::MessageForwarded {
|
|
room: target_room_info,
|
|
data,
|
|
}))
|
|
}
|
|
}
|