From ca1ad4297c8bf5f77a9a475f9f7bd996e306032a Mon Sep 17 00:00:00 2001 From: myOmikron Date: Sun, 21 May 2023 00:36:49 +0200 Subject: [PATCH] Added last_message_uuid to get all chats --- migrations/0001_initial.toml | 161 ++++++++++++++++++---------------- src/models/chat.rs | 4 + src/server/handler/chats.rs | 104 ++++++++++++++++------ src/server/handler/friends.rs | 1 + src/server/handler/lobbies.rs | 2 + src/server/swagger.rs | 3 +- 6 files changed, 170 insertions(+), 105 deletions(-) diff --git a/migrations/0001_initial.toml b/migrations/0001_initial.toml index 9e31617..acdcacd 100644 --- a/migrations/0001_initial.toml +++ b/migrations/0001_initial.toml @@ -1,5 +1,5 @@ [Migration] -Hash = "1007693435009946095" +Hash = "1464912175188051413" Initial = true Replaces = [] @@ -57,28 +57,7 @@ Annotations = [] [[Migration.Operations]] Type = "CreateModel" -Name = "invite" - -[[Migration.Operations.Fields]] -Name = "uuid" -Type = "varbinary" - -[[Migration.Operations.Fields.Annotations]] -Type = "primary_key" - -[[Migration.Operations.Fields]] -Name = "created_at" -Type = "datetime" - -[[Migration.Operations.Fields.Annotations]] -Type = "auto_create_time" - -[[Migration.Operations.Fields.Annotations]] -Type = "not_null" - -[[Migration.Operations]] -Type = "CreateModel" -Name = "friend" +Name = "chatroom" [[Migration.Operations.Fields]] Name = "uuid" @@ -88,22 +67,9 @@ Type = "varbinary" Type = "primary_key" [[Migration.Operations.Fields]] -Name = "is_request" -Type = "boolean" - -[[Migration.Operations.Fields.Annotations]] -Type = "not_null" - -[[Migration.Operations]] -Type = "CreateModel" -Name = "chatroom" - -[[Migration.Operations.Fields]] -Name = "uuid" +Name = "last_message_uuid" Type = "varbinary" - -[[Migration.Operations.Fields.Annotations]] -Type = "primary_key" +Annotations = [] [[Migration.Operations]] Type = "CreateModel" @@ -158,6 +124,24 @@ Type = "auto_create_time" [[Migration.Operations.Fields.Annotations]] Type = "not_null" +[[Migration.Operations]] +Type = "CreateModel" +Name = "friend" + +[[Migration.Operations.Fields]] +Name = "uuid" +Type = "varbinary" + +[[Migration.Operations.Fields.Annotations]] +Type = "primary_key" + +[[Migration.Operations.Fields]] +Name = "is_request" +Type = "boolean" + +[[Migration.Operations.Fields.Annotations]] +Type = "not_null" + [[Migration.Operations]] Type = "CreateModel" Name = "game" @@ -222,6 +206,27 @@ Type = "varbinary" [[Migration.Operations.Fields.Annotations]] Type = "primary_key" +[[Migration.Operations]] +Type = "CreateModel" +Name = "invite" + +[[Migration.Operations.Fields]] +Name = "uuid" +Type = "varbinary" + +[[Migration.Operations.Fields.Annotations]] +Type = "primary_key" + +[[Migration.Operations.Fields]] +Name = "created_at" +Type = "datetime" + +[[Migration.Operations.Fields.Annotations]] +Type = "auto_create_time" + +[[Migration.Operations.Fields.Annotations]] +Type = "not_null" + [[Migration.Operations]] Type = "CreateModel" Name = "lobby" @@ -352,17 +357,17 @@ Type = "not_null" [[Migration.Operations]] Type = "CreateField" -Model = "gameaccount" +Model = "friend" [Migration.Operations.Field] -Name = "game" +Name = "from" Type = "varbinary" [[Migration.Operations.Field.Annotations]] Type = "foreign_key" [Migration.Operations.Field.Annotations.Value] -TableName = "game" +TableName = "account" ColumnName = "uuid" OnDelete = "Cascade" OnUpdate = "Cascade" @@ -372,10 +377,10 @@ Type = "not_null" [[Migration.Operations]] Type = "CreateField" -Model = "gameaccount" +Model = "friend" [Migration.Operations.Field] -Name = "player" +Name = "to" Type = "varbinary" [[Migration.Operations.Field.Annotations]] @@ -392,27 +397,24 @@ Type = "not_null" [[Migration.Operations]] Type = "CreateField" -Model = "lobby" +Model = "friend" [Migration.Operations.Field] -Name = "owner" +Name = "chat_room" Type = "varbinary" [[Migration.Operations.Field.Annotations]] Type = "foreign_key" [Migration.Operations.Field.Annotations.Value] -TableName = "account" +TableName = "chatroom" ColumnName = "uuid" OnDelete = "Cascade" OnUpdate = "Cascade" -[[Migration.Operations.Field.Annotations]] -Type = "not_null" - [[Migration.Operations]] Type = "CreateField" -Model = "lobby" +Model = "chatroommember" [Migration.Operations.Field] Name = "chat_room" @@ -432,10 +434,10 @@ Type = "not_null" [[Migration.Operations]] Type = "CreateField" -Model = "invite" +Model = "chatroommember" [Migration.Operations.Field] -Name = "from" +Name = "member" Type = "varbinary" [[Migration.Operations.Field.Annotations]] @@ -452,10 +454,10 @@ Type = "not_null" [[Migration.Operations]] Type = "CreateField" -Model = "invite" +Model = "lobby" [Migration.Operations.Field] -Name = "to" +Name = "owner" Type = "varbinary" [[Migration.Operations.Field.Annotations]] @@ -472,17 +474,17 @@ Type = "not_null" [[Migration.Operations]] Type = "CreateField" -Model = "invite" +Model = "lobby" [Migration.Operations.Field] -Name = "lobby" +Name = "chat_room" Type = "varbinary" [[Migration.Operations.Field.Annotations]] Type = "foreign_key" [Migration.Operations.Field.Annotations.Value] -TableName = "lobby" +TableName = "chatroom" ColumnName = "uuid" OnDelete = "Cascade" OnUpdate = "Cascade" @@ -492,17 +494,17 @@ Type = "not_null" [[Migration.Operations]] Type = "CreateField" -Model = "chatroommember" +Model = "invite" [Migration.Operations.Field] -Name = "chat_room" +Name = "from" Type = "varbinary" [[Migration.Operations.Field.Annotations]] Type = "foreign_key" [Migration.Operations.Field.Annotations.Value] -TableName = "chatroom" +TableName = "account" ColumnName = "uuid" OnDelete = "Cascade" OnUpdate = "Cascade" @@ -512,10 +514,10 @@ Type = "not_null" [[Migration.Operations]] Type = "CreateField" -Model = "chatroommember" +Model = "invite" [Migration.Operations.Field] -Name = "member" +Name = "to" Type = "varbinary" [[Migration.Operations.Field.Annotations]] @@ -532,17 +534,17 @@ Type = "not_null" [[Migration.Operations]] Type = "CreateField" -Model = "friend" +Model = "invite" [Migration.Operations.Field] -Name = "from" +Name = "lobby" Type = "varbinary" [[Migration.Operations.Field.Annotations]] Type = "foreign_key" [Migration.Operations.Field.Annotations.Value] -TableName = "account" +TableName = "lobby" ColumnName = "uuid" OnDelete = "Cascade" OnUpdate = "Cascade" @@ -552,10 +554,10 @@ Type = "not_null" [[Migration.Operations]] Type = "CreateField" -Model = "friend" +Model = "chatroommessage" [Migration.Operations.Field] -Name = "to" +Name = "sender" Type = "varbinary" [[Migration.Operations.Field.Annotations]] @@ -572,7 +574,7 @@ Type = "not_null" [[Migration.Operations]] Type = "CreateField" -Model = "friend" +Model = "chatroommessage" [Migration.Operations.Field] Name = "chat_room" @@ -587,19 +589,22 @@ ColumnName = "uuid" OnDelete = "Cascade" OnUpdate = "Cascade" +[[Migration.Operations.Field.Annotations]] +Type = "not_null" + [[Migration.Operations]] Type = "CreateField" -Model = "lobbyaccount" +Model = "gameaccount" [Migration.Operations.Field] -Name = "lobby" +Name = "game" Type = "varbinary" [[Migration.Operations.Field.Annotations]] Type = "foreign_key" [Migration.Operations.Field.Annotations.Value] -TableName = "lobby" +TableName = "game" ColumnName = "uuid" OnDelete = "Cascade" OnUpdate = "Cascade" @@ -609,7 +614,7 @@ Type = "not_null" [[Migration.Operations]] Type = "CreateField" -Model = "lobbyaccount" +Model = "gameaccount" [Migration.Operations.Field] Name = "player" @@ -629,17 +634,17 @@ Type = "not_null" [[Migration.Operations]] Type = "CreateField" -Model = "chatroommessage" +Model = "lobbyaccount" [Migration.Operations.Field] -Name = "sender" +Name = "lobby" Type = "varbinary" [[Migration.Operations.Field.Annotations]] Type = "foreign_key" [Migration.Operations.Field.Annotations.Value] -TableName = "account" +TableName = "lobby" ColumnName = "uuid" OnDelete = "Cascade" OnUpdate = "Cascade" @@ -649,17 +654,17 @@ Type = "not_null" [[Migration.Operations]] Type = "CreateField" -Model = "chatroommessage" +Model = "lobbyaccount" [Migration.Operations.Field] -Name = "chat_room" +Name = "player" Type = "varbinary" [[Migration.Operations.Field.Annotations]] Type = "foreign_key" [Migration.Operations.Field.Annotations.Value] -TableName = "chatroom" +TableName = "account" ColumnName = "uuid" OnDelete = "Cascade" OnUpdate = "Cascade" diff --git a/src/models/chat.rs b/src/models/chat.rs index b60da1d..7359700 100644 --- a/src/models/chat.rs +++ b/src/models/chat.rs @@ -16,12 +16,16 @@ pub struct ChatRoom { /// A backref to the members of a specific chatroom pub messages: BackRef, + + /// The uuid of the most recent message + pub last_message_uuid: Option, } #[derive(Patch)] #[rorm(model = "ChatRoom")] pub(crate) struct ChatRoomInsert { pub(crate) uuid: Uuid, + pub(crate) last_message_uuid: Option, } /// The member <-> chatroom relation diff --git a/src/server/handler/chats.rs b/src/server/handler/chats.rs index a00c0a7..8464b42 100644 --- a/src/server/handler/chats.rs +++ b/src/server/handler/chats.rs @@ -7,7 +7,7 @@ use chrono::{DateTime, Utc}; use itertools::Itertools; use log::warn; use rorm::fields::ForeignModelByField; -use rorm::{and, insert, query, Database, Model}; +use rorm::{and, insert, query, update, Database, Model}; use serde::{Deserialize, Serialize}; use utoipa::ToSchema; use uuid::Uuid; @@ -61,11 +61,18 @@ pub struct ChatMember { /// /// `messages` should be sorted by the datetime of `message.created_at`. #[derive(Serialize, ToSchema)] -pub struct GetChatResponse { +pub struct ChatFull { members: Vec, messages: Vec, } +/// The small representation of a chatroom +#[derive(Serialize, ToSchema)] +pub struct ChatSmall { + pub(crate) uuid: Uuid, + pub(crate) last_message_uuid: Option, +} + /// Retrieve the messages of a chatroom /// /// `messages` should be sorted by the datetime of `message.created_at`. @@ -78,7 +85,7 @@ pub struct GetChatResponse { tag = "Chats", context_path = "/api/v2", responses( - (status = 200, description = "Returns the messages of the chat room", body = GetChatResponse), + (status = 200, description = "Returns the messages of the chat room", body = ChatFull), (status = 400, description = "Client error", body = ApiErrorResponse), (status = 500, description = "Server error", body = ApiErrorResponse), ), @@ -90,7 +97,7 @@ pub async fn get_chat( path: Path, db: Data, session: Session, -) -> ApiResult> { +) -> ApiResult> { let uuid: Uuid = session.get("uuid")?.ok_or(ApiError::SessionCorrupt)?; let mut tx = db.start_transaction().await?; @@ -145,7 +152,7 @@ pub async fn get_chat( tx.commit().await?; - Ok(Json(GetChatResponse { + Ok(Json(ChatFull { messages: messages .into_iter() .map( @@ -183,9 +190,9 @@ pub async fn get_chat( /// All chat rooms your user has access to #[derive(Serialize, ToSchema)] pub struct GetAllChatsResponse { - friend_chat_rooms: Vec, - lobby_chat_rooms: Vec, - game_chat_rooms: Vec, + friend_chat_rooms: Vec, + lobby_chat_rooms: Vec, + game_chat_rooms: Vec, } /// Retrieve all chats the executing user has access to. @@ -210,30 +217,66 @@ pub async fn get_all_chats( let mut tx = db.start_transaction().await?; - let friend_chat_room_uuids = query!(&mut tx, (Friend::F.chat_room.uuid,)) - .condition(and!( - Friend::F.is_request.equals(false), - Friend::F.from.uuid.equals(uuid.as_ref()) - )) - .all() - .await?; + let friend_chat_room_uuids = query!( + &mut tx, + ( + Friend::F.chat_room.uuid, + Friend::F.chat_room.last_message_uuid + ) + ) + .condition(and!( + Friend::F.is_request.equals(false), + Friend::F.from.uuid.equals(uuid.as_ref()) + )) + .all() + .await?; - let lobby_chat_room_uuids = query!(&mut tx, (LobbyAccount::F.lobby.chat_room.uuid)) - .condition(LobbyAccount::F.player.uuid.equals(uuid.as_ref())) - .all() - .await?; + let lobby_chat_room_uuids = query!( + &mut tx, + ( + LobbyAccount::F.lobby.chat_room.uuid, + LobbyAccount::F.lobby.chat_room.last_message_uuid + ) + ) + .condition(LobbyAccount::F.player.uuid.equals(uuid.as_ref())) + .all() + .await?; - let game_chat_room_uuids = query!(&mut tx, (GameAccount::F.game.chat_room.uuid,)) - .condition(GameAccount::F.uuid.equals(uuid.as_ref())) - .all() - .await?; + let game_chat_room_uuids = query!( + &mut tx, + ( + GameAccount::F.game.chat_room.uuid, + GameAccount::F.game.chat_room.last_message_uuid + ) + ) + .condition(GameAccount::F.uuid.equals(uuid.as_ref())) + .all() + .await?; tx.commit().await?; Ok(Json(GetAllChatsResponse { - lobby_chat_rooms: lobby_chat_room_uuids.into_iter().map(|x| x.0).collect(), - friend_chat_rooms: friend_chat_room_uuids.into_iter().map(|x| x.0).collect(), - game_chat_rooms: game_chat_room_uuids.into_iter().map(|x| x.0).collect(), + lobby_chat_rooms: lobby_chat_room_uuids + .into_iter() + .map(|(uuid, last_message_uuid)| ChatSmall { + uuid, + last_message_uuid, + }) + .collect(), + friend_chat_rooms: friend_chat_room_uuids + .into_iter() + .map(|(uuid, last_message_uuid)| ChatSmall { + uuid, + last_message_uuid, + }) + .collect(), + game_chat_rooms: game_chat_room_uuids + .into_iter() + .map(|(uuid, last_message_uuid)| ChatSmall { + uuid, + last_message_uuid, + }) + .collect(), })) } @@ -303,6 +346,15 @@ pub async fn send_message( }) .await?; + update!(&mut tx, ChatRoom) + .condition(ChatRoom::F.uuid.equals(path.uuid.as_ref())) + .set( + ChatRoom::F.last_message_uuid, + Some(chat_room_message.uuid.as_ref()), + ) + .exec() + .await?; + let chat_room_members = query!(&mut tx, (ChatRoomMember::F.member.uuid,)) .condition(ChatRoomMember::F.chat_room.equals(path.uuid.as_ref())) .all() diff --git a/src/server/handler/friends.rs b/src/server/handler/friends.rs index dd31098..8de505a 100644 --- a/src/server/handler/friends.rs +++ b/src/server/handler/friends.rs @@ -488,6 +488,7 @@ pub async fn accept_friend_request( .return_primary_key() .single(&ChatRoomInsert { uuid: Uuid::new_v4(), + last_message_uuid: None, }) .await?; diff --git a/src/server/handler/lobbies.rs b/src/server/handler/lobbies.rs index a9e21d4..ddf55a4 100644 --- a/src/server/handler/lobbies.rs +++ b/src/server/handler/lobbies.rs @@ -368,6 +368,7 @@ pub async fn create_lobby( .return_primary_key() .single(&ChatRoomInsert { uuid: Uuid::new_v4(), + last_message_uuid: None, }) .await?; @@ -470,6 +471,7 @@ pub async fn start_game( .return_primary_key() .single(&ChatRoomInsert { uuid: Uuid::new_v4(), + last_message_uuid: None, }) .await?; diff --git a/src/server/swagger.rs b/src/server/swagger.rs index f2166f1..6581cf8 100644 --- a/src/server/swagger.rs +++ b/src/server/swagger.rs @@ -75,7 +75,8 @@ impl Modify for CookieSecurity { handler::OnlineAccountResponse, handler::FriendRequestResponse, handler::LookupAccountUsernameRequest, - handler::GetChatResponse, + handler::ChatSmall, + handler::ChatFull, handler::ChatMessage, handler::ChatMember, handler::GetAllChatsResponse,