ui.components: fix ts types, move user pagination to user details

This commit is contained in:
derek 2020-07-14 01:13:43 -04:00
parent 563a66b053
commit ef62f4698a
7 changed files with 152 additions and 106 deletions

View File

@ -27,6 +27,10 @@ interface CommunitiesState {
loading: boolean; loading: boolean;
} }
interface CommunitiesProps {
page: number;
}
export class Communities extends Component<any, CommunitiesState> { export class Communities extends Component<any, CommunitiesState> {
private subscription: Subscription; private subscription: Subscription;
private emptyState: CommunitiesState = { private emptyState: CommunitiesState = {
@ -54,13 +58,13 @@ export class Communities extends Component<any, CommunitiesState> {
this.subscription.unsubscribe(); this.subscription.unsubscribe();
} }
static getDerivedStateFromProps(props) { static getDerivedStateFromProps(props: any): CommunitiesProps {
return { return {
page: getPageFromProps(props), page: getPageFromProps(props),
}; };
} }
componentDidUpdate(_, lastState) { componentDidUpdate(_: any, lastState: CommunitiesState) {
if (lastState.page !== this.state.page) { if (lastState.page !== this.state.page) {
this.setState({ loading: true }); this.setState({ loading: true });
this.refetch(); this.refetch();
@ -172,7 +176,7 @@ export class Communities extends Component<any, CommunitiesState> {
); );
} }
updateUrl(paramUpdates: { page: number }) { updateUrl(paramUpdates: CommunitiesProps) {
const page = paramUpdates.page || this.state.page; const page = paramUpdates.page || this.state.page;
this.props.history.push(`/communities/page/${page}`); this.props.history.push(`/communities/page/${page}`);
} }

View File

@ -65,6 +65,18 @@ interface State {
site: Site; site: Site;
} }
interface CommunityProps {
dataType: DataType;
sort: SortType;
page: number;
}
interface UrlParams {
dataType?: string;
sort?: string;
page?: number;
}
export class Community extends Component<any, State> { export class Community extends Component<any, State> {
private subscription: Subscription; private subscription: Subscription;
private emptyState: State = { private emptyState: State = {
@ -143,7 +155,7 @@ export class Community extends Component<any, State> {
this.subscription.unsubscribe(); this.subscription.unsubscribe();
} }
static getDerivedStateFromProps(props) { static getDerivedStateFromProps(props: any): CommunityProps {
return { return {
dataType: getDataTypeFromProps(props), dataType: getDataTypeFromProps(props),
sort: getSortTypeFromProps(props), sort: getSortTypeFromProps(props),
@ -151,7 +163,7 @@ export class Community extends Component<any, State> {
}; };
} }
componentDidUpdate(_, lastState) { componentDidUpdate(_: any, lastState: State) {
if ( if (
lastState.dataType !== this.state.dataType || lastState.dataType !== this.state.dataType ||
lastState.sort !== this.state.sort || lastState.sort !== this.state.sort ||
@ -293,17 +305,13 @@ export class Community extends Component<any, State> {
} }
handleDataTypeChange(val: DataType) { handleDataTypeChange(val: DataType) {
this.updateUrl({ data_type: DataType[val].toLowerCase(), page: 1 }); this.updateUrl({ dataType: DataType[val].toLowerCase(), page: 1 });
window.scrollTo(0, 0); window.scrollTo(0, 0);
} }
updateUrl(paramUpdates: { updateUrl(paramUpdates: UrlParams) {
data_type?: string;
sort?: string;
page?: number;
}) {
const dataTypeStr = const dataTypeStr =
paramUpdates.data_type || DataType[this.state.dataType].toLowerCase(); paramUpdates.dataType || DataType[this.state.dataType].toLowerCase();
const sortStr = const sortStr =
paramUpdates.sort || SortType[this.state.sort].toLowerCase(); paramUpdates.sort || SortType[this.state.sort].toLowerCase();
const page = paramUpdates.page || this.state.page; const page = paramUpdates.page || this.state.page;

View File

@ -70,6 +70,20 @@ interface MainState {
page: number; page: number;
} }
interface MainProps {
listingType: ListingType;
dataType: DataType;
sort: SortType;
page: number;
}
interface UrlParams {
listingType?: string;
dataType?: string;
sort?: string;
page?: number;
}
export class Main extends Component<any, MainState> { export class Main extends Component<any, MainState> {
private subscription: Subscription; private subscription: Subscription;
private emptyState: MainState = { private emptyState: MainState = {
@ -141,7 +155,7 @@ export class Main extends Component<any, MainState> {
this.subscription.unsubscribe(); this.subscription.unsubscribe();
} }
static getDerivedStateFromProps(props) { static getDerivedStateFromProps(props: any): MainProps {
return { return {
listingType: getListingTypeFromProps(props), listingType: getListingTypeFromProps(props),
dataType: getDataTypeFromProps(props), dataType: getDataTypeFromProps(props),
@ -150,7 +164,7 @@ export class Main extends Component<any, MainState> {
}; };
} }
componentDidUpdate(_, lastState) { componentDidUpdate(_: any, lastState: MainState) {
if ( if (
lastState.listingType !== this.state.listingType || lastState.listingType !== this.state.listingType ||
lastState.dataType !== this.state.dataType || lastState.dataType !== this.state.dataType ||
@ -263,17 +277,12 @@ export class Main extends Component<any, MainState> {
); );
} }
updateUrl(paramUpdates: { updateUrl(paramUpdates: UrlParams) {
listing_type?: string;
data_type?: string;
sort?: string;
page?: number;
}) {
const listingTypeStr = const listingTypeStr =
paramUpdates.listing_type || paramUpdates.listingType ||
ListingType[this.state.listingType].toLowerCase(); ListingType[this.state.listingType].toLowerCase();
const dataTypeStr = const dataTypeStr =
paramUpdates.data_type || DataType[this.state.dataType].toLowerCase(); paramUpdates.dataType || DataType[this.state.dataType].toLowerCase();
const sortStr = const sortStr =
paramUpdates.sort || SortType[this.state.sort].toLowerCase(); paramUpdates.sort || SortType[this.state.sort].toLowerCase();
const page = paramUpdates.page || this.state.page; const page = paramUpdates.page || this.state.page;
@ -560,12 +569,12 @@ export class Main extends Component<any, MainState> {
} }
handleListingTypeChange(val: ListingType) { handleListingTypeChange(val: ListingType) {
this.updateUrl({ listing_type: ListingType[val].toLowerCase(), page: 1 }); this.updateUrl({ listingType: ListingType[val].toLowerCase(), page: 1 });
window.scrollTo(0, 0); window.scrollTo(0, 0);
} }
handleDataTypeChange(val: DataType) { handleDataTypeChange(val: DataType) {
this.updateUrl({ data_type: DataType[val].toLowerCase(), page: 1 }); this.updateUrl({ dataType: DataType[val].toLowerCase(), page: 1 });
window.scrollTo(0, 0); window.scrollTo(0, 0);
} }

View File

@ -28,6 +28,7 @@ import {
createCommentLikeRes, createCommentLikeRes,
createPostLikeFindRes, createPostLikeFindRes,
commentsToFlatNodes, commentsToFlatNodes,
getPageFromProps,
} from '../utils'; } from '../utils';
import { PostListing } from './post-listing'; import { PostListing } from './post-listing';
import { UserListing } from './user-listing'; import { UserListing } from './user-listing';
@ -47,13 +48,27 @@ interface SearchState {
searchText: string; searchText: string;
} }
interface SearchProps {
q: string;
type_: SearchType;
sort: SortType;
page: number;
}
interface UrlParams {
q?: string;
type_?: string;
sort?: string;
page?: number;
}
export class Search extends Component<any, SearchState> { export class Search extends Component<any, SearchState> {
private subscription: Subscription; private subscription: Subscription;
private emptyState: SearchState = { private emptyState: SearchState = {
q: Search.getSearchQueryFromProps(this.props), q: Search.getSearchQueryFromProps(this.props),
type_: Search.getSearchTypeFromProps(this.props), type_: Search.getSearchTypeFromProps(this.props),
sort: Search.getSortTypeFromProps(this.props), sort: Search.getSortTypeFromProps(this.props),
page: Search.getPageFromProps(this.props), page: getPageFromProps(this.props),
searchText: Search.getSearchQueryFromProps(this.props), searchText: Search.getSearchQueryFromProps(this.props),
searchResponse: { searchResponse: {
type_: null, type_: null,
@ -95,10 +110,6 @@ export class Search extends Component<any, SearchState> {
: SortType.TopAll; : SortType.TopAll;
} }
static getPageFromProps(props: any): number {
return props.match.params.page ? Number(props.match.params.page) : 1;
}
constructor(props: any, context: any) { constructor(props: any, context: any) {
super(props, context); super(props, context);
@ -124,16 +135,16 @@ export class Search extends Component<any, SearchState> {
this.subscription.unsubscribe(); this.subscription.unsubscribe();
} }
static getDerivedStateFromProps(props) { static getDerivedStateFromProps(props: any): SearchProps {
return { return {
q: Search.getSearchQueryFromProps(props), q: Search.getSearchQueryFromProps(props),
type_: Search.getSearchTypeFromProps(props), type_: Search.getSearchTypeFromProps(props),
sort: Search.getSortTypeFromProps(props), sort: Search.getSortTypeFromProps(props),
page: Search.getPageFromProps(props), page: getPageFromProps(props),
}; };
} }
componentDidUpdate(_, lastState) { componentDidUpdate(_: any, lastState: SearchState) {
if ( if (
lastState.q !== this.state.q || lastState.q !== this.state.q ||
lastState.type_ !== this.state.type_ || lastState.type_ !== this.state.type_ ||
@ -443,19 +454,22 @@ export class Search extends Component<any, SearchState> {
} }
handleSortChange(val: SortType) { handleSortChange(val: SortType) {
this.updateUrl({ sort: val, page: 1 }); this.updateUrl({ sort: SortType[val].toLowerCase(), page: 1 });
} }
handleTypeChange(i: Search, event: any) { handleTypeChange(i: Search, event: any) {
i.updateUrl({ type_: Number(event.target.value), page: 1 }); i.updateUrl({
type_: SearchType[Number(event.target.value)].toLowerCase(),
page: 1,
});
} }
handleSearchSubmit(i: Search, event: any) { handleSearchSubmit(i: Search, event: any) {
event.preventDefault(); event.preventDefault();
i.updateUrl({ i.updateUrl({
q: i.state.searchText, q: i.state.searchText,
type_: i.state.type_, type_: SearchType[i.state.type_].toLowerCase(),
sort: i.state.sort, sort: SortType[i.state.sort].toLowerCase(),
page: i.state.page, page: i.state.page,
}); });
} }
@ -464,22 +478,15 @@ export class Search extends Component<any, SearchState> {
i.setState({ searchText: event.target.value }); i.setState({ searchText: event.target.value });
} }
updateUrl(paramUpdates: { updateUrl(paramUpdates: UrlParams) {
q?: string; const qStr = paramUpdates.q || this.state.q;
type_?: number;
sort?: SortType;
page?: number;
}) {
const qStr = paramUpdates.q || Search.getSearchQueryFromProps(this.props);
const typeStr = const typeStr =
SearchType[paramUpdates.type_] || paramUpdates.type_ || SearchType[this.state.type_].toLowerCase();
SearchType[Search.getSearchTypeFromProps(this.props)];
const sortStr = const sortStr =
SortType[paramUpdates.sort] || paramUpdates.sort || SortType[this.state.sort].toLowerCase();
SortType[Search.getSortTypeFromProps(this.props)]; const page = paramUpdates.page || this.state.page;
const page = paramUpdates.page || Search.getPageFromProps(this.props);
this.props.history.push( this.props.history.push(
`/search/q/${qStr}/type/${typeStr.toLowerCase()}/sort/${sortStr.toLowerCase()}/page/${page}` `/search/q/${qStr}/type/${typeStr}/sort/${sortStr}/page/${page}`
); );
} }

View File

@ -23,10 +23,9 @@ export class SortSelect extends Component<SortSelectProps, SortSelectState> {
this.state = this.emptyState; this.state = this.emptyState;
} }
static getDerivedStateFromProps(props) { static getDerivedStateFromProps(props: any): SortSelectState {
console.log('sort-select', props);
return { return {
sort: Number(props.sort), sort: props.sort,
}; };
} }

View File

@ -1,4 +1,4 @@
import { Component } from 'inferno'; import { Component, linkEvent } from 'inferno';
import { WebSocketService, UserService } from '../services'; import { WebSocketService, UserService } from '../services';
import { Subscription } from 'rxjs'; import { Subscription } from 'rxjs';
import { retryWhen, delay, take, last } from 'rxjs/operators'; import { retryWhen, delay, take, last } from 'rxjs/operators';
@ -40,6 +40,7 @@ interface UserDetailsProps {
enableDownvotes: boolean; enableDownvotes: boolean;
enableNsfw: boolean; enableNsfw: boolean;
view: UserDetailsView; view: UserDetailsView;
onPageChange(page: number): number | any;
} }
interface UserDetailsState { interface UserDetailsState {
@ -104,7 +105,12 @@ export class UserDetails extends Component<UserDetailsProps, UserDetailsState> {
} }
render() { render() {
return this.viewSelector(this.props.view); return (
<div>
{this.viewSelector(this.props.view)}
{this.paginator()}
</div>
);
} }
viewSelector(view: UserDetailsView) { viewSelector(view: UserDetailsView) {
@ -196,6 +202,37 @@ export class UserDetails extends Component<UserDetailsProps, UserDetailsState> {
); );
} }
paginator() {
return (
<div class="my-2">
{this.props.page > 1 && (
<button
class="btn btn-sm btn-secondary mr-1"
onClick={linkEvent(this, this.prevPage)}
>
{i18n.t('prev')}
</button>
)}
{this.state.comments.length + this.state.posts.length > 0 && (
<button
class="btn btn-sm btn-secondary"
onClick={linkEvent(this, this.nextPage)}
>
{i18n.t('next')}
</button>
)}
</div>
);
}
nextPage(i: UserDetails) {
i.props.onPageChange(i.props.page + 1);
}
prevPage(i: UserDetails) {
i.props.onPageChange(i.props.page - 1);
}
parseMessage(msg: WebSocketJsonResponse) { parseMessage(msg: WebSocketJsonResponse) {
const res = wsJsonToRes(msg); const res = wsJsonToRes(msg);

View File

@ -57,6 +57,20 @@ interface UserState {
site: Site; site: Site;
} }
interface UserProps {
view: UserDetailsView;
sort: SortType;
page: number;
user_id: number | null;
username: string;
}
interface UrlParams {
view?: string;
sort?: string;
page?: number;
}
export class User extends Component<any, UserState> { export class User extends Component<any, UserState> {
private subscription: Subscription; private subscription: Subscription;
private emptyState: UserState = { private emptyState: UserState = {
@ -119,7 +133,7 @@ export class User extends Component<any, UserState> {
constructor(props: any, context: any) { constructor(props: any, context: any) {
super(props, context); super(props, context);
this.state = Object.assign({}, this.emptyState); this.state = this.emptyState;
this.handleSortChange = this.handleSortChange.bind(this); this.handleSortChange = this.handleSortChange.bind(this);
this.handleUserSettingsSortTypeChange = this.handleUserSettingsSortTypeChange.bind( this.handleUserSettingsSortTypeChange = this.handleUserSettingsSortTypeChange.bind(
this this
@ -127,6 +141,7 @@ export class User extends Component<any, UserState> {
this.handleUserSettingsListingTypeChange = this.handleUserSettingsListingTypeChange.bind( this.handleUserSettingsListingTypeChange = this.handleUserSettingsListingTypeChange.bind(
this this
); );
this.handlePageChange = this.handlePageChange.bind(this);
this.state.user_id = Number(this.props.match.params.id) || null; this.state.user_id = Number(this.props.match.params.id) || null;
this.state.username = this.props.match.params.username; this.state.username = this.props.match.params.username;
@ -167,7 +182,7 @@ export class User extends Component<any, UserState> {
this.subscription.unsubscribe(); this.subscription.unsubscribe();
} }
static getDerivedStateFromProps(props) { static getDerivedStateFromProps(props: any): UserProps {
return { return {
view: this.getViewFromProps(props.match.params.view), view: this.getViewFromProps(props.match.params.view),
sort: this.getSortTypeFromProps(props.match.params.sort), sort: this.getSortTypeFromProps(props.match.params.sort),
@ -223,9 +238,8 @@ export class User extends Component<any, UserState> {
enableDownvotes={this.state.site.enable_downvotes} enableDownvotes={this.state.site.enable_downvotes}
enableNsfw={this.state.site.enable_nsfw} enableNsfw={this.state.site.enable_nsfw}
view={this.state.view} view={this.state.view}
key={this.state.user_id || this.state.username} onPageChange={this.handlePageChange}
/> />
{this.paginator()}
</div> </div>
<div class="col-12 col-md-4"> <div class="col-12 col-md-4">
{this.userInfo()} {this.userInfo()}
@ -794,67 +808,35 @@ export class User extends Component<any, UserState> {
); );
} }
paginator() { updateUrl(paramUpdates: UrlParams) {
return ( const page = paramUpdates.page || this.state.page;
<div class="my-2"> const viewStr =
{this.state.page > 1 && ( paramUpdates.view || UserDetailsView[this.state.view].toLowerCase();
<button const sortStr =
class="btn btn-sm btn-secondary mr-1" paramUpdates.sort || SortType[this.state.sort].toLowerCase();
onClick={linkEvent(this, this.prevPage)}
>
{i18n.t('prev')}
</button>
)}
{this.state.comments.length + this.state.posts.length > 0 && (
<button
class="btn btn-sm btn-secondary"
onClick={linkEvent(this, this.nextPage)}
>
{i18n.t('next')}
</button>
)}
</div>
);
}
updateUrl() {
let viewStr = UserDetailsView[this.state.view].toLowerCase();
let sortStr = SortType[this.state.sort].toLowerCase();
this.props.history.push( this.props.history.push(
`/u/${this.state.username}/view/${viewStr}/sort/${sortStr}/page/${this.state.page}` `/u/${this.state.username}/view/${viewStr}/sort/${sortStr}/page/${page}`
); );
this.setState(this.state);
} }
nextPage(i: User) { handlePageChange(page: number) {
i.state.page++; this.updateUrl({ page });
i.updateUrl();
}
prevPage(i: User) {
i.state.page--;
i.updateUrl();
} }
handleSortChange(val: SortType) { handleSortChange(val: SortType) {
this.state.sort = val; this.updateUrl({ sort: SortType[val].toLowerCase(), page: 1 });
this.state.page = 1;
this.updateUrl();
} }
handleViewChange(i: User, event: any) { handleViewChange(i: User, event: any) {
i.state.view = Number(event.target.value); i.updateUrl({
i.state.page = 1; view: UserDetailsView[Number(event.target.value)].toLowerCase(),
i.updateUrl(); page: 1,
});
} }
handleUserSettingsShowNsfwChange(i: User, event: any) { handleUserSettingsShowNsfwChange(i: User, event: any) {
i.setState({ i.state.userSettingsForm.show_nsfw = event.target.checked;
userSettingsForm: { i.setState(i.state);
...i.state.userSettingsForm,
show_nsfw: event.target.checked,
},
});
} }
handleUserSettingsShowAvatarsChange(i: User, event: any) { handleUserSettingsShowAvatarsChange(i: User, event: any) {