parent
f3cbe9e6ce
commit
ed688f9292
11 changed files with 332 additions and 148 deletions
|
@ -103,7 +103,7 @@ pub struct CreateCommunity {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Serialize, Deserialize)]
|
#[derive(Serialize, Deserialize)]
|
||||||
pub struct CreateCommunityResponse {
|
pub struct CommunityResponse {
|
||||||
op: String,
|
op: String,
|
||||||
community: CommunityView
|
community: CommunityView
|
||||||
}
|
}
|
||||||
|
@ -244,6 +244,7 @@ pub struct EditPost {
|
||||||
#[derive(Serialize, Deserialize)]
|
#[derive(Serialize, Deserialize)]
|
||||||
pub struct EditCommunity {
|
pub struct EditCommunity {
|
||||||
edit_id: i32,
|
edit_id: i32,
|
||||||
|
name: String,
|
||||||
title: String,
|
title: String,
|
||||||
description: Option<String>,
|
description: Option<String>,
|
||||||
category_id: i32,
|
category_id: i32,
|
||||||
|
@ -431,6 +432,10 @@ impl Handler<StandardMessage> for ChatServer {
|
||||||
let edit_post: EditPost = serde_json::from_str(&data.to_string()).unwrap();
|
let edit_post: EditPost = serde_json::from_str(&data.to_string()).unwrap();
|
||||||
edit_post.perform(self, msg.id)
|
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 {
|
let e = ErrorMessage {
|
||||||
op: "Unknown".to_string(),
|
op: "Unknown".to_string(),
|
||||||
|
@ -597,7 +602,7 @@ impl Perform for CreateCommunity {
|
||||||
let community_view = CommunityView::read(&conn, inserted_community.id).unwrap();
|
let community_view = CommunityView::read(&conn, inserted_community.id).unwrap();
|
||||||
|
|
||||||
serde_json::to_string(
|
serde_json::to_string(
|
||||||
&CreateCommunityResponse {
|
&CommunityResponse {
|
||||||
op: self.op_type().to_string(),
|
op: self.op_type().to_string(),
|
||||||
community: community_view
|
community: community_view
|
||||||
}
|
}
|
||||||
|
@ -796,7 +801,6 @@ impl Perform for GetCommunity {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
let moderators = match CommunityModeratorView::for_community(&conn, self.id) {
|
let moderators = match CommunityModeratorView::for_community(&conn, self.id) {
|
||||||
Ok(moderators) => moderators,
|
Ok(moderators) => moderators,
|
||||||
Err(_e) => {
|
Err(_e) => {
|
||||||
|
@ -1187,6 +1191,68 @@ impl Perform for EditPost {
|
||||||
post_out
|
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<Login> for ChatServer {
|
// impl Handler<Login> for ChatServer {
|
||||||
|
|
||||||
// type Result = MessageResult<Login>;
|
// type Result = MessageResult<Login>;
|
||||||
|
@ -1315,7 +1381,7 @@ impl Perform for EditPost {
|
||||||
|
|
||||||
// MessageResult(
|
// MessageResult(
|
||||||
// Ok(
|
// Ok(
|
||||||
// CreateCommunityResponse {
|
// CommunityResponse {
|
||||||
// op: UserOperation::CreateCommunity.to_string(),
|
// op: UserOperation::CreateCommunity.to_string(),
|
||||||
// community: community
|
// community: community
|
||||||
// }
|
// }
|
||||||
|
|
155
ui/src/components/community-form.tsx
Normal file
155
ui/src/components/community-form.tsx
Normal file
|
@ -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<Category>;
|
||||||
|
}
|
||||||
|
|
||||||
|
export class CommunityForm extends Component<CommunityFormProps, CommunityFormState> {
|
||||||
|
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 (
|
||||||
|
<form onSubmit={linkEvent(this, this.handleCreateCommunitySubmit)}>
|
||||||
|
<div class="form-group row">
|
||||||
|
<label class="col-sm-2 col-form-label">Name</label>
|
||||||
|
<div class="col-sm-10">
|
||||||
|
<input type="text" class="form-control" value={this.state.communityForm.name} onInput={linkEvent(this, this.handleCommunityNameChange)} required minLength={3} pattern="[a-z0-9_]+" title="lowercase, underscores, and no spaces."/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="form-group row">
|
||||||
|
<label class="col-sm-2 col-form-label">Title / Headline</label>
|
||||||
|
<div class="col-sm-10">
|
||||||
|
<input type="text" value={this.state.communityForm.title} onInput={linkEvent(this, this.handleCommunityTitleChange)} class="form-control" required minLength={3} />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="form-group row">
|
||||||
|
<label class="col-sm-2 col-form-label">Description / Sidebar</label>
|
||||||
|
<div class="col-sm-10">
|
||||||
|
<textarea value={this.state.communityForm.description} onInput={linkEvent(this, this.handleCommunityDescriptionChange)} class="form-control" rows={6} />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="form-group row">
|
||||||
|
<label class="col-sm-2 col-form-label">Category</label>
|
||||||
|
<div class="col-sm-10">
|
||||||
|
<select class="form-control" value={this.state.communityForm.category_id} onInput={linkEvent(this, this.handleCommunityCategoryChange)}>
|
||||||
|
{this.state.categories.map(category =>
|
||||||
|
<option value={category.id}>{category.name}</option>
|
||||||
|
)}
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="form-group row">
|
||||||
|
<div class="col-sm-10">
|
||||||
|
<button type="submit" class="btn btn-secondary">{this.props.community ? 'Edit' : 'Create'} Community</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
handleCreateCommunitySubmit(i: CommunityForm, event) {
|
||||||
|
event.preventDefault();
|
||||||
|
if (i.props.community) {
|
||||||
|
WebSocketService.Instance.editCommunity(i.state.communityForm);
|
||||||
|
} else {
|
||||||
|
WebSocketService.Instance.createCommunity(i.state.communityForm);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
handleCommunityNameChange(i: CommunityForm, event) {
|
||||||
|
i.state.communityForm.name = event.target.value;
|
||||||
|
i.setState(i.state);
|
||||||
|
}
|
||||||
|
|
||||||
|
handleCommunityTitleChange(i: CommunityForm, event) {
|
||||||
|
i.state.communityForm.title = event.target.value;
|
||||||
|
i.setState(i.state);
|
||||||
|
}
|
||||||
|
|
||||||
|
handleCommunityDescriptionChange(i: CommunityForm, event) {
|
||||||
|
i.state.communityForm.description = event.target.value;
|
||||||
|
i.setState(i.state);
|
||||||
|
}
|
||||||
|
|
||||||
|
handleCommunityCategoryChange(i: CommunityForm, event) {
|
||||||
|
i.state.communityForm.category_id = Number(event.target.value);
|
||||||
|
i.setState(i.state);
|
||||||
|
}
|
||||||
|
|
||||||
|
parseMessage(msg: any) {
|
||||||
|
let op: UserOperation = msgOp(msg);
|
||||||
|
console.log(msg);
|
||||||
|
if (msg.error) {
|
||||||
|
alert(msg.error);
|
||||||
|
return;
|
||||||
|
} else if (op == UserOperation.ListCategories){
|
||||||
|
let res: ListCategoriesResponse = msg;
|
||||||
|
this.state.categories = res.categories;
|
||||||
|
this.state.communityForm.category_id = res.categories[0].id;
|
||||||
|
this.setState(this.state);
|
||||||
|
} else if (op == UserOperation.CreateCommunity) {
|
||||||
|
let res: CommunityResponse = msg;
|
||||||
|
this.props.onCreate(res.community.id);
|
||||||
|
} else if (op == UserOperation.EditCommunity) {
|
||||||
|
let res: CommunityResponse = msg;
|
||||||
|
this.props.onEdit(res.community);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -2,7 +2,7 @@ import { Component, linkEvent } from 'inferno';
|
||||||
import { Link } from 'inferno-router';
|
import { Link } from 'inferno-router';
|
||||||
import { Subscription } from "rxjs";
|
import { Subscription } from "rxjs";
|
||||||
import { retryWhen, delay, take } from 'rxjs/operators';
|
import { retryWhen, delay, take } from 'rxjs/operators';
|
||||||
import { UserOperation, Community as CommunityI, CommunityResponse, Post, GetPostsForm, ListingSortType, ListingType, GetPostsResponse, CreatePostLikeForm, CreatePostLikeResponse, CommunityUser} from '../interfaces';
|
import { UserOperation, Community as CommunityI, GetCommunityResponse, CommunityResponse, Post, GetPostsForm, ListingSortType, ListingType, GetPostsResponse, CreatePostLikeForm, CreatePostLikeResponse, CommunityUser} from '../interfaces';
|
||||||
import { WebSocketService, UserService } from '../services';
|
import { WebSocketService, UserService } from '../services';
|
||||||
import { MomentTime } from './moment-time';
|
import { MomentTime } from './moment-time';
|
||||||
import { PostListing } from './post-listing';
|
import { PostListing } from './post-listing';
|
||||||
|
@ -127,7 +127,7 @@ export class Community extends Component<any, State> {
|
||||||
alert(msg.error);
|
alert(msg.error);
|
||||||
return;
|
return;
|
||||||
} else if (op == UserOperation.GetCommunity) {
|
} else if (op == UserOperation.GetCommunity) {
|
||||||
let res: CommunityResponse = msg;
|
let res: GetCommunityResponse = msg;
|
||||||
this.state.community = res.community;
|
this.state.community = res.community;
|
||||||
this.state.moderators = res.moderators;
|
this.state.moderators = res.moderators;
|
||||||
this.setState(this.state);
|
this.setState(this.state);
|
||||||
|
@ -143,6 +143,10 @@ export class Community extends Component<any, State> {
|
||||||
found.upvotes = res.post.upvotes;
|
found.upvotes = res.post.upvotes;
|
||||||
found.downvotes = res.post.downvotes;
|
found.downvotes = res.post.downvotes;
|
||||||
this.setState(this.state);
|
this.setState(this.state);
|
||||||
|
} else if (op == UserOperation.EditCommunity) {
|
||||||
|
let res: CommunityResponse = msg;
|
||||||
|
this.state.community = res.community;
|
||||||
|
this.setState(this.state);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,47 +1,11 @@
|
||||||
import { Component, linkEvent } from 'inferno';
|
import { Component, linkEvent } from 'inferno';
|
||||||
import { Subscription } from "rxjs";
|
import { CommunityForm } from './community-form';
|
||||||
import { retryWhen, delay, take } from 'rxjs/operators';
|
|
||||||
import { CommunityForm, UserOperation, Category, ListCategoriesResponse } from '../interfaces';
|
|
||||||
import { WebSocketService, UserService } from '../services';
|
|
||||||
import { msgOp } from '../utils';
|
|
||||||
|
|
||||||
import { Community } from '../interfaces';
|
export class CreateCommunity extends Component<any, any> {
|
||||||
|
|
||||||
interface State {
|
|
||||||
communityForm: CommunityForm;
|
|
||||||
categories: Array<Category>;
|
|
||||||
}
|
|
||||||
|
|
||||||
export class CreateCommunity extends Component<any, State> {
|
|
||||||
private subscription: Subscription;
|
|
||||||
|
|
||||||
private emptyState: State = {
|
|
||||||
communityForm: {
|
|
||||||
name: null,
|
|
||||||
title: null,
|
|
||||||
category_id: null
|
|
||||||
},
|
|
||||||
categories: []
|
|
||||||
}
|
|
||||||
|
|
||||||
constructor(props, context) {
|
constructor(props, context) {
|
||||||
super(props, context);
|
super(props, context);
|
||||||
|
this.handleCommunityCreate = this.handleCommunityCreate.bind(this);
|
||||||
this.state = this.emptyState;
|
|
||||||
|
|
||||||
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() {
|
render() {
|
||||||
|
@ -49,96 +13,17 @@ export class CreateCommunity extends Component<any, State> {
|
||||||
<div class="container">
|
<div class="container">
|
||||||
<div class="row">
|
<div class="row">
|
||||||
<div class="col-12 col-lg-6 mb-4">
|
<div class="col-12 col-lg-6 mb-4">
|
||||||
{this.communityForm()}
|
<h3>Create Forum</h3>
|
||||||
|
<CommunityForm onCreate={this.handleCommunityCreate}/>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
communityForm() {
|
handleCommunityCreate(id: number) {
|
||||||
return (
|
this.props.history.push(`/community/${id}`);
|
||||||
<div>
|
|
||||||
<form onSubmit={linkEvent(this, this.handleCreateCommunitySubmit)}>
|
|
||||||
<h3>Create Forum</h3>
|
|
||||||
<div class="form-group row">
|
|
||||||
<label class="col-sm-2 col-form-label">Name</label>
|
|
||||||
<div class="col-sm-10">
|
|
||||||
<input type="text" class="form-control" value={this.state.communityForm.name} onInput={linkEvent(this, this.handleCommunityNameChange)} required minLength={3} pattern="[a-z0-9_]+" title="lowercase, underscores, and no spaces."/>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="form-group row">
|
|
||||||
<label class="col-sm-2 col-form-label">Title / Headline</label>
|
|
||||||
<div class="col-sm-10">
|
|
||||||
<input type="text" value={this.state.communityForm.title} onInput={linkEvent(this, this.handleCommunityTitleChange)} class="form-control" required minLength={3} />
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="form-group row">
|
|
||||||
<label class="col-sm-2 col-form-label">Description / Sidebar</label>
|
|
||||||
<div class="col-sm-10">
|
|
||||||
<textarea value={this.state.communityForm.description} onInput={linkEvent(this, this.handleCommunityDescriptionChange)} class="form-control" rows={6} />
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="form-group row">
|
|
||||||
<label class="col-sm-2 col-form-label">Category</label>
|
|
||||||
<div class="col-sm-10">
|
|
||||||
<select class="form-control" value={this.state.communityForm.category_id} onInput={linkEvent(this, this.handleCommunityCategoryChange)}>
|
|
||||||
{this.state.categories.map(category =>
|
|
||||||
<option value={category.id}>{category.name}</option>
|
|
||||||
)}
|
|
||||||
</select>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="form-group row">
|
|
||||||
<div class="col-sm-10">
|
|
||||||
<button type="submit" class="btn btn-secondary">Create</button>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</form>
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
handleCreateCommunitySubmit(i: CreateCommunity, event) {
|
|
||||||
event.preventDefault();
|
|
||||||
WebSocketService.Instance.createCommunity(i.state.communityForm);
|
|
||||||
}
|
|
||||||
|
|
||||||
handleCommunityNameChange(i: CreateCommunity, event) {
|
|
||||||
i.state.communityForm.name = event.target.value;
|
|
||||||
i.setState(i.state);
|
|
||||||
}
|
|
||||||
|
|
||||||
handleCommunityTitleChange(i: CreateCommunity, event) {
|
|
||||||
i.state.communityForm.title = event.target.value;
|
|
||||||
i.setState(i.state);
|
|
||||||
}
|
|
||||||
|
|
||||||
handleCommunityDescriptionChange(i: CreateCommunity, event) {
|
|
||||||
i.state.communityForm.description = event.target.value;
|
|
||||||
i.setState(i.state);
|
|
||||||
}
|
|
||||||
|
|
||||||
handleCommunityCategoryChange(i: CreateCommunity, event) {
|
|
||||||
i.state.communityForm.category_id = Number(event.target.value);
|
|
||||||
i.setState(i.state);
|
|
||||||
}
|
|
||||||
|
|
||||||
parseMessage(msg: any) {
|
|
||||||
let op: UserOperation = msgOp(msg);
|
|
||||||
console.log(msg);
|
|
||||||
if (msg.error) {
|
|
||||||
alert(msg.error);
|
|
||||||
return;
|
|
||||||
} else if (op == UserOperation.ListCategories){
|
|
||||||
let res: ListCategoriesResponse = msg;
|
|
||||||
this.state.categories = res.categories;
|
|
||||||
this.state.communityForm.category_id = res.categories[0].id;
|
|
||||||
this.setState(this.state);
|
|
||||||
} else if (op == UserOperation.CreateCommunity) {
|
|
||||||
let community: Community = msg.community;
|
|
||||||
this.props.history.push(`/community/${community.id}`);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -105,7 +105,6 @@ export class PostForm extends Component<PostFormProps, PostFormState> {
|
||||||
|
|
||||||
handlePostSubmit(i: PostForm, event) {
|
handlePostSubmit(i: PostForm, event) {
|
||||||
event.preventDefault();
|
event.preventDefault();
|
||||||
console.log(i.state.postForm);
|
|
||||||
if (i.props.post) {
|
if (i.props.post) {
|
||||||
WebSocketService.Instance.editPost(i.state.postForm);
|
WebSocketService.Instance.editPost(i.state.postForm);
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -34,15 +34,15 @@ export class PostListing extends Component<PostListingProps, PostListingState> {
|
||||||
this.handleEditPost = this.handleEditPost.bind(this);
|
this.handleEditPost = this.handleEditPost.bind(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
return (
|
return (
|
||||||
<div>
|
<div>
|
||||||
{!this.state.showEdit
|
{!this.state.showEdit
|
||||||
? this.listing()
|
? this.listing()
|
||||||
: <PostForm post={this.props.post} onEdit={this.handleEditPost} />
|
: <PostForm post={this.props.post} onEdit={this.handleEditPost} />
|
||||||
}
|
}
|
||||||
</div>
|
</div>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
listing() {
|
listing() {
|
||||||
|
@ -90,7 +90,7 @@ export class PostListing extends Component<PostListingProps, PostListingState> {
|
||||||
<Link to={`/post/${post.id}`}>{post.number_of_comments} Comments</Link>
|
<Link to={`/post/${post.id}`}>{post.number_of_comments} Comments</Link>
|
||||||
</li>
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
{this.myPost &&
|
{this.myPost &&
|
||||||
<ul class="list-inline mb-1 text-muted small font-weight-bold">
|
<ul class="list-inline mb-1 text-muted small font-weight-bold">
|
||||||
<li className="list-inline-item">
|
<li className="list-inline-item">
|
||||||
<span class="pointer" onClick={linkEvent(this, this.handleEditClick)}>edit</span>
|
<span class="pointer" onClick={linkEvent(this, this.handleEditClick)}>edit</span>
|
||||||
|
@ -132,6 +132,7 @@ export class PostListing extends Component<PostListingProps, PostListingState> {
|
||||||
i.setState(i.state);
|
i.setState(i.state);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// The actual editing is done in the recieve for post
|
||||||
handleEditPost(post: Post) {
|
handleEditPost(post: Post) {
|
||||||
this.state.showEdit = false;
|
this.state.showEdit = false;
|
||||||
this.setState(this.state);
|
this.setState(this.state);
|
||||||
|
|
|
@ -2,7 +2,7 @@ import { Component, linkEvent } from 'inferno';
|
||||||
import { Link } from 'inferno-router';
|
import { Link } from 'inferno-router';
|
||||||
import { Subscription } from "rxjs";
|
import { Subscription } from "rxjs";
|
||||||
import { retryWhen, delay, take } from 'rxjs/operators';
|
import { retryWhen, delay, take } from 'rxjs/operators';
|
||||||
import { UserOperation, Community, Post as PostI, GetPostResponse, PostResponse, Comment, CommentForm as CommentFormI, CommentResponse, CommentLikeForm, CommentSortType, CreatePostLikeResponse, CommunityUser } from '../interfaces';
|
import { UserOperation, Community, Post as PostI, GetPostResponse, PostResponse, Comment, CommentForm as CommentFormI, CommentResponse, CommentLikeForm, CommentSortType, CreatePostLikeResponse, CommunityUser, CommunityResponse } from '../interfaces';
|
||||||
import { WebSocketService, UserService } from '../services';
|
import { WebSocketService, UserService } from '../services';
|
||||||
import { msgOp, hotRank,mdToHtml } from '../utils';
|
import { msgOp, hotRank,mdToHtml } from '../utils';
|
||||||
import { MomentTime } from './moment-time';
|
import { MomentTime } from './moment-time';
|
||||||
|
@ -223,6 +223,12 @@ export class Post extends Component<any, PostState> {
|
||||||
let res: PostResponse = msg;
|
let res: PostResponse = msg;
|
||||||
this.state.post = res.post;
|
this.state.post = res.post;
|
||||||
this.setState(this.state);
|
this.setState(this.state);
|
||||||
|
} else if (op == UserOperation.EditCommunity) {
|
||||||
|
let res: CommunityResponse = msg;
|
||||||
|
this.state.community = res.community;
|
||||||
|
this.state.post.community_id = res.community.id;
|
||||||
|
this.state.post.community_name = res.community.name;
|
||||||
|
this.setState(this.state);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,7 +1,9 @@
|
||||||
import { Component, linkEvent } from 'inferno';
|
import { Component, linkEvent } from 'inferno';
|
||||||
import { Link } from 'inferno-router';
|
import { Link } from 'inferno-router';
|
||||||
import { Community, CommunityUser } from '../interfaces';
|
import { Community, CommunityUser } from '../interfaces';
|
||||||
|
import { WebSocketService, UserService } from '../services';
|
||||||
import { mdToHtml } from '../utils';
|
import { mdToHtml } from '../utils';
|
||||||
|
import { CommunityForm } from './community-form';
|
||||||
|
|
||||||
interface SidebarProps {
|
interface SidebarProps {
|
||||||
community: Community;
|
community: Community;
|
||||||
|
@ -9,20 +11,49 @@ interface SidebarProps {
|
||||||
}
|
}
|
||||||
|
|
||||||
interface SidebarState {
|
interface SidebarState {
|
||||||
|
showEdit: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
export class Sidebar extends Component<SidebarProps, SidebarState> {
|
export class Sidebar extends Component<SidebarProps, SidebarState> {
|
||||||
|
|
||||||
constructor(props, context) {
|
private emptyState: SidebarState = {
|
||||||
super(props, context);
|
showEdit: false
|
||||||
}
|
}
|
||||||
|
|
||||||
|
constructor(props, context) {
|
||||||
|
super(props, context);
|
||||||
|
this.state = this.emptyState;
|
||||||
|
this.handleEditCommunity = this.handleEditCommunity.bind(this);
|
||||||
|
}
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
|
return (
|
||||||
|
<div>
|
||||||
|
{!this.state.showEdit
|
||||||
|
? this.sidebar()
|
||||||
|
: <CommunityForm community={this.props.community} onEdit={this.handleEditCommunity} />
|
||||||
|
}
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
sidebar() {
|
||||||
let community = this.props.community;
|
let community = this.props.community;
|
||||||
return (
|
return (
|
||||||
<div>
|
<div>
|
||||||
<h4>{community.title}</h4>
|
<h4>{community.title}</h4>
|
||||||
|
{this.amMod &&
|
||||||
|
<ul class="list-inline mb-1 text-muted small font-weight-bold">
|
||||||
|
<li className="list-inline-item">
|
||||||
|
<span class="pointer" onClick={linkEvent(this, this.handleEditClick)}>edit</span>
|
||||||
|
</li>
|
||||||
|
{this.amCreator &&
|
||||||
|
<li className="list-inline-item">
|
||||||
|
{/* <span class="pointer" onClick={linkEvent(this, this.handleDeleteClick)}>delete</span> */}
|
||||||
|
</li>
|
||||||
|
}
|
||||||
|
</ul>
|
||||||
|
}
|
||||||
<ul class="list-inline">
|
<ul class="list-inline">
|
||||||
<li className="list-inline-item"><Link className="badge badge-light" to="/communities">{community.category_name}</Link></li>
|
<li className="list-inline-item"><Link className="badge badge-light" to="/communities">{community.category_name}</Link></li>
|
||||||
<li className="list-inline-item badge badge-light">{community.number_of_subscribers} Subscribers</li>
|
<li className="list-inline-item badge badge-light">{community.number_of_subscribers} Subscribers</li>
|
||||||
|
@ -44,4 +75,29 @@ export class Sidebar extends Component<SidebarProps, SidebarState> {
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
handleEditClick(i: Sidebar, event) {
|
||||||
|
i.state.showEdit = true;
|
||||||
|
i.setState(i.state);
|
||||||
|
}
|
||||||
|
|
||||||
|
handleEditCommunity(community: Community) {
|
||||||
|
this.state.showEdit = false;
|
||||||
|
this.setState(this.state);
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO no deleting communities yet
|
||||||
|
handleDeleteClick(i: Sidebar, event) {
|
||||||
|
}
|
||||||
|
|
||||||
|
private get amCreator(): boolean {
|
||||||
|
return UserService.Instance.loggedIn && this.props.community.creator_id == UserService.Instance.user.id;
|
||||||
|
}
|
||||||
|
|
||||||
|
private get amMod(): boolean {
|
||||||
|
console.log(this.props.moderators);
|
||||||
|
console.log(this.props);
|
||||||
|
return UserService.Instance.loggedIn &&
|
||||||
|
this.props.moderators.map(m => m.user_id).includes(UserService.Instance.user.id);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -38,13 +38,20 @@ export interface CommunityForm {
|
||||||
title: string;
|
title: string;
|
||||||
description?: string,
|
description?: string,
|
||||||
category_id: number,
|
category_id: number,
|
||||||
|
edit_id?: number;
|
||||||
auth?: string;
|
auth?: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export interface GetCommunityResponse {
|
||||||
|
op: string;
|
||||||
|
community: Community;
|
||||||
|
moderators: Array<CommunityUser>;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
export interface CommunityResponse {
|
export interface CommunityResponse {
|
||||||
op: string;
|
op: string;
|
||||||
community: Community;
|
community: Community;
|
||||||
moderators: Array<CommunityUser>;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface ListCommunitiesResponse {
|
export interface ListCommunitiesResponse {
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
import { wsUri } from '../env';
|
import { wsUri } from '../env';
|
||||||
import { LoginForm, RegisterForm, UserOperation, CommunityForm, PostForm, CommentForm, CommentLikeForm, GetListingsForm, CreatePostLikeForm } from '../interfaces';
|
import { LoginForm, RegisterForm, UserOperation, CommunityForm, PostForm, CommentForm, CommentLikeForm, GetPostsForm, CreatePostLikeForm } from '../interfaces';
|
||||||
import { webSocket } from 'rxjs/webSocket';
|
import { webSocket } from 'rxjs/webSocket';
|
||||||
import { Subject } from 'rxjs';
|
import { Subject } from 'rxjs';
|
||||||
import { retryWhen, delay, take } from 'rxjs/operators';
|
import { retryWhen, delay, take } from 'rxjs/operators';
|
||||||
|
@ -37,6 +37,11 @@ export class WebSocketService {
|
||||||
this.subject.next(this.wsSendWrapper(UserOperation.CreateCommunity, communityForm));
|
this.subject.next(this.wsSendWrapper(UserOperation.CreateCommunity, communityForm));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public editCommunity(communityForm: CommunityForm) {
|
||||||
|
this.setAuth(communityForm);
|
||||||
|
this.subject.next(this.wsSendWrapper(UserOperation.EditCommunity, communityForm));
|
||||||
|
}
|
||||||
|
|
||||||
public listCommunities() {
|
public listCommunities() {
|
||||||
this.subject.next(this.wsSendWrapper(UserOperation.ListCommunities, undefined));
|
this.subject.next(this.wsSendWrapper(UserOperation.ListCommunities, undefined));
|
||||||
}
|
}
|
||||||
|
@ -74,7 +79,7 @@ export class WebSocketService {
|
||||||
this.subject.next(this.wsSendWrapper(UserOperation.CreateCommentLike, form));
|
this.subject.next(this.wsSendWrapper(UserOperation.CreateCommentLike, form));
|
||||||
}
|
}
|
||||||
|
|
||||||
public getPosts(form: GetListingsForm) {
|
public getPosts(form: GetPostsForm) {
|
||||||
this.setAuth(form, false);
|
this.setAuth(form, false);
|
||||||
this.subject.next(this.wsSendWrapper(UserOperation.GetPosts, form));
|
this.subject.next(this.wsSendWrapper(UserOperation.GetPosts, form));
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
{
|
{
|
||||||
"compilerOptions": {
|
"compilerOptions": {
|
||||||
"module": "commonjs",
|
"module": "commonjs",
|
||||||
"target": "es2015",
|
"target": "es2016",
|
||||||
"sourceMap": true,
|
"sourceMap": true,
|
||||||
"inlineSources": true,
|
"inlineSources": true,
|
||||||
"jsx": "preserve",
|
"jsx": "preserve",
|
||||||
|
|
Loading…
Reference in a new issue