lemmy-ui/src/shared/components/person/inbox.tsx

890 lines
27 KiB
TypeScript
Raw Normal View History

import { None, Some } from "@sniptt/monads";
2021-02-22 02:39:04 +00:00
import { Component, linkEvent } from "inferno";
import {
BlockPersonResponse,
CommentReplyResponse,
CommentReplyView,
CommentReportResponse,
CommentResponse,
CommentSortType,
2020-12-24 01:58:27 +00:00
CommentView,
2021-03-15 18:09:31 +00:00
GetPersonMentions,
GetPersonMentionsResponse,
2020-12-24 01:58:27 +00:00
GetPrivateMessages,
GetReplies,
GetRepliesResponse,
GetSiteResponse,
PersonMentionResponse,
PersonMentionView,
PostReportResponse,
PrivateMessageResponse,
PrivateMessagesResponse,
PrivateMessageView,
UserOperation,
wsJsonToRes,
wsUserOp,
2021-02-22 02:39:04 +00:00
} from "lemmy-js-client";
import { Subscription } from "rxjs";
import { i18n } from "../../i18next";
import { CommentViewType, InitialFetchRequest } from "../../interfaces";
import { UserService, WebSocketService } from "../../services";
import {
auth,
commentsToFlatNodes,
createCommentLikeRes,
editCommentRes,
enableDownvotes,
fetchLimit,
isBrowser,
relTags,
saveCommentRes,
2020-09-09 00:48:17 +00:00
setIsoData,
setupTippy,
toast,
updatePersonBlock,
wsClient,
2020-09-09 00:48:17 +00:00
wsSubscribe,
} from "../../utils";
import { CommentNodes } from "../comment/comment-nodes";
import { CommentSortSelect } from "../common/comment-sort-select";
import { HtmlTags } from "../common/html-tags";
import { Icon, Spinner } from "../common/icon";
import { Paginator } from "../common/paginator";
import { PrivateMessage } from "../private_message/private-message";
enum UnreadOrAll {
Unread,
All,
}
enum MessageType {
All,
Replies,
Mentions,
Messages,
}
2020-12-24 01:58:27 +00:00
enum ReplyEnum {
Reply,
Mention,
Message,
}
type ReplyType = {
id: number;
type_: ReplyEnum;
view: CommentView | PrivateMessageView | PersonMentionView | CommentReplyView;
2020-12-24 01:58:27 +00:00
published: string;
};
interface InboxState {
unreadOrAll: UnreadOrAll;
messageType: MessageType;
replies: CommentReplyView[];
2021-03-15 18:09:31 +00:00
mentions: PersonMentionView[];
2020-12-24 01:58:27 +00:00
messages: PrivateMessageView[];
2021-02-02 20:24:25 +00:00
combined: ReplyType[];
sort: CommentSortType;
page: number;
siteRes: GetSiteResponse;
2020-09-09 00:48:17 +00:00
loading: boolean;
}
export class Inbox extends Component<any, InboxState> {
private isoData = setIsoData(
this.context,
GetRepliesResponse,
GetPersonMentionsResponse,
PrivateMessagesResponse
);
private subscription: Subscription;
private emptyState: InboxState = {
unreadOrAll: UnreadOrAll.Unread,
messageType: MessageType.All,
replies: [],
mentions: [],
messages: [],
2021-02-02 20:24:25 +00:00
combined: [],
sort: CommentSortType.New,
page: 1,
siteRes: this.isoData.site_res,
2020-09-09 00:48:17 +00:00
loading: true,
};
constructor(props: any, context: any) {
super(props, context);
this.state = this.emptyState;
this.handleSortChange = this.handleSortChange.bind(this);
this.handlePageChange = this.handlePageChange.bind(this);
if (UserService.Instance.myUserInfo.isNone() && isBrowser()) {
2021-02-22 02:39:04 +00:00
toast(i18n.t("not_logged_in"), "danger");
2020-12-15 23:43:35 +00:00
this.context.router.history.push(`/login`);
}
2020-09-09 00:48:17 +00:00
this.parseMessage = this.parseMessage.bind(this);
this.subscription = wsSubscribe(this.parseMessage);
2020-09-09 00:48:17 +00:00
// Only fetch the data if coming from another route
if (this.isoData.path == this.context.router.route.match.url) {
this.state = {
...this.state,
replies:
(this.isoData.routeData[0] as GetRepliesResponse).replies || [],
mentions:
(this.isoData.routeData[1] as GetPersonMentionsResponse).mentions ||
[],
messages:
(this.isoData.routeData[2] as PrivateMessagesResponse)
.private_messages || [],
loading: false,
};
this.state = { ...this.state, combined: this.buildCombined() };
2020-09-09 00:48:17 +00:00
} else {
this.refetch();
}
}
componentWillUnmount() {
2020-09-09 00:48:17 +00:00
if (isBrowser()) {
this.subscription.unsubscribe();
}
}
get documentTitle(): string {
return this.state.siteRes.site_view.match({
some: siteView =>
UserService.Instance.myUserInfo.match({
some: mui =>
`@${mui.local_user_view.person.name} ${i18n.t("inbox")} - ${
siteView.site.name
}`,
none: "",
}),
none: "",
});
}
render() {
let inboxRss = auth()
.ok()
.map(a => `/feeds/inbox/${a}.xml`);
return (
<div className="container">
2020-09-09 00:48:17 +00:00
{this.state.loading ? (
<h5>
2021-07-17 20:21:31 +00:00
<Spinner large />
2020-09-09 00:48:17 +00:00
</h5>
) : (
<div className="row">
<div className="col-12">
2020-09-11 18:09:21 +00:00
<HtmlTags
title={this.documentTitle}
path={this.context.router.route.match.url}
description={None}
image={None}
2020-09-11 18:09:21 +00:00
/>
<h5 className="mb-2">
2021-02-22 02:39:04 +00:00
{i18n.t("inbox")}
{inboxRss.match({
some: rss => (
<small>
<a href={rss} title="RSS" rel={relTags}>
<Icon icon="rss" classes="ml-2 text-muted small" />
</a>
<link
rel="alternate"
type="application/atom+xml"
href={rss}
/>
</small>
),
none: <></>,
})}
2020-09-09 00:48:17 +00:00
</h5>
{this.state.replies.length +
this.state.mentions.length +
this.state.messages.length >
0 &&
this.state.unreadOrAll == UnreadOrAll.Unread && (
<button
className="btn btn-secondary mb-2"
onClick={linkEvent(this, this.markAllAsRead)}
>
{i18n.t("mark_all_as_read")}
</button>
2020-09-09 00:48:17 +00:00
)}
{this.selects()}
{this.state.messageType == MessageType.All && this.all()}
{this.state.messageType == MessageType.Replies && this.replies()}
{this.state.messageType == MessageType.Mentions &&
this.mentions()}
{this.state.messageType == MessageType.Messages &&
this.messages()}
<Paginator
page={this.state.page}
onChange={this.handlePageChange}
/>
2020-09-09 00:48:17 +00:00
</div>
</div>
2020-09-09 00:48:17 +00:00
)}
</div>
);
}
unreadOrAllRadios() {
return (
<div className="btn-group btn-group-toggle flex-wrap mb-2">
<label
className={`btn btn-outline-secondary pointer
2021-02-22 02:39:04 +00:00
${this.state.unreadOrAll == UnreadOrAll.Unread && "active"}
`}
>
<input
type="radio"
value={UnreadOrAll.Unread}
checked={this.state.unreadOrAll == UnreadOrAll.Unread}
onChange={linkEvent(this, this.handleUnreadOrAllChange)}
/>
2021-02-22 02:39:04 +00:00
{i18n.t("unread")}
</label>
<label
className={`btn btn-outline-secondary pointer
2021-02-22 02:39:04 +00:00
${this.state.unreadOrAll == UnreadOrAll.All && "active"}
`}
>
<input
type="radio"
value={UnreadOrAll.All}
checked={this.state.unreadOrAll == UnreadOrAll.All}
onChange={linkEvent(this, this.handleUnreadOrAllChange)}
/>
2021-02-22 02:39:04 +00:00
{i18n.t("all")}
</label>
</div>
);
}
messageTypeRadios() {
return (
<div className="btn-group btn-group-toggle flex-wrap mb-2">
<label
className={`btn btn-outline-secondary pointer
2021-02-22 02:39:04 +00:00
${this.state.messageType == MessageType.All && "active"}
`}
>
<input
type="radio"
value={MessageType.All}
checked={this.state.messageType == MessageType.All}
onChange={linkEvent(this, this.handleMessageTypeChange)}
/>
2021-02-22 02:39:04 +00:00
{i18n.t("all")}
</label>
<label
className={`btn btn-outline-secondary pointer
2021-02-22 02:39:04 +00:00
${this.state.messageType == MessageType.Replies && "active"}
`}
>
<input
type="radio"
value={MessageType.Replies}
checked={this.state.messageType == MessageType.Replies}
onChange={linkEvent(this, this.handleMessageTypeChange)}
/>
2021-02-22 02:39:04 +00:00
{i18n.t("replies")}
</label>
<label
className={`btn btn-outline-secondary pointer
2021-02-22 02:39:04 +00:00
${this.state.messageType == MessageType.Mentions && "active"}
`}
>
<input
type="radio"
value={MessageType.Mentions}
checked={this.state.messageType == MessageType.Mentions}
onChange={linkEvent(this, this.handleMessageTypeChange)}
/>
2021-02-22 02:39:04 +00:00
{i18n.t("mentions")}
</label>
<label
className={`btn btn-outline-secondary pointer
2021-02-22 02:39:04 +00:00
${this.state.messageType == MessageType.Messages && "active"}
`}
>
<input
type="radio"
value={MessageType.Messages}
checked={this.state.messageType == MessageType.Messages}
onChange={linkEvent(this, this.handleMessageTypeChange)}
/>
2021-02-22 02:39:04 +00:00
{i18n.t("messages")}
</label>
</div>
);
}
selects() {
return (
<div className="mb-2">
<span className="mr-3">{this.unreadOrAllRadios()}</span>
<span className="mr-3">{this.messageTypeRadios()}</span>
<CommentSortSelect
sort={this.state.sort}
onChange={this.handleSortChange}
/>
</div>
);
}
replyToReplyType(r: CommentReplyView): ReplyType {
2021-02-02 20:24:25 +00:00
return {
id: r.comment_reply.id,
2020-12-24 01:58:27 +00:00
type_: ReplyEnum.Reply,
view: r,
published: r.comment.published,
2021-02-02 20:24:25 +00:00
};
}
2021-03-15 18:09:31 +00:00
mentionToReplyType(r: PersonMentionView): ReplyType {
2021-02-02 20:24:25 +00:00
return {
2021-03-15 18:09:31 +00:00
id: r.person_mention.id,
2020-12-24 01:58:27 +00:00
type_: ReplyEnum.Mention,
view: r,
published: r.comment.published,
2021-02-02 20:24:25 +00:00
};
}
messageToReplyType(r: PrivateMessageView): ReplyType {
return {
id: r.private_message.id,
2020-12-24 01:58:27 +00:00
type_: ReplyEnum.Message,
view: r,
published: r.private_message.published,
2021-02-02 20:24:25 +00:00
};
}
buildCombined(): ReplyType[] {
let replies: ReplyType[] = this.state.replies.map(r =>
this.replyToReplyType(r)
);
let mentions: ReplyType[] = this.state.mentions.map(r =>
this.mentionToReplyType(r)
);
let messages: ReplyType[] = this.state.messages.map(r =>
this.messageToReplyType(r)
);
2020-12-24 01:58:27 +00:00
return [...replies, ...mentions, ...messages].sort((a, b) =>
b.published.localeCompare(a.published)
);
}
renderReplyType(i: ReplyType) {
switch (i.type_) {
case ReplyEnum.Reply:
return (
<CommentNodes
key={i.id}
nodes={[
{ comment_view: i.view as CommentView, children: [], depth: 0 },
]}
viewType={CommentViewType.Flat}
moderators={None}
admins={None}
maxCommentsShown={None}
2020-12-24 01:58:27 +00:00
noIndent
markable
showCommunity
showContext
enableDownvotes={enableDownvotes(this.state.siteRes)}
2020-12-24 01:58:27 +00:00
/>
);
case ReplyEnum.Mention:
return (
<CommentNodes
key={i.id}
nodes={[
{
comment_view: i.view as PersonMentionView,
children: [],
depth: 0,
},
]}
viewType={CommentViewType.Flat}
moderators={None}
admins={None}
maxCommentsShown={None}
2020-12-24 01:58:27 +00:00
noIndent
markable
showCommunity
showContext
enableDownvotes={enableDownvotes(this.state.siteRes)}
2020-12-24 01:58:27 +00:00
/>
);
case ReplyEnum.Message:
return (
<PrivateMessage
key={i.id}
private_message_view={i.view as PrivateMessageView}
/>
);
default:
return <div />;
}
}
all() {
2021-02-02 20:24:25 +00:00
return <div>{this.state.combined.map(i => this.renderReplyType(i))}</div>;
}
replies() {
return (
<div>
<CommentNodes
nodes={commentsToFlatNodes(this.state.replies)}
viewType={CommentViewType.Flat}
moderators={None}
admins={None}
maxCommentsShown={None}
noIndent
markable
showCommunity
showContext
enableDownvotes={enableDownvotes(this.state.siteRes)}
/>
</div>
);
}
mentions() {
return (
<div>
2020-12-24 01:58:27 +00:00
{this.state.mentions.map(umv => (
<CommentNodes
2021-03-15 18:09:31 +00:00
key={umv.person_mention.id}
nodes={[{ comment_view: umv, children: [], depth: 0 }]}
viewType={CommentViewType.Flat}
moderators={None}
admins={None}
maxCommentsShown={None}
noIndent
markable
showCommunity
showContext
enableDownvotes={enableDownvotes(this.state.siteRes)}
/>
))}
</div>
);
}
messages() {
return (
<div>
2020-12-24 01:58:27 +00:00
{this.state.messages.map(pmv => (
<PrivateMessage
key={pmv.private_message.id}
private_message_view={pmv}
/>
))}
</div>
);
}
handlePageChange(page: number) {
this.setState({ page });
this.refetch();
}
handleUnreadOrAllChange(i: Inbox, event: any) {
i.setState({ unreadOrAll: Number(event.target.value), page: 1 });
i.refetch();
}
handleMessageTypeChange(i: Inbox, event: any) {
i.setState({ messageType: Number(event.target.value), page: 1 });
i.refetch();
}
static fetchInitialData(req: InitialFetchRequest): Promise<any>[] {
2020-09-09 00:48:17 +00:00
let promises: Promise<any>[] = [];
let sort = Some(CommentSortType.New);
2020-09-09 00:48:17 +00:00
// It can be /u/me, or /username/1
let repliesForm = new GetReplies({
sort,
unread_only: Some(true),
page: Some(1),
limit: Some(fetchLimit),
auth: req.auth.unwrap(),
});
promises.push(req.client.getReplies(repliesForm));
2020-09-09 00:48:17 +00:00
let personMentionsForm = new GetPersonMentions({
sort,
unread_only: Some(true),
page: Some(1),
limit: Some(fetchLimit),
auth: req.auth.unwrap(),
});
2021-03-15 18:09:31 +00:00
promises.push(req.client.getPersonMentions(personMentionsForm));
2020-09-09 00:48:17 +00:00
let privateMessagesForm = new GetPrivateMessages({
unread_only: Some(true),
page: Some(1),
limit: Some(fetchLimit),
auth: req.auth.unwrap(),
});
promises.push(req.client.getPrivateMessages(privateMessagesForm));
2020-09-09 00:48:17 +00:00
return promises;
}
refetch() {
let sort = Some(this.state.sort);
let unread_only = Some(this.state.unreadOrAll == UnreadOrAll.Unread);
let page = Some(this.state.page);
let limit = Some(fetchLimit);
let repliesForm = new GetReplies({
sort,
unread_only,
page,
limit,
auth: auth().unwrap(),
});
WebSocketService.Instance.send(wsClient.getReplies(repliesForm));
let personMentionsForm = new GetPersonMentions({
sort,
unread_only,
page,
limit,
auth: auth().unwrap(),
});
2021-03-15 18:09:31 +00:00
WebSocketService.Instance.send(
wsClient.getPersonMentions(personMentionsForm)
);
let privateMessagesForm = new GetPrivateMessages({
unread_only,
page,
limit,
auth: auth().unwrap(),
});
WebSocketService.Instance.send(
wsClient.getPrivateMessages(privateMessagesForm)
);
}
handleSortChange(val: CommentSortType) {
this.setState({ sort: val, page: 1 });
this.refetch();
}
markAllAsRead(i: Inbox) {
WebSocketService.Instance.send(
wsClient.markAllAsRead({
auth: auth().unwrap(),
})
);
i.setState({ replies: [], mentions: [], messages: [] });
i.setState({ combined: i.buildCombined() });
2021-10-17 17:42:30 +00:00
UserService.Instance.unreadInboxCountSub.next(0);
window.scrollTo(0, 0);
i.setState(i.state);
}
2021-10-17 17:42:30 +00:00
sendUnreadCount(read: boolean) {
let urcs = UserService.Instance.unreadInboxCountSub;
if (read) {
urcs.next(urcs.getValue() - 1);
} else {
urcs.next(urcs.getValue() + 1);
}
}
2020-12-24 01:58:27 +00:00
parseMessage(msg: any) {
let op = wsUserOp(msg);
2021-02-02 20:24:25 +00:00
console.log(msg);
if (msg.error) {
2021-02-22 02:39:04 +00:00
toast(i18n.t(msg.error), "danger");
return;
} else if (msg.reconnect) {
this.refetch();
2020-12-24 01:58:27 +00:00
} else if (op == UserOperation.GetReplies) {
let data = wsJsonToRes<GetRepliesResponse>(msg, GetRepliesResponse);
this.setState({ replies: data.replies });
this.setState({ combined: this.buildCombined(), loading: false });
window.scrollTo(0, 0);
setupTippy();
2021-03-15 18:09:31 +00:00
} else if (op == UserOperation.GetPersonMentions) {
let data = wsJsonToRes<GetPersonMentionsResponse>(
msg,
GetPersonMentionsResponse
);
this.setState({ mentions: data.mentions });
this.setState({ combined: this.buildCombined() });
window.scrollTo(0, 0);
setupTippy();
2020-12-24 01:58:27 +00:00
} else if (op == UserOperation.GetPrivateMessages) {
let data = wsJsonToRes<PrivateMessagesResponse>(
msg,
PrivateMessagesResponse
);
this.setState({ messages: data.private_messages });
this.setState({ combined: this.buildCombined() });
window.scrollTo(0, 0);
setupTippy();
2020-12-24 01:58:27 +00:00
} else if (op == UserOperation.EditPrivateMessage) {
let data = wsJsonToRes<PrivateMessageResponse>(
msg,
PrivateMessageResponse
);
2020-12-24 01:58:27 +00:00
let found: PrivateMessageView = this.state.messages.find(
m =>
m.private_message.id === data.private_message_view.private_message.id
);
if (found) {
2021-02-02 20:24:25 +00:00
let combinedView = this.state.combined.find(
i => i.id == data.private_message_view.private_message.id
).view as PrivateMessageView;
found.private_message.content = combinedView.private_message.content =
2020-12-24 01:58:27 +00:00
data.private_message_view.private_message.content;
2021-02-02 20:24:25 +00:00
found.private_message.updated = combinedView.private_message.updated =
2020-12-24 01:58:27 +00:00
data.private_message_view.private_message.updated;
}
this.setState(this.state);
2020-12-24 01:58:27 +00:00
} else if (op == UserOperation.DeletePrivateMessage) {
let data = wsJsonToRes<PrivateMessageResponse>(
msg,
PrivateMessageResponse
);
2020-12-24 01:58:27 +00:00
let found: PrivateMessageView = this.state.messages.find(
m =>
m.private_message.id === data.private_message_view.private_message.id
);
if (found) {
2021-02-02 20:24:25 +00:00
let combinedView = this.state.combined.find(
i => i.id == data.private_message_view.private_message.id
).view as PrivateMessageView;
found.private_message.deleted = combinedView.private_message.deleted =
2020-12-24 01:58:27 +00:00
data.private_message_view.private_message.deleted;
2021-02-02 20:24:25 +00:00
found.private_message.updated = combinedView.private_message.updated =
2020-12-24 01:58:27 +00:00
data.private_message_view.private_message.updated;
}
this.setState(this.state);
2020-12-24 01:58:27 +00:00
} else if (op == UserOperation.MarkPrivateMessageAsRead) {
let data = wsJsonToRes<PrivateMessageResponse>(
msg,
PrivateMessageResponse
);
2020-12-24 01:58:27 +00:00
let found: PrivateMessageView = this.state.messages.find(
m =>
m.private_message.id === data.private_message_view.private_message.id
);
if (found) {
2021-02-02 20:24:25 +00:00
let combinedView = this.state.combined.find(
i =>
i.id == data.private_message_view.private_message.id &&
i.type_ == ReplyEnum.Message
2021-02-02 20:24:25 +00:00
).view as PrivateMessageView;
found.private_message.updated = combinedView.private_message.updated =
2020-12-24 01:58:27 +00:00
data.private_message_view.private_message.updated;
// If youre in the unread view, just remove it from the list
2020-12-24 01:58:27 +00:00
if (
this.state.unreadOrAll == UnreadOrAll.Unread &&
data.private_message_view.private_message.read
) {
this.setState({
messages: this.state.messages.filter(
r =>
r.private_message.id !==
data.private_message_view.private_message.id
),
});
this.setState({
combined: this.state.combined.filter(
r => r.id !== data.private_message_view.private_message.id
),
});
2021-02-02 20:24:25 +00:00
} else {
found.private_message.read = combinedView.private_message.read =
2020-12-24 01:58:27 +00:00
data.private_message_view.private_message.read;
}
}
2021-10-17 17:42:30 +00:00
this.sendUnreadCount(data.private_message_view.private_message.read);
this.setState(this.state);
2020-12-24 01:58:27 +00:00
} else if (op == UserOperation.MarkAllAsRead) {
// Moved to be instant
} else if (
2020-12-24 01:58:27 +00:00
op == UserOperation.EditComment ||
op == UserOperation.DeleteComment ||
op == UserOperation.RemoveComment
) {
let data = wsJsonToRes<CommentResponse>(msg, CommentResponse);
2020-12-24 01:58:27 +00:00
editCommentRes(data.comment_view, this.state.replies);
this.setState(this.state);
} else if (op == UserOperation.MarkCommentReplyAsRead) {
let data = wsJsonToRes<CommentReplyResponse>(msg, CommentReplyResponse);
let found = this.state.replies.find(
c => c.comment_reply.id == data.comment_reply_view.comment_reply.id
);
if (found) {
2021-02-02 20:24:25 +00:00
let combinedView = this.state.combined.find(
i =>
i.id == data.comment_reply_view.comment_reply.id &&
i.type_ == ReplyEnum.Reply
).view as CommentReplyView;
found.comment.content = combinedView.comment.content =
data.comment_reply_view.comment.content;
found.comment.updated = combinedView.comment.updated =
data.comment_reply_view.comment.updated;
found.comment.removed = combinedView.comment.removed =
data.comment_reply_view.comment.removed;
found.comment.deleted = combinedView.comment.deleted =
data.comment_reply_view.comment.deleted;
found.counts.upvotes = combinedView.counts.upvotes =
data.comment_reply_view.counts.upvotes;
found.counts.downvotes = combinedView.counts.downvotes =
data.comment_reply_view.counts.downvotes;
found.counts.score = combinedView.counts.score =
data.comment_reply_view.counts.score;
2021-10-17 17:42:30 +00:00
// If youre in the unread view, just remove it from the list
if (
this.state.unreadOrAll == UnreadOrAll.Unread &&
data.comment_reply_view.comment_reply.read
) {
this.setState({
replies: this.state.replies.filter(
r =>
r.comment_reply.id !== data.comment_reply_view.comment_reply.id
),
});
this.setState({
combined: this.state.combined.filter(
r => r.id !== data.comment_reply_view.comment_reply.id
),
});
} else {
found.comment_reply.read = combinedView.comment_reply.read =
data.comment_reply_view.comment_reply.read;
}
}
this.sendUnreadCount(data.comment_reply_view.comment_reply.read);
this.setState(this.state);
2021-03-15 18:09:31 +00:00
} else if (op == UserOperation.MarkPersonMentionAsRead) {
let data = wsJsonToRes<PersonMentionResponse>(msg, PersonMentionResponse);
2020-12-24 01:58:27 +00:00
// TODO this might not be correct, it might need to use the comment id
let found = this.state.mentions.find(
2021-03-15 18:09:31 +00:00
c => c.person_mention.id == data.person_mention_view.person_mention.id
2020-12-24 01:58:27 +00:00
);
2021-02-02 20:24:25 +00:00
if (found) {
let combinedView = this.state.combined.find(
i =>
i.id == data.person_mention_view.person_mention.id &&
i.type_ == ReplyEnum.Mention
2021-03-15 18:09:31 +00:00
).view as PersonMentionView;
2021-02-02 20:24:25 +00:00
found.comment.content = combinedView.comment.content =
2021-03-15 18:09:31 +00:00
data.person_mention_view.comment.content;
2021-02-02 20:24:25 +00:00
found.comment.updated = combinedView.comment.updated =
2021-03-15 18:09:31 +00:00
data.person_mention_view.comment.updated;
2021-02-02 20:24:25 +00:00
found.comment.removed = combinedView.comment.removed =
2021-03-15 18:09:31 +00:00
data.person_mention_view.comment.removed;
2021-02-02 20:24:25 +00:00
found.comment.deleted = combinedView.comment.deleted =
2021-03-15 18:09:31 +00:00
data.person_mention_view.comment.deleted;
2021-02-02 20:24:25 +00:00
found.counts.upvotes = combinedView.counts.upvotes =
2021-03-15 18:09:31 +00:00
data.person_mention_view.counts.upvotes;
2021-02-02 20:24:25 +00:00
found.counts.downvotes = combinedView.counts.downvotes =
2021-03-15 18:09:31 +00:00
data.person_mention_view.counts.downvotes;
2021-02-02 20:24:25 +00:00
found.counts.score = combinedView.counts.score =
2021-03-15 18:09:31 +00:00
data.person_mention_view.counts.score;
2021-02-02 20:24:25 +00:00
// If youre in the unread view, just remove it from the list
if (
this.state.unreadOrAll == UnreadOrAll.Unread &&
2021-03-15 18:09:31 +00:00
data.person_mention_view.person_mention.read
2021-02-02 20:24:25 +00:00
) {
this.setState({
mentions: this.state.mentions.filter(
r =>
r.person_mention.id !==
data.person_mention_view.person_mention.id
),
});
this.setState({
combined: this.state.combined.filter(
r => r.id !== data.person_mention_view.person_mention.id
),
});
2021-02-02 20:24:25 +00:00
} else {
// TODO test to make sure these mentions are getting marked as read
2021-03-15 18:09:31 +00:00
found.person_mention.read = combinedView.person_mention.read =
data.person_mention_view.person_mention.read;
2021-02-02 20:24:25 +00:00
}
}
2021-10-17 17:42:30 +00:00
this.sendUnreadCount(data.person_mention_view.person_mention.read);
this.setState(this.state);
2020-12-24 01:58:27 +00:00
} else if (op == UserOperation.CreatePrivateMessage) {
let data = wsJsonToRes<PrivateMessageResponse>(
msg,
PrivateMessageResponse
);
UserService.Instance.myUserInfo.match({
some: mui => {
if (
data.private_message_view.recipient.id ==
mui.local_user_view.person.id
) {
this.state.messages.unshift(data.private_message_view);
this.state.combined.unshift(
this.messageToReplyType(data.private_message_view)
);
this.setState(this.state);
}
},
none: void 0,
});
2020-12-24 01:58:27 +00:00
} else if (op == UserOperation.SaveComment) {
let data = wsJsonToRes<CommentResponse>(msg, CommentResponse);
2020-12-24 01:58:27 +00:00
saveCommentRes(data.comment_view, this.state.replies);
this.setState(this.state);
setupTippy();
2020-12-24 01:58:27 +00:00
} else if (op == UserOperation.CreateCommentLike) {
let data = wsJsonToRes<CommentResponse>(msg, CommentResponse);
2020-12-24 01:58:27 +00:00
createCommentLikeRes(data.comment_view, this.state.replies);
this.setState(this.state);
} else if (op == UserOperation.BlockPerson) {
let data = wsJsonToRes<BlockPersonResponse>(msg, BlockPersonResponse);
updatePersonBlock(data);
} else if (op == UserOperation.CreatePostReport) {
let data = wsJsonToRes<PostReportResponse>(msg, PostReportResponse);
if (data) {
toast(i18n.t("report_created"));
}
} else if (op == UserOperation.CreateCommentReport) {
let data = wsJsonToRes<CommentReportResponse>(msg, CommentReportResponse);
if (data) {
toast(i18n.t("report_created"));
}
}
}
isMention(view: any): view is PersonMentionView {
return (view as PersonMentionView).person_mention !== undefined;
}
isReply(view: any): view is CommentReplyView {
return (view as CommentReplyView).comment_reply !== undefined;
}
}