From 7d302e18016811b7c6809c396b371cf423794584 Mon Sep 17 00:00:00 2001 From: Dessalines Date: Thu, 4 Apr 2019 15:29:14 -0700 Subject: [PATCH] Community editing - Community editing mostly working. Fixes #26 --- server/src/websocket_server/server.rs | 74 +++++++++++- ui/src/components/community-form.tsx | 155 +++++++++++++++++++++++++ ui/src/components/community.tsx | 8 +- ui/src/components/create-community.tsx | 133 ++------------------- ui/src/components/post-form.tsx | 1 - ui/src/components/post-listing.tsx | 21 ++-- ui/src/components/post.tsx | 8 +- ui/src/components/sidebar.tsx | 60 +++++++++- ui/src/interfaces.ts | 9 +- ui/src/services/WebSocketService.ts | 9 +- ui/tsconfig.json | 2 +- 11 files changed, 332 insertions(+), 148 deletions(-) create mode 100644 ui/src/components/community-form.tsx diff --git a/server/src/websocket_server/server.rs b/server/src/websocket_server/server.rs index 4c13aade..28b5832a 100644 --- a/server/src/websocket_server/server.rs +++ b/server/src/websocket_server/server.rs @@ -103,7 +103,7 @@ pub struct CreateCommunity { } #[derive(Serialize, Deserialize)] -pub struct CreateCommunityResponse { +pub struct CommunityResponse { op: String, community: CommunityView } @@ -244,6 +244,7 @@ pub struct EditPost { #[derive(Serialize, Deserialize)] pub struct EditCommunity { edit_id: i32, + name: String, title: String, description: Option, category_id: i32, @@ -431,6 +432,10 @@ impl Handler for ChatServer { let edit_post: EditPost = serde_json::from_str(&data.to_string()).unwrap(); edit_post.perform(self, msg.id) }, + UserOperation::EditCommunity => { + let edit_community: EditCommunity = serde_json::from_str(&data.to_string()).unwrap(); + edit_community.perform(self, msg.id) + }, _ => { let e = ErrorMessage { op: "Unknown".to_string(), @@ -597,7 +602,7 @@ impl Perform for CreateCommunity { let community_view = CommunityView::read(&conn, inserted_community.id).unwrap(); serde_json::to_string( - &CreateCommunityResponse { + &CommunityResponse { op: self.op_type().to_string(), community: community_view } @@ -796,7 +801,6 @@ impl Perform for GetCommunity { } }; - let moderators = match CommunityModeratorView::for_community(&conn, self.id) { Ok(moderators) => moderators, Err(_e) => { @@ -1187,6 +1191,68 @@ impl Perform for EditPost { post_out } } + +impl Perform for EditCommunity { + fn op_type(&self) -> UserOperation { + UserOperation::EditCommunity + } + + fn perform(&self, chat: &mut ChatServer, addr: usize) -> String { + + let conn = establish_connection(); + + let claims = match Claims::decode(&self.auth) { + Ok(claims) => claims.claims, + Err(_e) => { + return self.error("Not logged in."); + } + }; + + let user_id = claims.id; + + let community_form = CommunityForm { + name: self.name.to_owned(), + title: self.title.to_owned(), + description: self.description.to_owned(), + category_id: self.category_id.to_owned(), + creator_id: user_id, + updated: Some(naive_now()) + }; + + let _updated_community = match Community::update(&conn, self.edit_id, &community_form) { + Ok(community) => community, + Err(_e) => { + return self.error("Couldn't update Community"); + } + }; + + let community_view = CommunityView::read(&conn, self.edit_id).unwrap(); + + // Do the subscriber stuff here + // let mut community_sent = post_view.clone(); + // community_sent.my_vote = None; + + let community_out = serde_json::to_string( + &CommunityResponse { + op: self.op_type().to_string(), + community: community_view + } + ) + .unwrap(); + + // let post_sent_out = serde_json::to_string( + // &PostResponse { + // op: self.op_type().to_string(), + // post: post_sent + // } + // ) + // .unwrap(); + + chat.send_room_message(self.edit_id, &community_out, addr); + + community_out + } +} // impl Handler for ChatServer { // type Result = MessageResult; @@ -1315,7 +1381,7 @@ impl Perform for EditPost { // MessageResult( // Ok( -// CreateCommunityResponse { +// CommunityResponse { // op: UserOperation::CreateCommunity.to_string(), // community: community // } diff --git a/ui/src/components/community-form.tsx b/ui/src/components/community-form.tsx new file mode 100644 index 00000000..a8ea7b11 --- /dev/null +++ b/ui/src/components/community-form.tsx @@ -0,0 +1,155 @@ +import { Component, linkEvent } from 'inferno'; +import { Subscription } from "rxjs"; +import { retryWhen, delay, take } from 'rxjs/operators'; +import { CommunityForm as CommunityFormI, UserOperation, Category, ListCategoriesResponse, CommunityResponse } from '../interfaces'; +import { WebSocketService, UserService } from '../services'; +import { msgOp } from '../utils'; + +import { Community } from '../interfaces'; + +interface CommunityFormProps { + community?: Community; // If a community is given, that means this is an edit + onCancel?(); + onCreate?(id: number); + onEdit?(community: Community); +} + +interface CommunityFormState { + communityForm: CommunityFormI; + categories: Array; +} + +export class CommunityForm extends Component { + private subscription: Subscription; + + private emptyState: CommunityFormState = { + communityForm: { + name: null, + title: null, + category_id: null + }, + categories: [] + } + + constructor(props, context) { + super(props, context); + + this.state = this.emptyState; + + if (this.props.community) { + this.state.communityForm = { + name: this.props.community.name, + title: this.props.community.title, + category_id: this.props.community.category_id, + description: this.props.community.description, + edit_id: this.props.community.id, + auth: null + } + } + + this.subscription = WebSocketService.Instance.subject + .pipe(retryWhen(errors => errors.pipe(delay(3000), take(10)))) + .subscribe( + (msg) => this.parseMessage(msg), + (err) => console.error(err), + () => console.log("complete") + ); + + WebSocketService.Instance.listCategories(); + } + + componentWillUnmount() { + this.subscription.unsubscribe(); + } + + + render() { + return ( +
+
+ +
+ +
+
+
+ +
+ +
+
+
+ +
+