Externalize into sort-select component.

- Fixes #311
This commit is contained in:
Dessalines 2019-10-20 17:49:13 -07:00
parent 3a4505aaab
commit a7dedaf273
8 changed files with 148 additions and 190 deletions

16
ui/package.json vendored
View File

@ -58,23 +58,13 @@
"engineStrict": true, "engineStrict": true,
"husky": { "husky": {
"hooks": { "hooks": {
"pre-commit": "yarn run lint && lint-staged" "pre-commit": "lint-staged"
} }
}, },
"lint-staged": { "lint-staged": {
"*.js": [ "*.{ts,tsx,js}": [
"prettier --write", "prettier --write",
"yarn run lint", "eslint --fix",
"git add"
],
"*.ts": [
"prettier --write",
"yarn run lint",
"git add"
],
"*.tsx": [
"prettier --write",
"yarn run lint",
"git add" "git add"
], ],
"package.json": [ "package.json": [

View File

@ -17,6 +17,7 @@ import {
} from '../interfaces'; } from '../interfaces';
import { WebSocketService } from '../services'; import { WebSocketService } from '../services';
import { PostListings } from './post-listings'; import { PostListings } from './post-listings';
import { SortSelect } from './sort-select';
import { Sidebar } from './sidebar'; import { Sidebar } from './sidebar';
import { import {
msgOp, msgOp,
@ -82,6 +83,7 @@ export class Community extends Component<any, State> {
super(props, context); super(props, context);
this.state = this.emptyState; this.state = this.emptyState;
this.handleSortChange = this.handleSortChange.bind(this);
this.subscription = WebSocketService.Instance.subject this.subscription = WebSocketService.Instance.subject
.pipe( .pipe(
@ -112,10 +114,13 @@ export class Community extends Component<any, State> {
// Necessary for back button for some reason // Necessary for back button for some reason
componentWillReceiveProps(nextProps: any) { componentWillReceiveProps(nextProps: any) {
if (nextProps.history.action == 'POP') { if (
this.state = this.emptyState; nextProps.history.action == 'POP' ||
nextProps.history.action == 'PUSH'
) {
this.state.sort = this.getSortTypeFromProps(nextProps); this.state.sort = this.getSortTypeFromProps(nextProps);
this.state.page = this.getPageFromProps(nextProps); this.state.page = this.getPageFromProps(nextProps);
this.setState(this.state);
this.fetchPosts(); this.fetchPosts();
} }
} }
@ -164,38 +169,8 @@ export class Community extends Component<any, State> {
selects() { selects() {
return ( return (
<div className="mb-2"> <div class="mb-2">
<select <SortSelect sort={this.state.sort} onChange={this.handleSortChange} />
value={this.state.sort}
onChange={linkEvent(this, this.handleSortChange)}
class="custom-select custom-select-sm w-auto"
>
<option disabled>
<T i18nKey="sort_type">#</T>
</option>
<option value={SortType.Hot}>
<T i18nKey="hot">#</T>
</option>
<option value={SortType.New}>
<T i18nKey="new">#</T>
</option>
<option disabled></option>
<option value={SortType.TopDay}>
<T i18nKey="top_day">#</T>
</option>
<option value={SortType.TopWeek}>
<T i18nKey="week">#</T>
</option>
<option value={SortType.TopMonth}>
<T i18nKey="month">#</T>
</option>
<option value={SortType.TopYear}>
<T i18nKey="year">#</T>
</option>
<option value={SortType.TopAll}>
<T i18nKey="all">#</T>
</option>
</select>
</div> </div>
); );
} }
@ -237,12 +212,13 @@ export class Community extends Component<any, State> {
window.scrollTo(0, 0); window.scrollTo(0, 0);
} }
handleSortChange(i: Community, event: any) { handleSortChange(val: SortType) {
i.state.sort = Number(event.target.value); this.state.sort = val;
i.state.page = 1; this.state.page = 1;
i.setState(i.state); this.state.loading = true;
i.updateUrl(); this.setState(this.state);
i.fetchPosts(); this.updateUrl();
this.fetchPosts();
window.scrollTo(0, 0); window.scrollTo(0, 0);
} }

View File

@ -16,6 +16,7 @@ import {
import { WebSocketService, UserService } from '../services'; import { WebSocketService, UserService } from '../services';
import { msgOp } from '../utils'; import { msgOp } from '../utils';
import { CommentNodes } from './comment-nodes'; import { CommentNodes } from './comment-nodes';
import { SortSelect } from './sort-select';
import { i18n } from '../i18next'; import { i18n } from '../i18next';
import { T } from 'inferno-i18next'; import { T } from 'inferno-i18next';
@ -54,6 +55,7 @@ export class Inbox extends Component<any, InboxState> {
super(props, context); super(props, context);
this.state = this.emptyState; this.state = this.emptyState;
this.handleSortChange = this.handleSortChange.bind(this);
this.subscription = WebSocketService.Instance.subject this.subscription = WebSocketService.Instance.subject
.pipe( .pipe(
@ -153,33 +155,11 @@ export class Inbox extends Component<any, InboxState> {
<T i18nKey="mentions">#</T> <T i18nKey="mentions">#</T>
</option> </option>
</select> </select>
<select <SortSelect
value={this.state.sort} sort={this.state.sort}
onChange={linkEvent(this, this.handleSortChange)} onChange={this.handleSortChange}
class="custom-select custom-select-sm w-auto" hideHot
> />
<option disabled>
<T i18nKey="sort_type">#</T>
</option>
<option value={SortType.New}>
<T i18nKey="new">#</T>
</option>
<option value={SortType.TopDay}>
<T i18nKey="top_day">#</T>
</option>
<option value={SortType.TopWeek}>
<T i18nKey="week">#</T>
</option>
<option value={SortType.TopMonth}>
<T i18nKey="month">#</T>
</option>
<option value={SortType.TopYear}>
<T i18nKey="year">#</T>
</option>
<option value={SortType.TopAll}>
<T i18nKey="all">#</T>
</option>
</select>
</div> </div>
); );
} }
@ -300,11 +280,11 @@ export class Inbox extends Component<any, InboxState> {
WebSocketService.Instance.getUserMentions(userMentionsForm); WebSocketService.Instance.getUserMentions(userMentionsForm);
} }
handleSortChange(i: Inbox, event: any) { handleSortChange(val: SortType) {
i.state.sort = Number(event.target.value); this.state.sort = val;
i.state.page = 1; this.state.page = 1;
i.setState(i.state); this.setState(this.state);
i.refetch(); this.refetch();
} }
markAllAsRead() { markAllAsRead() {

View File

@ -20,6 +20,7 @@ import {
} from '../interfaces'; } from '../interfaces';
import { WebSocketService, UserService } from '../services'; import { WebSocketService, UserService } from '../services';
import { PostListings } from './post-listings'; import { PostListings } from './post-listings';
import { SortSelect } from './sort-select';
import { SiteForm } from './site-form'; import { SiteForm } from './site-form';
import { import {
msgOp, msgOp,
@ -99,6 +100,7 @@ export class Main extends Component<any, MainState> {
this.state = this.emptyState; this.state = this.emptyState;
this.handleEditCancel = this.handleEditCancel.bind(this); this.handleEditCancel = this.handleEditCancel.bind(this);
this.handleSortChange = this.handleSortChange.bind(this);
this.subscription = WebSocketService.Instance.subject this.subscription = WebSocketService.Instance.subject
.pipe( .pipe(
@ -450,37 +452,9 @@ export class Main extends Component<any, MainState> {
{i18n.t('all')} {i18n.t('all')}
</label> </label>
</div> </div>
<select <span class="ml-2">
value={this.state.sort} <SortSelect sort={this.state.sort} onChange={this.handleSortChange} />
onChange={linkEvent(this, this.handleSortChange)} </span>
class="ml-2 custom-select custom-select-sm w-auto"
>
<option disabled>
<T i18nKey="sort_type">#</T>
</option>
<option value={SortType.Hot}>
<T i18nKey="hot">#</T>
</option>
<option value={SortType.New}>
<T i18nKey="new">#</T>
</option>
<option disabled></option>
<option value={SortType.TopDay}>
<T i18nKey="top_day">#</T>
</option>
<option value={SortType.TopWeek}>
<T i18nKey="week">#</T>
</option>
<option value={SortType.TopMonth}>
<T i18nKey="month">#</T>
</option>
<option value={SortType.TopYear}>
<T i18nKey="year">#</T>
</option>
<option value={SortType.TopAll}>
<T i18nKey="all">#</T>
</option>
</select>
</div> </div>
); );
} }
@ -543,13 +517,13 @@ export class Main extends Component<any, MainState> {
window.scrollTo(0, 0); window.scrollTo(0, 0);
} }
handleSortChange(i: Main, event: any) { handleSortChange(val: SortType) {
i.state.sort = Number(event.target.value); this.state.sort = val;
i.state.page = 1; this.state.page = 1;
i.state.loading = true; this.state.loading = true;
i.setState(i.state); this.setState(this.state);
i.updateUrl(); this.updateUrl();
i.fetchPosts(); this.fetchPosts();
window.scrollTo(0, 0); window.scrollTo(0, 0);
} }

View File

@ -21,6 +21,7 @@ import {
routeSortTypeToEnum, routeSortTypeToEnum,
} from '../utils'; } from '../utils';
import { PostListing } from './post-listing'; import { PostListing } from './post-listing';
import { SortSelect } from './sort-select';
import { CommentNodes } from './comment-nodes'; import { CommentNodes } from './comment-nodes';
import { i18n } from '../i18next'; import { i18n } from '../i18next';
import { T } from 'inferno-i18next'; import { T } from 'inferno-i18next';
@ -76,6 +77,7 @@ export class Search extends Component<any, SearchState> {
super(props, context); super(props, context);
this.state = this.emptyState; this.state = this.emptyState;
this.handleSortChange = this.handleSortChange.bind(this);
this.subscription = WebSocketService.Instance.subject this.subscription = WebSocketService.Instance.subject
.pipe( .pipe(
@ -203,33 +205,13 @@ export class Search extends Component<any, SearchState> {
<T i18nKey="users">#</T> <T i18nKey="users">#</T>
</option> </option>
</select> </select>
<select <span class="ml-2">
value={this.state.sort} <SortSelect
onChange={linkEvent(this, this.handleSortChange)} sort={this.state.sort}
class="custom-select custom-select-sm w-auto ml-2" onChange={this.handleSortChange}
> hideHot
<option disabled> />
<T i18nKey="sort_type">#</T> </span>
</option>
<option value={SortType.New}>
<T i18nKey="new">#</T>
</option>
<option value={SortType.TopDay}>
<T i18nKey="top_day">#</T>
</option>
<option value={SortType.TopWeek}>
<T i18nKey="week">#</T>
</option>
<option value={SortType.TopMonth}>
<T i18nKey="month">#</T>
</option>
<option value={SortType.TopYear}>
<T i18nKey="year">#</T>
</option>
<option value={SortType.TopAll}>
<T i18nKey="all">#</T>
</option>
</select>
</div> </div>
); );
} }
@ -438,11 +420,11 @@ export class Search extends Component<any, SearchState> {
} }
} }
handleSortChange(i: Search, event: any) { handleSortChange(val: SortType) {
i.state.sort = Number(event.target.value); this.state.sort = val;
i.state.page = 1; this.state.page = 1;
i.setState(i.state); this.setState(this.state);
i.updateUrl(); this.updateUrl();
} }
handleTypeChange(i: Search, event: any) { handleTypeChange(i: Search, event: any) {

69
ui/src/components/sort-select.tsx vendored Normal file
View File

@ -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<SortSelectProps, SortSelectState> {
private emptyState: SortSelectState = {
sort: this.props.sort,
};
constructor(props: any, context: any) {
super(props, context);
this.state = this.emptyState;
}
render() {
return (
<select
value={this.state.sort}
onChange={linkEvent(this, this.handleSortChange)}
class="custom-select custom-select-sm w-auto"
>
<option disabled>
<T i18nKey="sort_type">#</T>
</option>
{!this.props.hideHot && (
<option value={SortType.Hot}>
<T i18nKey="hot">#</T>
</option>
)}
<option value={SortType.New}>
<T i18nKey="new">#</T>
</option>
<option disabled></option>
<option value={SortType.TopDay}>
<T i18nKey="top_day">#</T>
</option>
<option value={SortType.TopWeek}>
<T i18nKey="week">#</T>
</option>
<option value={SortType.TopMonth}>
<T i18nKey="month">#</T>
</option>
<option value={SortType.TopYear}>
<T i18nKey="year">#</T>
</option>
<option value={SortType.TopAll}>
<T i18nKey="all">#</T>
</option>
</select>
);
}
handleSortChange(i: SortSelect, event: any) {
i.state.sort = Number(event.target.value);
i.setState(i.state);
i.props.onChange(i.state.sort);
}
}

View File

@ -28,6 +28,7 @@ import {
setTheme, setTheme,
} from '../utils'; } from '../utils';
import { PostListing } from './post-listing'; import { PostListing } from './post-listing';
import { SortSelect } from './sort-select';
import { CommentNodes } from './comment-nodes'; import { CommentNodes } from './comment-nodes';
import { MomentTime } from './moment-time'; import { MomentTime } from './moment-time';
import { i18n } from '../i18next'; import { i18n } from '../i18next';
@ -103,6 +104,7 @@ export class User extends Component<any, UserState> {
super(props, context); super(props, context);
this.state = this.emptyState; this.state = this.emptyState;
this.handleSortChange = this.handleSortChange.bind(this);
this.state.user_id = Number(this.props.match.params.id); this.state.user_id = Number(this.props.match.params.id);
this.state.username = this.props.match.params.username; this.state.username = this.props.match.params.username;
@ -154,11 +156,14 @@ export class User extends Component<any, UserState> {
// Necessary for back button for some reason // Necessary for back button for some reason
componentWillReceiveProps(nextProps: any) { componentWillReceiveProps(nextProps: any) {
if (nextProps.history.action == 'POP') { if (
this.state = this.emptyState; nextProps.history.action == 'POP' ||
nextProps.history.action == 'PUSH'
) {
this.state.view = this.getViewFromProps(nextProps); this.state.view = this.getViewFromProps(nextProps);
this.state.sort = this.getSortTypeFromProps(nextProps); this.state.sort = this.getSortTypeFromProps(nextProps);
this.state.page = this.getPageFromProps(nextProps); this.state.page = this.getPageFromProps(nextProps);
this.setState(this.state);
this.refetch(); this.refetch();
} }
} }
@ -219,33 +224,13 @@ export class User extends Component<any, UserState> {
<T i18nKey="saved">#</T> <T i18nKey="saved">#</T>
</option> </option>
</select> </select>
<select <span class="ml-2">
value={this.state.sort} <SortSelect
onChange={linkEvent(this, this.handleSortChange)} sort={this.state.sort}
class="custom-select custom-select-sm w-auto ml-2" onChange={this.handleSortChange}
> hideHot
<option disabled> />
<T i18nKey="sort_type">#</T> </span>
</option>
<option value={SortType.New}>
<T i18nKey="new">#</T>
</option>
<option value={SortType.TopDay}>
<T i18nKey="top_day">#</T>
</option>
<option value={SortType.TopWeek}>
<T i18nKey="week">#</T>
</option>
<option value={SortType.TopMonth}>
<T i18nKey="month">#</T>
</option>
<option value={SortType.TopYear}>
<T i18nKey="year">#</T>
</option>
<option value={SortType.TopAll}>
<T i18nKey="all">#</T>
</option>
</select>
</div> </div>
); );
} }
@ -608,12 +593,12 @@ export class User extends Component<any, UserState> {
WebSocketService.Instance.getUserDetails(form); WebSocketService.Instance.getUserDetails(form);
} }
handleSortChange(i: User, event: any) { handleSortChange(val: SortType) {
i.state.sort = Number(event.target.value); this.state.sort = val;
i.state.page = 1; this.state.page = 1;
i.setState(i.state); this.setState(this.state);
i.updateUrl(); this.updateUrl();
i.refetch(); this.refetch();
} }
handleViewChange(i: User, event: any) { handleViewChange(i: User, event: any) {

2
ui/src/utils.ts vendored
View File

@ -166,6 +166,8 @@ export function routeSortTypeToEnum(sort: string): SortType {
return SortType.TopWeek; return SortType.TopWeek;
} else if (sort == 'topmonth') { } else if (sort == 'topmonth') {
return SortType.TopMonth; return SortType.TopMonth;
} else if (sort == 'topyear') {
return SortType.TopYear;
} else if (sort == 'topall') { } else if (sort == 'topall') {
return SortType.TopAll; return SortType.TopAll;
} }