summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--server/migrations/2019-03-30-212058_create_post_view/up.sql1
-rw-r--r--server/src/actions/post_view.rs10
-rw-r--r--server/src/websocket_server/server.rs31
-rw-r--r--ui/src/components/comment-node.tsx14
-rw-r--r--ui/src/components/community.tsx14
-rw-r--r--ui/src/components/post-listing.tsx20
-rw-r--r--ui/src/components/post.tsx6
-rw-r--r--ui/src/components/sidebar.tsx39
-rw-r--r--ui/src/interfaces.ts2
9 files changed, 88 insertions, 49 deletions
diff --git a/server/migrations/2019-03-30-212058_create_post_view/up.sql b/server/migrations/2019-03-30-212058_create_post_view/up.sql
index 17dc8604..4a4fd146 100644
--- a/server/migrations/2019-03-30-212058_create_post_view/up.sql
+++ b/server/migrations/2019-03-30-212058_create_post_view/up.sql
@@ -16,6 +16,7 @@ with all_post as
p.*,
(select name from user_ where p.creator_id = user_.id) as creator_name,
(select name from community where p.community_id = community.id) as community_name,
+ (select removed from community c where p.community_id = c.id) as community_removed,
(select count(*) from comment where comment.post_id = p.id) as number_of_comments,
coalesce(sum(pl.score), 0) as score,
count (case when pl.score = 1 then 1 else null end) as upvotes,
diff --git a/server/src/actions/post_view.rs b/server/src/actions/post_view.rs
index ba42fe27..ccad9317 100644
--- a/server/src/actions/post_view.rs
+++ b/server/src/actions/post_view.rs
@@ -25,6 +25,7 @@ table! {
updated -> Nullable<Timestamp>,
creator_name -> Varchar,
community_name -> Varchar,
+ community_removed -> Bool,
number_of_comments -> BigInt,
score -> BigInt,
upvotes -> BigInt,
@@ -54,6 +55,7 @@ pub struct PostView {
pub updated: Option<chrono::NaiveDateTime>,
pub creator_name: String,
pub community_name: String,
+ pub community_removed: bool,
pub number_of_comments: i64,
pub score: i64,
pub upvotes: i64,
@@ -133,13 +135,11 @@ impl PostView {
.order_by(score.desc())
};
-
- // TODO make sure community removed isn't fetched either
-
query = query
.limit(limit)
.offset(offset)
- .filter(removed.eq(false));
+ .filter(removed.eq(false))
+ .filter(community_removed.eq(false));
query.load::<Self>(conn)
}
@@ -255,6 +255,7 @@ mod tests {
removed: false,
locked: false,
community_name: community_name.to_owned(),
+ community_removed: false,
number_of_comments: 0,
score: 1,
upvotes: 1,
@@ -280,6 +281,7 @@ mod tests {
creator_name: user_name.to_owned(),
community_id: inserted_community.id,
community_name: community_name.to_owned(),
+ community_removed: false,
number_of_comments: 0,
score: 1,
upvotes: 1,
diff --git a/server/src/websocket_server/server.rs b/server/src/websocket_server/server.rs
index ba6e176b..068fd027 100644
--- a/server/src/websocket_server/server.rs
+++ b/server/src/websocket_server/server.rs
@@ -196,7 +196,8 @@ pub struct GetCommunity {
pub struct GetCommunityResponse {
op: String,
community: CommunityView,
- moderators: Vec<CommunityModeratorView>
+ moderators: Vec<CommunityModeratorView>,
+ admins: Vec<UserView>,
}
#[derive(Serialize, Deserialize)]
@@ -1165,13 +1166,16 @@ impl Perform for GetCommunity {
}
};
+ let admins = UserView::admins(&conn)?;
+
// Return the jwt
Ok(
serde_json::to_string(
&GetCommunityResponse {
op: self.op_type().to_string(),
community: community_view,
- moderators: moderators
+ moderators: moderators,
+ admins: admins,
}
)?
)
@@ -1817,11 +1821,24 @@ impl Perform for EditCommunity {
}
// Verify its a mod
- let moderator_view = CommunityModeratorView::for_community(&conn, self.edit_id)?;
- let mod_ids: Vec<i32> = moderator_view.into_iter().map(|m| m.user_id).collect();
- if !mod_ids.contains(&user_id) {
- return Err(self.error("Incorrect creator."))?
- };
+ let mut editors: Vec<i32> = Vec::new();
+ editors.append(
+ &mut CommunityModeratorView::for_community(&conn, self.edit_id)
+ ?
+ .into_iter()
+ .map(|m| m.user_id)
+ .collect()
+ );
+ editors.append(
+ &mut UserView::admins(&conn)
+ ?
+ .into_iter()
+ .map(|a| a.id)
+ .collect()
+ );
+ if !editors.contains(&user_id) {
+ return Err(self.error("Not allowed to edit community"))?
+ }
let community_form = CommunityForm {
name: self.name.to_owned(),
diff --git a/ui/src/components/comment-node.tsx b/ui/src/components/comment-node.tsx
index cf7b1bce..415dad77 100644
--- a/ui/src/components/comment-node.tsx
+++ b/ui/src/components/comment-node.tsx
@@ -210,13 +210,6 @@ export class CommentNode extends Component<CommentNodeProps, CommentNodeState> {
return UserService.Instance.user && this.props.node.comment.creator_id == UserService.Instance.user.id;
}
- get canMod(): boolean {
- let adminsThenMods = this.props.admins.map(a => a.id)
- .concat(this.props.moderators.map(m => m.user_id));
-
- return canMod(UserService.Instance.user, adminsThenMods, this.props.node.comment.creator_id);
- }
-
get isMod(): boolean {
return this.props.moderators && isMod(this.props.moderators.map(m => m.user_id), this.props.node.comment.creator_id);
}
@@ -225,6 +218,13 @@ export class CommentNode extends Component<CommentNodeProps, CommentNodeState> {
return this.props.admins && isMod(this.props.admins.map(a => a.id), this.props.node.comment.creator_id);
}
+ get canMod(): boolean {
+ let adminsThenMods = this.props.admins.map(a => a.id)
+ .concat(this.props.moderators.map(m => m.user_id));
+
+ return canMod(UserService.Instance.user, adminsThenMods, this.props.node.comment.creator_id);
+ }
+
get canAdmin(): boolean {
return this.props.admins && canMod(UserService.Instance.user, this.props.admins.map(a => a.id), this.props.node.comment.creator_id);
}
diff --git a/ui/src/components/community.tsx b/ui/src/components/community.tsx
index 6271bde5..c89d2f06 100644
--- a/ui/src/components/community.tsx
+++ b/ui/src/components/community.tsx
@@ -1,7 +1,7 @@
import { Component } from 'inferno';
import { Subscription } from "rxjs";
import { retryWhen, delay, take } from 'rxjs/operators';
-import { UserOperation, Community as CommunityI, GetCommunityResponse, CommunityResponse, CommunityUser} from '../interfaces';
+import { UserOperation, Community as CommunityI, GetCommunityResponse, CommunityResponse, CommunityUser, UserView } from '../interfaces';
import { WebSocketService } from '../services';
import { PostListings } from './post-listings';
import { Sidebar } from './sidebar';
@@ -11,6 +11,7 @@ interface State {
community: CommunityI;
communityId: number;
moderators: Array<CommunityUser>;
+ admins: Array<UserView>;
loading: boolean;
}
@@ -29,9 +30,11 @@ export class Community extends Component<any, State> {
number_of_subscribers: null,
number_of_posts: null,
number_of_comments: null,
- published: null
+ published: null,
+ removed: null,
},
moderators: [],
+ admins: [],
communityId: Number(this.props.match.params.id),
loading: true
}
@@ -71,7 +74,11 @@ export class Community extends Component<any, State> {
<PostListings communityId={this.state.communityId} />
</div>
<div class="col-12 col-md-3">
- <Sidebar community={this.state.community} moderators={this.state.moderators} />
+ <Sidebar
+ community={this.state.community}
+ moderators={this.state.moderators}
+ admins={this.state.admins}
+ />
</div>
</div>
}
@@ -90,6 +97,7 @@ export class Community extends Component<any, State> {
let res: GetCommunityResponse = msg;
this.state.community = res.community;
this.state.moderators = res.moderators;
+ this.state.admins = res.admins;
this.state.loading = false;
this.setState(this.state);
} else if (op == UserOperation.EditCommunity) {
diff --git a/ui/src/components/post-listing.tsx b/ui/src/components/post-listing.tsx
index 8803d629..93e88071 100644
--- a/ui/src/components/post-listing.tsx
+++ b/ui/src/components/post-listing.tsx
@@ -174,6 +174,14 @@ export class PostListing extends Component<PostListingProps, PostListingState> {
return UserService.Instance.user && this.props.post.creator_id == UserService.Instance.user.id;
}
+ get isMod(): boolean {
+ return this.props.moderators && isMod(this.props.moderators.map(m => m.user_id), this.props.post.creator_id);
+ }
+
+ get isAdmin(): boolean {
+ return this.props.admins && isMod(this.props.admins.map(a => a.id), this.props.post.creator_id);
+ }
+
get canMod(): boolean {
if (this.props.editable) {
@@ -185,18 +193,6 @@ export class PostListing extends Component<PostListingProps, PostListingState> {
} else return false;
}
- get isMod(): boolean {
- return this.props.moderators && isMod(this.props.moderators.map(m => m.user_id), this.props.post.creator_id);
- }
-
- get isAdmin(): boolean {
- return this.props.admins && isMod(this.props.admins.map(a => a.id), this.props.post.creator_id);
- }
-
- get canAdmin(): boolean {
- return this.props.admins && canMod(UserService.Instance.user, this.props.admins.map(a => a.id), this.props.post.creator_id);
- }
-
handlePostLike(i: PostListing) {
let form: CreatePostLikeForm = {
diff --git a/ui/src/components/post.tsx b/ui/src/components/post.tsx
index 3f243220..3ece6747 100644
--- a/ui/src/components/post.tsx
+++ b/ui/src/components/post.tsx
@@ -148,7 +148,11 @@ export class Post extends Component<any, PostState> {
sidebar() {
return (
<div class="sticky-top">
- <Sidebar community={this.state.community} moderators={this.state.moderators} />
+ <Sidebar
+ community={this.state.community}
+ moderators={this.state.moderators}
+ admins={this.state.admins}
+ />
</div>
);
}
diff --git a/ui/src/components/sidebar.tsx b/ui/src/components/sidebar.tsx
index 2f231f9a..95880448 100644
--- a/ui/src/components/sidebar.tsx
+++ b/ui/src/components/sidebar.tsx
@@ -1,6 +1,6 @@
import { Component, linkEvent } from 'inferno';
import { Link } from 'inferno-router';
-import { Community, CommunityUser, FollowCommunityForm, CommunityForm as CommunityFormI } from '../interfaces';
+import { Community, CommunityUser, FollowCommunityForm, CommunityForm as CommunityFormI, UserView } from '../interfaces';
import { WebSocketService, UserService } from '../services';
import { mdToHtml, getUnixTime } from '../utils';
import { CommunityForm } from './community-form';
@@ -8,6 +8,7 @@ import { CommunityForm } from './community-form';
interface SidebarProps {
community: Community;
moderators: Array<CommunityUser>;
+ admins: Array<UserView>;
}
interface SidebarState {
@@ -54,24 +55,29 @@ export class Sidebar extends Component<SidebarProps, SidebarState> {
}
</h5>
<Link className="text-muted" to={`/community/${community.id}`}>/f/{community.name}</Link>
- {community.am_mod &&
- <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 &&
+ <ul class="list-inline mb-1 text-muted small font-weight-bold">
+ {this.canMod &&
+ <>
<li className="list-inline-item">
- {/* <span class="pointer" onClick={linkEvent(this, this.handleDeleteClick)}>delete</span> */}
+ <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>
+ }
+ </>
+ }
+ {this.canAdmin &&
<li className="list-inline-item">
{!this.props.community.removed ?
<span class="pointer" onClick={linkEvent(this, this.handleModRemoveShow)}>remove</span> :
<span class="pointer" onClick={linkEvent(this, this.handleModRemoveSubmit)}>restore</span>
}
</li>
- </ul>
- }
+
+ }
+ </ul>
{this.state.showRemoveDialog &&
<form onSubmit={linkEvent(this, this.handleModRemoveSubmit)}>
<div class="form-group row">
@@ -156,10 +162,13 @@ export class Sidebar extends Component<SidebarProps, SidebarState> {
return this.props.community.creator_id == UserService.Instance.user.id;
}
- // private get amMod(): boolean {
- // return UserService.Instance.loggedIn &&
- // this.props.moderators.map(m => m.user_id).includes(UserService.Instance.user.id);
- // }
+ get canMod(): boolean {
+ return UserService.Instance.user && this.props.moderators.map(m => m.user_id).includes(UserService.Instance.user.id);
+ }
+
+ get canAdmin(): boolean {
+ return UserService.Instance.user && this.props.admins.map(a => a.id).includes(UserService.Instance.user.id);
+ }
handleDeleteClick() {
}
diff --git a/ui/src/interfaces.ts b/ui/src/interfaces.ts
index 24bb6157..23b86074 100644
--- a/ui/src/interfaces.ts
+++ b/ui/src/interfaces.ts
@@ -72,6 +72,7 @@ export interface Post {
updated?: string;
creator_name: string;
community_name: string;
+ community_removed: boolean;
number_of_comments: number;
score: number;
upvotes: number;
@@ -350,6 +351,7 @@ export interface GetCommunityResponse {
op: string;
community: Community;
moderators: Array<CommunityUser>;
+ admins: Array<UserView>;
}