mirror of
https://github.com/LemmyNet/lemmy.git
synced 2024-11-26 07:52:13 +00:00
ui.components: split user component up to fix duplicate requests
Replace componentWillReceiveProps with getDerivedState and pass state as props to new component
This commit is contained in:
parent
d71897620c
commit
f1d01f4fa0
270
ui/src/components/user-details.tsx
vendored
Normal file
270
ui/src/components/user-details.tsx
vendored
Normal file
|
@ -0,0 +1,270 @@
|
|||
import { Component } from 'inferno';
|
||||
import { WebSocketService, UserService } from '../services';
|
||||
import { Subscription } from 'rxjs';
|
||||
import { retryWhen, delay, take, last } from 'rxjs/operators';
|
||||
import { i18n } from '../i18next';
|
||||
import {
|
||||
UserOperation,
|
||||
Post,
|
||||
Comment,
|
||||
CommunityUser,
|
||||
SortType,
|
||||
UserDetailsResponse,
|
||||
UserView,
|
||||
WebSocketJsonResponse,
|
||||
UserDetailsView,
|
||||
CommentResponse,
|
||||
BanUserResponse,
|
||||
PostResponse,
|
||||
AddAdminResponse,
|
||||
} from '../interfaces';
|
||||
import {
|
||||
wsJsonToRes,
|
||||
toast,
|
||||
commentsToFlatNodes,
|
||||
setupTippy,
|
||||
editCommentRes,
|
||||
saveCommentRes,
|
||||
createCommentLikeRes,
|
||||
createPostLikeFindRes,
|
||||
} from '../utils';
|
||||
import { PostListing } from './post-listing';
|
||||
import { CommentNodes } from './comment-nodes';
|
||||
|
||||
interface UserDetailsProps {
|
||||
username?: string;
|
||||
user_id?: number;
|
||||
page: number;
|
||||
limit: number;
|
||||
sort: string;
|
||||
enableDownvotes: boolean;
|
||||
enableNsfw: boolean;
|
||||
view: UserDetailsView;
|
||||
}
|
||||
|
||||
interface UserDetailsState {
|
||||
follows: Array<CommunityUser>;
|
||||
moderates: Array<CommunityUser>;
|
||||
comments: Array<Comment>;
|
||||
posts: Array<Post>;
|
||||
saved?: Array<Post>;
|
||||
admins: Array<UserView>;
|
||||
}
|
||||
|
||||
export class UserDetails extends Component<UserDetailsProps, UserDetailsState> {
|
||||
private subscription: Subscription;
|
||||
constructor(props: any, context: any) {
|
||||
super(props, context);
|
||||
|
||||
this.state = {
|
||||
follows: [],
|
||||
moderates: [],
|
||||
comments: [],
|
||||
posts: [],
|
||||
saved: [],
|
||||
admins: [],
|
||||
};
|
||||
|
||||
this.subscription = WebSocketService.Instance.subject
|
||||
.pipe(retryWhen(errors => errors.pipe(delay(3000), take(10))))
|
||||
.subscribe(
|
||||
msg => this.parseMessage(msg),
|
||||
err => console.error(err),
|
||||
() => console.log('complete')
|
||||
);
|
||||
}
|
||||
|
||||
componentWillUnmount() {
|
||||
this.subscription.unsubscribe();
|
||||
}
|
||||
|
||||
componentDidMount() {
|
||||
this.fetchUserData();
|
||||
}
|
||||
|
||||
componentDidUpdate(lastProps: UserDetailsProps) {
|
||||
for (const key of Object.keys(lastProps)) {
|
||||
if (lastProps[key] !== this.props[key]) {
|
||||
this.fetchUserData();
|
||||
break;
|
||||
}
|
||||
}
|
||||
setupTippy();
|
||||
}
|
||||
|
||||
fetchUserData() {
|
||||
WebSocketService.Instance.getUserDetails({
|
||||
user_id: this.props.user_id,
|
||||
username: this.props.username,
|
||||
sort: this.props.sort,
|
||||
saved_only: this.props.view === UserDetailsView.Saved,
|
||||
page: this.props.page,
|
||||
limit: this.props.limit,
|
||||
});
|
||||
}
|
||||
|
||||
render() {
|
||||
return this.viewSelector(this.props.view);
|
||||
}
|
||||
|
||||
viewSelector(view: UserDetailsView) {
|
||||
if (view === UserDetailsView.Overview || view === UserDetailsView.Saved) {
|
||||
return this.overview();
|
||||
}
|
||||
if (view === UserDetailsView.Comments) {
|
||||
return this.comments();
|
||||
}
|
||||
if (view === UserDetailsView.Posts) {
|
||||
return this.posts();
|
||||
}
|
||||
}
|
||||
|
||||
overview() {
|
||||
const comments = this.state.comments.map((c: Comment) => {
|
||||
return { type: 'comments', data: c };
|
||||
});
|
||||
const posts = this.state.posts.map((p: Post) => {
|
||||
return { type: 'posts', data: p };
|
||||
});
|
||||
|
||||
const combined: Array<{ type: string; data: Comment | Post }> = [
|
||||
...comments,
|
||||
...posts,
|
||||
];
|
||||
|
||||
// Sort it
|
||||
if (SortType[this.props.sort] === SortType.New) {
|
||||
combined.sort((a, b) => b.data.published.localeCompare(a.data.published));
|
||||
} else {
|
||||
combined.sort((a, b) => b.data.score - a.data.score);
|
||||
}
|
||||
|
||||
return (
|
||||
<div>
|
||||
{combined.map(i => (
|
||||
<div>
|
||||
{i.type === 'posts' ? (
|
||||
<PostListing
|
||||
post={i.data as Post}
|
||||
admins={this.state.admins}
|
||||
showCommunity
|
||||
enableDownvotes={this.props.enableDownvotes}
|
||||
enableNsfw={this.props.enableNsfw}
|
||||
/>
|
||||
) : (
|
||||
<CommentNodes
|
||||
nodes={[{ comment: i.data as Comment }]}
|
||||
admins={this.state.admins}
|
||||
noIndent
|
||||
showContext
|
||||
enableDownvotes={this.props.enableDownvotes}
|
||||
/>
|
||||
)}
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
comments() {
|
||||
return (
|
||||
<div>
|
||||
<CommentNodes
|
||||
nodes={commentsToFlatNodes(this.state.comments)}
|
||||
admins={this.state.admins}
|
||||
noIndent
|
||||
showContext
|
||||
enableDownvotes={this.props.enableDownvotes}
|
||||
/>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
posts() {
|
||||
return (
|
||||
<div>
|
||||
{this.state.posts.map(post => (
|
||||
<PostListing
|
||||
post={post}
|
||||
admins={this.state.admins}
|
||||
showCommunity
|
||||
enableDownvotes={this.props.enableDownvotes}
|
||||
enableNsfw={this.props.enableNsfw}
|
||||
/>
|
||||
))}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
parseMessage(msg: WebSocketJsonResponse) {
|
||||
const res = wsJsonToRes(msg);
|
||||
|
||||
if (msg.error) {
|
||||
toast(i18n.t(msg.error), 'danger');
|
||||
if (msg.error == 'couldnt_find_that_username_or_email') {
|
||||
this.context.router.history.push('/');
|
||||
}
|
||||
return;
|
||||
} else if (msg.reconnect) {
|
||||
this.fetchUserData();
|
||||
} else if (res.op == UserOperation.GetUserDetails) {
|
||||
const data = res.data as UserDetailsResponse;
|
||||
this.setState({
|
||||
comments: data.comments,
|
||||
follows: data.follows,
|
||||
moderates: data.moderates,
|
||||
posts: data.posts,
|
||||
admins: data.admins,
|
||||
});
|
||||
} else if (res.op == UserOperation.CreateCommentLike) {
|
||||
const data = res.data as CommentResponse;
|
||||
createCommentLikeRes(data, this.state.comments);
|
||||
this.setState({
|
||||
comments: this.state.comments,
|
||||
});
|
||||
} else if (res.op == UserOperation.EditComment) {
|
||||
const data = res.data as CommentResponse;
|
||||
editCommentRes(data, this.state.comments);
|
||||
this.setState({
|
||||
comments: this.state.comments,
|
||||
});
|
||||
} else if (res.op == UserOperation.CreateComment) {
|
||||
const data = res.data as CommentResponse;
|
||||
if (
|
||||
UserService.Instance.user &&
|
||||
data.comment.creator_id == UserService.Instance.user.id
|
||||
) {
|
||||
toast(i18n.t('reply_sent'));
|
||||
}
|
||||
} else if (res.op == UserOperation.SaveComment) {
|
||||
const data = res.data as CommentResponse;
|
||||
saveCommentRes(data, this.state.comments);
|
||||
this.setState({
|
||||
comments: this.state.comments,
|
||||
});
|
||||
} else if (res.op == UserOperation.CreatePostLike) {
|
||||
const data = res.data as PostResponse;
|
||||
createPostLikeFindRes(data, this.state.posts);
|
||||
this.setState({
|
||||
posts: this.state.posts,
|
||||
});
|
||||
} else if (res.op == UserOperation.BanUser) {
|
||||
const data = res.data as BanUserResponse;
|
||||
this.state.comments
|
||||
.filter(c => c.creator_id == data.user.id)
|
||||
.forEach(c => (c.banned = data.banned));
|
||||
this.state.posts
|
||||
.filter(c => c.creator_id == data.user.id)
|
||||
.forEach(c => (c.banned = data.banned));
|
||||
this.setState({
|
||||
posts: this.state.posts,
|
||||
comments: this.state.comments,
|
||||
});
|
||||
} else if (res.op == UserOperation.AddAdmin) {
|
||||
const data = res.data as AddAdminResponse;
|
||||
this.setState({
|
||||
admins: data.admins,
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
369
ui/src/components/user.tsx
vendored
369
ui/src/components/user.tsx
vendored
|
@ -4,24 +4,18 @@ import { Subscription } from 'rxjs';
|
|||
import { retryWhen, delay, take } from 'rxjs/operators';
|
||||
import {
|
||||
UserOperation,
|
||||
Post,
|
||||
Comment,
|
||||
CommunityUser,
|
||||
GetUserDetailsForm,
|
||||
SortType,
|
||||
ListingType,
|
||||
UserDetailsResponse,
|
||||
UserView,
|
||||
CommentResponse,
|
||||
UserSettingsForm,
|
||||
LoginResponse,
|
||||
BanUserResponse,
|
||||
AddAdminResponse,
|
||||
DeleteAccountForm,
|
||||
PostResponse,
|
||||
WebSocketJsonResponse,
|
||||
GetSiteResponse,
|
||||
Site,
|
||||
UserDetailsView,
|
||||
UserDetailsResponse,
|
||||
} from '../interfaces';
|
||||
import { WebSocketService, UserService } from '../services';
|
||||
import {
|
||||
|
@ -34,28 +28,15 @@ import {
|
|||
languages,
|
||||
showAvatars,
|
||||
toast,
|
||||
editCommentRes,
|
||||
saveCommentRes,
|
||||
createCommentLikeRes,
|
||||
createPostLikeFindRes,
|
||||
commentsToFlatNodes,
|
||||
setupTippy,
|
||||
} from '../utils';
|
||||
import { PostListing } from './post-listing';
|
||||
import { UserListing } from './user-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';
|
||||
import moment from 'moment';
|
||||
|
||||
enum View {
|
||||
Overview,
|
||||
Comments,
|
||||
Posts,
|
||||
Saved,
|
||||
}
|
||||
import { UserDetails } from './user-details';
|
||||
|
||||
interface UserState {
|
||||
user: UserView;
|
||||
|
@ -63,11 +44,7 @@ interface UserState {
|
|||
username: string;
|
||||
follows: Array<CommunityUser>;
|
||||
moderates: Array<CommunityUser>;
|
||||
comments: Array<Comment>;
|
||||
posts: Array<Post>;
|
||||
saved?: Array<Post>;
|
||||
admins: Array<UserView>;
|
||||
view: View;
|
||||
view: UserDetailsView;
|
||||
sort: SortType;
|
||||
page: number;
|
||||
loading: boolean;
|
||||
|
@ -102,14 +79,11 @@ export class User extends Component<any, UserState> {
|
|||
username: null,
|
||||
follows: [],
|
||||
moderates: [],
|
||||
comments: [],
|
||||
posts: [],
|
||||
admins: [],
|
||||
loading: true,
|
||||
loading: false,
|
||||
avatarLoading: false,
|
||||
view: this.getViewFromProps(this.props),
|
||||
sort: this.getSortTypeFromProps(this.props),
|
||||
page: this.getPageFromProps(this.props),
|
||||
view: User.getViewFromProps(this.props.match.view),
|
||||
sort: User.getSortTypeFromProps(this.props.match.sort),
|
||||
page: User.getPageFromProps(this.props.match.page),
|
||||
userSettingsForm: {
|
||||
show_nsfw: null,
|
||||
theme: null,
|
||||
|
@ -145,7 +119,7 @@ export class User extends Component<any, UserState> {
|
|||
constructor(props: any, context: any) {
|
||||
super(props, context);
|
||||
|
||||
this.state = this.emptyState;
|
||||
this.state = Object.assign({}, this.emptyState);
|
||||
this.handleSortChange = this.handleSortChange.bind(this);
|
||||
this.handleUserSettingsSortTypeChange = this.handleUserSettingsSortTypeChange.bind(
|
||||
this
|
||||
|
@ -154,7 +128,7 @@ export class User extends Component<any, UserState> {
|
|||
this
|
||||
);
|
||||
|
||||
this.state.user_id = Number(this.props.match.params.id);
|
||||
this.state.user_id = Number(this.props.match.params.id) || null;
|
||||
this.state.username = this.props.match.params.username;
|
||||
|
||||
this.subscription = WebSocketService.Instance.subject
|
||||
|
@ -165,7 +139,6 @@ export class User extends Component<any, UserState> {
|
|||
() => console.log('complete')
|
||||
);
|
||||
|
||||
this.refetch();
|
||||
WebSocketService.Instance.getSite();
|
||||
}
|
||||
|
||||
|
@ -176,38 +149,32 @@ export class User extends Component<any, UserState> {
|
|||
);
|
||||
}
|
||||
|
||||
getViewFromProps(props: any): View {
|
||||
return props.match.params.view
|
||||
? View[capitalizeFirstLetter(props.match.params.view)]
|
||||
: View.Overview;
|
||||
static getViewFromProps(view: any): UserDetailsView {
|
||||
return view
|
||||
? UserDetailsView[capitalizeFirstLetter(view)]
|
||||
: UserDetailsView.Overview;
|
||||
}
|
||||
|
||||
getSortTypeFromProps(props: any): SortType {
|
||||
return props.match.params.sort
|
||||
? routeSortTypeToEnum(props.match.params.sort)
|
||||
: SortType.New;
|
||||
static getSortTypeFromProps(sort: any): SortType {
|
||||
return sort ? routeSortTypeToEnum(sort) : SortType.New;
|
||||
}
|
||||
|
||||
getPageFromProps(props: any): number {
|
||||
return props.match.params.page ? Number(props.match.params.page) : 1;
|
||||
static getPageFromProps(page: any): number {
|
||||
return page ? Number(page) : 1;
|
||||
}
|
||||
|
||||
componentWillUnmount() {
|
||||
this.subscription.unsubscribe();
|
||||
}
|
||||
|
||||
// Necessary for back button for some reason
|
||||
componentWillReceiveProps(nextProps: any) {
|
||||
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();
|
||||
}
|
||||
static getDerivedStateFromProps(props) {
|
||||
return {
|
||||
view: this.getViewFromProps(props.match.params.view),
|
||||
sort: this.getSortTypeFromProps(props.match.params.sort),
|
||||
page: this.getPageFromProps(props.match.params.page),
|
||||
user_id: Number(props.match.params.id) || null,
|
||||
username: props.match.params.username,
|
||||
};
|
||||
}
|
||||
|
||||
componentDidUpdate(lastProps: any, _lastState: UserState, _snapshot: any) {
|
||||
|
@ -219,6 +186,8 @@ export class User extends Component<any, UserState> {
|
|||
// Couldnt get a refresh working. This does for now.
|
||||
location.reload();
|
||||
}
|
||||
document.title = `/u/${this.state.username} - ${this.state.site.name}`;
|
||||
setupTippy();
|
||||
}
|
||||
|
||||
render() {
|
||||
|
@ -242,13 +211,20 @@ export class User extends Component<any, UserState> {
|
|||
class="rounded-circle mr-2"
|
||||
/>
|
||||
)}
|
||||
<span>/u/{this.state.user.name}</span>
|
||||
<span>/u/{this.state.username}</span>
|
||||
</h5>
|
||||
{this.selects()}
|
||||
{this.state.view == View.Overview && this.overview()}
|
||||
{this.state.view == View.Comments && this.comments()}
|
||||
{this.state.view == View.Posts && this.posts()}
|
||||
{this.state.view == View.Saved && this.overview()}
|
||||
<UserDetails
|
||||
user_id={this.state.user_id}
|
||||
username={this.state.username}
|
||||
sort={SortType[this.state.sort]}
|
||||
page={this.state.page}
|
||||
limit={fetchLimit}
|
||||
enableDownvotes={this.state.site.enable_downvotes}
|
||||
enableNsfw={this.state.site.enable_nsfw}
|
||||
view={this.state.view}
|
||||
key={this.state.user_id || this.state.username}
|
||||
/>
|
||||
{this.paginator()}
|
||||
</div>
|
||||
<div class="col-12 col-md-4">
|
||||
|
@ -268,52 +244,52 @@ export class User extends Component<any, UserState> {
|
|||
<div class="btn-group btn-group-toggle">
|
||||
<label
|
||||
className={`btn btn-sm btn-secondary pointer btn-outline-light
|
||||
${this.state.view == View.Overview && 'active'}
|
||||
${this.state.view == UserDetailsView.Overview && 'active'}
|
||||
`}
|
||||
>
|
||||
<input
|
||||
type="radio"
|
||||
value={View.Overview}
|
||||
checked={this.state.view == View.Overview}
|
||||
value={UserDetailsView.Overview}
|
||||
checked={this.state.view === UserDetailsView.Overview}
|
||||
onChange={linkEvent(this, this.handleViewChange)}
|
||||
/>
|
||||
{i18n.t('overview')}
|
||||
</label>
|
||||
<label
|
||||
className={`btn btn-sm btn-secondary pointer btn-outline-light
|
||||
${this.state.view == View.Comments && 'active'}
|
||||
${this.state.view == UserDetailsView.Comments && 'active'}
|
||||
`}
|
||||
>
|
||||
<input
|
||||
type="radio"
|
||||
value={View.Comments}
|
||||
checked={this.state.view == View.Comments}
|
||||
value={UserDetailsView.Comments}
|
||||
checked={this.state.view == UserDetailsView.Comments}
|
||||
onChange={linkEvent(this, this.handleViewChange)}
|
||||
/>
|
||||
{i18n.t('comments')}
|
||||
</label>
|
||||
<label
|
||||
className={`btn btn-sm btn-secondary pointer btn-outline-light
|
||||
${this.state.view == View.Posts && 'active'}
|
||||
${this.state.view == UserDetailsView.Posts && 'active'}
|
||||
`}
|
||||
>
|
||||
<input
|
||||
type="radio"
|
||||
value={View.Posts}
|
||||
checked={this.state.view == View.Posts}
|
||||
value={UserDetailsView.Posts}
|
||||
checked={this.state.view == UserDetailsView.Posts}
|
||||
onChange={linkEvent(this, this.handleViewChange)}
|
||||
/>
|
||||
{i18n.t('posts')}
|
||||
</label>
|
||||
<label
|
||||
className={`btn btn-sm btn-secondary pointer btn-outline-light
|
||||
${this.state.view == View.Saved && 'active'}
|
||||
${this.state.view == UserDetailsView.Saved && 'active'}
|
||||
`}
|
||||
>
|
||||
<input
|
||||
type="radio"
|
||||
value={View.Saved}
|
||||
checked={this.state.view == View.Saved}
|
||||
value={UserDetailsView.Saved}
|
||||
checked={this.state.view == UserDetailsView.Saved}
|
||||
onChange={linkEvent(this, this.handleViewChange)}
|
||||
/>
|
||||
{i18n.t('saved')}
|
||||
|
@ -347,84 +323,6 @@ export class User extends Component<any, UserState> {
|
|||
);
|
||||
}
|
||||
|
||||
overview() {
|
||||
let combined: Array<{ type_: string; data: Comment | Post }> = [];
|
||||
let comments = this.state.comments.map(e => {
|
||||
return { type_: 'comments', data: e };
|
||||
});
|
||||
let posts = this.state.posts.map(e => {
|
||||
return { type_: 'posts', data: e };
|
||||
});
|
||||
|
||||
combined.push(...comments);
|
||||
combined.push(...posts);
|
||||
|
||||
// Sort it
|
||||
if (this.state.sort == SortType.New) {
|
||||
combined.sort((a, b) => b.data.published.localeCompare(a.data.published));
|
||||
} else {
|
||||
combined.sort((a, b) => b.data.score - a.data.score);
|
||||
}
|
||||
|
||||
return (
|
||||
<div>
|
||||
{combined.map(i => (
|
||||
<div>
|
||||
{i.type_ == 'posts' ? (
|
||||
<PostListing
|
||||
post={i.data as Post}
|
||||
admins={this.state.admins}
|
||||
showCommunity
|
||||
enableDownvotes={this.state.site.enable_downvotes}
|
||||
enableNsfw={this.state.site.enable_nsfw}
|
||||
/>
|
||||
) : (
|
||||
<CommentNodes
|
||||
nodes={[{ comment: i.data as Comment }]}
|
||||
admins={this.state.admins}
|
||||
noIndent
|
||||
showCommunity
|
||||
showContext
|
||||
enableDownvotes={this.state.site.enable_downvotes}
|
||||
/>
|
||||
)}
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
comments() {
|
||||
return (
|
||||
<div>
|
||||
<CommentNodes
|
||||
nodes={commentsToFlatNodes(this.state.comments)}
|
||||
admins={this.state.admins}
|
||||
noIndent
|
||||
showCommunity
|
||||
showContext
|
||||
enableDownvotes={this.state.site.enable_downvotes}
|
||||
/>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
posts() {
|
||||
return (
|
||||
<div>
|
||||
{this.state.posts.map(post => (
|
||||
<PostListing
|
||||
post={post}
|
||||
admins={this.state.admins}
|
||||
showCommunity
|
||||
enableDownvotes={this.state.site.enable_downvotes}
|
||||
enableNsfw={this.state.site.enable_nsfw}
|
||||
/>
|
||||
))}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
userInfo() {
|
||||
let user = this.state.user;
|
||||
return (
|
||||
|
@ -920,58 +818,43 @@ export class User extends Component<any, UserState> {
|
|||
}
|
||||
|
||||
updateUrl() {
|
||||
let viewStr = View[this.state.view].toLowerCase();
|
||||
let viewStr = UserDetailsView[this.state.view].toLowerCase();
|
||||
let sortStr = SortType[this.state.sort].toLowerCase();
|
||||
this.props.history.push(
|
||||
`/u/${this.state.user.name}/view/${viewStr}/sort/${sortStr}/page/${this.state.page}`
|
||||
`/u/${this.state.username}/view/${viewStr}/sort/${sortStr}/page/${this.state.page}`
|
||||
);
|
||||
this.setState(this.state);
|
||||
}
|
||||
|
||||
nextPage(i: User) {
|
||||
i.state.page++;
|
||||
i.setState(i.state);
|
||||
i.updateUrl();
|
||||
i.refetch();
|
||||
}
|
||||
|
||||
prevPage(i: User) {
|
||||
i.state.page--;
|
||||
i.setState(i.state);
|
||||
i.updateUrl();
|
||||
i.refetch();
|
||||
}
|
||||
|
||||
refetch() {
|
||||
let form: GetUserDetailsForm = {
|
||||
user_id: this.state.user_id,
|
||||
username: this.state.username,
|
||||
sort: SortType[this.state.sort],
|
||||
saved_only: this.state.view == View.Saved,
|
||||
page: this.state.page,
|
||||
limit: fetchLimit,
|
||||
};
|
||||
WebSocketService.Instance.getUserDetails(form);
|
||||
}
|
||||
|
||||
handleSortChange(val: SortType) {
|
||||
this.state.sort = val;
|
||||
this.state.page = 1;
|
||||
this.setState(this.state);
|
||||
this.updateUrl();
|
||||
this.refetch();
|
||||
}
|
||||
|
||||
handleViewChange(i: User, event: any) {
|
||||
i.state.view = Number(event.target.value);
|
||||
i.state.page = 1;
|
||||
i.setState(i.state);
|
||||
i.updateUrl();
|
||||
i.refetch();
|
||||
}
|
||||
|
||||
handleUserSettingsShowNsfwChange(i: User, event: any) {
|
||||
i.state.userSettingsForm.show_nsfw = event.target.checked;
|
||||
i.setState(i.state);
|
||||
i.setState({
|
||||
userSettingsForm: {
|
||||
...i.state.userSettingsForm,
|
||||
show_nsfw: event.target.checked,
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
handleUserSettingsShowAvatarsChange(i: User, event: any) {
|
||||
|
@ -1136,102 +1019,66 @@ export class User extends Component<any, UserState> {
|
|||
}
|
||||
|
||||
parseMessage(msg: WebSocketJsonResponse) {
|
||||
console.log(msg);
|
||||
let res = wsJsonToRes(msg);
|
||||
const res = wsJsonToRes(msg);
|
||||
if (msg.error) {
|
||||
toast(i18n.t(msg.error), 'danger');
|
||||
this.state.deleteAccountLoading = false;
|
||||
this.state.avatarLoading = false;
|
||||
this.state.userSettingsLoading = false;
|
||||
if (msg.error == 'couldnt_find_that_username_or_email') {
|
||||
this.context.router.history.push('/');
|
||||
}
|
||||
this.setState(this.state);
|
||||
this.setState({
|
||||
deleteAccountLoading: false,
|
||||
avatarLoading: false,
|
||||
userSettingsLoading: false,
|
||||
});
|
||||
return;
|
||||
} else if (msg.reconnect) {
|
||||
this.refetch();
|
||||
} else if (res.op == UserOperation.GetUserDetails) {
|
||||
let data = res.data as UserDetailsResponse;
|
||||
this.state.user = data.user;
|
||||
this.state.comments = data.comments;
|
||||
this.state.follows = data.follows;
|
||||
this.state.moderates = data.moderates;
|
||||
this.state.posts = data.posts;
|
||||
this.state.admins = data.admins;
|
||||
this.state.loading = false;
|
||||
if (this.isCurrentUser) {
|
||||
this.state.userSettingsForm.show_nsfw =
|
||||
UserService.Instance.user.show_nsfw;
|
||||
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;
|
||||
this.state.userSettingsForm.lang = UserService.Instance.user.lang;
|
||||
this.state.userSettingsForm.avatar = UserService.Instance.user.avatar;
|
||||
this.state.userSettingsForm.email = this.state.user.email;
|
||||
this.state.userSettingsForm.send_notifications_to_email = this.state.user.send_notifications_to_email;
|
||||
this.state.userSettingsForm.show_avatars =
|
||||
UserService.Instance.user.show_avatars;
|
||||
this.state.userSettingsForm.matrix_user_id = this.state.user.matrix_user_id;
|
||||
// Since the UserDetails contains posts/comments as well as some general user info we listen here as well
|
||||
// and set the parent state if it is not set or differs
|
||||
const data = res.data as UserDetailsResponse;
|
||||
|
||||
if (this.state.user.id !== data.user.id) {
|
||||
this.state.user = data.user;
|
||||
this.state.follows = data.follows;
|
||||
this.state.moderates = data.moderates;
|
||||
|
||||
if (this.isCurrentUser) {
|
||||
this.state.userSettingsForm.show_nsfw =
|
||||
UserService.Instance.user.show_nsfw;
|
||||
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;
|
||||
this.state.userSettingsForm.lang = UserService.Instance.user.lang;
|
||||
this.state.userSettingsForm.avatar = UserService.Instance.user.avatar;
|
||||
this.state.userSettingsForm.email = this.state.user.email;
|
||||
this.state.userSettingsForm.send_notifications_to_email = this.state.user.send_notifications_to_email;
|
||||
this.state.userSettingsForm.show_avatars =
|
||||
UserService.Instance.user.show_avatars;
|
||||
this.state.userSettingsForm.matrix_user_id = this.state.user.matrix_user_id;
|
||||
}
|
||||
this.setState(this.state);
|
||||
}
|
||||
document.title = `/u/${this.state.user.name} - ${this.state.site.name}`;
|
||||
window.scrollTo(0, 0);
|
||||
this.setState(this.state);
|
||||
setupTippy();
|
||||
} else if (res.op == UserOperation.EditComment) {
|
||||
let data = res.data as CommentResponse;
|
||||
editCommentRes(data, this.state.comments);
|
||||
this.setState(this.state);
|
||||
} else if (res.op == UserOperation.CreateComment) {
|
||||
let data = res.data as CommentResponse;
|
||||
if (
|
||||
UserService.Instance.user &&
|
||||
data.comment.creator_id == UserService.Instance.user.id
|
||||
) {
|
||||
toast(i18n.t('reply_sent'));
|
||||
}
|
||||
} else if (res.op == UserOperation.SaveComment) {
|
||||
let data = res.data as CommentResponse;
|
||||
saveCommentRes(data, this.state.comments);
|
||||
this.setState(this.state);
|
||||
} else if (res.op == UserOperation.CreateCommentLike) {
|
||||
let data = res.data as CommentResponse;
|
||||
createCommentLikeRes(data, this.state.comments);
|
||||
this.setState(this.state);
|
||||
} else if (res.op == UserOperation.CreatePostLike) {
|
||||
let data = res.data as PostResponse;
|
||||
createPostLikeFindRes(data, this.state.posts);
|
||||
this.setState(this.state);
|
||||
} else if (res.op == UserOperation.BanUser) {
|
||||
let data = res.data as BanUserResponse;
|
||||
this.state.comments
|
||||
.filter(c => c.creator_id == data.user.id)
|
||||
.forEach(c => (c.banned = data.banned));
|
||||
this.state.posts
|
||||
.filter(c => c.creator_id == data.user.id)
|
||||
.forEach(c => (c.banned = data.banned));
|
||||
this.setState(this.state);
|
||||
} else if (res.op == UserOperation.AddAdmin) {
|
||||
let data = res.data as AddAdminResponse;
|
||||
this.state.admins = data.admins;
|
||||
this.setState(this.state);
|
||||
} else if (res.op == UserOperation.SaveUserSettings) {
|
||||
let data = res.data as LoginResponse;
|
||||
this.state.userSettingsLoading = false;
|
||||
this.setState(this.state);
|
||||
const data = res.data as LoginResponse;
|
||||
UserService.Instance.login(data);
|
||||
this.setState({
|
||||
userSettingsLoading: false,
|
||||
});
|
||||
window.scrollTo(0, 0);
|
||||
} else if (res.op == UserOperation.DeleteAccount) {
|
||||
this.state.deleteAccountLoading = false;
|
||||
this.state.deleteAccountShowConfirm = false;
|
||||
this.setState(this.state);
|
||||
this.setState({
|
||||
deleteAccountLoading: false,
|
||||
deleteAccountShowConfirm: false,
|
||||
});
|
||||
this.context.router.history.push('/');
|
||||
} else if (res.op == UserOperation.GetSite) {
|
||||
let data = res.data as GetSiteResponse;
|
||||
this.state.site = data.site;
|
||||
this.setState(this.state);
|
||||
const data = res.data as GetSiteResponse;
|
||||
this.setState({
|
||||
site: data.site,
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
7
ui/src/interfaces.ts
vendored
7
ui/src/interfaces.ts
vendored
|
@ -937,3 +937,10 @@ export interface WebSocketJsonResponse {
|
|||
error?: string;
|
||||
reconnect?: boolean;
|
||||
}
|
||||
|
||||
export enum UserDetailsView {
|
||||
Overview,
|
||||
Comments,
|
||||
Posts,
|
||||
Saved,
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue