]> Untitled Git - lemmy.git/commitdiff
Adding default sort / filter into user settings.
authorDessalines <tyhou13@gmx.com>
Mon, 21 Oct 2019 04:21:54 +0000 (21:21 -0700)
committerDessalines <tyhou13@gmx.com>
Mon, 21 Oct 2019 04:21:54 +0000 (21:21 -0700)
- Fixes #295

22 files changed:
server/migrations/2019-10-21-011237_add_default_sorts/down.sql [new file with mode: 0644]
server/migrations/2019-10-21-011237_add_default_sorts/up.sql [new file with mode: 0644]
server/src/api/post.rs
server/src/api/site.rs
server/src/api/user.rs
server/src/apub.rs
server/src/db/comment.rs
server/src/db/comment_view.rs
server/src/db/community.rs
server/src/db/mod.rs
server/src/db/moderator.rs
server/src/db/post.rs
server/src/db/post_view.rs
server/src/db/user.rs
server/src/db/user_mention.rs
server/src/schema.rs
server/src/websocket/server.rs
ui/src/components/community.tsx
ui/src/components/listing-type-select.tsx [new file with mode: 0644]
ui/src/components/main.tsx
ui/src/components/user.tsx
ui/src/interfaces.ts

diff --git a/server/migrations/2019-10-21-011237_add_default_sorts/down.sql b/server/migrations/2019-10-21-011237_add_default_sorts/down.sql
new file mode 100644 (file)
index 0000000..238c9e7
--- /dev/null
@@ -0,0 +1,2 @@
+alter table user_ drop column default_sort_type;
+alter table user_ drop column default_listing_type;
diff --git a/server/migrations/2019-10-21-011237_add_default_sorts/up.sql b/server/migrations/2019-10-21-011237_add_default_sorts/up.sql
new file mode 100644 (file)
index 0000000..4bb9600
--- /dev/null
@@ -0,0 +1,2 @@
+alter table user_ add column default_sort_type smallint default 0 not null;
+alter table user_ add column default_listing_type smallint default 1 not null;
index d53d2064ac772b97d9345ee28bc3a7501e18fe73..5df42990ae8567b2f358ecacaabc5f61df537311 100644 (file)
@@ -235,7 +235,7 @@ impl Perform<GetPostsResponse> for Oper<GetPosts> {
       None => false,
     };
 
-    let type_ = PostListingType::from_str(&data.type_)?;
+    let type_ = ListingType::from_str(&data.type_)?;
     let sort = SortType::from_str(&data.sort)?;
 
     let posts = match PostView::list(
index 40b1592ddb75747936016f3c2dc0a25959c1e75d..618295fca372cda377437a3e00f497b84682182e 100644 (file)
@@ -321,7 +321,7 @@ impl Perform<SearchResponse> for Oper<Search> {
       SearchType::Posts => {
         posts = PostView::list(
           &conn,
-          PostListingType::All,
+          ListingType::All,
           &sort,
           data.community_id,
           None,
@@ -365,7 +365,7 @@ impl Perform<SearchResponse> for Oper<Search> {
       SearchType::All => {
         posts = PostView::list(
           &conn,
-          PostListingType::All,
+          ListingType::All,
           &sort,
           data.community_id,
           None,
@@ -403,7 +403,7 @@ impl Perform<SearchResponse> for Oper<Search> {
       SearchType::Url => {
         posts = PostView::list(
           &conn,
-          PostListingType::All,
+          ListingType::All,
           &sort,
           data.community_id,
           None,
index 563ae0a229d28766ee8eb46f91d034fc40f27313..5ac2b4321def058f0c5419683029ac227e632eec 100644 (file)
@@ -22,6 +22,8 @@ pub struct Register {
 pub struct SaveUserSettings {
   show_nsfw: bool,
   theme: String,
+  default_sort_type: i16,
+  default_listing_type: i16,
   auth: String,
 }
 
@@ -198,6 +200,8 @@ impl Perform<LoginResponse> for Oper<Register> {
       banned: false,
       show_nsfw: data.show_nsfw,
       theme: "darkly".into(),
+      default_sort_type: SortType::Hot as i16,
+      default_listing_type: ListingType::Subscribed as i16,
     };
 
     // Create the user
@@ -289,6 +293,8 @@ impl Perform<LoginResponse> for Oper<SaveUserSettings> {
       banned: read_user.banned,
       show_nsfw: data.show_nsfw,
       theme: data.theme.to_owned(),
+      default_sort_type: data.default_sort_type,
+      default_listing_type: data.default_listing_type,
     };
 
     let updated_user = match User_::update(&conn, user_id, &user_form) {
@@ -346,7 +352,7 @@ impl Perform<GetUserDetailsResponse> for Oper<GetUserDetails> {
     let posts = if data.saved_only {
       PostView::list(
         &conn,
-        PostListingType::All,
+        ListingType::All,
         &sort,
         data.community_id,
         None,
@@ -362,7 +368,7 @@ impl Perform<GetUserDetailsResponse> for Oper<GetUserDetails> {
     } else {
       PostView::list(
         &conn,
-        PostListingType::All,
+        ListingType::All,
         &sort,
         data.community_id,
         Some(user_details_id),
@@ -453,6 +459,8 @@ impl Perform<AddAdminResponse> for Oper<AddAdmin> {
       banned: read_user.banned,
       show_nsfw: read_user.show_nsfw,
       theme: read_user.theme,
+      default_sort_type: read_user.default_sort_type,
+      default_listing_type: read_user.default_listing_type,
     };
 
     match User_::update(&conn, data.user_id, &user_form) {
@@ -512,6 +520,8 @@ impl Perform<BanUserResponse> for Oper<BanUser> {
       banned: data.ban,
       show_nsfw: read_user.show_nsfw,
       theme: read_user.theme,
+      default_sort_type: read_user.default_sort_type,
+      default_listing_type: read_user.default_listing_type,
     };
 
     match User_::update(&conn, data.user_id, &user_form) {
@@ -751,7 +761,7 @@ impl Perform<LoginResponse> for Oper<DeleteAccount> {
     // Posts
     let posts = PostView::list(
       &conn,
-      PostListingType::All,
+      ListingType::All,
       &SortType::New,
       None,
       Some(user_id),
index 958a8df18c20fa8505d01c0313d39d36d511c472..3c7202b2756dd3c404436e21529ae428e7e2517e 100644 (file)
@@ -55,6 +55,7 @@ impl User_ {
 #[cfg(test)]
 mod tests {
   use super::User_;
+  use crate::db::{ListingType, SortType};
   use crate::naive_now;
 
   #[test]
@@ -73,6 +74,8 @@ mod tests {
       updated: None,
       show_nsfw: false,
       theme: "darkly".into(),
+      default_sort_type: SortType::Hot as i16,
+      default_listing_type: ListingType::Subscribed as i16,
     };
 
     let person = expected_user.person();
index 32aa4de923dde78ac27ecff06f8202f9745489b2..64532b8388aa5b2959a9cb976fc1891412e9ada4 100644 (file)
@@ -179,6 +179,8 @@ mod tests {
       updated: None,
       show_nsfw: false,
       theme: "darkly".into(),
+      default_sort_type: SortType::Hot as i16,
+      default_listing_type: ListingType::Subscribed as i16,
     };
 
     let inserted_user = User_::create(&conn, &new_user).unwrap();
index 88190464c6cc01ea38e7347daab3de1cd4c18828..9f75447310a98f69cae6bc8b6449b46d8dc50da5 100644 (file)
@@ -264,6 +264,8 @@ mod tests {
       updated: None,
       show_nsfw: false,
       theme: "darkly".into(),
+      default_sort_type: SortType::Hot as i16,
+      default_listing_type: ListingType::Subscribed as i16,
     };
 
     let inserted_user = User_::create(&conn, &new_user).unwrap();
index 53c238bd3fbeceb9f094d335b7fd54c9d2520238..bfc6089bc8395b65d15bdf1ea118f8f258d8662e 100644 (file)
@@ -265,6 +265,8 @@ mod tests {
       updated: None,
       show_nsfw: false,
       theme: "darkly".into(),
+      default_sort_type: SortType::Hot as i16,
+      default_listing_type: ListingType::Subscribed as i16,
     };
 
     let inserted_user = User_::create(&conn, &new_user).unwrap();
index ac3c3ae3356adc1bb918c295760c982fa32226f2..2045692d5c6660116ae38f27e45f3c3299d7d5c9 100644 (file)
@@ -106,6 +106,13 @@ pub enum SortType {
   TopAll,
 }
 
+#[derive(EnumString, ToString, Debug, Serialize, Deserialize)]
+pub enum ListingType {
+  All,
+  Subscribed,
+  Community,
+}
+
 #[derive(EnumString, ToString, Debug, Serialize, Deserialize)]
 pub enum SearchType {
   All,
index 82e0a4971477e83471d71399b03d39b98fa274e0..b04c6c623cf3034c2b158a094995ffca5e8171e3 100644 (file)
@@ -447,6 +447,8 @@ mod tests {
       updated: None,
       show_nsfw: false,
       theme: "darkly".into(),
+      default_sort_type: SortType::Hot as i16,
+      default_listing_type: ListingType::Subscribed as i16,
     };
 
     let inserted_mod = User_::create(&conn, &new_mod).unwrap();
@@ -462,6 +464,8 @@ mod tests {
       updated: None,
       show_nsfw: false,
       theme: "darkly".into(),
+      default_sort_type: SortType::Hot as i16,
+      default_listing_type: ListingType::Subscribed as i16,
     };
 
     let inserted_user = User_::create(&conn, &new_user).unwrap();
index 1bc6e11e624f0c334210cd350deb2461cfb115e0..f185bd75411fbecfe2dd75064b3f100776f107d0 100644 (file)
@@ -192,6 +192,8 @@ mod tests {
       updated: None,
       show_nsfw: false,
       theme: "darkly".into(),
+      default_sort_type: SortType::Hot as i16,
+      default_listing_type: ListingType::Subscribed as i16,
     };
 
     let inserted_user = User_::create(&conn, &new_user).unwrap();
index 1180a7702a6d49e3dc5bdc7becd9c8f2a70ea9cd..51dea027fd13eacf7b7fd7112ec48f3cc89e65f7 100644 (file)
@@ -1,12 +1,5 @@
 use super::*;
 
-#[derive(EnumString, ToString, Debug, Serialize, Deserialize)]
-pub enum PostListingType {
-  All,
-  Subscribed,
-  Community,
-}
-
 // The faked schema since diesel doesn't do views
 table! {
   post_view (id) {
@@ -83,7 +76,7 @@ pub struct PostView {
 impl PostView {
   pub fn list(
     conn: &PgConnection,
-    type_: PostListingType,
+    type_: ListingType,
     sort: &SortType,
     for_community_id: Option<i32>,
     for_creator_id: Option<i32>,
@@ -129,7 +122,7 @@ impl PostView {
     };
 
     match type_ {
-      PostListingType::Subscribed => {
+      ListingType::Subscribed => {
         query = query.filter(subscribed.eq(true));
       }
       _ => {}
@@ -226,6 +219,8 @@ mod tests {
       banned: false,
       show_nsfw: false,
       theme: "darkly".into(),
+      default_sort_type: SortType::Hot as i16,
+      default_listing_type: ListingType::Subscribed as i16,
     };
 
     let inserted_user = User_::create(&conn, &new_user).unwrap();
@@ -351,7 +346,7 @@ mod tests {
 
     let read_post_listings_with_user = PostView::list(
       &conn,
-      PostListingType::Community,
+      ListingType::Community,
       &SortType::New,
       Some(inserted_community.id),
       None,
@@ -367,7 +362,7 @@ mod tests {
     .unwrap();
     let read_post_listings_no_user = PostView::list(
       &conn,
-      PostListingType::Community,
+      ListingType::Community,
       &SortType::New,
       Some(inserted_community.id),
       None,
index a37e19c461cd27ac9f4a6f767003052960620158..a378d3c25368b1b2fd22a6afdf9204acbe8c6ac1 100644 (file)
@@ -21,6 +21,8 @@ pub struct User_ {
   pub updated: Option<chrono::NaiveDateTime>,
   pub show_nsfw: bool,
   pub theme: String,
+  pub default_sort_type: i16,
+  pub default_listing_type: i16,
 }
 
 #[derive(Insertable, AsChangeset, Clone)]
@@ -36,6 +38,8 @@ pub struct UserForm {
   pub updated: Option<chrono::NaiveDateTime>,
   pub show_nsfw: bool,
   pub theme: String,
+  pub default_sort_type: i16,
+  pub default_listing_type: i16,
 }
 
 impl Crud<UserForm> for User_ {
@@ -77,6 +81,8 @@ pub struct Claims {
   pub iss: String,
   pub show_nsfw: bool,
   pub theme: String,
+  pub default_sort_type: i16,
+  pub default_listing_type: i16,
 }
 
 impl Claims {
@@ -98,6 +104,8 @@ impl User_ {
       iss: self.fedi_name.to_owned(),
       show_nsfw: self.show_nsfw,
       theme: self.theme.to_owned(),
+      default_sort_type: self.default_sort_type,
+      default_listing_type: self.default_listing_type,
     };
     encode(
       &Header::default(),
@@ -146,6 +154,8 @@ mod tests {
       updated: None,
       show_nsfw: false,
       theme: "darkly".into(),
+      default_sort_type: SortType::Hot as i16,
+      default_listing_type: ListingType::Subscribed as i16,
     };
 
     let inserted_user = User_::create(&conn, &new_user).unwrap();
@@ -164,6 +174,8 @@ mod tests {
       updated: None,
       show_nsfw: false,
       theme: "darkly".into(),
+      default_sort_type: SortType::Hot as i16,
+      default_listing_type: ListingType::Subscribed as i16,
     };
 
     let read_user = User_::read(&conn, inserted_user.id).unwrap();
index d4dc0a51a69e2d82d6b342d66c2057ba1ad9754c..668d28fcc3203840226a09033f258730d2b35167 100644 (file)
@@ -73,6 +73,8 @@ mod tests {
       updated: None,
       show_nsfw: false,
       theme: "darkly".into(),
+      default_sort_type: SortType::Hot as i16,
+      default_listing_type: ListingType::Subscribed as i16,
     };
 
     let inserted_user = User_::create(&conn, &new_user).unwrap();
@@ -88,6 +90,8 @@ mod tests {
       updated: None,
       show_nsfw: false,
       theme: "darkly".into(),
+      default_sort_type: SortType::Hot as i16,
+      default_listing_type: ListingType::Subscribed as i16,
     };
 
     let inserted_recipient = User_::create(&conn, &recipient_form).unwrap();
index 9111c8e30504af22eae45243cffc4c93d045da56..e087e20e1d4973b4b17f85d72141ac823d914b52 100644 (file)
@@ -255,6 +255,8 @@ table! {
         updated -> Nullable<Timestamp>,
         show_nsfw -> Bool,
         theme -> Varchar,
+        default_sort_type -> Int2,
+        default_listing_type -> Int2,
     }
 }
 
index aeca8c0c1518c7465aedc3ec9b4fd57a452e2c01..1927421990a9eab92a11eec0d0b12d1d2cfacb96 100644 (file)
@@ -136,7 +136,7 @@ impl ChatServer {
     let conn = establish_connection();
     let posts = PostView::list(
       &conn,
-      PostListingType::Community,
+      ListingType::Community,
       &SortType::New,
       Some(*community_id),
       None,
index efeaa1b326d9998cbc344222dd609560f74774a2..8f36178c86b9e0678383d2c3700f73784872d118 100644 (file)
@@ -15,7 +15,7 @@ import {
   GetPostsResponse,
   CreatePostLikeResponse,
 } from '../interfaces';
-import { WebSocketService } from '../services';
+import { WebSocketService, UserService } from '../services';
 import { PostListings } from './post-listings';
 import { SortSelect } from './sort-select';
 import { Sidebar } from './sidebar';
@@ -72,6 +72,8 @@ export class Community extends Component<any, State> {
   getSortTypeFromProps(props: any): SortType {
     return props.match.params.sort
       ? routeSortTypeToEnum(props.match.params.sort)
+      : UserService.Instance.user
+      ? UserService.Instance.user.default_sort_type
       : SortType.Hot;
   }
 
diff --git a/ui/src/components/listing-type-select.tsx b/ui/src/components/listing-type-select.tsx
new file mode 100644 (file)
index 0000000..d583b93
--- /dev/null
@@ -0,0 +1,68 @@
+import { Component, linkEvent } from 'inferno';
+import { ListingType } from '../interfaces';
+import { UserService } from '../services';
+
+import { i18n } from '../i18next';
+
+interface ListingTypeSelectProps {
+  type_: ListingType;
+  onChange?(val: ListingType): any;
+}
+
+interface ListingTypeSelectState {
+  type_: ListingType;
+}
+
+export class ListingTypeSelect extends Component<
+  ListingTypeSelectProps,
+  ListingTypeSelectState
+> {
+  private emptyState: ListingTypeSelectState = {
+    type_: this.props.type_,
+  };
+
+  constructor(props: any, context: any) {
+    super(props, context);
+    this.state = this.emptyState;
+  }
+
+  render() {
+    return (
+      <div class="btn-group btn-group-toggle">
+        <label
+          className={`btn btn-sm btn-secondary 
+            ${this.state.type_ == ListingType.Subscribed && 'active'}
+            ${UserService.Instance.user == undefined ? 'disabled' : 'pointer'}
+          `}
+        >
+          <input
+            type="radio"
+            value={ListingType.Subscribed}
+            checked={this.state.type_ == ListingType.Subscribed}
+            onChange={linkEvent(this, this.handleTypeChange)}
+            disabled={UserService.Instance.user == undefined}
+          />
+          {i18n.t('subscribed')}
+        </label>
+        <label
+          className={`pointer btn btn-sm btn-secondary ${this.state.type_ ==
+            ListingType.All && 'active'}`}
+        >
+          <input
+            type="radio"
+            value={ListingType.All}
+            checked={this.state.type_ == ListingType.All}
+            onChange={linkEvent(this, this.handleTypeChange)}
+          />
+          {i18n.t('all')}
+        </label>
+      </div>
+    );
+  }
+
+  handleTypeChange(i: ListingTypeSelect, event: any) {
+    i.state.type_ = Number(event.target.value);
+    i.setState(i.state);
+    i.props.onChange(i.state.type_);
+  }
+}
index e4ff5a509dadfdc1aae32aa2b572e0a4aa543333..c871db72bca3fa1fe19c1a11d52267213b5fc075 100644 (file)
@@ -21,6 +21,7 @@ import {
 import { WebSocketService, UserService } from '../services';
 import { PostListings } from './post-listings';
 import { SortSelect } from './sort-select';
+import { ListingTypeSelect } from './listing-type-select';
 import { SiteForm } from './site-form';
 import {
   msgOp,
@@ -81,13 +82,15 @@ export class Main extends Component<any, MainState> {
     return props.match.params.type
       ? routeListingTypeToEnum(props.match.params.type)
       : UserService.Instance.user
-      ? ListingType.Subscribed
+      ? UserService.Instance.user.default_listing_type
       : ListingType.All;
   }
 
   getSortTypeFromProps(props: any): SortType {
     return props.match.params.sort
       ? routeSortTypeToEnum(props.match.params.sort)
+      : UserService.Instance.user
+      ? UserService.Instance.user.default_sort_type
       : SortType.Hot;
   }
 
@@ -101,6 +104,7 @@ export class Main extends Component<any, MainState> {
     this.state = this.emptyState;
     this.handleEditCancel = this.handleEditCancel.bind(this);
     this.handleSortChange = this.handleSortChange.bind(this);
+    this.handleTypeChange = this.handleTypeChange.bind(this);
 
     this.subscription = WebSocketService.Instance.subject
       .pipe(
@@ -423,35 +427,10 @@ export class Main extends Component<any, MainState> {
   selects() {
     return (
       <div className="mb-3">
-        <div class="btn-group btn-group-toggle">
-          <label
-            className={`btn btn-sm btn-secondary 
-            ${this.state.type_ == ListingType.Subscribed && 'active'}
-            ${UserService.Instance.user == undefined ? 'disabled' : 'pointer'}
-            `}
-          >
-            <input
-              type="radio"
-              value={ListingType.Subscribed}
-              checked={this.state.type_ == ListingType.Subscribed}
-              onChange={linkEvent(this, this.handleTypeChange)}
-              disabled={UserService.Instance.user == undefined}
-            />
-            {i18n.t('subscribed')}
-          </label>
-          <label
-            className={`pointer btn btn-sm btn-secondary ${this.state.type_ ==
-              ListingType.All && 'active'}`}
-          >
-            <input
-              type="radio"
-              value={ListingType.All}
-              checked={this.state.type_ == ListingType.All}
-              onChange={linkEvent(this, this.handleTypeChange)}
-            />
-            {i18n.t('all')}
-          </label>
-        </div>
+        <ListingTypeSelect
+          type_={this.state.type_}
+          onChange={this.handleTypeChange}
+        />
         <span class="ml-2">
           <SortSelect sort={this.state.sort} onChange={this.handleSortChange} />
         </span>
@@ -527,13 +506,13 @@ export class Main extends Component<any, MainState> {
     window.scrollTo(0, 0);
   }
 
-  handleTypeChange(i: Main, event: any) {
-    i.state.type_ = Number(event.target.value);
-    i.state.page = 1;
-    i.state.loading = true;
-    i.setState(i.state);
-    i.updateUrl();
-    i.fetchPosts();
+  handleTypeChange(val: ListingType) {
+    this.state.type_ = val;
+    this.state.page = 1;
+    this.state.loading = true;
+    this.setState(this.state);
+    this.updateUrl();
+    this.fetchPosts();
     window.scrollTo(0, 0);
   }
 
index 671997b917ba2bcc1395cbf303c7f4da9f61f04c..3006afc43b0b32193b3c55877719d85f7f086ac9 100644 (file)
@@ -9,6 +9,7 @@ import {
   CommunityUser,
   GetUserDetailsForm,
   SortType,
+  ListingType,
   UserDetailsResponse,
   UserView,
   CommentResponse,
@@ -29,6 +30,7 @@ import {
 } from '../utils';
 import { PostListing } from './post-listing';
 import { SortSelect } from './sort-select';
+import { ListingTypeSelect } from './listing-type-select';
 import { CommentNodes } from './comment-nodes';
 import { MomentTime } from './moment-time';
 import { i18n } from '../i18next';
@@ -90,6 +92,8 @@ export class User extends Component<any, UserState> {
     userSettingsForm: {
       show_nsfw: null,
       theme: null,
+      default_sort_type: null,
+      default_listing_type: null,
       auth: null,
     },
     userSettingsLoading: null,
@@ -105,6 +109,12 @@ export class User extends Component<any, UserState> {
 
     this.state = this.emptyState;
     this.handleSortChange = this.handleSortChange.bind(this);
+    this.handleUserSettingsSortTypeChange = this.handleUserSettingsSortTypeChange.bind(
+      this
+    );
+    this.handleUserSettingsListingTypeChange = this.handleUserSettingsListingTypeChange.bind(
+      this
+    );
 
     this.state.user_id = Number(this.props.match.params.id);
     this.state.username = this.props.match.params.username;
@@ -403,6 +413,32 @@ export class User extends Component<any, UserState> {
                   </select>
                 </div>
               </div>
+              <form className="form-group">
+                <div class="col-12">
+                  <label>
+                    <T i18nKey="sort_type" class="mr-2">
+                      #
+                    </T>
+                  </label>
+                  <ListingTypeSelect
+                    type_={this.state.userSettingsForm.default_listing_type}
+                    onChange={this.handleUserSettingsListingTypeChange}
+                  />
+                </div>
+              </form>
+              <form className="form-group">
+                <div class="col-12">
+                  <label>
+                    <T i18nKey="type" class="mr-2">
+                      #
+                    </T>
+                  </label>
+                  <SortSelect
+                    sort={this.state.userSettingsForm.default_sort_type}
+                    onChange={this.handleUserSettingsSortTypeChange}
+                  />
+                </div>
+              </form>
               <div class="form-group">
                 <div class="col-12">
                   <div class="form-check">
@@ -421,9 +457,12 @@ export class User extends Component<any, UserState> {
                   </div>
                 </div>
               </div>
-              <div class="form-group row mb-0">
+              <div class="form-group">
                 <div class="col-12">
-                  <button type="submit" class="btn btn-secondary mr-4">
+                  <button
+                    type="submit"
+                    class="btn btn-block btn-secondary mr-4"
+                  >
                     {this.state.userSettingsLoading ? (
                       <svg class="icon icon-spinner spin">
                         <use xlinkHref="#icon-spinner"></use>
@@ -432,8 +471,13 @@ export class User extends Component<any, UserState> {
                       capitalizeFirstLetter(i18n.t('save'))
                     )}
                   </button>
+                </div>
+              </div>
+              <hr />
+              <div class="form-group mb-0">
+                <div class="col-12">
                   <button
-                    class="btn btn-danger"
+                    class="btn btn-block btn-danger"
                     onClick={linkEvent(
                       this,
                       this.handleDeleteAccountShowConfirmToggle
@@ -620,6 +664,16 @@ export class User extends Component<any, UserState> {
     i.setState(i.state);
   }
 
+  handleUserSettingsSortTypeChange(val: SortType) {
+    this.state.userSettingsForm.default_sort_type = val;
+    this.setState(this.state);
+  }
+
+  handleUserSettingsListingTypeChange(val: ListingType) {
+    this.state.userSettingsForm.default_listing_type = val;
+    this.setState(this.state);
+  }
+
   handleUserSettingsSubmit(i: User, event: any) {
     event.preventDefault();
     i.state.userSettingsLoading = true;
@@ -670,6 +724,10 @@ export class User extends Component<any, UserState> {
         this.state.userSettingsForm.theme = UserService.Instance.user.theme
           ? UserService.Instance.user.theme
           : 'darkly';
+        this.state.userSettingsForm.default_sort_type =
+          UserService.Instance.user.default_sort_type;
+        this.state.userSettingsForm.default_listing_type =
+          UserService.Instance.user.default_listing_type;
       }
       document.title = `/u/${this.state.user.name} - ${WebSocketService.Instance.site.name}`;
       window.scrollTo(0, 0);
index 4056e05d0f4c1256c23a569e3ff1a344adca71e5..2f75efd9ba5ec475b96ce3b514ff61c73e9eeeca 100644 (file)
@@ -75,6 +75,8 @@ export interface User {
   username: string;
   show_nsfw: boolean;
   theme: string;
+  default_sort_type: SortType;
+  default_listing_type: ListingType;
 }
 
 export interface UserView {
@@ -463,6 +465,8 @@ export interface LoginResponse {
 export interface UserSettingsForm {
   show_nsfw: boolean;
   theme: string;
+  default_sort_type: SortType;
+  default_listing_type: ListingType;
   auth: string;
 }