summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--server/migrations/2019-12-11-181820_add_site_fields/down.sql16
-rw-r--r--server/migrations/2019-12-11-181820_add_site_fields/up.sql16
-rw-r--r--server/src/api/comment.rs8
-rw-r--r--server/src/api/mod.rs2
-rw-r--r--server/src/api/post.rs8
-rw-r--r--server/src/api/site.rs15
-rw-r--r--server/src/api/user.rs7
-rw-r--r--server/src/db/community.rs46
-rw-r--r--server/src/db/community_view.rs41
-rw-r--r--server/src/db/mod.rs2
-rw-r--r--server/src/db/site.rs52
-rw-r--r--server/src/db/site_view.rs48
-rw-r--r--server/src/feeds.rs2
-rw-r--r--server/src/lib.rs2
-rw-r--r--server/src/nodeinfo.rs2
-rw-r--r--server/src/schema.rs3
-rw-r--r--ui/src/components/comment-node.tsx22
-rw-r--r--ui/src/components/community-form.tsx29
-rw-r--r--ui/src/components/login.tsx28
-rw-r--r--ui/src/components/post-form.tsx28
-rw-r--r--ui/src/components/post-listing.tsx22
-rw-r--r--ui/src/components/site-form.tsx69
-rw-r--r--ui/src/components/user.tsx34
-rw-r--r--ui/src/interfaces.ts9
-rw-r--r--ui/src/translations/en.ts5
25 files changed, 349 insertions, 167 deletions
diff --git a/server/migrations/2019-12-11-181820_add_site_fields/down.sql b/server/migrations/2019-12-11-181820_add_site_fields/down.sql
new file mode 100644
index 00000000..72eedba4
--- /dev/null
+++ b/server/migrations/2019-12-11-181820_add_site_fields/down.sql
@@ -0,0 +1,16 @@
+-- Drop the columns
+drop view site_view;
+alter table site drop column enable_downvotes;
+alter table site drop column open_registration;
+alter table site drop column enable_nsfw;
+
+-- Rebuild the views
+
+create view site_view as
+select *,
+(select name from user_ u where s.creator_id = u.id) as creator_name,
+(select count(*) from user_) as number_of_users,
+(select count(*) from post) as number_of_posts,
+(select count(*) from comment) as number_of_comments,
+(select count(*) from community) as number_of_communities
+from site s;
diff --git a/server/migrations/2019-12-11-181820_add_site_fields/up.sql b/server/migrations/2019-12-11-181820_add_site_fields/up.sql
new file mode 100644
index 00000000..e107b1ac
--- /dev/null
+++ b/server/migrations/2019-12-11-181820_add_site_fields/up.sql
@@ -0,0 +1,16 @@
+-- Add the column
+alter table site add column enable_downvotes boolean default true not null;
+alter table site add column open_registration boolean default true not null;
+alter table site add column enable_nsfw boolean default true not null;
+
+-- Reload the view
+drop view site_view;
+
+create view site_view as
+select *,
+(select name from user_ u where s.creator_id = u.id) as creator_name,
+(select count(*) from user_) as number_of_users,
+(select count(*) from post) as number_of_posts,
+(select count(*) from comment) as number_of_comments,
+(select count(*) from community) as number_of_communities
+from site s;
diff --git a/server/src/api/comment.rs b/server/src/api/comment.rs
index eb5da62b..9f9d46d3 100644
--- a/server/src/api/comment.rs
+++ b/server/src/api/comment.rs
@@ -298,6 +298,14 @@ impl Perform<CommentResponse> for Oper<CreateCommentLike> {
let user_id = claims.id;
+ // Don't do a downvote if site has downvotes disabled
+ if data.score == -1 {
+ let site = SiteView::read(&conn)?;
+ if site.enable_downvotes == false {
+ return Err(APIError::err(&self.op, "downvotes_disabled"))?;
+ }
+ }
+
// Check for a community ban
let post = Post::read(&conn, data.post_id)?;
if CommunityUserBanView::get(&conn, user_id, post.community_id).is_ok() {
diff --git a/server/src/api/mod.rs b/server/src/api/mod.rs
index 2d5dec87..97a11900 100644
--- a/server/src/api/mod.rs
+++ b/server/src/api/mod.rs
@@ -8,6 +8,8 @@ use crate::db::moderator_views::*;
use crate::db::password_reset_request::*;
use crate::db::post::*;
use crate::db::post_view::*;
+use crate::db::site::*;
+use crate::db::site_view::*;
use crate::db::user::*;
use crate::db::user_mention::*;
use crate::db::user_mention_view::*;
diff --git a/server/src/api/post.rs b/server/src/api/post.rs
index 0b54840f..4b2395a8 100644
--- a/server/src/api/post.rs
+++ b/server/src/api/post.rs
@@ -265,6 +265,14 @@ impl Perform<CreatePostLikeResponse> for Oper<CreatePostLike> {
let user_id = claims.id;
+ // Don't do a downvote if site has downvotes disabled
+ if data.score == -1 {
+ let site = SiteView::read(&conn)?;
+ if site.enable_downvotes == false {
+ return Err(APIError::err(&self.op, "downvotes_disabled"))?;
+ }
+ }
+
// Check for a community ban
let post = Post::read(&conn, data.post_id)?;
if CommunityUserBanView::get(&conn, user_id, post.community_id).is_ok() {
diff --git a/server/src/api/site.rs b/server/src/api/site.rs
index cb6edfd5..ec89e46c 100644
--- a/server/src/api/site.rs
+++ b/server/src/api/site.rs
@@ -56,6 +56,9 @@ pub struct GetModlogResponse {
pub struct CreateSite {
name: String,
description: Option<String>,
+ enable_downvotes: bool,
+ open_registration: bool,
+ enable_nsfw: bool,
auth: String,
}
@@ -63,6 +66,9 @@ pub struct CreateSite {
pub struct EditSite {
name: String,
description: Option<String>,
+ enable_downvotes: bool,
+ open_registration: bool,
+ enable_nsfw: bool,
auth: String,
}
@@ -208,6 +214,9 @@ impl Perform<SiteResponse> for Oper<CreateSite> {
name: data.name.to_owned(),
description: data.description.to_owned(),
creator_id: user_id,
+ enable_downvotes: data.enable_downvotes,
+ open_registration: data.open_registration,
+ enable_nsfw: data.enable_nsfw,
updated: None,
};
@@ -255,6 +264,9 @@ impl Perform<SiteResponse> for Oper<EditSite> {
description: data.description.to_owned(),
creator_id: found_site.creator_id,
updated: Some(naive_now()),
+ enable_downvotes: data.enable_downvotes,
+ open_registration: data.open_registration,
+ enable_nsfw: data.enable_nsfw,
};
match Site::update(&conn, 1, &site_form) {
@@ -431,6 +443,9 @@ impl Perform<GetSiteResponse> for Oper<TransferSite> {
description: read_site.description,
creator_id: data.user_id,
updated: Some(naive_now()),
+ enable_downvotes: read_site.enable_downvotes,
+ open_registration: read_site.open_registration,
+ enable_nsfw: read_site.enable_nsfw,
};
match Site::update(&conn, 1, &site_form) {
diff --git a/server/src/api/user.rs b/server/src/api/user.rs
index 3047a0d3..df38dc99 100644
--- a/server/src/api/user.rs
+++ b/server/src/api/user.rs
@@ -193,6 +193,13 @@ impl Perform<LoginResponse> for Oper<Register> {
let data: &Register = &self.data;
let conn = establish_connection();
+ // Make sure site has open registration
+ if let Ok(site) = SiteView::read(&conn) {
+ if !site.open_registration {
+ return Err(APIError::err(&self.op, "registration_closed"))?;
+ }
+ }
+
// Make sure passwords match
if &data.password != &data.password_verify {
return Err(APIError::err(&self.op, "passwords_dont_match"))?;
diff --git a/server/src/db/community.rs b/server/src/db/community.rs
index 95469075..57b962d1 100644
--- a/server/src/db/community.rs
+++ b/server/src/db/community.rs
@@ -1,5 +1,5 @@
use super::*;
-use crate::schema::{community, community_follower, community_moderator, community_user_ban, site};
+use crate::schema::{community, community_follower, community_moderator, community_user_ban};
#[derive(Queryable, Identifiable, PartialEq, Debug, Serialize, Deserialize)]
#[table_name = "community"]
@@ -202,50 +202,6 @@ impl Followable<CommunityFollowerForm> for CommunityFollower {
}
}
-#[derive(Queryable, Identifiable, PartialEq, Debug, Serialize, Deserialize)]
-#[table_name = "site"]
-pub struct Site {
- pub id: i32,
- pub name: String,
- pub description: Option<String>,
- pub creator_id: i32,
- pub published: chrono::NaiveDateTime,
- pub updated: Option<chrono::NaiveDateTime>,
-}
-
-#[derive(Insertable, AsChangeset, Clone, Serialize, Deserialize)]
-#[table_name = "site"]
-pub struct SiteForm {
- pub name: String,
- pub description: Option<String>,
- pub creator_id: i32,
- pub updated: Option<chrono::NaiveDateTime>,
-}
-
-impl Crud<SiteForm> for Site {
- fn read(conn: &PgConnection, _site_id: i32) -> Result<Self, Error> {
- use crate::schema::site::dsl::*;
- site.first::<Self>(conn)
- }
-
- fn delete(conn: &PgConnection, site_id: i32) -> Result<usize, Error> {
- use crate::schema::site::dsl::*;
- diesel::delete(site.find(site_id)).execute(conn)
- }
-
- fn create(conn: &PgConnection, new_site: &SiteForm) -> Result<Self, Error> {
- use crate::schema::site::dsl::*;
- insert_into(site).values(new_site).get_result::<Self>(conn)
- }
-
- fn update(conn: &PgConnection, site_id: i32, new_site: &SiteForm) -> Result<Self, Error> {
- use crate::schema::site::dsl::*;
- diesel::update(site.find(site_id))
- .set(new_site)
- .get_result::<Self>(conn)
- }
-}
-
#[cfg(test)]
mod tests {
use super::super::user::*;
diff --git a/server/src/db/community_view.rs b/server/src/db/community_view.rs
index 04b68441..157c4d91 100644
--- a/server/src/db/community_view.rs
+++ b/server/src/db/community_view.rs
@@ -59,22 +59,6 @@ table! {
}
}
-table! {
- site_view (id) {
- id -> Int4,
- name -> Varchar,
- description -> Nullable<Text>,
- creator_id -> Int4,
- published -> Timestamp,
- updated -> Nullable<Timestamp>,
- creator_name -> Varchar,
- number_of_users -> BigInt,
- number_of_posts -> BigInt,
- number_of_comments -> BigInt,
- number_of_communities -> BigInt,
- }
-}
-
#[derive(
Queryable, Identifiable, PartialEq, Debug, Serialize, Deserialize, QueryableByName, Clone,
)]
@@ -328,28 +312,3 @@ impl CommunityUserBanView {
.first::<Self>(conn)
}
}
-
-#[derive(
- Queryable, Identifiable, PartialEq, Debug, Serialize, Deserialize, QueryableByName, Clone,
-)]
-#[table_name = "site_view"]
-pub struct SiteView {
- pub id: i32,
- pub name: String,
- pub description: Option<String>,
- pub creator_id: i32,
- pub published: chrono::NaiveDateTime,
- pub updated: Option<chrono::NaiveDateTime>,
- pub creator_name: String,
- pub number_of_users: i64,
- pub number_of_posts: i64,
- pub number_of_comments: i64,
- pub number_of_communities: i64,
-}
-
-impl SiteView {
- pub fn read(conn: &PgConnection) -> Result<Self, Error> {
- use super::community_view::site_view::dsl::*;
- site_view.first::<Self>(conn)
- }
-}
diff --git a/server/src/db/mod.rs b/server/src/db/mod.rs
index 3501fcda..a7961f12 100644
--- a/server/src/db/mod.rs
+++ b/server/src/db/mod.rs
@@ -14,6 +14,8 @@ pub mod moderator_views;
pub mod password_reset_request;
pub mod post;
pub mod post_view;
+pub mod site;
+pub mod site_view;
pub mod user;
pub mod user_mention;
pub mod user_mention_view;
diff --git a/server/src/db/site.rs b/server/src/db/site.rs
new file mode 100644
index 00000000..3b8366d8
--- /dev/null
+++ b/server/src/db/site.rs
@@ -0,0 +1,52 @@
+use super::*;
+use crate::schema::site;
+
+#[derive(Queryable, Identifiable, PartialEq, Debug, Serialize, Deserialize)]
+#[table_name = "site"]
+pub struct Site {
+ pub id: i32,
+ pub name: String,
+ pub description: Option<String>,
+ pub creator_id: i32,
+ pub published: chrono::NaiveDateTime,
+ pub updated: Option<chrono::NaiveDateTime>,
+ pub enable_downvotes: bool,
+ pub open_registration: bool,
+ pub enable_nsfw: bool,
+}
+
+#[derive(Insertable, AsChangeset, Clone, Serialize, Deserialize)]
+#[table_name = "site"]
+pub struct SiteForm {
+ pub name: String,
+ pub description: Option<String>,
+ pub creator_id: i32,
+ pub updated: Option<chrono::NaiveDateTime>,
+ pub enable_downvotes: bool,
+ pub open_registration: bool,
+ pub enable_nsfw: bool,
+}
+
+impl Crud<SiteForm> for Site {
+ fn read(conn: &PgConnection, _site_id: i32) -> Result<Self, Error> {
+ use crate::schema::site::dsl::*;
+ site.first::<Self>(conn)
+ }
+
+ fn delete(conn: &PgConnection, site_id: i32) -> Result<usize, Error> {
+ use crate::schema::site::dsl::*;
+ diesel::delete(site.find(site_id)).execute(conn)
+ }
+
+ fn create(conn: &PgConnection, new_site: &SiteForm) -> Result<Self, Error> {
+ use crate::schema::site::dsl::*;
+ insert_into(site).values(new_site).get_result::<Self>(conn)
+ }
+
+ fn update(conn: &PgConnection, site_id: i32, new_site: &SiteForm) -> Result<Self, Error> {
+ use crate::schema::site::dsl::*;
+ diesel::update(site.find(site_id))
+ .set(new_site)
+ .get_result::<Self>(conn)
+ }
+}
diff --git a/server/src/db/site_view.rs b/server/src/db/site_view.rs
new file mode 100644
index 00000000..40b1265f
--- /dev/null
+++ b/server/src/db/site_view.rs
@@ -0,0 +1,48 @@
+use super::*;
+
+table! {
+ site_view (id) {
+ id -> Int4,
+ name -> Varchar,
+ description -> Nullable<Text>,
+ creator_id -> Int4,
+ published -> Timestamp,
+ updated -> Nullable<Timestamp>,
+ enable_downvotes -> Bool,
+ open_registration -> Bool,
+ enable_nsfw -> Bool,
+ creator_name -> Varchar,
+ number_of_users -> BigInt,
+ number_of_posts -> BigInt,
+ number_of_comments -> BigInt,
+ number_of_communities -> BigInt,
+ }
+}
+
+#[derive(
+ Queryable, Identifiable, PartialEq, Debug, Serialize, Deserialize, QueryableByName, Clone,
+)]
+#[table_name = "site_view"]
+pub struct SiteView {
+ pub id: i32,
+ pub name: String,
+ pub description: Option<String>,
+ pub creator_id: i32,
+ pub published: chrono::NaiveDateTime,
+ pub updated: Option<chrono::NaiveDateTime>,
+ pub enable_downvotes: bool,
+ pub open_registration: bool,
+ pub enable_nsfw: bool,
+ pub creator_name: String,
+ pub number_of_users: i64,
+ pub number_of_posts: i64,
+ pub number_of_comments: i64,
+ pub number_of_communities: i64,
+}
+
+impl SiteView {
+ pub fn read(conn: &PgConnection) -> Result<Self, Error> {
+ use super::site_view::site_view::dsl::*;
+ site_view.first::<Self>(conn)
+ }
+}
diff --git a/server/src/feeds.rs b/server/src/feeds.rs
index 810f6d59..a16116d4 100644
--- a/server/src/feeds.rs
+++ b/server/src/feeds.rs
@@ -3,8 +3,8 @@ extern crate rss;
use super::*;
use crate::db::comment_view::{ReplyQueryBuilder, ReplyView};
use crate::db::community::Community;
-use crate::db::community_view::SiteView;
use crate::db::post_view::{PostQueryBuilder, PostView};
+use crate::db::site_view::SiteView;
use crate::db::user::User_;
use crate::db::user_mention_view::{UserMentionQueryBuilder, UserMentionView};
use crate::db::{establish_connection, ListingType, SortType};
diff --git a/server/src/lib.rs b/server/src/lib.rs
index 2568143d..c2fa2189 100644
--- a/server/src/lib.rs
+++ b/server/src/lib.rs
@@ -118,7 +118,7 @@ impl Settings {
.unwrap_or("3600".to_string())
.parse()
.unwrap(),
- email_config: email_config,
+ email_config,
}
}
fn api_endpoint(&self) -> String {
diff --git a/server/src/nodeinfo.rs b/server/src/nodeinfo.rs
index 69c86919..f8135c7d 100644
--- a/server/src/nodeinfo.rs
+++ b/server/src/nodeinfo.rs
@@ -1,5 +1,5 @@
-use crate::db::community_view::SiteView;
use crate::db::establish_connection;
+use crate::db::site_view::SiteView;
use crate::version;
use crate::Settings;
use actix_web::body::Body;
diff --git a/server/src/schema.rs b/server/src/schema.rs
index bd73aabf..118f5f4a 100644
--- a/server/src/schema.rs
+++ b/server/src/schema.rs
@@ -246,6 +246,9 @@ table! {
creator_id -> Int4,
published -> Timestamp,
updated -> Nullable<Timestamp>,
+ enable_downvotes -> Bool,
+ open_registration -> Bool,
+ enable_nsfw -> Bool,
}
}
diff --git a/ui/src/components/comment-node.tsx b/ui/src/components/comment-node.tsx
index e3d82196..f408ef27 100644
--- a/ui/src/components/comment-node.tsx
+++ b/ui/src/components/comment-node.tsx
@@ -102,16 +102,18 @@ export class CommentNode extends Component<CommentNodeProps, CommentNodeState> {
<div class={`font-weight-bold text-muted`}>
{node.comment.score}
</div>
- <button
- className={`btn p-0 ${
- node.comment.my_vote == -1 ? 'text-danger' : 'text-muted'
- }`}
- onClick={linkEvent(node, this.handleCommentDisLike)}
- >
- <svg class="icon downvote">
- <use xlinkHref="#icon-arrow-down"></use>
- </svg>
- </button>
+ {WebSocketService.Instance.site.enable_downvotes && (
+ <button
+ className={`btn p-0 ${
+ node.comment.my_vote == -1 ? 'text-danger' : 'text-muted'
+ }`}
+ onClick={linkEvent(node, this.handleCommentDisLike)}
+ >
+ <svg class="icon downvote">
+ <use xlinkHref="#icon-arrow-down"></use>
+ </svg>
+ </button>
+ )}
</div>
)}
<div
diff --git a/ui/src/components/community-form.tsx b/ui/src/components/community-form.tsx
index e6c8ef09..d5efb432 100644
--- a/ui/src/components/community-form.tsx
+++ b/ui/src/components/community-form.tsx
@@ -156,21 +156,24 @@ export class CommunityForm extends Component<
</select>
</div>
</div>
- <div class="form-group row">
- <div class="col-12">
- <div class="form-check">
- <input
- class="form-check-input"
- type="checkbox"
- checked={this.state.communityForm.nsfw}
- onChange={linkEvent(this, this.handleCommunityNsfwChange)}
- />
- <label class="form-check-label">
- <T i18nKey="nsfw">#</T>
- </label>
+
+ {WebSocketService.Instance.site.enable_nsfw && (
+ <div class="form-group row">
+ <div class="col-12">
+ <div class="form-check">
+ <input
+ class="form-check-input"
+ type="checkbox"
+ checked={this.state.communityForm.nsfw}
+ onChange={linkEvent(this, this.handleCommunityNsfwChange)}
+ />
+ <label class="form-check-label">
+ <T i18nKey="nsfw">#</T>
+ </label>
+ </div>
</div>
</div>
- </div>
+ )}
<div class="form-group row">
<div class="col-12">
<button type="submit" class="btn btn-secondary mr-2">
diff --git a/ui/src/components/login.tsx b/ui/src/components/login.tsx
index 8d0df3e3..9a3cf3e3 100644
--- a/ui/src/components/login.tsx
+++ b/ui/src/components/login.tsx
@@ -205,21 +205,23 @@ export class Login extends Component<any, State> {
/>
</div>
</div>
- <div class="form-group row">
- <div class="col-sm-10">
- <div class="form-check">
- <input
- class="form-check-input"
- type="checkbox"
- checked={this.state.registerForm.show_nsfw}
- onChange={linkEvent(this, this.handleRegisterShowNsfwChange)}
- />
- <label class="form-check-label">
- <T i18nKey="show_nsfw">#</T>
- </label>
+ {WebSocketService.Instance.site.enable_nsfw && (
+ <div class="form-group row">
+ <div class="col-sm-10">
+ <div class="form-check">
+ <input
+ class="form-check-input"
+ type="checkbox"
+ checked={this.state.registerForm.show_nsfw}
+ onChange={linkEvent(this, this.handleRegisterShowNsfwChange)}
+ />
+ <label class="form-check-label">
+ <T i18nKey="show_nsfw">#</T>
+ </label>
+ </div>
</div>
</div>
- </div>
+ )}
<div class="form-group row">
<div class="col-sm-10">
<button type="submit" class="btn btn-secondary">
diff --git a/ui/src/components/post-form.tsx b/ui/src/components/post-form.tsx
index a3ea8fa3..12fb42c5 100644
--- a/ui/src/components/post-form.tsx
+++ b/ui/src/components/post-form.tsx
@@ -280,21 +280,23 @@ export class PostForm extends Component<PostFormProps, PostFormState> {
</div>
</div>
)}
- <div class="form-group row">
- <div class="col-sm-10">
- <div class="form-check">
- <input
- class="form-check-input"
- type="checkbox"
- checked={this.state.postForm.nsfw}
- onChange={linkEvent(this, this.handlePostNsfwChange)}
- />
- <label class="form-check-label">
- <T i18nKey="nsfw">#</T>
- </label>
+ {WebSocketService.Instance.site.enable_nsfw && (
+ <div class="form-group row">
+ <div class="col-sm-10">
+ <div class="form-check">
+ <input
+ class="form-check-input"
+ type="checkbox"
+ checked={this.state.postForm.nsfw}
+ onChange={linkEvent(this, this.handlePostNsfwChange)}
+ />
+ <label class="form-check-label">
+ <T i18nKey="nsfw">#</T>
+ </label>
+ </div>
</div>
</div>
- </div>
+ )}
<div class="form-group row">
<div class="col-sm-10">
<button type="submit" class="btn btn-secondary mr-2">
diff --git a/ui/src/components/post-listing.tsx b/ui/src/components/post-listing.tsx
index 94cd4d54..61a4c865 100644
--- a/ui/src/components/post-listing.tsx
+++ b/ui/src/components/post-listing.tsx
@@ -114,16 +114,18 @@ export class PostListing extends Component<PostListingProps, PostListingState> {
</svg>
</button>
<div class={`font-weight-bold text-muted`}>{post.score}</div>
- <button
- className={`btn p-0 ${
- post.my_vote == -1 ? 'text-danger' : 'text-muted'
- }`}
- onClick={linkEvent(this, this.handlePostDisLike)}
- >
- <svg class="icon downvote">
- <use xlinkHref="#icon-arrow-down"></use>
- </svg>
- </button>
+ {WebSocketService.Instance.site.enable_downvotes && (
+ <button
+ className={`btn p-0 ${
+ post.my_vote == -1 ? 'text-danger' : 'text-muted'
+ }`}
+ onClick={linkEvent(this, this.handlePostDisLike)}
+ >
+ <svg class="icon downvote">
+ <use xlinkHref="#icon-arrow-down"></use>
+ </svg>
+ </button>
+ )}
</div>
{post.url && isImage(post.url) && !post.nsfw && !post.community_nsfw && (
<span
diff --git a/ui/src/components/site-form.tsx b/ui/src/components/site-form.tsx
index 7f8c229d..283a87d2 100644
--- a/ui/src/components/site-form.tsx
+++ b/ui/src/components/site-form.tsx
@@ -19,6 +19,9 @@ interface SiteFormState {
export class SiteForm extends Component<SiteFormProps, SiteFormState> {
private emptyState: SiteFormState = {
siteForm: {
+ enable_downvotes: true,
+ open_registration: true,
+ enable_nsfw: true,
name: null,
},
loading: false,
@@ -31,6 +34,9 @@ export class SiteForm extends Component<SiteFormProps, SiteFormState> {
this.state.siteForm = {
name: this.props.site.name,
description: this.props.site.description,
+ enable_downvotes: this.props.site.enable_downvotes,
+ open_registration: this.props.site.open_registration,
+ enable_nsfw: this.props.site.enable_nsfw,
};
}
}
@@ -79,6 +85,54 @@ export class SiteForm extends Component<SiteFormProps, SiteFormState> {
</div>
<div class="form-group row">
<div class="col-12">
+ <div class="form-check">
+ <input
+ class="form-check-input"
+ type="checkbox"
+ checked={this.state.siteForm.enable_downvotes}
+ onChange={linkEvent(this, this.handleSiteEnableDownvotesChange)}
+ />
+ <label class="form-check-label">
+ <T i18nKey="enable_downvotes">#</T>
+ </label>
+ </div>
+ </div>
+ </div>
+ <div class="form-group row">
+ <div class="col-12">
+ <div class="form-check">
+ <input
+ class="form-check-input"
+ type="checkbox"
+ checked={this.state.siteForm.enable_nsfw}
+ onChange={linkEvent(this, this.handleSiteEnableNsfwChange)}
+ />
+ <label class="form-check-label">
+ <T i18nKey="enable_nsfw">#</T>
+ </label>
+ </div>
+ </div>
+ </div>
+ <div class="form-group row">
+ <div class="col-12">
+ <div class="form-check">
+ <input
+ class="form-check-input"
+ type="checkbox"
+ checked={this.state.siteForm.open_registration}
+ onChange={linkEvent(
+ this,
+ this.handleSiteOpenRegistrationChange
+ )}
+ />
+ <label class="form-check-label">
+ <T i18nKey="open_registration">#</T>
+ </label>
+ </div>
+ </div>
+ </div>
+ <div class="form-group row">
+ <div class="col-12">
<button type="submit" class="btn btn-secondary mr-2">
{this.state.loading ? (
<svg class="icon icon-spinner spin">
@@ -126,6 +180,21 @@ export class SiteForm extends Component<SiteFormProps, SiteFormState> {
i.setState(i.state);
}
+ handleSiteEnableNsfwChange(i: SiteForm, event: any) {
+ i.state.siteForm.enable_nsfw = event.target.checked;
+ i.setState(i.state);
+ }
+
+ handleSiteOpenRegistrationChange(i: SiteForm, event: any) {
+ i.state.siteForm.open_registration = event.target.checked;
+ i.setState(i.state);
+ }
+
+ handleSiteEnableDownvotesChange(i: SiteForm, event: any) {
+ i.state.siteForm.enable_downvotes = event.target.checked;
+ i.setState(i.state);
+ }
+
handleCancel(i: SiteForm) {
i.props.onCancel();
}
diff --git a/ui/src/components/user.tsx b/ui/src/components/user.tsx
index bf77d4b7..2624a966 100644
--- a/ui/src/components/user.tsx
+++ b/ui/src/components/user.tsx
@@ -496,24 +496,26 @@ export class User extends Component<any, UserState> {
/>
</div>
</form>
- <div class="form-group">
- <div class="col-12">
- <div class="form-check">
- <input
- class="form-check-input"
- type="checkbox"
- checked={this.state.userSettingsForm.show_nsfw}
- onChange={linkEvent(
- this,
- this.handleUserSettingsShowNsfwChange
- )}
- />
- <label class="form-check-label">
- <T i18nKey="show_nsfw">#</T>
- </label>
+ {WebSocketService.Instance.site.enable_nsfw && (
+ <div class="form-group">
+ <div class="col-12">
+ <div class="form-check">
+ <input
+ class="form-check-input"
+ type="checkbox"
+ checked={this.state.userSettingsForm.show_nsfw}
+ onChange={linkEvent(
+ this,
+ this.handleUserSettingsShowNsfwChange
+ )}
+ />
+ <label class="form-check-label">
+ <T i18nKey="show_nsfw">#</T>
+ </label>
+ </div>