14 import { RouteDataResponse } from "@utils/types";
15 import { Component, linkEvent } from "inferno";
20 BanFromCommunityResponse,
27 CommentReportResponse,
35 CreatePrivateMessageReport,
41 GetPersonMentionsResponse,
44 MarkCommentReplyAsRead,
45 MarkPersonMentionAsRead,
46 MarkPrivateMessageAsRead,
47 PersonMentionResponse,
49 PrivateMessageReportResponse,
50 PrivateMessageResponse,
52 PrivateMessagesResponse,
60 } from "lemmy-js-client";
61 import { fetchLimit, relTags } from "../../config";
62 import { i18n } from "../../i18next";
63 import { CommentViewType, InitialFetchRequest } from "../../interfaces";
64 import { UserService } from "../../services";
65 import { FirstLoadService } from "../../services/FirstLoadService";
66 import { HttpService, RequestState } from "../../services/HttpService";
67 import { toast } from "../../toast";
68 import { CommentNodes } from "../comment/comment-nodes";
69 import { CommentSortSelect } from "../common/comment-sort-select";
70 import { HtmlTags } from "../common/html-tags";
71 import { Icon, Spinner } from "../common/icon";
72 import { Paginator } from "../common/paginator";
73 import { PrivateMessage } from "../private_message/private-message";
93 type InboxData = RouteDataResponse<{
94 repliesRes: GetRepliesResponse;
95 mentionsRes: GetPersonMentionsResponse;
96 messagesRes: PrivateMessagesResponse;
102 view: CommentView | PrivateMessageView | PersonMentionView | CommentReplyView;
106 interface InboxState {
107 unreadOrAll: UnreadOrAll;
108 messageType: MessageType;
109 repliesRes: RequestState<GetRepliesResponse>;
110 mentionsRes: RequestState<GetPersonMentionsResponse>;
111 messagesRes: RequestState<PrivateMessagesResponse>;
112 markAllAsReadRes: RequestState<GetRepliesResponse>;
113 sort: CommentSortType;
115 siteRes: GetSiteResponse;
116 finished: Map<CommentId, boolean | undefined>;
117 isIsomorphic: boolean;
120 export class Inbox extends Component<any, InboxState> {
121 private isoData = setIsoData<InboxData>(this.context);
122 state: InboxState = {
123 unreadOrAll: UnreadOrAll.Unread,
124 messageType: MessageType.All,
127 siteRes: this.isoData.site_res,
128 repliesRes: { state: "empty" },
129 mentionsRes: { state: "empty" },
130 messagesRes: { state: "empty" },
131 markAllAsReadRes: { state: "empty" },
136 constructor(props: any, context: any) {
137 super(props, context);
139 this.handleSortChange = this.handleSortChange.bind(this);
140 this.handlePageChange = this.handlePageChange.bind(this);
142 this.handleCreateComment = this.handleCreateComment.bind(this);
143 this.handleEditComment = this.handleEditComment.bind(this);
144 this.handleSaveComment = this.handleSaveComment.bind(this);
145 this.handleBlockPerson = this.handleBlockPerson.bind(this);
146 this.handleDeleteComment = this.handleDeleteComment.bind(this);
147 this.handleRemoveComment = this.handleRemoveComment.bind(this);
148 this.handleCommentVote = this.handleCommentVote.bind(this);
149 this.handleAddModToCommunity = this.handleAddModToCommunity.bind(this);
150 this.handleAddAdmin = this.handleAddAdmin.bind(this);
151 this.handlePurgePerson = this.handlePurgePerson.bind(this);
152 this.handlePurgeComment = this.handlePurgeComment.bind(this);
153 this.handleCommentReport = this.handleCommentReport.bind(this);
154 this.handleDistinguishComment = this.handleDistinguishComment.bind(this);
155 this.handleTransferCommunity = this.handleTransferCommunity.bind(this);
156 this.handleCommentReplyRead = this.handleCommentReplyRead.bind(this);
157 this.handlePersonMentionRead = this.handlePersonMentionRead.bind(this);
158 this.handleBanFromCommunity = this.handleBanFromCommunity.bind(this);
159 this.handleBanPerson = this.handleBanPerson.bind(this);
161 this.handleDeleteMessage = this.handleDeleteMessage.bind(this);
162 this.handleMarkMessageAsRead = this.handleMarkMessageAsRead.bind(this);
163 this.handleMessageReport = this.handleMessageReport.bind(this);
164 this.handleCreateMessage = this.handleCreateMessage.bind(this);
165 this.handleEditMessage = this.handleEditMessage.bind(this);
167 // Only fetch the data if coming from another route
168 if (FirstLoadService.isFirstLoad) {
169 const { mentionsRes, messagesRes, repliesRes } = this.isoData.routeData;
181 async componentDidMount() {
182 if (!this.state.isIsomorphic) {
183 await this.refetch();
187 get documentTitle(): string {
188 const mui = UserService.Instance.myUserInfo;
190 ? `@${mui.local_user_view.person.name} ${i18n.t("inbox")} - ${
191 this.state.siteRes.site_view.site.name
196 get hasUnreads(): boolean {
197 if (this.state.unreadOrAll == UnreadOrAll.Unread) {
198 const { repliesRes, mentionsRes, messagesRes } = this.state;
200 repliesRes.state == "success" ? repliesRes.data.replies.length : 0;
202 mentionsRes.state == "success" ? mentionsRes.data.mentions.length : 0;
204 messagesRes.state == "success"
205 ? messagesRes.data.private_messages.length
208 return replyCount + mentionCount + messageCount > 0;
215 const auth = myAuth();
216 const inboxRss = auth ? `/feeds/inbox/${auth}.xml` : undefined;
218 <div className="inbox container-lg">
219 <div className="row">
220 <div className="col-12">
222 title={this.documentTitle}
223 path={this.context.router.route.match.url}
225 <h5 className="mb-2">
229 <a href={inboxRss} title="RSS" rel={relTags}>
230 <Icon icon="rss" classes="ms-2 text-muted small" />
234 type="application/atom+xml"
240 {this.hasUnreads && (
242 className="btn btn-secondary mb-2"
243 onClick={linkEvent(this, this.handleMarkAllAsRead)}
245 {this.state.markAllAsReadRes.state == "loading" ? (
248 i18n.t("mark_all_as_read")
255 page={this.state.page}
256 onChange={this.handlePageChange}
265 switch (this.state.messageType) {
266 case MessageType.All: {
269 case MessageType.Replies: {
270 return this.replies();
272 case MessageType.Mentions: {
273 return this.mentions();
275 case MessageType.Messages: {
276 return this.messages();
284 unreadOrAllRadios() {
286 <div className="btn-group btn-group-toggle flex-wrap mb-2">
288 className={`btn btn-outline-secondary pointer
289 ${this.state.unreadOrAll == UnreadOrAll.Unread && "active"}
294 className="btn-check"
295 value={UnreadOrAll.Unread}
296 checked={this.state.unreadOrAll == UnreadOrAll.Unread}
297 onChange={linkEvent(this, this.handleUnreadOrAllChange)}
302 className={`btn btn-outline-secondary pointer
303 ${this.state.unreadOrAll == UnreadOrAll.All && "active"}
308 className="btn-check"
309 value={UnreadOrAll.All}
310 checked={this.state.unreadOrAll == UnreadOrAll.All}
311 onChange={linkEvent(this, this.handleUnreadOrAllChange)}
319 messageTypeRadios() {
321 <div className="btn-group btn-group-toggle flex-wrap mb-2">
323 className={`btn btn-outline-secondary pointer
324 ${this.state.messageType == MessageType.All && "active"}
329 className="btn-check"
330 value={MessageType.All}
331 checked={this.state.messageType == MessageType.All}
332 onChange={linkEvent(this, this.handleMessageTypeChange)}
337 className={`btn btn-outline-secondary pointer
338 ${this.state.messageType == MessageType.Replies && "active"}
343 className="btn-check"
344 value={MessageType.Replies}
345 checked={this.state.messageType == MessageType.Replies}
346 onChange={linkEvent(this, this.handleMessageTypeChange)}
351 className={`btn btn-outline-secondary pointer
352 ${this.state.messageType == MessageType.Mentions && "active"}
357 className="btn-check"
358 value={MessageType.Mentions}
359 checked={this.state.messageType == MessageType.Mentions}
360 onChange={linkEvent(this, this.handleMessageTypeChange)}
365 className={`btn btn-outline-secondary pointer
366 ${this.state.messageType == MessageType.Messages && "active"}
371 className="btn-check"
372 value={MessageType.Messages}
373 checked={this.state.messageType == MessageType.Messages}
374 onChange={linkEvent(this, this.handleMessageTypeChange)}
384 <div className="mb-2">
385 <span className="me-3">{this.unreadOrAllRadios()}</span>
386 <span className="me-3">{this.messageTypeRadios()}</span>
388 sort={this.state.sort}
389 onChange={this.handleSortChange}
395 replyToReplyType(r: CommentReplyView): ReplyType {
397 id: r.comment_reply.id,
398 type_: ReplyEnum.Reply,
400 published: r.comment.published,
404 mentionToReplyType(r: PersonMentionView): ReplyType {
406 id: r.person_mention.id,
407 type_: ReplyEnum.Mention,
409 published: r.comment.published,
413 messageToReplyType(r: PrivateMessageView): ReplyType {
415 id: r.private_message.id,
416 type_: ReplyEnum.Message,
418 published: r.private_message.published,
422 buildCombined(): ReplyType[] {
423 const replies: ReplyType[] =
424 this.state.repliesRes.state == "success"
425 ? this.state.repliesRes.data.replies.map(this.replyToReplyType)
427 const mentions: ReplyType[] =
428 this.state.mentionsRes.state == "success"
429 ? this.state.mentionsRes.data.mentions.map(this.mentionToReplyType)
431 const messages: ReplyType[] =
432 this.state.messagesRes.state == "success"
433 ? this.state.messagesRes.data.private_messages.map(
434 this.messageToReplyType
438 return [...replies, ...mentions, ...messages].sort((a, b) =>
439 b.published.localeCompare(a.published)
443 renderReplyType(i: ReplyType) {
445 case ReplyEnum.Reply:
450 { comment_view: i.view as CommentView, children: [], depth: 0 },
452 viewType={CommentViewType.Flat}
453 finished={this.state.finished}
458 enableDownvotes={enableDownvotes(this.state.siteRes)}
459 allLanguages={this.state.siteRes.all_languages}
460 siteLanguages={this.state.siteRes.discussion_languages}
461 onSaveComment={this.handleSaveComment}
462 onBlockPerson={this.handleBlockPerson}
463 onDeleteComment={this.handleDeleteComment}
464 onRemoveComment={this.handleRemoveComment}
465 onCommentVote={this.handleCommentVote}
466 onCommentReport={this.handleCommentReport}
467 onDistinguishComment={this.handleDistinguishComment}
468 onAddModToCommunity={this.handleAddModToCommunity}
469 onAddAdmin={this.handleAddAdmin}
470 onTransferCommunity={this.handleTransferCommunity}
471 onPurgeComment={this.handlePurgeComment}
472 onPurgePerson={this.handlePurgePerson}
473 onCommentReplyRead={this.handleCommentReplyRead}
474 onPersonMentionRead={this.handlePersonMentionRead}
475 onBanPersonFromCommunity={this.handleBanFromCommunity}
476 onBanPerson={this.handleBanPerson}
477 onCreateComment={this.handleCreateComment}
478 onEditComment={this.handleEditComment}
481 case ReplyEnum.Mention:
487 comment_view: i.view as PersonMentionView,
492 finished={this.state.finished}
493 viewType={CommentViewType.Flat}
498 enableDownvotes={enableDownvotes(this.state.siteRes)}
499 allLanguages={this.state.siteRes.all_languages}
500 siteLanguages={this.state.siteRes.discussion_languages}
501 onSaveComment={this.handleSaveComment}
502 onBlockPerson={this.handleBlockPerson}
503 onDeleteComment={this.handleDeleteComment}
504 onRemoveComment={this.handleRemoveComment}
505 onCommentVote={this.handleCommentVote}
506 onCommentReport={this.handleCommentReport}
507 onDistinguishComment={this.handleDistinguishComment}
508 onAddModToCommunity={this.handleAddModToCommunity}
509 onAddAdmin={this.handleAddAdmin}
510 onTransferCommunity={this.handleTransferCommunity}
511 onPurgeComment={this.handlePurgeComment}
512 onPurgePerson={this.handlePurgePerson}
513 onCommentReplyRead={this.handleCommentReplyRead}
514 onPersonMentionRead={this.handlePersonMentionRead}
515 onBanPersonFromCommunity={this.handleBanFromCommunity}
516 onBanPerson={this.handleBanPerson}
517 onCreateComment={this.handleCreateComment}
518 onEditComment={this.handleEditComment}
521 case ReplyEnum.Message:
525 private_message_view={i.view as PrivateMessageView}
526 onDelete={this.handleDeleteMessage}
527 onMarkRead={this.handleMarkMessageAsRead}
528 onReport={this.handleMessageReport}
529 onCreate={this.handleCreateMessage}
530 onEdit={this.handleEditMessage}
540 this.state.repliesRes.state == "loading" ||
541 this.state.mentionsRes.state == "loading" ||
542 this.state.messagesRes.state == "loading"
551 <div>{this.buildCombined().map(r => this.renderReplyType(r))}</div>
557 switch (this.state.repliesRes.state) {
565 const replies = this.state.repliesRes.data.replies;
569 nodes={commentsToFlatNodes(replies)}
570 viewType={CommentViewType.Flat}
571 finished={this.state.finished}
576 enableDownvotes={enableDownvotes(this.state.siteRes)}
577 allLanguages={this.state.siteRes.all_languages}
578 siteLanguages={this.state.siteRes.discussion_languages}
579 onSaveComment={this.handleSaveComment}
580 onBlockPerson={this.handleBlockPerson}
581 onDeleteComment={this.handleDeleteComment}
582 onRemoveComment={this.handleRemoveComment}
583 onCommentVote={this.handleCommentVote}
584 onCommentReport={this.handleCommentReport}
585 onDistinguishComment={this.handleDistinguishComment}
586 onAddModToCommunity={this.handleAddModToCommunity}
587 onAddAdmin={this.handleAddAdmin}
588 onTransferCommunity={this.handleTransferCommunity}
589 onPurgeComment={this.handlePurgeComment}
590 onPurgePerson={this.handlePurgePerson}
591 onCommentReplyRead={this.handleCommentReplyRead}
592 onPersonMentionRead={this.handlePersonMentionRead}
593 onBanPersonFromCommunity={this.handleBanFromCommunity}
594 onBanPerson={this.handleBanPerson}
595 onCreateComment={this.handleCreateComment}
596 onEditComment={this.handleEditComment}
605 switch (this.state.mentionsRes.state) {
613 const mentions = this.state.mentionsRes.data.mentions;
616 {mentions.map(umv => (
618 key={umv.person_mention.id}
619 nodes={[{ comment_view: umv, children: [], depth: 0 }]}
620 viewType={CommentViewType.Flat}
621 finished={this.state.finished}
626 enableDownvotes={enableDownvotes(this.state.siteRes)}
627 allLanguages={this.state.siteRes.all_languages}
628 siteLanguages={this.state.siteRes.discussion_languages}
629 onSaveComment={this.handleSaveComment}
630 onBlockPerson={this.handleBlockPerson}
631 onDeleteComment={this.handleDeleteComment}
632 onRemoveComment={this.handleRemoveComment}
633 onCommentVote={this.handleCommentVote}
634 onCommentReport={this.handleCommentReport}
635 onDistinguishComment={this.handleDistinguishComment}
636 onAddModToCommunity={this.handleAddModToCommunity}
637 onAddAdmin={this.handleAddAdmin}
638 onTransferCommunity={this.handleTransferCommunity}
639 onPurgeComment={this.handlePurgeComment}
640 onPurgePerson={this.handlePurgePerson}
641 onCommentReplyRead={this.handleCommentReplyRead}
642 onPersonMentionRead={this.handlePersonMentionRead}
643 onBanPersonFromCommunity={this.handleBanFromCommunity}
644 onBanPerson={this.handleBanPerson}
645 onCreateComment={this.handleCreateComment}
646 onEditComment={this.handleEditComment}
656 switch (this.state.messagesRes.state) {
664 const messages = this.state.messagesRes.data.private_messages;
667 {messages.map(pmv => (
669 key={pmv.private_message.id}
670 private_message_view={pmv}
671 onDelete={this.handleDeleteMessage}
672 onMarkRead={this.handleMarkMessageAsRead}
673 onReport={this.handleMessageReport}
674 onCreate={this.handleCreateMessage}
675 onEdit={this.handleEditMessage}
684 async handlePageChange(page: number) {
685 this.setState({ page });
686 await this.refetch();
689 async handleUnreadOrAllChange(i: Inbox, event: any) {
690 i.setState({ unreadOrAll: Number(event.target.value), page: 1 });
694 async handleMessageTypeChange(i: Inbox, event: any) {
695 i.setState({ messageType: Number(event.target.value), page: 1 });
699 static async fetchInitialData({
702 }: InitialFetchRequest): Promise<InboxData> {
703 const sort: CommentSortType = "New";
707 ? await client.getPersonMentions({
714 : { state: "empty" },
716 ? await client.getPrivateMessages({
722 : { state: "empty" },
724 ? await client.getReplies({
731 : { state: "empty" },
736 const sort = this.state.sort;
737 const unread_only = this.state.unreadOrAll == UnreadOrAll.Unread;
738 const page = this.state.page;
739 const limit = fetchLimit;
740 const auth = myAuthRequired();
742 this.setState({ repliesRes: { state: "loading" } });
744 repliesRes: await HttpService.client.getReplies({
753 this.setState({ mentionsRes: { state: "loading" } });
755 mentionsRes: await HttpService.client.getPersonMentions({
764 this.setState({ messagesRes: { state: "loading" } });
766 messagesRes: await HttpService.client.getPrivateMessages({
775 async handleSortChange(val: CommentSortType) {
776 this.setState({ sort: val, page: 1 });
777 await this.refetch();
780 async handleMarkAllAsRead(i: Inbox) {
781 i.setState({ markAllAsReadRes: { state: "loading" } });
784 markAllAsReadRes: await HttpService.client.markAllAsRead({
785 auth: myAuthRequired(),
789 if (i.state.markAllAsReadRes.state == "success") {
791 repliesRes: { state: "empty" },
792 mentionsRes: { state: "empty" },
793 messagesRes: { state: "empty" },
798 async handleAddModToCommunity(form: AddModToCommunity) {
799 // TODO not sure what to do here
800 HttpService.client.addModToCommunity(form);
803 async handlePurgePerson(form: PurgePerson) {
804 const purgePersonRes = await HttpService.client.purgePerson(form);
805 this.purgeItem(purgePersonRes);
808 async handlePurgeComment(form: PurgeComment) {
809 const purgeCommentRes = await HttpService.client.purgeComment(form);
810 this.purgeItem(purgeCommentRes);
813 async handlePurgePost(form: PurgePost) {
814 const purgeRes = await HttpService.client.purgePost(form);
815 this.purgeItem(purgeRes);
818 async handleBlockPerson(form: BlockPerson) {
819 const blockPersonRes = await HttpService.client.blockPerson(form);
820 if (blockPersonRes.state == "success") {
821 updatePersonBlock(blockPersonRes.data);
825 async handleCreateComment(form: CreateComment) {
826 const res = await HttpService.client.createComment(form);
828 if (res.state === "success") {
829 toast(i18n.t("reply_sent"));
830 this.findAndUpdateComment(res);
836 async handleEditComment(form: EditComment) {
837 const res = await HttpService.client.editComment(form);
839 if (res.state === "success") {
840 toast(i18n.t("edit"));
841 this.findAndUpdateComment(res);
842 } else if (res.state === "failed") {
843 toast(res.msg, "danger");
849 async handleDeleteComment(form: DeleteComment) {
850 const res = await HttpService.client.deleteComment(form);
851 if (res.state == "success") {
852 toast(i18n.t("deleted"));
853 this.findAndUpdateComment(res);
857 async handleRemoveComment(form: RemoveComment) {
858 const res = await HttpService.client.removeComment(form);
859 if (res.state == "success") {
860 toast(i18n.t("remove_comment"));
861 this.findAndUpdateComment(res);
865 async handleSaveComment(form: SaveComment) {
866 const res = await HttpService.client.saveComment(form);
867 this.findAndUpdateComment(res);
870 async handleCommentVote(form: CreateCommentLike) {
871 const res = await HttpService.client.likeComment(form);
872 this.findAndUpdateComment(res);
875 async handleCommentReport(form: CreateCommentReport) {
876 const reportRes = await HttpService.client.createCommentReport(form);
877 this.reportToast(reportRes);
880 async handleDistinguishComment(form: DistinguishComment) {
881 const res = await HttpService.client.distinguishComment(form);
882 this.findAndUpdateComment(res);
885 async handleAddAdmin(form: AddAdmin) {
886 const addAdminRes = await HttpService.client.addAdmin(form);
888 if (addAdminRes.state === "success") {
889 this.setState(s => ((s.siteRes.admins = addAdminRes.data.admins), s));
893 async handleTransferCommunity(form: TransferCommunity) {
894 await HttpService.client.transferCommunity(form);
895 toast(i18n.t("transfer_community"));
898 async handleCommentReplyRead(form: MarkCommentReplyAsRead) {
899 const res = await HttpService.client.markCommentReplyAsRead(form);
900 this.findAndUpdateCommentReply(res);
903 async handlePersonMentionRead(form: MarkPersonMentionAsRead) {
904 const res = await HttpService.client.markPersonMentionAsRead(form);
905 this.findAndUpdateMention(res);
908 async handleBanFromCommunity(form: BanFromCommunity) {
909 const banRes = await HttpService.client.banFromCommunity(form);
910 this.updateBanFromCommunity(banRes);
913 async handleBanPerson(form: BanPerson) {
914 const banRes = await HttpService.client.banPerson(form);
915 this.updateBan(banRes);
918 async handleDeleteMessage(form: DeletePrivateMessage) {
919 const res = await HttpService.client.deletePrivateMessage(form);
920 this.findAndUpdateMessage(res);
923 async handleEditMessage(form: EditPrivateMessage) {
924 const res = await HttpService.client.editPrivateMessage(form);
925 this.findAndUpdateMessage(res);
928 async handleMarkMessageAsRead(form: MarkPrivateMessageAsRead) {
929 const res = await HttpService.client.markPrivateMessageAsRead(form);
930 this.findAndUpdateMessage(res);
933 async handleMessageReport(form: CreatePrivateMessageReport) {
934 const res = await HttpService.client.createPrivateMessageReport(form);
935 this.reportToast(res);
938 async handleCreateMessage(form: CreatePrivateMessage) {
939 const res = await HttpService.client.createPrivateMessage(form);
941 if (s.messagesRes.state == "success" && res.state == "success") {
942 s.messagesRes.data.private_messages.unshift(
943 res.data.private_message_view
951 findAndUpdateMessage(res: RequestState<PrivateMessageResponse>) {
953 if (s.messagesRes.state === "success" && res.state === "success") {
954 s.messagesRes.data.private_messages = editPrivateMessage(
955 res.data.private_message_view,
956 s.messagesRes.data.private_messages
963 updateBanFromCommunity(banRes: RequestState<BanFromCommunityResponse>) {
964 // Maybe not necessary
965 if (banRes.state == "success") {
967 if (s.repliesRes.state == "success") {
968 s.repliesRes.data.replies
969 .filter(c => c.creator.id == banRes.data.person_view.person.id)
971 c => (c.creator_banned_from_community = banRes.data.banned)
974 if (s.mentionsRes.state == "success") {
975 s.mentionsRes.data.mentions
976 .filter(c => c.creator.id == banRes.data.person_view.person.id)
978 c => (c.creator_banned_from_community = banRes.data.banned)
986 updateBan(banRes: RequestState<BanPersonResponse>) {
987 // Maybe not necessary
988 if (banRes.state == "success") {
990 if (s.repliesRes.state == "success") {
991 s.repliesRes.data.replies
992 .filter(c => c.creator.id == banRes.data.person_view.person.id)
993 .forEach(c => (c.creator.banned = banRes.data.banned));
995 if (s.mentionsRes.state == "success") {
996 s.mentionsRes.data.mentions
997 .filter(c => c.creator.id == banRes.data.person_view.person.id)
998 .forEach(c => (c.creator.banned = banRes.data.banned));
1005 purgeItem(purgeRes: RequestState<PurgeItemResponse>) {
1006 if (purgeRes.state == "success") {
1007 toast(i18n.t("purge_success"));
1008 this.context.router.history.push(`/`);
1013 res: RequestState<PrivateMessageReportResponse | CommentReportResponse>
1015 if (res.state == "success") {
1016 toast(i18n.t("report_created"));
1020 // A weird case, since you have only replies and mentions, not comment responses
1021 findAndUpdateComment(res: RequestState<CommentResponse>) {
1022 if (res.state == "success") {
1023 this.setState(s => {
1024 if (s.repliesRes.state == "success") {
1025 s.repliesRes.data.replies = editWith(
1026 res.data.comment_view,
1027 s.repliesRes.data.replies
1030 if (s.mentionsRes.state == "success") {
1031 s.mentionsRes.data.mentions = editWith(
1032 res.data.comment_view,
1033 s.mentionsRes.data.mentions
1036 // Set finished for the parent
1038 getCommentParentId(res.data.comment_view.comment) ?? 0,
1046 findAndUpdateCommentReply(res: RequestState<CommentReplyResponse>) {
1047 this.setState(s => {
1048 if (s.repliesRes.state == "success" && res.state == "success") {
1049 s.repliesRes.data.replies = editCommentReply(
1050 res.data.comment_reply_view,
1051 s.repliesRes.data.replies
1058 findAndUpdateMention(res: RequestState<PersonMentionResponse>) {
1059 this.setState(s => {
1060 if (s.mentionsRes.state == "success" && res.state == "success") {
1061 s.mentionsRes.data.mentions = editMention(
1062 res.data.person_mention_view,
1063 s.mentionsRes.data.mentions