diff --git a/server/src/websocket_server/server.rs b/server/src/websocket_server/server.rs index 9c609a470..3e361f691 100644 --- a/server/src/websocket_server/server.rs +++ b/server/src/websocket_server/server.rs @@ -27,7 +27,7 @@ use actions::moderator::*; #[derive(EnumString,ToString,Debug)] pub enum UserOperation { - Login, Register, CreateCommunity, CreatePost, ListCommunities, ListCategories, GetPost, GetCommunity, CreateComment, EditComment, SaveComment, CreateCommentLike, GetPosts, CreatePostLike, EditPost, SavePost, EditCommunity, FollowCommunity, GetFollowedCommunities, GetUserDetails, GetReplies, GetModlog, BanFromCommunity, AddModToCommunity, CreateSite, EditSite, GetSite, AddAdmin, BanUser, Search + Login, Register, CreateCommunity, CreatePost, ListCommunities, ListCategories, GetPost, GetCommunity, CreateComment, EditComment, SaveComment, CreateCommentLike, GetPosts, CreatePostLike, EditPost, SavePost, EditCommunity, FollowCommunity, GetFollowedCommunities, GetUserDetails, GetReplies, GetModlog, BanFromCommunity, AddModToCommunity, CreateSite, EditSite, GetSite, AddAdmin, BanUser, Search, MarkAllAsRead } #[derive(Fail, Debug)] @@ -478,6 +478,11 @@ pub struct SearchResponse { posts: Vec, } +#[derive(Serialize, Deserialize)] +pub struct MarkAllAsRead { + auth: String +} + /// `ChatServer` manages chat rooms and responsible for coordinating chat /// session. implementation is super primitive pub struct ChatServer { @@ -728,6 +733,10 @@ fn parse_json_message(chat: &mut ChatServer, msg: StandardMessage) -> Result { + let mark_all_as_read: MarkAllAsRead = serde_json::from_str(data)?; + mark_all_as_read.perform(chat, msg.id) + }, } } @@ -2709,3 +2718,56 @@ impl Perform for Search { ) } } + + +impl Perform for MarkAllAsRead { + fn op_type(&self) -> UserOperation { + UserOperation::MarkAllAsRead + } + + fn perform(&self, _chat: &mut ChatServer, _addr: usize) -> Result { + + let conn = establish_connection(); + + let claims = match Claims::decode(&self.auth) { + Ok(claims) => claims.claims, + Err(_e) => { + return Err(self.error("Not logged in."))? + } + }; + + let user_id = claims.id; + + let replies = ReplyView::get_replies(&conn, user_id, &SortType::New, true, Some(1), Some(999))?; + + for reply in &replies { + let comment_form = CommentForm { + content: reply.to_owned().content, + parent_id: reply.to_owned().parent_id, + post_id: reply.to_owned().post_id, + creator_id: reply.to_owned().creator_id, + removed: None, + read: Some(true), + updated: reply.to_owned().updated + }; + + let _updated_comment = match Comment::update(&conn, reply.id, &comment_form) { + Ok(comment) => comment, + Err(_e) => { + return Err(self.error("Couldn't update Comment"))? + } + }; + } + + let replies = ReplyView::get_replies(&conn, user_id, &SortType::New, true, Some(1), Some(999))?; + + Ok( + serde_json::to_string( + &GetRepliesResponse { + op: self.op_type().to_string(), + replies: replies, + } + )? + ) + } +} diff --git a/ui/package.json b/ui/package.json index b5bb14ef9..d806575c3 100644 --- a/ui/package.json +++ b/ui/package.json @@ -19,6 +19,7 @@ "@types/js-cookie": "^2.2.1", "@types/jwt-decode": "^2.2.1", "@types/markdown-it": "^0.0.7", + "@types/markdown-it-container": "^2.0.2", "autosize": "^4.0.2", "classcat": "^1.1.3", "dotenv": "^6.1.0", @@ -27,6 +28,7 @@ "js-cookie": "^2.2.0", "jwt-decode": "^2.2.0", "markdown-it": "^8.4.2", + "markdown-it-container": "^2.0.0", "moment": "^2.24.0", "rxjs": "^6.4.0" }, diff --git a/ui/src/components/create-post.tsx b/ui/src/components/create-post.tsx index e2998ca7e..1958be72d 100644 --- a/ui/src/components/create-post.tsx +++ b/ui/src/components/create-post.tsx @@ -18,13 +18,23 @@ export class CreatePost extends Component {
Create a Post
- +
) } + get prevCommunityName(): string { + if (this.props.location.state) { + let lastLocation = this.props.location.state.prevPath; + if (lastLocation.includes("/c/")) { + return lastLocation.split("/c/")[1]; + } + } + return undefined; + } + handlePostCreate(id: number) { this.props.history.push(`/post/${id}`); } diff --git a/ui/src/components/inbox.tsx b/ui/src/components/inbox.tsx index 02d813f3e..f4ef2ecdc 100644 --- a/ui/src/components/inbox.tsx +++ b/ui/src/components/inbox.tsx @@ -58,7 +58,16 @@ export class Inbox extends Component {
-
Inbox for {user.username}
+
+ Inbox for {user.username} +
+ {this.state.replies.length > 0 && this.state.unreadType == UnreadType.Unread && +
    +
  • + mark all as read +
  • +
+ } {this.selects()} {this.replies()} {this.paginator()} @@ -147,13 +156,17 @@ export class Inbox extends Component { i.refetch(); } + markAllAsRead() { + WebSocketService.Instance.markAllAsRead(); + } + parseMessage(msg: any) { console.log(msg); let op: UserOperation = msgOp(msg); if (msg.error) { alert(msg.error); return; - } else if (op == UserOperation.GetReplies) { + } else if (op == UserOperation.GetReplies || op == UserOperation.MarkAllAsRead) { let res: GetRepliesResponse = msg; this.state.replies = res.replies; this.sendRepliesCount(); diff --git a/ui/src/components/navbar.tsx b/ui/src/components/navbar.tsx index 31dab61b6..ee19e5c5b 100644 --- a/ui/src/components/navbar.tsx +++ b/ui/src/components/navbar.tsx @@ -79,7 +79,7 @@ export class Navbar extends Component { Search