]> Untitled Git - lemmy.git/commitdiff
Adding some site oriented settings.
authorDessalines <tyhou13@gmx.com>
Wed, 11 Dec 2019 20:21:47 +0000 (12:21 -0800)
committerDessalines <tyhou13@gmx.com>
Wed, 11 Dec 2019 20:21:47 +0000 (12:21 -0800)
- Adding option to close registration. Fixes #350
- Adding option to disable showing NSFW buttons. Fixes #364
- Adding option to disable downvotes. Fixes #239

25 files changed:
server/migrations/2019-12-11-181820_add_site_fields/down.sql [new file with mode: 0644]
server/migrations/2019-12-11-181820_add_site_fields/up.sql [new file with mode: 0644]
server/src/api/comment.rs
server/src/api/mod.rs
server/src/api/post.rs
server/src/api/site.rs
server/src/api/user.rs
server/src/db/community.rs
server/src/db/community_view.rs
server/src/db/mod.rs
server/src/db/site.rs [new file with mode: 0644]
server/src/db/site_view.rs [new file with mode: 0644]
server/src/feeds.rs
server/src/lib.rs
server/src/nodeinfo.rs
server/src/schema.rs
ui/src/components/comment-node.tsx
ui/src/components/community-form.tsx
ui/src/components/login.tsx
ui/src/components/post-form.tsx
ui/src/components/post-listing.tsx
ui/src/components/site-form.tsx
ui/src/components/user.tsx
ui/src/interfaces.ts
ui/src/translations/en.ts

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 (file)
index 0000000..72eedba
--- /dev/null
@@ -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 (file)
index 0000000..e107b1a
--- /dev/null
@@ -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;
index eb5da62badb5d7885bf882700f61f0be3d8a9f30..9f9d46d3096ec098a9c5781e13d45c67fca6726e 100644 (file)
@@ -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() {
index 2d5dec8706097619d99a8a312d2a92f06acb3a4e..97a1190007ebed843fcdc9a3264ff5e15da5c03b 100644 (file)
@@ -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::*;
index 0b54840f4ef2958429d33530f2e23acdc8cb3a98..4b2395a8aac84c76b9d8f027ddb73dc8c38ece3a 100644 (file)
@@ -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() {
index cb6edfd587a067169494e0cff74ef886799b0db9..ec89e46cd9f4c2b85dfd1d8ffcba4c58b763f53a 100644 (file)
@@ -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) {
index 3047a0d3f17cf9d26d383b74d170490fff7b0826..df38dc99e7d4ad959bae6e7e8cafb1b5f9f2e00d 100644 (file)
@@ -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"))?;
index 9546907515612119d7e1365e85bb361ebf768fc1..57b962d13609e6ddad3a9064e12973e8798d5403 100644 (file)
@@ -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::*;
index 04b68441aa2a4da4dff018c485dbc7fe5b9bb527..157c4d91297b504e97450de9ebd9ed78496cb723 100644 (file)
@@ -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)
-  }
-}
index 3501fcda6cffdd6d2dc05b0389aecff0e7ba5eb7..a7961f122f3937f6bf5a2f77b0d96220c5b2d98e 100644 (file)
@@ -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 (file)
index 0000000..3b8366d
--- /dev/null
@@ -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 (file)
index 0000000..40b1265
--- /dev/null
@@ -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)
+  }
+}
index 810f6d5967991cbeed1807a92118f4fba23d8ffa..a16116d45ef3ead924ffc4ea0b3f12fa7b62b76b 100644 (file)
@@ -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};
index 2568143d36e99019c432f557b0142a320eed9051..c2fa2189dbf83b8f2cf0a6c00e74efb410e475b9 100644 (file)
@@ -118,7 +118,7 @@ impl Settings {
         .unwrap_or("3600".to_string())
         .parse()
         .unwrap(),
-      email_config: email_config,
+      email_config,
     }
   }
   fn api_endpoint(&self) -> String {
index 69c86919ce93125c2c11bb00edd432f53ce0299d..f8135c7d003f34e68ef9a62d1f2abaff3245b889 100644 (file)
@@ -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;
index bd73aabf5cf000e6c8385623062f46b95c004552..118f5f4a616a07b807d8b1cd291e32c61cc897d8 100644 (file)
@@ -246,6 +246,9 @@ table! {
         creator_id -> Int4,
         published -> Timestamp,
         updated -> Nullable<Timestamp>,
+        enable_downvotes -> Bool,
+        open_registration -> Bool,
+        enable_nsfw -> Bool,
     }
 }
 
index e3d821968d98d4e074ba2387b06afecc5a0a4942..f408ef2766c89acfbdc1e964947aff5f4ac2c153 100644 (file)
@@ -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
index e6c8ef0924f7cc8231f179c1f54d5680a1ff32ac..d5efb4324de06378665764f62b3c628db2080c3f 100644 (file)
@@ -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">
index 8d0df3e33b0c1cce2615c122a50e86edc31b0ffe..9a3cf3e33a2e023f706b22b37680abe0e93be7c9 100644 (file)
@@ -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">
index a3ea8fa33cdcb6296da70de0b09fa8032f388414..12fb42c5eb39f72c6724678f77bf7c4275f3e54f 100644 (file)
@@ -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">
index 94cd4d545c0d97a262ac9006244cfc76229a8971..61a4c865c484a1082457f51656676f728ffc5e6f 100644 (file)
@@ -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
index 7f8c229dadadc03c701aa2d989b22390c8ae6a0d..283a87d2a97aa6fe6da2510ff816950c18daf891 100644 (file)
@@ -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,
       };
     }
   }
@@ -77,6 +83,54 @@ export class SiteForm extends Component<SiteFormProps, SiteFormState> {
             />
           </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_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">
@@ -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();
   }
index bf77d4b7df0851e1dc8a229f05e99831dbd0580e..2624a9662049fecaf9d16fe1103f88b9ef47061e 100644 (file)
@@ -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>
                   </div>
                 </div>
-              </div>
+              )}
               <div class="form-group">
                 <div class="col-12">
                   <button
index f327202a494a50910bf55e8893bd885a5f6c27fc..8b86088751f5718ffe91b4c156fe7fa1531f0431 100644 (file)
@@ -199,6 +199,9 @@ export interface Site {
   number_of_posts: number;
   number_of_comments: number;
   number_of_communities: number;
+  enable_downvotes: boolean;
+  open_registration: boolean;
+  enable_nsfw: boolean;
 }
 
 export enum BanType {
@@ -625,9 +628,9 @@ export interface CreatePostLikeResponse {
 export interface SiteForm {
   name: string;
   description?: string;
-  removed?: boolean;
-  reason?: string;
-  expires?: number;
+  enable_downvotes: boolean;
+  open_registration: boolean;
+  enable_nsfw: boolean;
   auth?: string;
 }
 
index ce5fcdcc07be815c2f63102dd996f9f12e023376..60a73a30d6b04bfe0163d22f9912460c837580ec 100644 (file)
@@ -127,6 +127,11 @@ export const en = {
     expires: 'Expires',
     language: 'Language',
     browser_default: 'Browser Default',
+    downvotes_disabled: 'Downvotes disabled',
+    enable_downvotes: 'Enable Downvotes',
+    open_registration: 'Open Registration',
+    registration_closed: 'Registration closed',
+    enable_nsfw: 'Enable NSFW',
     url: 'URL',
     body: 'Body',
     copy_suggested_title: 'copy suggested title: {{title}}',