From 3a4505aaab4a3a7a809bacf18af50ac3bec9412d Mon Sep 17 00:00:00 2001 From: Dessalines Date: Sat, 19 Oct 2019 23:24:26 -0700 Subject: [PATCH 1/4] Update translation report. --- README.md | 16 ++++++++-------- ui/package.json | 5 ++--- 2 files changed, 10 insertions(+), 11 deletions(-) diff --git a/README.md b/README.md index 80c4993c8..f5b3d77f5 100644 --- a/README.md +++ b/README.md @@ -201,14 +201,14 @@ If you'd like to add translations, take a look a look at the [english translatio lang | done | missing --- | --- | --- -de | 82% | cross_posts,cross_post,users,number_of_communities,preview,upload_image,formatting_help,view_source,sticky,unsticky,settings,stickied,delete_account,delete_account_confirm,banned,creator,number_online,subscribed,expires,recent_comments,nsfw,show_nsfw,theme,crypto,monero,joined,by,to,transfer_community,transfer_site,are_you_sure,yes,no -eo | 91% | number_of_communities,preview,upload_image,formatting_help,view_source,sticky,unsticky,stickied,delete_account,delete_account_confirm,banned,creator,number_online,theme,are_you_sure,yes,no -es | 100% | -fr | 100% | -nl | 93% | preview,upload_image,formatting_help,view_source,sticky,unsticky,stickied,delete_account,delete_account_confirm,banned,creator,number_online,theme -ru | 86% | cross_posts,cross_post,number_of_communities,preview,upload_image,formatting_help,view_source,sticky,unsticky,stickied,delete_account,delete_account_confirm,banned,creator,number_online,recent_comments,theme,monero,by,to,transfer_community,transfer_site,are_you_sure,yes,no -sv | 100% | -zh | 84% | cross_posts,cross_post,users,number_of_communities,preview,upload_image,formatting_help,view_source,sticky,unsticky,settings,stickied,delete_account,delete_account_confirm,banned,creator,number_online,recent_comments,nsfw,show_nsfw,theme,monero,by,to,transfer_community,transfer_site,are_you_sure,yes,no +de | 81% | cross_posts,cross_post,users,number_of_communities,preview,upload_image,formatting_help,view_source,sticky,unsticky,settings,stickied,delete_account,delete_account_confirm,banned,creator,number_online,subscribed,replies,mentions,expires,recent_comments,nsfw,show_nsfw,theme,crypto,monero,joined,by,to,transfer_community,transfer_site,are_you_sure,yes,no +eo | 90% | number_of_communities,preview,upload_image,formatting_help,view_source,sticky,unsticky,stickied,delete_account,delete_account_confirm,banned,creator,number_online,replies,mentions,theme,are_you_sure,yes,no +es | 99% | replies,mentions +fr | 99% | replies,mentions +nl | 92% | preview,upload_image,formatting_help,view_source,sticky,unsticky,stickied,delete_account,delete_account_confirm,banned,creator,number_online,replies,mentions,theme +ru | 86% | cross_posts,cross_post,number_of_communities,preview,upload_image,formatting_help,view_source,sticky,unsticky,stickied,delete_account,delete_account_confirm,banned,creator,number_online,replies,mentions,recent_comments,theme,monero,by,to,transfer_community,transfer_site,are_you_sure,yes,no +sv | 99% | replies,mentions +zh | 83% | cross_posts,cross_post,users,number_of_communities,preview,upload_image,formatting_help,view_source,sticky,unsticky,settings,stickied,delete_account,delete_account_confirm,banned,creator,number_online,replies,mentions,recent_comments,nsfw,show_nsfw,theme,monero,by,to,transfer_community,transfer_site,are_you_sure,yes,no If you'd like to update this report, run: diff --git a/ui/package.json b/ui/package.json index d64946b24..f20c9ab0e 100644 --- a/ui/package.json +++ b/ui/package.json @@ -22,6 +22,7 @@ "classcat": "^1.1.3", "dotenv": "^6.1.0", "emoji-short-name": "^0.1.0", + "husky": "^3.0.9", "i18next": "^17.0.9", "inferno": "^7.0.1", "inferno-i18next": "nimbusec-oss/inferno-i18next", @@ -45,7 +46,6 @@ "eslint-plugin-inferno": "^7.14.3", "eslint-plugin-jane": "^7.0.0", "fuse-box": "^3.1.3", - "husky": "^3.0.9", "lint-staged": "^9.4.2", "sortpack": "^2.0.1", "ts-transform-classcat": "^0.0.2", @@ -58,8 +58,7 @@ "engineStrict": true, "husky": { "hooks": { - "pre-commit": "lint-staged", - "pre-push": "yarn run lint" + "pre-commit": "yarn run lint && lint-staged" } }, "lint-staged": { From a7dedaf273b6fd2ebd9c9b8b9d6a7d227f376797 Mon Sep 17 00:00:00 2001 From: Dessalines Date: Sun, 20 Oct 2019 17:49:13 -0700 Subject: [PATCH 2/4] Externalize into sort-select component. - Fixes #311 --- ui/package.json | 16 ++----- ui/src/components/community.tsx | 56 +++++++------------------ ui/src/components/inbox.tsx | 44 ++++++-------------- ui/src/components/main.tsx | 50 ++++++---------------- ui/src/components/search.tsx | 46 +++++++-------------- ui/src/components/sort-select.tsx | 69 +++++++++++++++++++++++++++++++ ui/src/components/user.tsx | 55 +++++++++--------------- ui/src/utils.ts | 2 + 8 files changed, 148 insertions(+), 190 deletions(-) create mode 100644 ui/src/components/sort-select.tsx diff --git a/ui/package.json b/ui/package.json index f20c9ab0e..f816b4f62 100644 --- a/ui/package.json +++ b/ui/package.json @@ -58,23 +58,13 @@ "engineStrict": true, "husky": { "hooks": { - "pre-commit": "yarn run lint && lint-staged" + "pre-commit": "lint-staged" } }, "lint-staged": { - "*.js": [ + "*.{ts,tsx,js}": [ "prettier --write", - "yarn run lint", - "git add" - ], - "*.ts": [ - "prettier --write", - "yarn run lint", - "git add" - ], - "*.tsx": [ - "prettier --write", - "yarn run lint", + "eslint --fix", "git add" ], "package.json": [ diff --git a/ui/src/components/community.tsx b/ui/src/components/community.tsx index 434f45305..efeaa1b32 100644 --- a/ui/src/components/community.tsx +++ b/ui/src/components/community.tsx @@ -17,6 +17,7 @@ import { } from '../interfaces'; import { WebSocketService } from '../services'; import { PostListings } from './post-listings'; +import { SortSelect } from './sort-select'; import { Sidebar } from './sidebar'; import { msgOp, @@ -82,6 +83,7 @@ export class Community extends Component { super(props, context); this.state = this.emptyState; + this.handleSortChange = this.handleSortChange.bind(this); this.subscription = WebSocketService.Instance.subject .pipe( @@ -112,10 +114,13 @@ export class Community extends Component { // Necessary for back button for some reason componentWillReceiveProps(nextProps: any) { - if (nextProps.history.action == 'POP') { - this.state = this.emptyState; + if ( + nextProps.history.action == 'POP' || + nextProps.history.action == 'PUSH' + ) { this.state.sort = this.getSortTypeFromProps(nextProps); this.state.page = this.getPageFromProps(nextProps); + this.setState(this.state); this.fetchPosts(); } } @@ -164,38 +169,8 @@ export class Community extends Component { selects() { return ( -
- +
+
); } @@ -237,12 +212,13 @@ export class Community extends Component { window.scrollTo(0, 0); } - handleSortChange(i: Community, event: any) { - i.state.sort = Number(event.target.value); - i.state.page = 1; - i.setState(i.state); - i.updateUrl(); - i.fetchPosts(); + handleSortChange(val: SortType) { + this.state.sort = val; + this.state.page = 1; + this.state.loading = true; + this.setState(this.state); + this.updateUrl(); + this.fetchPosts(); window.scrollTo(0, 0); } diff --git a/ui/src/components/inbox.tsx b/ui/src/components/inbox.tsx index 6e961b171..bcde9363b 100644 --- a/ui/src/components/inbox.tsx +++ b/ui/src/components/inbox.tsx @@ -16,6 +16,7 @@ import { import { WebSocketService, UserService } from '../services'; import { msgOp } from '../utils'; import { CommentNodes } from './comment-nodes'; +import { SortSelect } from './sort-select'; import { i18n } from '../i18next'; import { T } from 'inferno-i18next'; @@ -54,6 +55,7 @@ export class Inbox extends Component { super(props, context); this.state = this.emptyState; + this.handleSortChange = this.handleSortChange.bind(this); this.subscription = WebSocketService.Instance.subject .pipe( @@ -153,33 +155,11 @@ export class Inbox extends Component { # - +
); } @@ -300,11 +280,11 @@ export class Inbox extends Component { WebSocketService.Instance.getUserMentions(userMentionsForm); } - handleSortChange(i: Inbox, event: any) { - i.state.sort = Number(event.target.value); - i.state.page = 1; - i.setState(i.state); - i.refetch(); + handleSortChange(val: SortType) { + this.state.sort = val; + this.state.page = 1; + this.setState(this.state); + this.refetch(); } markAllAsRead() { diff --git a/ui/src/components/main.tsx b/ui/src/components/main.tsx index b1ddef4ce..e4ff5a509 100644 --- a/ui/src/components/main.tsx +++ b/ui/src/components/main.tsx @@ -20,6 +20,7 @@ import { } from '../interfaces'; import { WebSocketService, UserService } from '../services'; import { PostListings } from './post-listings'; +import { SortSelect } from './sort-select'; import { SiteForm } from './site-form'; import { msgOp, @@ -99,6 +100,7 @@ export class Main extends Component { this.state = this.emptyState; this.handleEditCancel = this.handleEditCancel.bind(this); + this.handleSortChange = this.handleSortChange.bind(this); this.subscription = WebSocketService.Instance.subject .pipe( @@ -450,37 +452,9 @@ export class Main extends Component { {i18n.t('all')} - + + + ); } @@ -543,13 +517,13 @@ export class Main extends Component { window.scrollTo(0, 0); } - handleSortChange(i: Main, event: any) { - i.state.sort = Number(event.target.value); - i.state.page = 1; - i.state.loading = true; - i.setState(i.state); - i.updateUrl(); - i.fetchPosts(); + handleSortChange(val: SortType) { + this.state.sort = val; + this.state.page = 1; + this.state.loading = true; + this.setState(this.state); + this.updateUrl(); + this.fetchPosts(); window.scrollTo(0, 0); } diff --git a/ui/src/components/search.tsx b/ui/src/components/search.tsx index 68b4ee88e..bba7c5adc 100644 --- a/ui/src/components/search.tsx +++ b/ui/src/components/search.tsx @@ -21,6 +21,7 @@ import { routeSortTypeToEnum, } from '../utils'; import { PostListing } from './post-listing'; +import { SortSelect } from './sort-select'; import { CommentNodes } from './comment-nodes'; import { i18n } from '../i18next'; import { T } from 'inferno-i18next'; @@ -76,6 +77,7 @@ export class Search extends Component { super(props, context); this.state = this.emptyState; + this.handleSortChange = this.handleSortChange.bind(this); this.subscription = WebSocketService.Instance.subject .pipe( @@ -203,33 +205,13 @@ export class Search extends Component { # - + + + ); } @@ -438,11 +420,11 @@ export class Search extends Component { } } - handleSortChange(i: Search, event: any) { - i.state.sort = Number(event.target.value); - i.state.page = 1; - i.setState(i.state); - i.updateUrl(); + handleSortChange(val: SortType) { + this.state.sort = val; + this.state.page = 1; + this.setState(this.state); + this.updateUrl(); } handleTypeChange(i: Search, event: any) { diff --git a/ui/src/components/sort-select.tsx b/ui/src/components/sort-select.tsx new file mode 100644 index 000000000..a3ef0f8d4 --- /dev/null +++ b/ui/src/components/sort-select.tsx @@ -0,0 +1,69 @@ +import { Component, linkEvent } from 'inferno'; +import { SortType } from '../interfaces'; + +import { T } from 'inferno-i18next'; + +interface SortSelectProps { + sort: SortType; + onChange?(val: SortType): any; + hideHot?: boolean; +} + +interface SortSelectState { + sort: SortType; +} + +export class SortSelect extends Component { + private emptyState: SortSelectState = { + sort: this.props.sort, + }; + + constructor(props: any, context: any) { + super(props, context); + this.state = this.emptyState; + } + + render() { + return ( + + ); + } + + handleSortChange(i: SortSelect, event: any) { + i.state.sort = Number(event.target.value); + i.setState(i.state); + i.props.onChange(i.state.sort); + } +} diff --git a/ui/src/components/user.tsx b/ui/src/components/user.tsx index 393d91d5a..671997b91 100644 --- a/ui/src/components/user.tsx +++ b/ui/src/components/user.tsx @@ -28,6 +28,7 @@ import { setTheme, } from '../utils'; import { PostListing } from './post-listing'; +import { SortSelect } from './sort-select'; import { CommentNodes } from './comment-nodes'; import { MomentTime } from './moment-time'; import { i18n } from '../i18next'; @@ -103,6 +104,7 @@ export class User extends Component { super(props, context); this.state = this.emptyState; + this.handleSortChange = this.handleSortChange.bind(this); this.state.user_id = Number(this.props.match.params.id); this.state.username = this.props.match.params.username; @@ -154,11 +156,14 @@ export class User extends Component { // Necessary for back button for some reason componentWillReceiveProps(nextProps: any) { - if (nextProps.history.action == 'POP') { - this.state = this.emptyState; + if ( + nextProps.history.action == 'POP' || + nextProps.history.action == 'PUSH' + ) { this.state.view = this.getViewFromProps(nextProps); this.state.sort = this.getSortTypeFromProps(nextProps); this.state.page = this.getPageFromProps(nextProps); + this.setState(this.state); this.refetch(); } } @@ -219,33 +224,13 @@ export class User extends Component { # - + + + ); } @@ -608,12 +593,12 @@ export class User extends Component { WebSocketService.Instance.getUserDetails(form); } - handleSortChange(i: User, event: any) { - i.state.sort = Number(event.target.value); - i.state.page = 1; - i.setState(i.state); - i.updateUrl(); - i.refetch(); + handleSortChange(val: SortType) { + this.state.sort = val; + this.state.page = 1; + this.setState(this.state); + this.updateUrl(); + this.refetch(); } handleViewChange(i: User, event: any) { diff --git a/ui/src/utils.ts b/ui/src/utils.ts index ce221e325..867ff91e6 100644 --- a/ui/src/utils.ts +++ b/ui/src/utils.ts @@ -166,6 +166,8 @@ export function routeSortTypeToEnum(sort: string): SortType { return SortType.TopWeek; } else if (sort == 'topmonth') { return SortType.TopMonth; + } else if (sort == 'topyear') { + return SortType.TopYear; } else if (sort == 'topall') { return SortType.TopAll; } From 90ce1f1a3fca5c8d8a13e91f991b23ecb77f1faf Mon Sep 17 00:00:00 2001 From: Dessalines Date: Sun, 20 Oct 2019 21:21:54 -0700 Subject: [PATCH 3/4] Adding default sort / filter into user settings. - Fixes #295 --- .../down.sql | 2 + .../up.sql | 2 + server/src/api/post.rs | 2 +- server/src/api/site.rs | 6 +- server/src/api/user.rs | 16 ++++- server/src/apub.rs | 3 + server/src/db/comment.rs | 2 + server/src/db/comment_view.rs | 2 + server/src/db/community.rs | 2 + server/src/db/mod.rs | 7 ++ server/src/db/moderator.rs | 4 ++ server/src/db/post.rs | 2 + server/src/db/post_view.rs | 17 ++--- server/src/db/user.rs | 12 ++++ server/src/db/user_mention.rs | 4 ++ server/src/schema.rs | 2 + server/src/websocket/server.rs | 2 +- ui/src/components/community.tsx | 4 +- ui/src/components/listing-type-select.tsx | 68 +++++++++++++++++++ ui/src/components/main.tsx | 53 +++++---------- ui/src/components/user.tsx | 64 ++++++++++++++++- ui/src/interfaces.ts | 4 ++ 22 files changed, 220 insertions(+), 60 deletions(-) create mode 100644 server/migrations/2019-10-21-011237_add_default_sorts/down.sql create mode 100644 server/migrations/2019-10-21-011237_add_default_sorts/up.sql create mode 100644 ui/src/components/listing-type-select.tsx 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 index 000000000..238c9e796 --- /dev/null +++ b/server/migrations/2019-10-21-011237_add_default_sorts/down.sql @@ -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 index 000000000..4bb960094 --- /dev/null +++ b/server/migrations/2019-10-21-011237_add_default_sorts/up.sql @@ -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; diff --git a/server/src/api/post.rs b/server/src/api/post.rs index d53d2064a..5df42990a 100644 --- a/server/src/api/post.rs +++ b/server/src/api/post.rs @@ -235,7 +235,7 @@ impl Perform for Oper { 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( diff --git a/server/src/api/site.rs b/server/src/api/site.rs index 40b1592dd..618295fca 100644 --- a/server/src/api/site.rs +++ b/server/src/api/site.rs @@ -321,7 +321,7 @@ impl Perform for Oper { SearchType::Posts => { posts = PostView::list( &conn, - PostListingType::All, + ListingType::All, &sort, data.community_id, None, @@ -365,7 +365,7 @@ impl Perform for Oper { SearchType::All => { posts = PostView::list( &conn, - PostListingType::All, + ListingType::All, &sort, data.community_id, None, @@ -403,7 +403,7 @@ impl Perform for Oper { SearchType::Url => { posts = PostView::list( &conn, - PostListingType::All, + ListingType::All, &sort, data.community_id, None, diff --git a/server/src/api/user.rs b/server/src/api/user.rs index 563ae0a22..5ac2b4321 100644 --- a/server/src/api/user.rs +++ b/server/src/api/user.rs @@ -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 for Oper { 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 for Oper { 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 for Oper { let posts = if data.saved_only { PostView::list( &conn, - PostListingType::All, + ListingType::All, &sort, data.community_id, None, @@ -362,7 +368,7 @@ impl Perform for Oper { } else { PostView::list( &conn, - PostListingType::All, + ListingType::All, &sort, data.community_id, Some(user_details_id), @@ -453,6 +459,8 @@ impl Perform for Oper { 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 for Oper { 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 for Oper { // Posts let posts = PostView::list( &conn, - PostListingType::All, + ListingType::All, &SortType::New, None, Some(user_id), diff --git a/server/src/apub.rs b/server/src/apub.rs index 958a8df18..3c7202b27 100644 --- a/server/src/apub.rs +++ b/server/src/apub.rs @@ -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(); diff --git a/server/src/db/comment.rs b/server/src/db/comment.rs index 32aa4de92..64532b838 100644 --- a/server/src/db/comment.rs +++ b/server/src/db/comment.rs @@ -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(); diff --git a/server/src/db/comment_view.rs b/server/src/db/comment_view.rs index 88190464c..9f7544731 100644 --- a/server/src/db/comment_view.rs +++ b/server/src/db/comment_view.rs @@ -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(); diff --git a/server/src/db/community.rs b/server/src/db/community.rs index 53c238bd3..bfc6089bc 100644 --- a/server/src/db/community.rs +++ b/server/src/db/community.rs @@ -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(); diff --git a/server/src/db/mod.rs b/server/src/db/mod.rs index ac3c3ae33..2045692d5 100644 --- a/server/src/db/mod.rs +++ b/server/src/db/mod.rs @@ -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, diff --git a/server/src/db/moderator.rs b/server/src/db/moderator.rs index 82e0a4971..b04c6c623 100644 --- a/server/src/db/moderator.rs +++ b/server/src/db/moderator.rs @@ -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(); diff --git a/server/src/db/post.rs b/server/src/db/post.rs index 1bc6e11e6..f185bd754 100644 --- a/server/src/db/post.rs +++ b/server/src/db/post.rs @@ -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(); diff --git a/server/src/db/post_view.rs b/server/src/db/post_view.rs index 1180a7702..51dea027f 100644 --- a/server/src/db/post_view.rs +++ b/server/src/db/post_view.rs @@ -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, for_creator_id: Option, @@ -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, diff --git a/server/src/db/user.rs b/server/src/db/user.rs index a37e19c46..a378d3c25 100644 --- a/server/src/db/user.rs +++ b/server/src/db/user.rs @@ -21,6 +21,8 @@ pub struct User_ { pub updated: Option, 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, pub show_nsfw: bool, pub theme: String, + pub default_sort_type: i16, + pub default_listing_type: i16, } impl Crud 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(); diff --git a/server/src/db/user_mention.rs b/server/src/db/user_mention.rs index d4dc0a51a..668d28fcc 100644 --- a/server/src/db/user_mention.rs +++ b/server/src/db/user_mention.rs @@ -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(); diff --git a/server/src/schema.rs b/server/src/schema.rs index 9111c8e30..e087e20e1 100644 --- a/server/src/schema.rs +++ b/server/src/schema.rs @@ -255,6 +255,8 @@ table! { updated -> Nullable, show_nsfw -> Bool, theme -> Varchar, + default_sort_type -> Int2, + default_listing_type -> Int2, } } diff --git a/server/src/websocket/server.rs b/server/src/websocket/server.rs index aeca8c0c1..192742199 100644 --- a/server/src/websocket/server.rs +++ b/server/src/websocket/server.rs @@ -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, diff --git a/ui/src/components/community.tsx b/ui/src/components/community.tsx index efeaa1b32..8f36178c8 100644 --- a/ui/src/components/community.tsx +++ b/ui/src/components/community.tsx @@ -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 { 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 index 000000000..d583b93cd --- /dev/null +++ b/ui/src/components/listing-type-select.tsx @@ -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 ( +
+ + +
+ ); + } + + handleTypeChange(i: ListingTypeSelect, event: any) { + i.state.type_ = Number(event.target.value); + i.setState(i.state); + i.props.onChange(i.state.type_); + } +} diff --git a/ui/src/components/main.tsx b/ui/src/components/main.tsx index e4ff5a509..c871db72b 100644 --- a/ui/src/components/main.tsx +++ b/ui/src/components/main.tsx @@ -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 { 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 { 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 { selects() { return (
-
- - -
+ @@ -527,13 +506,13 @@ export class Main extends Component { 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); } diff --git a/ui/src/components/user.tsx b/ui/src/components/user.tsx index 671997b91..3006afc43 100644 --- a/ui/src/components/user.tsx +++ b/ui/src/components/user.tsx @@ -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 { 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 { 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 {
+
+
+ + +
+
+
+
+ + +
+
@@ -421,9 +457,12 @@ export class User extends Component {
-
+
- +
+
+
+
+