X-Git-Url: http://these/git/?a=blobdiff_plain;f=src%2Fshared%2Fcomponents%2Fhome%2Fhome.tsx;h=8be983042a5ce584988bb282d928656678ddfeb0;hb=2b1af707c3df6126b3e6890106c03c60ad49b1be;hp=52a82126082eb3d371fb47fc16c5a0c8fe8512dc;hpb=f61037f5d89f12818c8100f907a98b74e980112a;p=lemmy-ui.git diff --git a/src/shared/components/home/home.tsx b/src/shared/components/home/home.tsx index 52a8212..8be9830 100644 --- a/src/shared/components/home/home.tsx +++ b/src/shared/components/home/home.tsx @@ -3,13 +3,27 @@ import { Component, linkEvent, MouseEventHandler } from "inferno"; import { T } from "inferno-i18next-dess"; import { Link } from "inferno-router"; import { - AddAdminResponse, + AddAdmin, + AddModToCommunity, + BanFromCommunity, + BanFromCommunityResponse, + BanPerson, BanPersonResponse, - BlockPersonResponse, - CommentReportResponse, + BlockPerson, + CommentId, + CommentReplyResponse, CommentResponse, - CommentView, - CommunityView, + CreateComment, + CreateCommentLike, + CreateCommentReport, + CreatePostLike, + CreatePostReport, + DeleteComment, + DeletePost, + DistinguishComment, + EditComment, + EditPost, + FeaturePost, GetComments, GetCommentsResponse, GetPosts, @@ -18,50 +32,51 @@ import { ListCommunities, ListCommunitiesResponse, ListingType, - PostReportResponse, + LockPost, + MarkCommentReplyAsRead, + MarkPersonMentionAsRead, PostResponse, - PostView, + PurgeComment, PurgeItemResponse, - SiteResponse, + PurgePerson, + PurgePost, + RemoveComment, + RemovePost, + SaveComment, + SavePost, SortType, - UserOperation, - wsJsonToRes, - wsUserOp, + TransferCommunity, } from "lemmy-js-client"; -import { Subscription } from "rxjs"; import { i18n } from "../../i18next"; import { CommentViewType, DataType, InitialFetchRequest, } from "../../interfaces"; -import { UserService, WebSocketService } from "../../services"; +import { UserService } from "../../services"; +import { FirstLoadService } from "../../services/FirstLoadService"; +import { HttpService, RequestState } from "../../services/HttpService"; import { canCreateCommunity, commentsToFlatNodes, - createCommentLikeRes, - createPostLikeFindRes, - editCommentRes, - editPostFindRes, + editComment, + editPost, + editWith, enableDownvotes, enableNsfw, fetchLimit, + getCommentParentId, getDataTypeString, getPageFromString, getQueryParams, getQueryString, getRandomFromList, - isBrowser, - isPostBlocked, mdToHtml, myAuth, - notifyPost, - nsfwCheck, postToCommentSortType, QueryParams, relTags, restoreScrollPosition, - saveCommentRes, saveScrollPosition, setIsoData, setupTippy, @@ -69,8 +84,6 @@ import { toast, trendingFetchLimit, updatePersonBlock, - wsClient, - wsSubscribe, } from "../../utils"; import { CommentNodes } from "../comment/comment-nodes"; import { DataTypeSelect } from "../common/data-type-select"; @@ -84,16 +97,17 @@ import { PostListings } from "../post/post-listings"; import { SiteSidebar } from "./site-sidebar"; interface HomeState { - trendingCommunities: CommunityView[]; - siteRes: GetSiteResponse; - posts: PostView[]; - comments: CommentView[]; + postsRes: RequestState; + commentsRes: RequestState; + trendingCommunitiesRes: RequestState; showSubscribedMobile: boolean; showTrendingMobile: boolean; showSidebarMobile: boolean; subscribedCollapsed: boolean; - loading: boolean; tagline?: string; + siteRes: GetSiteResponse; + finished: Map; + isIsomorphic: boolean; } interface HomeProps { @@ -112,7 +126,7 @@ function getListingTypeFromQuery(type?: string): ListingType { UserService.Instance.myUserInfo?.local_user_view?.local_user ?.default_listing_type; - return type ? (type as ListingType) : myListingType ?? "Local"; + return (type ? (type as ListingType) : myListingType) ?? "Local"; } function getSortTypeFromQuery(type?: string): SortType { @@ -120,7 +134,7 @@ function getSortTypeFromQuery(type?: string): SortType { UserService.Instance.myUserInfo?.local_user_view?.local_user ?.default_sort_type; - return type ? (type as SortType) : mySortType ?? "Active"; + return (type ? (type as SortType) : mySortType) ?? "Active"; } const getHomeQueryParams = () => @@ -131,48 +145,6 @@ const getHomeQueryParams = () => dataType: getDataTypeFromQuery, }); -function fetchTrendingCommunities() { - const listCommunitiesForm: ListCommunities = { - type_: "Local", - sort: "Hot", - limit: trendingFetchLimit, - auth: myAuth(false), - }; - WebSocketService.Instance.send(wsClient.listCommunities(listCommunitiesForm)); -} - -function fetchData() { - const auth = myAuth(false); - const { dataType, page, listingType, sort } = getHomeQueryParams(); - let req: string; - - if (dataType === DataType.Post) { - const getPostsForm: GetPosts = { - page, - limit: fetchLimit, - sort, - saved_only: false, - type_: listingType, - auth, - }; - - req = wsClient.getPosts(getPostsForm); - } else { - const getCommentsForm: GetComments = { - page, - limit: fetchLimit, - sort: postToCommentSortType(sort), - saved_only: false, - type_: listingType, - auth, - }; - - req = wsClient.getComments(getCommentsForm); - } - - WebSocketService.Instance.send(req); -} - const MobileButton = ({ textKey, show, @@ -203,52 +175,19 @@ const LinkButton = ({ ); -function getRss(listingType: ListingType) { - const { sort } = getHomeQueryParams(); - const auth = myAuth(false); - - let rss: string | undefined = undefined; - - switch (listingType) { - case "All": { - rss = `/feeds/all.xml?sort=${sort}`; - break; - } - case "Local": { - rss = `/feeds/local.xml?sort=${sort}`; - break; - } - case "Subscribed": { - rss = auth ? `/feeds/front/${auth}.xml?sort=${sort}` : undefined; - break; - } - } - - return ( - rss && ( - <> - - - - - - ) - ); -} - export class Home extends Component { private isoData = setIsoData(this.context); - private subscription?: Subscription; state: HomeState = { - trendingCommunities: [], + postsRes: { state: "empty" }, + commentsRes: { state: "empty" }, + trendingCommunitiesRes: { state: "empty" }, siteRes: this.isoData.site_res, showSubscribedMobile: false, showTrendingMobile: false, showSidebarMobile: false, subscribedCollapsed: false, - loading: true, - posts: [], - comments: [], + finished: new Map(), + isIsomorphic: false, }; constructor(props: any, context: any) { @@ -259,65 +198,69 @@ export class Home extends Component { this.handleDataTypeChange = this.handleDataTypeChange.bind(this); this.handlePageChange = this.handlePageChange.bind(this); - this.parseMessage = this.parseMessage.bind(this); - this.subscription = wsSubscribe(this.parseMessage); + this.handleCreateComment = this.handleCreateComment.bind(this); + this.handleEditComment = this.handleEditComment.bind(this); + this.handleSaveComment = this.handleSaveComment.bind(this); + this.handleBlockPerson = this.handleBlockPerson.bind(this); + this.handleDeleteComment = this.handleDeleteComment.bind(this); + this.handleRemoveComment = this.handleRemoveComment.bind(this); + this.handleCommentVote = this.handleCommentVote.bind(this); + this.handleAddModToCommunity = this.handleAddModToCommunity.bind(this); + this.handleAddAdmin = this.handleAddAdmin.bind(this); + this.handlePurgePerson = this.handlePurgePerson.bind(this); + this.handlePurgeComment = this.handlePurgeComment.bind(this); + this.handleCommentReport = this.handleCommentReport.bind(this); + this.handleDistinguishComment = this.handleDistinguishComment.bind(this); + this.handleTransferCommunity = this.handleTransferCommunity.bind(this); + this.handleCommentReplyRead = this.handleCommentReplyRead.bind(this); + this.handlePersonMentionRead = this.handlePersonMentionRead.bind(this); + this.handleBanFromCommunity = this.handleBanFromCommunity.bind(this); + this.handleBanPerson = this.handleBanPerson.bind(this); + this.handlePostEdit = this.handlePostEdit.bind(this); + this.handlePostVote = this.handlePostVote.bind(this); + this.handlePostReport = this.handlePostReport.bind(this); + this.handleLockPost = this.handleLockPost.bind(this); + this.handleDeletePost = this.handleDeletePost.bind(this); + this.handleRemovePost = this.handleRemovePost.bind(this); + this.handleSavePost = this.handleSavePost.bind(this); + this.handlePurgePost = this.handlePurgePost.bind(this); + this.handleFeaturePost = this.handleFeaturePost.bind(this); // Only fetch the data if coming from another route - if (this.isoData.path === this.context.router.route.match.url) { - const postsRes = this.isoData.routeData[0] as - | GetPostsResponse - | undefined; - const commentsRes = this.isoData.routeData[1] as - | GetCommentsResponse - | undefined; - const trendingRes = this.isoData.routeData[2] as - | ListCommunitiesResponse - | undefined; - - if (postsRes) { - this.state = { ...this.state, posts: postsRes.posts }; - } - - if (commentsRes) { - this.state = { ...this.state, comments: commentsRes.comments }; - } + if (FirstLoadService.isFirstLoad) { + const [postsRes, commentsRes, trendingCommunitiesRes] = + this.isoData.routeData; - if (isBrowser()) { - WebSocketService.Instance.send( - wsClient.communityJoin({ community_id: 0 }) - ); - } - const taglines = this.state?.siteRes?.taglines ?? []; this.state = { ...this.state, - trendingCommunities: trendingRes?.communities ?? [], - loading: false, - tagline: getRandomFromList(taglines)?.content, + postsRes, + commentsRes, + trendingCommunitiesRes, + tagline: getRandomFromList(this.state?.siteRes?.taglines ?? []) + ?.content, + isIsomorphic: true, }; - } else { - fetchTrendingCommunities(); - fetchData(); } } - componentDidMount() { - // This means it hasn't been set up yet - if (!this.state.siteRes.site_view.local_site.site_setup) { - this.context.router.history.push("/setup"); + async componentDidMount() { + if (!this.state.isIsomorphic) { + await Promise.all([this.fetchTrendingCommunities(), this.fetchData()]); } setupTippy(); } componentWillUnmount() { saveScrollPosition(this.context); - this.subscription?.unsubscribe(); } static fetchInitialData({ client, auth, query: { dataType: urlDataType, listingType, page: urlPage, sort: urlSort }, - }: InitialFetchRequest>): Promise[] { + }: InitialFetchRequest>): Promise< + RequestState + >[] { const dataType = getDataTypeFromQuery(urlDataType); // TODO figure out auth default_listingType, default_sort_type @@ -326,7 +269,7 @@ export class Home extends Component { const page = urlPage ? Number(urlPage) : 1; - const promises: Promise[] = []; + const promises: Promise>[] = []; if (dataType === DataType.Post) { const getPostsForm: GetPosts = { @@ -339,7 +282,7 @@ export class Home extends Component { }; promises.push(client.getPosts(getPostsForm)); - promises.push(Promise.resolve()); + promises.push(Promise.resolve({ state: "empty" })); } else { const getCommentsForm: GetComments = { page, @@ -349,7 +292,7 @@ export class Home extends Component { saved_only: false, auth, }; - promises.push(Promise.resolve()); + promises.push(Promise.resolve({ state: "empty" })); promises.push(client.getComments(getCommentsForm)); } @@ -475,69 +418,77 @@ export class Home extends Component { admins, online, }, - loading, } = this.state; return (
- {!loading && ( -
-
-
- {this.trendingCommunities()} - {canCreateCommunity(this.state.siteRes) && ( - - )} +
+
+
+ {this.trendingCommunities()} + {canCreateCommunity(this.state.siteRes) && ( -
+ )} +
- - {this.hasFollows && ( -
-
{this.subscribedCommunities}
-
- )}
- )} + + {this.hasFollows && ( +
+
{this.subscribedCommunities}
+
+ )} +
); } trendingCommunities(isMobile = false) { - return ( -
-
- - # - - # - - -
-
    - {this.state.trendingCommunities.map(cv => ( -
  • - -
  • - ))} -
-
- ); + switch (this.state.trendingCommunitiesRes.state) { + case "loading": + return ( +
+ +
+ ); + case "success": { + const trending = this.state.trendingCommunitiesRes.data.communities; + return ( +
+
+ + # + + # + + +
+
    + {trending.map(cv => ( +
  • + +
  • + ))} +
+
+ ); + } + } } get subscribedCommunities() { @@ -580,7 +531,7 @@ export class Home extends Component { ); } - updateUrl({ dataType, listingType, page, sort }: Partial) { + async updateUrl({ dataType, listingType, page, sort }: Partial) { const { dataType: urlDataType, listingType: urlListingType, @@ -600,13 +551,7 @@ export class Home extends Component { search: getQueryString(queryParams), }); - this.setState({ - loading: true, - posts: [], - comments: [], - }); - - fetchData(); + await this.fetchData(); } posts() { @@ -614,50 +559,105 @@ export class Home extends Component { return (
- {this.state.loading ? ( -
- -
- ) : ( -
- {this.selects()} - {this.listings} - -
- )} +
+ {this.selects} + {this.listings} + +
); } get listings() { const { dataType } = getHomeQueryParams(); - const { siteRes, posts, comments } = this.state; - - return dataType === DataType.Post ? ( - - ) : ( - - ); + const siteRes = this.state.siteRes; + + if (dataType === DataType.Post) { + switch (this.state.postsRes.state) { + case "loading": + return ( +
+ +
+ ); + case "success": { + const posts = this.state.postsRes.data.posts; + return ( + + ); + } + } + } else { + switch (this.state.commentsRes.state) { + case "loading": + return ( +
+ +
+ ); + case "success": { + const comments = this.state.commentsRes.data.comments; + return ( + + ); + } + } + } } - selects() { + get selects() { const { listingType, dataType, sort } = getHomeQueryParams(); return ( @@ -679,11 +679,90 @@ export class Home extends Component { - {getRss(listingType)} + {this.getRss(listingType)}
); } + getRss(listingType: ListingType) { + const { sort } = getHomeQueryParams(); + const auth = myAuth(); + + let rss: string | undefined = undefined; + + switch (listingType) { + case "All": { + rss = `/feeds/all.xml?sort=${sort}`; + break; + } + case "Local": { + rss = `/feeds/local.xml?sort=${sort}`; + break; + } + case "Subscribed": { + rss = auth ? `/feeds/front/${auth}.xml?sort=${sort}` : undefined; + break; + } + } + + return ( + rss && ( + <> + + + + + + ) + ); + } + + async fetchTrendingCommunities() { + this.setState({ trendingCommunitiesRes: { state: "loading" } }); + this.setState({ + trendingCommunitiesRes: await HttpService.client.listCommunities({ + type_: "Local", + sort: "Hot", + limit: trendingFetchLimit, + auth: myAuth(), + }), + }); + } + + async fetchData() { + const auth = myAuth(); + const { dataType, page, listingType, sort } = getHomeQueryParams(); + + if (dataType === DataType.Post) { + this.setState({ postsRes: { state: "loading" } }); + this.setState({ + postsRes: await HttpService.client.getPosts({ + page, + limit: fetchLimit, + sort, + saved_only: false, + type_: listingType, + auth, + }), + }); + } else { + this.setState({ commentsRes: { state: "loading" } }); + this.setState({ + commentsRes: await HttpService.client.getComments({ + page, + limit: fetchLimit, + sort: postToCommentSortType(sort), + saved_only: false, + type_: listingType, + auth, + }), + }); + } + + restoreScrollPosition(this.context); + setupTippy(); + } + handleShowSubscribedMobile(i: Home) { i.setState({ showSubscribedMobile: !i.state.showSubscribedMobile }); } @@ -720,229 +799,252 @@ export class Home extends Component { window.scrollTo(0, 0); } - parseMessage(msg: any) { - const op = wsUserOp(msg); - console.log(msg); + async handleAddModToCommunity(form: AddModToCommunity) { + // TODO not sure what to do here + await HttpService.client.addModToCommunity(form); + } - if (msg.error) { - toast(i18n.t(msg.error), "danger"); - } else if (msg.reconnect) { - WebSocketService.Instance.send( - wsClient.communityJoin({ community_id: 0 }) - ); - fetchData(); - } else { - switch (op) { - case UserOperation.ListCommunities: { - const { communities } = wsJsonToRes(msg); - this.setState({ trendingCommunities: communities }); + async handlePurgePerson(form: PurgePerson) { + const purgePersonRes = await HttpService.client.purgePerson(form); + this.purgeItem(purgePersonRes); + } - break; - } + async handlePurgeComment(form: PurgeComment) { + const purgeCommentRes = await HttpService.client.purgeComment(form); + this.purgeItem(purgeCommentRes); + } - case UserOperation.EditSite: { - const { site_view } = wsJsonToRes(msg); - this.setState(s => ((s.siteRes.site_view = site_view), s)); - toast(i18n.t("site_saved")); + async handlePurgePost(form: PurgePost) { + const purgeRes = await HttpService.client.purgePost(form); + this.purgeItem(purgeRes); + } - break; - } + async handleBlockPerson(form: BlockPerson) { + const blockPersonRes = await HttpService.client.blockPerson(form); + if (blockPersonRes.state == "success") { + updatePersonBlock(blockPersonRes.data); + } + } - case UserOperation.GetPosts: { - const { posts } = wsJsonToRes(msg); - this.setState({ posts, loading: false }); - WebSocketService.Instance.send( - wsClient.communityJoin({ community_id: 0 }) - ); - restoreScrollPosition(this.context); - setupTippy(); + async handleCreateComment(form: CreateComment) { + const createCommentRes = await HttpService.client.createComment(form); + this.createAndUpdateComments(createCommentRes); - break; - } + return createCommentRes; + } - case UserOperation.CreatePost: { - const { page, listingType } = getHomeQueryParams(); - const { post_view } = wsJsonToRes(msg); - - // Only push these if you're on the first page, you pass the nsfw check, and it isn't blocked - if (page === 1 && nsfwCheck(post_view) && !isPostBlocked(post_view)) { - const mui = UserService.Instance.myUserInfo; - const showPostNotifs = - mui?.local_user_view.local_user.show_new_post_notifs; - let shouldAddPost: boolean; - - switch (listingType) { - case "Subscribed": { - // If you're on subscribed, only push it if you're subscribed. - shouldAddPost = !!mui?.follows.some( - ({ community: { id } }) => id === post_view.community.id - ); - break; - } - case "Local": { - // If you're on the local view, only push it if its local - shouldAddPost = post_view.post.local; - break; - } - default: { - shouldAddPost = true; - break; - } - } - - if (shouldAddPost) { - this.setState(({ posts }) => ({ - posts: [post_view].concat(posts), - })); - if (showPostNotifs) { - notifyPost(post_view, this.context.router); - } - } - } - - break; - } + async handleEditComment(form: EditComment) { + const editCommentRes = await HttpService.client.editComment(form); + this.findAndUpdateComment(editCommentRes); - case UserOperation.EditPost: - case UserOperation.DeletePost: - case UserOperation.RemovePost: - case UserOperation.LockPost: - case UserOperation.FeaturePost: - case UserOperation.SavePost: { - const { post_view } = wsJsonToRes(msg); - editPostFindRes(post_view, this.state.posts); - this.setState(this.state); - - break; - } + return editCommentRes; + } - case UserOperation.CreatePostLike: { - const { post_view } = wsJsonToRes(msg); - createPostLikeFindRes(post_view, this.state.posts); - this.setState(this.state); + async handleDeleteComment(form: DeleteComment) { + const deleteCommentRes = await HttpService.client.deleteComment(form); + this.findAndUpdateComment(deleteCommentRes); + } - break; - } + async handleDeletePost(form: DeletePost) { + const deleteRes = await HttpService.client.deletePost(form); + this.findAndUpdatePost(deleteRes); + } - case UserOperation.AddAdmin: { - const { admins } = wsJsonToRes(msg); - this.setState(s => ((s.siteRes.admins = admins), s)); + async handleRemovePost(form: RemovePost) { + const removeRes = await HttpService.client.removePost(form); + this.findAndUpdatePost(removeRes); + } - break; - } + async handleRemoveComment(form: RemoveComment) { + const removeCommentRes = await HttpService.client.removeComment(form); + this.findAndUpdateComment(removeCommentRes); + } - case UserOperation.BanPerson: { - const { - banned, - person_view: { - person: { id }, - }, - } = wsJsonToRes(msg); + async handleSaveComment(form: SaveComment) { + const saveCommentRes = await HttpService.client.saveComment(form); + this.findAndUpdateComment(saveCommentRes); + } - this.state.posts - .filter(p => p.creator.id == id) - .forEach(p => (p.creator.banned = banned)); - this.setState(this.state); + async handleSavePost(form: SavePost) { + const saveRes = await HttpService.client.savePost(form); + this.findAndUpdatePost(saveRes); + } - break; - } + async handleFeaturePost(form: FeaturePost) { + const featureRes = await HttpService.client.featurePost(form); + this.findAndUpdatePost(featureRes); + } - case UserOperation.GetComments: { - const { comments } = wsJsonToRes(msg); - this.setState({ comments, loading: false }); + async handleCommentVote(form: CreateCommentLike) { + const voteRes = await HttpService.client.likeComment(form); + this.findAndUpdateComment(voteRes); + } - break; - } + async handlePostEdit(form: EditPost) { + const res = await HttpService.client.editPost(form); + this.findAndUpdatePost(res); + } - case UserOperation.EditComment: - case UserOperation.DeleteComment: - case UserOperation.RemoveComment: { - const { comment_view } = wsJsonToRes(msg); - editCommentRes(comment_view, this.state.comments); - this.setState(this.state); + async handlePostVote(form: CreatePostLike) { + const voteRes = await HttpService.client.likePost(form); + this.findAndUpdatePost(voteRes); + } - break; - } + async handleCommentReport(form: CreateCommentReport) { + const reportRes = await HttpService.client.createCommentReport(form); + if (reportRes.state == "success") { + toast(i18n.t("report_created")); + } + } - case UserOperation.CreateComment: { - const { form_id, comment_view } = wsJsonToRes(msg); - - // Necessary since it might be a user reply - if (form_id) { - const { listingType } = getHomeQueryParams(); - - // If you're on subscribed, only push it if you're subscribed. - const shouldAddComment = - listingType === "Subscribed" - ? UserService.Instance.myUserInfo?.follows.some( - ({ community: { id } }) => id === comment_view.community.id - ) - : true; - - if (shouldAddComment) { - this.setState(({ comments }) => ({ - comments: [comment_view].concat(comments), - })); - } - } - - break; - } + async handlePostReport(form: CreatePostReport) { + const reportRes = await HttpService.client.createPostReport(form); + if (reportRes.state == "success") { + toast(i18n.t("report_created")); + } + } - case UserOperation.SaveComment: { - const { comment_view } = wsJsonToRes(msg); - saveCommentRes(comment_view, this.state.comments); - this.setState(this.state); + async handleLockPost(form: LockPost) { + const lockRes = await HttpService.client.lockPost(form); + this.findAndUpdatePost(lockRes); + } - break; - } + async handleDistinguishComment(form: DistinguishComment) { + const distinguishRes = await HttpService.client.distinguishComment(form); + this.findAndUpdateComment(distinguishRes); + } - case UserOperation.CreateCommentLike: { - const { comment_view } = wsJsonToRes(msg); - createCommentLikeRes(comment_view, this.state.comments); - this.setState(this.state); + async handleAddAdmin(form: AddAdmin) { + const addAdminRes = await HttpService.client.addAdmin(form); - break; - } + if (addAdminRes.state == "success") { + this.setState(s => ((s.siteRes.admins = addAdminRes.data.admins), s)); + } + } - case UserOperation.BlockPerson: { - const data = wsJsonToRes(msg); - updatePersonBlock(data); + async handleTransferCommunity(form: TransferCommunity) { + await HttpService.client.transferCommunity(form); + toast(i18n.t("transfer_community")); + } - break; - } + async handleCommentReplyRead(form: MarkCommentReplyAsRead) { + const readRes = await HttpService.client.markCommentReplyAsRead(form); + this.findAndUpdateCommentReply(readRes); + } - case UserOperation.CreatePostReport: { - const data = wsJsonToRes(msg); - if (data) { - toast(i18n.t("report_created")); - } + async handlePersonMentionRead(form: MarkPersonMentionAsRead) { + // TODO not sure what to do here. Maybe it is actually optional, because post doesn't need it. + await HttpService.client.markPersonMentionAsRead(form); + } - break; - } + async handleBanFromCommunity(form: BanFromCommunity) { + const banRes = await HttpService.client.banFromCommunity(form); + this.updateBanFromCommunity(banRes); + } - case UserOperation.CreateCommentReport: { - const data = wsJsonToRes(msg); - if (data) { - toast(i18n.t("report_created")); - } + async handleBanPerson(form: BanPerson) { + const banRes = await HttpService.client.banPerson(form); + this.updateBan(banRes); + } - break; + updateBanFromCommunity(banRes: RequestState) { + // Maybe not necessary + if (banRes.state == "success") { + this.setState(s => { + if (s.postsRes.state == "success") { + s.postsRes.data.posts + .filter(c => c.creator.id == banRes.data.person_view.person.id) + .forEach( + c => (c.creator_banned_from_community = banRes.data.banned) + ); } + if (s.commentsRes.state == "success") { + s.commentsRes.data.comments + .filter(c => c.creator.id == banRes.data.person_view.person.id) + .forEach( + c => (c.creator_banned_from_community = banRes.data.banned) + ); + } + return s; + }); + } + } - case UserOperation.PurgePerson: - case UserOperation.PurgePost: - case UserOperation.PurgeComment: - case UserOperation.PurgeCommunity: { - const data = wsJsonToRes(msg); - if (data.success) { - toast(i18n.t("purge_success")); - this.context.router.history.push(`/`); - } - - break; + updateBan(banRes: RequestState) { + // Maybe not necessary + if (banRes.state == "success") { + this.setState(s => { + if (s.postsRes.state == "success") { + s.postsRes.data.posts + .filter(c => c.creator.id == banRes.data.person_view.person.id) + .forEach(c => (c.creator.banned = banRes.data.banned)); } - } + if (s.commentsRes.state == "success") { + s.commentsRes.data.comments + .filter(c => c.creator.id == banRes.data.person_view.person.id) + .forEach(c => (c.creator.banned = banRes.data.banned)); + } + return s; + }); } } + + purgeItem(purgeRes: RequestState) { + if (purgeRes.state == "success") { + toast(i18n.t("purge_success")); + this.context.router.history.push(`/`); + } + } + + findAndUpdateComment(res: RequestState) { + this.setState(s => { + if (s.commentsRes.state == "success" && res.state == "success") { + s.commentsRes.data.comments = editComment( + res.data.comment_view, + s.commentsRes.data.comments + ); + s.finished.set(res.data.comment_view.comment.id, true); + } + return s; + }); + } + + createAndUpdateComments(res: RequestState) { + this.setState(s => { + if (s.commentsRes.state == "success" && res.state == "success") { + s.commentsRes.data.comments.unshift(res.data.comment_view); + + // Set finished for the parent + s.finished.set( + getCommentParentId(res.data.comment_view.comment) ?? 0, + true + ); + } + return s; + }); + } + + findAndUpdateCommentReply(res: RequestState) { + this.setState(s => { + if (s.commentsRes.state == "success" && res.state == "success") { + s.commentsRes.data.comments = editWith( + res.data.comment_reply_view, + s.commentsRes.data.comments + ); + } + return s; + }); + } + + findAndUpdatePost(res: RequestState) { + this.setState(s => { + if (s.postsRes.state == "success" && res.state == "success") { + s.postsRes.data.posts = editPost( + res.data.post_view, + s.postsRes.data.posts + ); + } + return s; + }); + } }