diff --git a/docs/src/contributing_websocket_http_api.md b/docs/src/contributing_websocket_http_api.md index 5628c3287..63d8f994b 100644 --- a/docs/src/contributing_websocket_http_api.md +++ b/docs/src/contributing_websocket_http_api.md @@ -464,14 +464,14 @@ Only the first user will be able to be the admin. `GET /user/mentions` -#### Edit User Mention +#### Mark User Mention as read ##### Request ```rust { - op: "EditUserMention", + op: "MarkUserMentionAsRead", data: { user_mention_id: i32, - read: Option, + read: bool, auth: String, } } @@ -479,7 +479,7 @@ Only the first user will be able to be the admin. ##### Response ```rust { - op: "EditUserMention", + op: "MarkUserMentionAsRead", data: { mention: UserMentionView, } @@ -487,7 +487,7 @@ Only the first user will be able to be the admin. ``` ##### HTTP -`PUT /user/mention` +`POST /user/mention/mark_as_read` #### Get Private Messages ##### Request diff --git a/server/lemmy_db/src/user_mention.rs b/server/lemmy_db/src/user_mention.rs index 5dc899b29..f32318e0a 100644 --- a/server/lemmy_db/src/user_mention.rs +++ b/server/lemmy_db/src/user_mention.rs @@ -52,6 +52,30 @@ impl Crud for UserMention { } } +impl UserMention { + pub fn update_read( + conn: &PgConnection, + user_mention_id: i32, + new_read: bool, + ) -> Result { + use crate::schema::user_mention::dsl::*; + diesel::update(user_mention.find(user_mention_id)) + .set(read.eq(new_read)) + .get_result::(conn) + } + + pub fn mark_all_as_read(conn: &PgConnection, for_recipient_id: i32) -> Result, Error> { + use crate::schema::user_mention::dsl::*; + diesel::update( + user_mention + .filter(recipient_id.eq(for_recipient_id)) + .filter(read.eq(false)), + ) + .set(read.eq(true)) + .get_results::(conn) + } +} + #[cfg(test)] mod tests { use crate::{ diff --git a/server/src/api/user.rs b/server/src/api/user.rs index a83b794a9..2e6218239 100644 --- a/server/src/api/user.rs +++ b/server/src/api/user.rs @@ -174,9 +174,9 @@ pub struct GetUserMentions { } #[derive(Serialize, Deserialize)] -pub struct EditUserMention { +pub struct MarkUserMentionAsRead { user_mention_id: i32, - read: Option, + read: bool, auth: String, } @@ -874,7 +874,7 @@ impl Perform for Oper { } #[async_trait::async_trait(?Send)] -impl Perform for Oper { +impl Perform for Oper { type Response = UserMentionResponse; async fn perform( @@ -882,7 +882,7 @@ impl Perform for Oper { pool: &DbPool, _websocket_info: Option, ) -> Result { - let data: &EditUserMention = &self.data; + let data: &MarkUserMentionAsRead = &self.data; let claims = match Claims::decode(&data.auth) { Ok(claims) => claims.claims, @@ -899,15 +899,9 @@ impl Perform for Oper { return Err(APIError::err("couldnt_update_comment").into()); } - let user_mention_form = UserMentionForm { - recipient_id: read_user_mention.recipient_id, - comment_id: read_user_mention.comment_id, - read: data.read.to_owned(), - }; - let user_mention_id = read_user_mention.id; - let update_mention = - move |conn: &'_ _| UserMention::update(conn, user_mention_id, &user_mention_form); + let read = data.read; + let update_mention = move |conn: &'_ _| UserMention::update_read(conn, user_mention_id, read); if blocking(pool, update_mention).await?.is_err() { return Err(APIError::err("couldnt_update_comment").into()); }; @@ -960,30 +954,10 @@ impl Perform for Oper { } } - // Mentions - let mentions = blocking(pool, move |conn| { - UserMentionQueryBuilder::create(conn, user_id) - .unread_only(true) - .page(1) - .limit(999) - .list() - }) - .await??; - - // TODO: this should probably be a bulk operation - for mention in &mentions { - let mention_form = UserMentionForm { - recipient_id: mention.to_owned().recipient_id, - comment_id: mention.to_owned().id, - read: Some(true), - }; - - let user_mention_id = mention.user_mention_id; - let update_mention = - move |conn: &'_ _| UserMention::update(conn, user_mention_id, &mention_form); - if blocking(pool, update_mention).await?.is_err() { - return Err(APIError::err("couldnt_update_comment").into()); - } + // Mark all user mentions as read + let update_user_mentions = move |conn: &'_ _| UserMention::mark_all_as_read(conn, user_id); + if blocking(pool, update_user_mentions).await?.is_err() { + return Err(APIError::err("couldnt_update_comment").into()); } // Mark all private_messages as read diff --git a/server/src/routes/api.rs b/server/src/routes/api.rs index 69ecbc8fd..a02f1d3b5 100644 --- a/server/src/routes/api.rs +++ b/server/src/routes/api.rs @@ -115,7 +115,10 @@ pub fn config(cfg: &mut web::ServiceConfig, rate_limit: &RateLimit) { .wrap(rate_limit.message()) .route("", web::get().to(route_get::)) .route("/mention", web::get().to(route_get::)) - .route("/mention", web::put().to(route_post::)) + .route( + "/mention/mark_as_read", + web::post().to(route_post::), + ) .route("/replies", web::get().to(route_get::)) .route( "/followed_communities", diff --git a/server/src/websocket/mod.rs b/server/src/websocket/mod.rs index 0e938c7ef..431273d25 100644 --- a/server/src/websocket/mod.rs +++ b/server/src/websocket/mod.rs @@ -40,7 +40,7 @@ pub enum UserOperation { GetUserDetails, GetReplies, GetUserMentions, - EditUserMention, + MarkUserMentionAsRead, GetModlog, BanFromCommunity, AddModToCommunity, diff --git a/server/src/websocket/server.rs b/server/src/websocket/server.rs index 4543781a3..490990844 100644 --- a/server/src/websocket/server.rs +++ b/server/src/websocket/server.rs @@ -443,7 +443,9 @@ impl ChatServer { UserOperation::AddAdmin => do_user_operation::(args).await, UserOperation::BanUser => do_user_operation::(args).await, UserOperation::GetUserMentions => do_user_operation::(args).await, - UserOperation::EditUserMention => do_user_operation::(args).await, + UserOperation::MarkUserMentionAsRead => { + do_user_operation::(args).await + } UserOperation::MarkAllAsRead => do_user_operation::(args).await, UserOperation::DeleteAccount => do_user_operation::(args).await, UserOperation::PasswordReset => do_user_operation::(args).await, diff --git a/ui/src/components/comment-node.tsx b/ui/src/components/comment-node.tsx index a6b9b7bac..dfe52ec1c 100644 --- a/ui/src/components/comment-node.tsx +++ b/ui/src/components/comment-node.tsx @@ -4,7 +4,7 @@ import { CommentNode as CommentNodeI, CommentLikeForm, CommentForm as CommentFormI, - EditUserMentionForm, + MarkUserMentionAsReadForm, SaveCommentForm, BanFromCommunityForm, BanUserForm, @@ -969,11 +969,11 @@ export class CommentNode extends Component { handleMarkRead(i: CommentNode) { // if it has a user_mention_id field, then its a mention if (i.props.node.comment.user_mention_id) { - let form: EditUserMentionForm = { + let form: MarkUserMentionAsReadForm = { user_mention_id: i.props.node.comment.user_mention_id, read: !i.props.node.comment.read, }; - WebSocketService.Instance.editUserMention(form); + WebSocketService.Instance.markUserMentionAsRead(form); } else { let form: CommentFormI = { content: i.props.node.comment.content, diff --git a/ui/src/components/inbox.tsx b/ui/src/components/inbox.tsx index faedb4b13..5609879cc 100644 --- a/ui/src/components/inbox.tsx +++ b/ui/src/components/inbox.tsx @@ -500,7 +500,7 @@ export class Inbox extends Component { this.sendUnreadCount(); this.setState(this.state); setupTippy(); - } else if (res.op == UserOperation.EditUserMention) { + } else if (res.op == UserOperation.MarkUserMentionAsRead) { let data = res.data as UserMentionResponse; let found = this.state.mentions.find(c => c.id == data.mention.id); diff --git a/ui/src/interfaces.ts b/ui/src/interfaces.ts index 17b5f694a..0beb0ff92 100644 --- a/ui/src/interfaces.ts +++ b/ui/src/interfaces.ts @@ -21,7 +21,7 @@ export enum UserOperation { GetUserDetails, GetReplies, GetUserMentions, - EditUserMention, + MarkUserMentionAsRead, GetModlog, BanFromCommunity, AddModToCommunity, @@ -357,9 +357,9 @@ export interface GetUserMentionsResponse { mentions: Array; } -export interface EditUserMentionForm { +export interface MarkUserMentionAsReadForm { user_mention_id: number; - read?: boolean; + read: boolean; auth?: string; } @@ -901,7 +901,7 @@ export type MessageType = | GetUserDetailsForm | GetRepliesForm | GetUserMentionsForm - | EditUserMentionForm + | MarkUserMentionAsReadForm | GetModlogForm | SiteForm | SearchForm diff --git a/ui/src/services/WebSocketService.ts b/ui/src/services/WebSocketService.ts index f0fb6fc77..54dc96359 100644 --- a/ui/src/services/WebSocketService.ts +++ b/ui/src/services/WebSocketService.ts @@ -28,7 +28,7 @@ import { UserView, GetRepliesForm, GetUserMentionsForm, - EditUserMentionForm, + MarkUserMentionAsReadForm, SearchForm, UserSettingsForm, DeleteAccountForm, @@ -247,9 +247,9 @@ export class WebSocketService { this.ws.send(this.wsSendWrapper(UserOperation.GetUserMentions, form)); } - public editUserMention(form: EditUserMentionForm) { + public markUserMentionAsRead(form: MarkUserMentionAsReadForm) { this.setAuth(form); - this.ws.send(this.wsSendWrapper(UserOperation.EditUserMention, form)); + this.ws.send(this.wsSendWrapper(UserOperation.MarkUserMentionAsRead, form)); } public getModlog(form: GetModlogForm) {