From: Dessalines <dessalines@users.noreply.github.com> Date: Thu, 11 May 2023 18:32:32 +0000 (-0400) Subject: Using auto-generated types from ts-rs. (#1003) X-Git-Url: http://these/git/%7B%60https:/%7BjoinLemmyUrl%7D?a=commitdiff_plain;h=c5fd084577e908f91421f94c1bd744d154deb49f;p=lemmy-ui.git Using auto-generated types from ts-rs. (#1003) * Using auto-generated types from ts-rs. - Fixes #998 - Added support for new `GetFederatedInstances` - Fixed a few bugs in the process. * Update imports to use SleeplessOne1917's fix. --- diff --git a/lemmy-translations b/lemmy-translations index 007e536..3bb45c2 160000 --- a/lemmy-translations +++ b/lemmy-translations @@ -1 +1 @@ -Subproject commit 007e53683768aeba63e9e4c179c1d240217bcee2 +Subproject commit 3bb45c26cb54325c3d8d605f4334447b9b78293a diff --git a/package.json b/package.json index 425251a..8777a4b 100644 --- a/package.json +++ b/package.json @@ -59,7 +59,7 @@ "inferno-server": "^8.1.1", "isomorphic-cookie": "^1.2.4", "jwt-decode": "^3.1.2", - "lemmy-js-client": "0.17.2-rc.5", + "lemmy-js-client": "0.17.2-rc.14", "markdown-it": "^13.0.1", "markdown-it-container": "^3.0.0", "markdown-it-emoji": "^2.0.2", diff --git a/src/shared/components/app/footer.tsx b/src/shared/components/app/footer.tsx index a62a8ac..bbe4998 100644 --- a/src/shared/components/app/footer.tsx +++ b/src/shared/components/app/footer.tsx @@ -39,7 +39,7 @@ export class Footer extends Component<FooterProps, any> { </NavLink> </li> )} - {this.props.site.federated_instances && ( + {this.props.site.site_view.local_site.federation_enabled && ( <li className="nav-item"> <NavLink className="nav-link" to="/instances"> {i18n.t("instances")} diff --git a/src/shared/components/app/navbar.tsx b/src/shared/components/app/navbar.tsx index 44345cc..448e92c 100644 --- a/src/shared/components/app/navbar.tsx +++ b/src/shared/components/app/navbar.tsx @@ -40,9 +40,9 @@ interface NavbarProps { interface NavbarState { expanded: boolean; - unreadInboxCount: number; - unreadReportCount: number; - unreadApplicationCount: number; + unreadInboxCount: bigint; + unreadReportCount: bigint; + unreadApplicationCount: bigint; showDropdown: boolean; onSiteBanner?(url: string): any; } @@ -54,9 +54,9 @@ export class Navbar extends Component<NavbarProps, NavbarState> { private unreadReportCountSub: Subscription; private unreadApplicationCountSub: Subscription; state: NavbarState = { - unreadInboxCount: 0, - unreadReportCount: 0, - unreadApplicationCount: 0, + unreadInboxCount: 0n, + unreadReportCount: 0n, + unreadApplicationCount: 0n, expanded: false, showDropdown: false, }; @@ -144,7 +144,7 @@ export class Navbar extends Component<NavbarProps, NavbarState> { className="p-1 navbar-toggler nav-link border-0" onMouseUp={linkEvent(this, this.handleHideExpandNavbar)} title={i18n.t("unread_messages", { - count: this.state.unreadInboxCount, + count: Number(this.state.unreadInboxCount), formattedCount: numToSI(this.state.unreadInboxCount), })} > @@ -165,7 +165,7 @@ export class Navbar extends Component<NavbarProps, NavbarState> { className="p-1 navbar-toggler nav-link border-0" onMouseUp={linkEvent(this, this.handleHideExpandNavbar)} title={i18n.t("unread_reports", { - count: this.state.unreadReportCount, + count: Number(this.state.unreadReportCount), formattedCount: numToSI(this.state.unreadReportCount), })} > @@ -187,7 +187,7 @@ export class Navbar extends Component<NavbarProps, NavbarState> { className="p-1 navbar-toggler nav-link border-0" onMouseUp={linkEvent(this, this.handleHideExpandNavbar)} title={i18n.t("unread_registration_applications", { - count: this.state.unreadApplicationCount, + count: Number(this.state.unreadApplicationCount), formattedCount: numToSI( this.state.unreadApplicationCount ), @@ -305,7 +305,7 @@ export class Navbar extends Component<NavbarProps, NavbarState> { to="/inbox" onMouseUp={linkEvent(this, this.handleHideExpandNavbar)} title={i18n.t("unread_messages", { - count: this.state.unreadInboxCount, + count: Number(this.state.unreadInboxCount), formattedCount: numToSI(this.state.unreadInboxCount), })} > @@ -326,7 +326,7 @@ export class Navbar extends Component<NavbarProps, NavbarState> { to="/reports" onMouseUp={linkEvent(this, this.handleHideExpandNavbar)} title={i18n.t("unread_reports", { - count: this.state.unreadReportCount, + count: Number(this.state.unreadReportCount), formattedCount: numToSI(this.state.unreadReportCount), })} > @@ -348,7 +348,7 @@ export class Navbar extends Component<NavbarProps, NavbarState> { className="nav-link" onMouseUp={linkEvent(this, this.handleHideExpandNavbar)} title={i18n.t("unread_registration_applications", { - count: this.state.unreadApplicationCount, + count: Number(this.state.unreadApplicationCount), formattedCount: numToSI( this.state.unreadApplicationCount ), @@ -512,7 +512,7 @@ export class Navbar extends Component<NavbarProps, NavbarState> { unreadReportCount: data.post_reports + data.comment_reports + - (data.private_message_reports ?? 0), + (data.private_message_reports ?? 0n), }); this.sendReportUnread(); } else if (op == UserOperation.GetUnreadRegistrationApplicationCount) { @@ -528,7 +528,7 @@ export class Navbar extends Component<NavbarProps, NavbarState> { data.recipient_ids.includes(mui.local_user_view.local_user.id) ) { this.setState({ - unreadInboxCount: this.state.unreadInboxCount + 1, + unreadInboxCount: this.state.unreadInboxCount + 1n, }); this.sendUnreadCount(); notifyComment(data.comment_view, this.context.router); @@ -541,7 +541,7 @@ export class Navbar extends Component<NavbarProps, NavbarState> { UserService.Instance.myUserInfo?.local_user_view.person.id ) { this.setState({ - unreadInboxCount: this.state.unreadInboxCount + 1, + unreadInboxCount: this.state.unreadInboxCount + 1n, }); this.sendUnreadCount(); notifyPrivateMessage(data.private_message_view, this.context.router); diff --git a/src/shared/components/comment/comment-form.tsx b/src/shared/components/comment/comment-form.tsx index 9c29381..c728519 100644 --- a/src/shared/components/comment/comment-form.tsx +++ b/src/shared/components/comment/comment-form.tsx @@ -2,7 +2,6 @@ import { Component } from "inferno"; import { T } from "inferno-i18next-dess"; import { Link } from "inferno-router"; import { - CommentNode as CommentNodeI, CommentResponse, CreateComment, EditComment, @@ -12,6 +11,7 @@ import { wsUserOp, } from "lemmy-js-client"; import { Subscription } from "rxjs"; +import { CommentNodeI } from "shared/interfaces"; import { i18n } from "../../i18next"; import { UserService, WebSocketService } from "../../services"; import { diff --git a/src/shared/components/comment/comment-node.tsx b/src/shared/components/comment/comment-node.tsx index 99db143..2b7ea6e 100644 --- a/src/shared/components/comment/comment-node.tsx +++ b/src/shared/components/comment/comment-node.tsx @@ -7,21 +7,19 @@ import { BanFromCommunity, BanPerson, BlockPerson, - CommentNode as CommentNodeI, CommentReplyView, CommentView, CommunityModeratorView, CreateCommentLike, CreateCommentReport, DeleteComment, - EditComment, + DistinguishComment, GetComments, Language, - ListingType, MarkCommentReplyAsRead, MarkPersonMentionAsRead, PersonMentionView, - PersonViewSafe, + PersonView, PurgeComment, PurgePerson, RemoveComment, @@ -30,7 +28,12 @@ import { } from "lemmy-js-client"; import moment from "moment"; import { i18n } from "../../i18next"; -import { BanType, CommentViewType, PurgeType } from "../../interfaces"; +import { + BanType, + CommentNodeI, + CommentViewType, + PurgeType, +} from "../../interfaces"; import { UserService, WebSocketService } from "../../services"; import { amCommunityCreator, @@ -81,9 +84,9 @@ interface CommentNodeState { showReportDialog: boolean; reportReason?: string; my_vote?: number; - score: number; - upvotes: number; - downvotes: number; + score: bigint; + upvotes: bigint; + downvotes: bigint; readLoading: boolean; saveLoading: boolean; } @@ -91,7 +94,7 @@ interface CommentNodeState { interface CommentNodeProps { node: CommentNodeI; moderators?: CommunityModeratorView[]; - admins?: PersonViewSafe[]; + admins?: PersonView[]; noBorder?: boolean; noIndent?: boolean; viewOnly?: boolean; @@ -296,8 +299,8 @@ export class CommentNode extends Component<CommentNodeProps, CommentNodeState> { <span className="mr-1 font-weight-bold" aria-label={i18n.t("number_of_points", { - count: this.state.score, - formattedCount: this.state.score, + count: Number(this.state.score), + formattedCount: numToSI(this.state.score), })} > {numToSI(this.state.score)} @@ -835,7 +838,9 @@ export class CommentNode extends Component<CommentNodeProps, CommentNodeState> { > {i18n.t("x_more_replies", { count: node.comment_view.counts.child_count, - formattedCount: numToSI(node.comment_view.counts.child_count), + formattedCount: numToSI( + BigInt(node.comment_view.counts.child_count) + ), })}{" "} â </button> @@ -1152,19 +1157,19 @@ export class CommentNode extends Component<CommentNodeProps, CommentNodeState> { if (myVote == 1) { this.setState({ - score: this.state.score - 1, - upvotes: this.state.upvotes - 1, + score: this.state.score - 1n, + upvotes: this.state.upvotes - 1n, }); } else if (myVote == -1) { this.setState({ - downvotes: this.state.downvotes - 1, - upvotes: this.state.upvotes + 1, - score: this.state.score + 2, + downvotes: this.state.downvotes - 1n, + upvotes: this.state.upvotes + 1n, + score: this.state.score + 2n, }); } else { this.setState({ - score: this.state.score + 1, - upvotes: this.state.upvotes + 1, + score: this.state.score + 1n, + upvotes: this.state.upvotes + 1n, }); } @@ -1189,19 +1194,19 @@ export class CommentNode extends Component<CommentNodeProps, CommentNodeState> { if (myVote == 1) { this.setState({ - downvotes: this.state.downvotes + 1, - upvotes: this.state.upvotes - 1, - score: this.state.score - 2, + downvotes: this.state.downvotes + 1n, + upvotes: this.state.upvotes - 1n, + score: this.state.score - 2n, }); } else if (myVote == -1) { this.setState({ - downvotes: this.state.downvotes - 1, - score: this.state.score + 1, + downvotes: this.state.downvotes - 1n, + score: this.state.score + 1n, }); } else { this.setState({ - downvotes: this.state.downvotes + 1, - score: this.state.score - 1, + downvotes: this.state.downvotes + 1n, + score: this.state.score - 1n, }); } @@ -1278,7 +1283,7 @@ export class CommentNode extends Component<CommentNodeProps, CommentNodeState> { let comment = i.props.node.comment_view.comment; let auth = myAuth(); if (auth) { - let form: EditComment = { + let form: DistinguishComment = { comment_id: comment.id, distinguished: !comment.distinguished, auth, @@ -1542,8 +1547,8 @@ export class CommentNode extends Component<CommentNodeProps, CommentNodeState> { post_id: i.props.node.comment_view.post.id, parent_id: i.props.node.comment_view.comment.id, max_depth: commentTreeMaxDepth, - limit: 999, // TODO - type_: ListingType.All, + limit: 999n, // TODO + type_: "All", saved_only: false, auth: myAuth(false), }; @@ -1563,18 +1568,18 @@ export class CommentNode extends Component<CommentNodeProps, CommentNodeState> { get pointsTippy(): string { let points = i18n.t("number_of_points", { - count: this.state.score, - formattedCount: this.state.score, + count: Number(this.state.score), + formattedCount: numToSI(this.state.score), }); let upvotes = i18n.t("number_of_upvotes", { - count: this.state.upvotes, - formattedCount: this.state.upvotes, + count: Number(this.state.upvotes), + formattedCount: numToSI(this.state.upvotes), }); let downvotes = i18n.t("number_of_downvotes", { - count: this.state.downvotes, - formattedCount: this.state.downvotes, + count: Number(this.state.downvotes), + formattedCount: numToSI(this.state.downvotes), }); return `${points} ⢠${upvotes} ⢠${downvotes}`; diff --git a/src/shared/components/comment/comment-nodes.tsx b/src/shared/components/comment/comment-nodes.tsx index c8fd1cf..ba8997a 100644 --- a/src/shared/components/comment/comment-nodes.tsx +++ b/src/shared/components/comment/comment-nodes.tsx @@ -1,17 +1,12 @@ import { Component } from "inferno"; -import { - CommentNode as CommentNodeI, - CommunityModeratorView, - Language, - PersonViewSafe, -} from "lemmy-js-client"; -import { CommentViewType } from "../../interfaces"; +import { CommunityModeratorView, Language, PersonView } from "lemmy-js-client"; +import { CommentNodeI, CommentViewType } from "../../interfaces"; import { CommentNode } from "./comment-node"; interface CommentNodesProps { nodes: CommentNodeI[]; moderators?: CommunityModeratorView[]; - admins?: PersonViewSafe[]; + admins?: PersonView[]; maxCommentsShown?: number; noBorder?: boolean; noIndent?: boolean; diff --git a/src/shared/components/comment/comment-report.tsx b/src/shared/components/comment/comment-report.tsx index 5f7c24c..232fec6 100644 --- a/src/shared/components/comment/comment-report.tsx +++ b/src/shared/components/comment/comment-report.tsx @@ -1,14 +1,12 @@ import { Component, linkEvent } from "inferno"; import { T } from "inferno-i18next-dess"; import { - CommentNode as CommentNodeI, CommentReportView, CommentView, ResolveCommentReport, - SubscribedType, } from "lemmy-js-client"; import { i18n } from "../../i18next"; -import { CommentViewType } from "../../interfaces"; +import { CommentNodeI, CommentViewType } from "../../interfaces"; import { WebSocketService } from "../../services"; import { myAuth, wsClient } from "../../utils"; import { Icon } from "../common/icon"; @@ -41,7 +39,7 @@ export class CommentReport extends Component<CommentReportProps, any> { community: r.community, creator_banned_from_community: r.creator_banned_from_community, counts: r.counts, - subscribed: SubscribedType.NotSubscribed, + subscribed: "NotSubscribed", saved: false, creator_blocked: false, my_vote: r.my_vote, diff --git a/src/shared/components/common/comment-sort-select.tsx b/src/shared/components/common/comment-sort-select.tsx index 1874776..486d99f 100644 --- a/src/shared/components/common/comment-sort-select.tsx +++ b/src/shared/components/common/comment-sort-select.tsx @@ -46,10 +46,10 @@ export class CommentSortSelect extends Component< <option disabled aria-hidden="true"> {i18n.t("sort_type")} </option> - <option value={CommentSortType.Hot}>{i18n.t("hot")}</option>, - <option value={CommentSortType.Top}>{i18n.t("top")}</option>, - <option value={CommentSortType.New}>{i18n.t("new")}</option> - <option value={CommentSortType.Old}>{i18n.t("old")}</option> + <option value={"Hot"}>{i18n.t("hot")}</option>, + <option value={"Top"}>{i18n.t("top")}</option>, + <option value={"New"}>{i18n.t("new")}</option> + <option value={"Old"}>{i18n.t("old")}</option> </select> <a className="text-muted" diff --git a/src/shared/components/common/listing-type-select.tsx b/src/shared/components/common/listing-type-select.tsx index c214d44..abafe37 100644 --- a/src/shared/components/common/listing-type-select.tsx +++ b/src/shared/components/common/listing-type-select.tsx @@ -44,15 +44,15 @@ export class ListingTypeSelect extends Component< <label title={i18n.t("subscribed_description")} className={`btn btn-outline-secondary - ${this.state.type_ == ListingType.Subscribed && "active"} + ${this.state.type_ == "Subscribed" && "active"} ${!UserService.Instance.myUserInfo ? "disabled" : "pointer"} `} > <input id={`${this.id}-subscribed`} type="radio" - value={ListingType.Subscribed} - checked={this.state.type_ == ListingType.Subscribed} + value={"Subscribed"} + checked={this.state.type_ == "Subscribed"} onChange={linkEvent(this, this.handleTypeChange)} disabled={!UserService.Instance.myUserInfo} /> @@ -63,14 +63,14 @@ export class ListingTypeSelect extends Component< <label title={i18n.t("local_description")} className={`pointer btn btn-outline-secondary ${ - this.state.type_ == ListingType.Local && "active" + this.state.type_ == "Local" && "active" }`} > <input id={`${this.id}-local`} type="radio" - value={ListingType.Local} - checked={this.state.type_ == ListingType.Local} + value={"Local"} + checked={this.state.type_ == "Local"} onChange={linkEvent(this, this.handleTypeChange)} /> {i18n.t("local")} @@ -79,17 +79,15 @@ export class ListingTypeSelect extends Component< <label title={i18n.t("all_description")} className={`pointer btn btn-outline-secondary ${ - (this.state.type_ == ListingType.All && "active") || - (!this.props.showLocal && - this.state.type_ == ListingType.Local && - "active") + (this.state.type_ == "All" && "active") || + (!this.props.showLocal && this.state.type_ == "Local" && "active") }`} > <input id={`${this.id}-all`} type="radio" - value={ListingType.All} - checked={this.state.type_ == ListingType.All} + value={"All"} + checked={this.state.type_ == "All"} onChange={linkEvent(this, this.handleTypeChange)} /> {i18n.t("all")} diff --git a/src/shared/components/common/markdown-textarea.tsx b/src/shared/components/common/markdown-textarea.tsx index 5aaa127..8e65a0c 100644 --- a/src/shared/components/common/markdown-textarea.tsx +++ b/src/shared/components/common/markdown-textarea.tsx @@ -353,7 +353,7 @@ export class MarkdownTextArea extends Component< if (files.length > maxUploadImages) { toast( i18n.t("too_many_images_upload", { - count: maxUploadImages, + count: Number(maxUploadImages), formattedCount: numToSI(maxUploadImages), }), "danger" diff --git a/src/shared/components/common/paginator.tsx b/src/shared/components/common/paginator.tsx index 75acde3..2c87757 100644 --- a/src/shared/components/common/paginator.tsx +++ b/src/shared/components/common/paginator.tsx @@ -2,8 +2,8 @@ import { Component, linkEvent } from "inferno"; import { i18n } from "../../i18next"; interface PaginatorProps { - page: number; - onChange(val: number): any; + page: bigint; + onChange(val: bigint): any; } export class Paginator extends Component<PaginatorProps, any> { @@ -15,7 +15,7 @@ export class Paginator extends Component<PaginatorProps, any> { <div className="my-2"> <button className="btn btn-secondary mr-2" - disabled={this.props.page == 1} + disabled={this.props.page == 1n} onClick={linkEvent(this, this.handlePrev)} > {i18n.t("prev")} @@ -31,10 +31,10 @@ export class Paginator extends Component<PaginatorProps, any> { } handlePrev(i: Paginator) { - i.props.onChange(i.props.page - 1); + i.props.onChange(i.props.page - 1n); } handleNext(i: Paginator) { - i.props.onChange(i.props.page + 1); + i.props.onChange(i.props.page + 1n); } } diff --git a/src/shared/components/common/sort-select.tsx b/src/shared/components/common/sort-select.tsx index c0d277f..f54d87d 100644 --- a/src/shared/components/common/sort-select.tsx +++ b/src/shared/components/common/sort-select.tsx @@ -46,31 +46,31 @@ export class SortSelect extends Component<SortSelectProps, SortSelectState> { {i18n.t("sort_type")} </option> {!this.props.hideHot && [ - <option key={SortType.Hot} value={SortType.Hot}> + <option key={"Hot"} value={"Hot"}> {i18n.t("hot")} </option>, - <option key={SortType.Active} value={SortType.Active}> + <option key={"Active"} value={"Active"}> {i18n.t("active")} </option>, ]} - <option value={SortType.New}>{i18n.t("new")}</option> - <option value={SortType.Old}>{i18n.t("old")}</option> + <option value={"New"}>{i18n.t("new")}</option> + <option value={"Old"}>{i18n.t("old")}</option> {!this.props.hideMostComments && [ - <option key={SortType.MostComments} value={SortType.MostComments}> + <option key={"MostComments"} value={"MostComments"}> {i18n.t("most_comments")} </option>, - <option key={SortType.NewComments} value={SortType.NewComments}> + <option key={"NewComments"} value={"NewComments"}> {i18n.t("new_comments")} </option>, ]} <option disabled aria-hidden="true"> âââââ </option> - <option value={SortType.TopDay}>{i18n.t("top_day")}</option> - <option value={SortType.TopWeek}>{i18n.t("top_week")}</option> - <option value={SortType.TopMonth}>{i18n.t("top_month")}</option> - <option value={SortType.TopYear}>{i18n.t("top_year")}</option> - <option value={SortType.TopAll}>{i18n.t("top_all")}</option> + <option value={"TopDay"}>{i18n.t("top_day")}</option> + <option value={"TopWeek"}>{i18n.t("top_week")}</option> + <option value={"TopMonth"}>{i18n.t("top_month")}</option> + <option value={"TopYear"}>{i18n.t("top_year")}</option> + <option value={"TopAll"}>{i18n.t("top_all")}</option> </select> <a className="text-muted" diff --git a/src/shared/components/community/communities.tsx b/src/shared/components/community/communities.tsx index 502039e..af7d827 100644 --- a/src/shared/components/community/communities.tsx +++ b/src/shared/components/community/communities.tsx @@ -6,8 +6,6 @@ import { ListCommunities, ListCommunitiesResponse, ListingType, - SortType, - SubscribedType, UserOperation, wsJsonToRes, wsUserOp, @@ -24,7 +22,6 @@ import { isBrowser, myAuth, numToSI, - routeListingTypeToEnum, setIsoData, showLocal, toast, @@ -37,7 +34,7 @@ import { ListingTypeSelect } from "../common/listing-type-select"; import { Paginator } from "../common/paginator"; import { CommunityLink } from "./community-link"; -const communityLimit = 50; +const communityLimit = 50n; interface CommunitiesState { listCommunitiesResponse?: ListCommunitiesResponse; @@ -48,7 +45,7 @@ interface CommunitiesState { interface CommunitiesProps { listingType: ListingType; - page: number; + page: bigint; } function getCommunitiesQueryParams() { @@ -59,7 +56,7 @@ function getCommunitiesQueryParams() { } function getListingTypeFromQuery(listingType?: string): ListingType { - return routeListingTypeToEnum(listingType ?? "", ListingType.Local); + return listingType ? (listingType as ListingType) : "Local"; } function toggleSubscribe(community_id: number, follow: boolean) { @@ -80,7 +77,7 @@ function refetch() { const listCommunitiesForm: ListCommunities = { type_: listingType, - sort: SortType.TopMonth, + sort: "TopMonth", limit: communityLimit, page, auth: myAuth(false), @@ -203,7 +200,7 @@ export class Communities extends Component<any, CommunitiesState> { {numToSI(cv.counts.comments)} </td> <td className="text-right"> - {cv.subscribed == SubscribedType.Subscribed && ( + {cv.subscribed == "Subscribed" && ( <button className="btn btn-link d-inline-block" onClick={linkEvent( @@ -214,7 +211,7 @@ export class Communities extends Component<any, CommunitiesState> { {i18n.t("unsubscribe")} </button> )} - {cv.subscribed === SubscribedType.NotSubscribed && ( + {cv.subscribed === "NotSubscribed" && ( <button className="btn btn-link d-inline-block" onClick={linkEvent( @@ -225,7 +222,7 @@ export class Communities extends Component<any, CommunitiesState> { {i18n.t("subscribe")} </button> )} - {cv.subscribed === SubscribedType.Pending && ( + {cv.subscribed === "Pending" && ( <div className="text-warning d-inline-block"> {i18n.t("subscribe_pending")} </div> @@ -283,14 +280,14 @@ export class Communities extends Component<any, CommunitiesState> { refetch(); } - handlePageChange(page: number) { + handlePageChange(page: bigint) { this.updateUrl({ page }); } handleListingTypeChange(val: ListingType) { this.updateUrl({ listingType: val, - page: 1, + page: 1n, }); } @@ -318,7 +315,7 @@ export class Communities extends Component<any, CommunitiesState> { }: InitialFetchRequest<QueryParams<CommunitiesProps>>): Promise<any>[] { const listCommunitiesForm: ListCommunities = { type_: getListingTypeFromQuery(listingType), - sort: SortType.TopMonth, + sort: "TopMonth", limit: communityLimit, page: getPageFromString(page), auth: auth, diff --git a/src/shared/components/community/community-link.tsx b/src/shared/components/community/community-link.tsx index 04e7a51..bf15971 100644 --- a/src/shared/components/community/community-link.tsx +++ b/src/shared/components/community/community-link.tsx @@ -1,11 +1,11 @@ import { Component } from "inferno"; import { Link } from "inferno-router"; -import { CommunitySafe } from "lemmy-js-client"; +import { Community } from "lemmy-js-client"; import { hostname, relTags, showAvatars } from "../../utils"; import { PictrsImage } from "../common/pictrs-image"; interface CommunityLinkProps { - community: CommunitySafe; + community: Community; realLink?: boolean; useApubName?: boolean; muted?: boolean; diff --git a/src/shared/components/community/community.tsx b/src/shared/components/community/community.tsx index 4776b4c..8a70378 100644 --- a/src/shared/components/community/community.tsx +++ b/src/shared/components/community/community.tsx @@ -14,7 +14,6 @@ import { GetCommunityResponse, GetPosts, GetPostsResponse, - ListingType, PostReportResponse, PostResponse, PostView, @@ -54,8 +53,6 @@ import { postToCommentSortType, relTags, restoreScrollPosition, - routeDataTypeToEnum, - routeSortTypeToEnum, saveCommentRes, saveScrollPosition, setIsoData, @@ -91,7 +88,7 @@ interface State { interface CommunityProps { dataType: DataType; sort: SortType; - page: number; + page: bigint; } function getCommunityQueryParams() { @@ -102,18 +99,16 @@ function getCommunityQueryParams() { }); } -const getDataTypeFromQuery = (type?: string): DataType => - routeDataTypeToEnum(type ?? "", DataType.Post); +function getDataTypeFromQuery(type?: string): DataType { + return type ? DataType[type] : DataType.Post; +} function getSortTypeFromQuery(type?: string): SortType { const mySortType = UserService.Instance.myUserInfo?.local_user_view.local_user .default_sort_type; - return routeSortTypeToEnum( - type ?? "", - mySortType ? Object.values(SortType)[mySortType] : SortType.Active - ); + return type ? (type as SortType) : mySortType ?? "Active"; } export class Community extends Component< @@ -217,7 +212,7 @@ export class Community extends Component< page, limit: fetchLimit, sort, - type_: ListingType.All, + type_: "All", saved_only: false, auth, }; @@ -229,7 +224,7 @@ export class Community extends Component< page, limit: fetchLimit, sort: postToCommentSortType(sort), - type_: ListingType.All, + type_: "All", saved_only: false, auth, }; @@ -432,18 +427,18 @@ export class Community extends Component< ); } - handlePageChange(page: number) { + handlePageChange(page: bigint) { this.updateUrl({ page }); window.scrollTo(0, 0); } handleSortChange(sort: SortType) { - this.updateUrl({ sort, page: 1 }); + this.updateUrl({ sort, page: 1n }); window.scrollTo(0, 0); } handleDataTypeChange(dataType: DataType) { - this.updateUrl({ dataType, page: 1 }); + this.updateUrl({ dataType, page: 1n }); window.scrollTo(0, 0); } @@ -489,7 +484,7 @@ export class Community extends Component< page, limit: fetchLimit, sort, - type_: ListingType.All, + type_: "All", community_name: name, saved_only: false, auth: myAuth(false), @@ -500,7 +495,7 @@ export class Community extends Component< page, limit: fetchLimit, sort: postToCommentSortType(sort), - type_: ListingType.All, + type_: "All", community_name: name, saved_only: false, auth: myAuth(false), @@ -611,7 +606,11 @@ export class Community extends Component< .show_new_post_notifs; // 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)) { + if ( + page === 1n && + nsfwCheck(post_view) && + !isPostBlocked(post_view) + ) { this.state.posts.unshift(post_view); if (showPostNotifs) { notifyPost(post_view, this.context.router); diff --git a/src/shared/components/community/sidebar.tsx b/src/shared/components/community/sidebar.tsx index c7b1046..4316755 100644 --- a/src/shared/components/community/sidebar.tsx +++ b/src/shared/components/community/sidebar.tsx @@ -8,10 +8,9 @@ import { DeleteCommunity, FollowCommunity, Language, - PersonViewSafe, + PersonView, PurgeCommunity, RemoveCommunity, - SubscribedType, } from "lemmy-js-client"; import { i18n } from "../../i18next"; import { UserService, WebSocketService } from "../../services"; @@ -35,7 +34,7 @@ import { PersonListing } from "../person/person-listing"; interface SidebarProps { community_view: CommunityView; moderators: CommunityModeratorView[]; - admins: PersonViewSafe[]; + admins: PersonView[]; allLanguages: Language[]; siteLanguages: number[]; communityLanguages?: number[]; @@ -134,7 +133,7 @@ export class Sidebar extends Component<SidebarProps, SidebarState> { <BannerIconHeader icon={community.icon} banner={community.banner} /> )} <span className="mr-2">{community.title}</span> - {subscribed === SubscribedType.Subscribed && ( + {subscribed === "Subscribed" && ( <button className="btn btn-secondary btn-sm mr-2" onClick={linkEvent(this, this.handleUnsubscribe)} @@ -143,7 +142,7 @@ export class Sidebar extends Component<SidebarProps, SidebarState> { {i18n.t("joined")} </button> )} - {subscribed === SubscribedType.Pending && ( + {subscribed === "Pending" && ( <button className="btn btn-warning mr-2" onClick={linkEvent(this, this.handleUnsubscribe)} @@ -186,18 +185,18 @@ export class Sidebar extends Component<SidebarProps, SidebarState> { <li className="list-inline-item badge badge-secondary"> {i18n.t("number_online", { count: this.props.online, - formattedCount: numToSI(this.props.online), + formattedCount: numToSI(BigInt(this.props.online)), })} </li> <li className="list-inline-item badge badge-secondary pointer" data-tippy-content={i18n.t("active_users_in_the_last_day", { - count: counts.users_active_day, - formattedCount: counts.users_active_day, + count: Number(counts.users_active_day), + formattedCount: numToSI(counts.users_active_day), })} > {i18n.t("number_of_users", { - count: counts.users_active_day, + count: Number(counts.users_active_day), formattedCount: numToSI(counts.users_active_day), })}{" "} / {i18n.t("day")} @@ -205,12 +204,12 @@ export class Sidebar extends Component<SidebarProps, SidebarState> { <li className="list-inline-item badge badge-secondary pointer" data-tippy-content={i18n.t("active_users_in_the_last_week", { - count: counts.users_active_week, - formattedCount: counts.users_active_week, + count: Number(counts.users_active_week), + formattedCount: numToSI(counts.users_active_week), })} > {i18n.t("number_of_users", { - count: counts.users_active_week, + count: Number(counts.users_active_week), formattedCount: numToSI(counts.users_active_week), })}{" "} / {i18n.t("week")} @@ -218,12 +217,12 @@ export class Sidebar extends Component<SidebarProps, SidebarState> { <li className="list-inline-item badge badge-secondary pointer" data-tippy-content={i18n.t("active_users_in_the_last_month", { - count: counts.users_active_month, - formattedCount: counts.users_active_month, + count: Number(counts.users_active_month), + formattedCount: numToSI(counts.users_active_month), })} > {i18n.t("number_of_users", { - count: counts.users_active_month, + count: Number(counts.users_active_month), formattedCount: numToSI(counts.users_active_month), })}{" "} / {i18n.t("month")} @@ -231,31 +230,31 @@ export class Sidebar extends Component<SidebarProps, SidebarState> { <li className="list-inline-item badge badge-secondary pointer" data-tippy-content={i18n.t("active_users_in_the_last_six_months", { - count: counts.users_active_half_year, - formattedCount: counts.users_active_half_year, + count: Number(counts.users_active_half_year), + formattedCount: numToSI(counts.users_active_half_year), })} > {i18n.t("number_of_users", { - count: counts.users_active_half_year, + count: Number(counts.users_active_half_year), formattedCount: numToSI(counts.users_active_half_year), })}{" "} / {i18n.t("number_of_months", { count: 6, formattedCount: 6 })} </li> <li className="list-inline-item badge badge-secondary"> {i18n.t("number_of_subscribers", { - count: counts.subscribers, + count: Number(counts.subscribers), formattedCount: numToSI(counts.subscribers), })} </li> <li className="list-inline-item badge badge-secondary"> {i18n.t("number_of_posts", { - count: counts.posts, + count: Number(counts.posts), formattedCount: numToSI(counts.posts), })} </li> <li className="list-inline-item badge badge-secondary"> {i18n.t("number_of_comments", { - count: counts.comments, + count: Number(counts.comments), formattedCount: numToSI(counts.comments), })} </li> @@ -302,7 +301,7 @@ export class Sidebar extends Component<SidebarProps, SidebarState> { let community_view = this.props.community_view; return ( <div className="mb-2"> - {community_view.subscribed == SubscribedType.NotSubscribed && ( + {community_view.subscribed == "NotSubscribed" && ( <button className="btn btn-secondary btn-block" onClick={linkEvent(this, this.handleSubscribe)} @@ -320,7 +319,7 @@ export class Sidebar extends Component<SidebarProps, SidebarState> { return ( <div className="mb-2"> - {community_view.subscribed == SubscribedType.NotSubscribed && + {community_view.subscribed == "NotSubscribed" && (blocked ? ( <button className="btn btn-danger btn-block" diff --git a/src/shared/components/home/admin-settings.tsx b/src/shared/components/home/admin-settings.tsx index 6d2707e..ab897fe 100644 --- a/src/shared/components/home/admin-settings.tsx +++ b/src/shared/components/home/admin-settings.tsx @@ -3,8 +3,9 @@ import { Component, linkEvent } from "inferno"; import { BannedPersonsResponse, GetBannedPersons, + GetFederatedInstancesResponse, GetSiteResponse, - PersonViewSafe, + PersonView, SiteResponse, UserOperation, wsJsonToRes, @@ -34,7 +35,8 @@ import { TaglineForm } from "./tagline-form"; interface AdminSettingsState { siteRes: GetSiteResponse; - banned: PersonViewSafe[]; + instancesRes?: GetFederatedInstancesResponse; + banned: PersonView[]; loading: boolean; leaveAdminTeamLoading: boolean; currentTab: string; @@ -63,6 +65,8 @@ export class AdminSettings extends Component<any, AdminSettingsState> { this.state = { ...this.state, banned: (this.isoData.routeData[0] as BannedPersonsResponse).banned, + instancesRes: this.isoData + .routeData[1] as GetFederatedInstancesResponse, loading: false, }; } else { @@ -73,6 +77,9 @@ export class AdminSettings extends Component<any, AdminSettingsState> { auth: cAuth, }) ); + WebSocketService.Instance.send( + wsClient.getFederatedInstances({ auth: cAuth }) + ); } } } @@ -84,6 +91,7 @@ export class AdminSettings extends Component<any, AdminSettingsState> { if (auth) { let bannedPersonsForm: GetBannedPersons = { auth }; promises.push(req.client.getBannedPersons(bannedPersonsForm)); + promises.push(req.client.getFederatedInstances({ auth })); } return promises; @@ -167,6 +175,7 @@ export class AdminSettings extends Component<any, AdminSettingsState> { <div className="col-12 col-md-6"> <SiteForm siteRes={this.state.siteRes} + instancesRes={this.state.instancesRes} showLocal={showLocal(this.isoData)} /> </div> @@ -269,9 +278,11 @@ export class AdminSettings extends Component<any, AdminSettingsState> { let data = wsJsonToRes<GetSiteResponse>(msg); this.setState(s => ((s.siteRes.site_view = data.site_view), s)); this.setState({ leaveAdminTeamLoading: false }); - toast(i18n.t("left_admin_team")); this.context.router.history.push("/"); + } else if (op == UserOperation.GetFederatedInstances) { + let data = wsJsonToRes<GetFederatedInstancesResponse>(msg); + this.setState({ instancesRes: data }); } } } diff --git a/src/shared/components/home/emojis-form.tsx b/src/shared/components/home/emojis-form.tsx index 62ac661..409e1c4 100644 --- a/src/shared/components/home/emojis-form.tsx +++ b/src/shared/components/home/emojis-form.tsx @@ -1,17 +1,15 @@ import { Component, linkEvent } from "inferno"; -import { - GetSiteResponse, - UserOperation, - wsJsonToRes, - wsUserOp, -} from "lemmy-js-client"; import { CreateCustomEmoji, CustomEmojiResponse, DeleteCustomEmoji, DeleteCustomEmojiResponse, EditCustomEmoji, -} from "lemmy-js-client/dist/interfaces/api/custom_emoji"; + GetSiteResponse, + UserOperation, + wsJsonToRes, + wsUserOp, +} from "lemmy-js-client"; import { Subscription } from "rxjs"; import { i18n } from "../../i18next"; import { WebSocketService } from "../../services"; @@ -37,7 +35,7 @@ interface EmojiFormState { siteRes: GetSiteResponse; customEmojis: CustomEmojiViewForm[]; loading: boolean; - page: number; + page: bigint; } interface CustomEmojiViewForm { @@ -48,7 +46,7 @@ interface CustomEmojiViewForm { alt_text: string; keywords: string; changed: boolean; - page: number; + page: bigint; } export class EmojiForm extends Component<any, EmojiFormState> { @@ -66,9 +64,9 @@ export class EmojiForm extends Component<any, EmojiFormState> { alt_text: x.custom_emoji.alt_text, keywords: x.keywords.map(x => x.keyword).join(" "), changed: false, - page: 1 + Math.floor(index / this.itemsPerPage), + page: BigInt(1 + Math.floor(index / this.itemsPerPage)), })), - page: 1, + page: 1n, }; state: EmojiFormState; private scrollRef: any = {}; @@ -127,8 +125,11 @@ export class EmojiForm extends Component<any, EmojiFormState> { <tbody> {this.state.customEmojis .slice( - (this.state.page - 1) * this.itemsPerPage, - (this.state.page - 1) * this.itemsPerPage + this.itemsPerPage + Number((this.state.page - 1n) * BigInt(this.itemsPerPage)), + Number( + (this.state.page - 1n) * BigInt(this.itemsPerPage) + + BigInt(this.itemsPerPage) + ) ) .map((cv, index) => ( <tr key={index} ref={e => (this.scrollRef[cv.shortcode] = e)}> @@ -303,7 +304,7 @@ export class EmojiForm extends Component<any, EmojiFormState> { else return i18n.t("custom_emoji_save_validation"); } - handlePageChange(page: number) { + handlePageChange(page: bigint) { this.setState({ page: page }); } @@ -326,13 +327,14 @@ export class EmojiForm extends Component<any, EmojiFormState> { ) { let custom_emojis = [...props.form.state.customEmojis]; let pagedIndex = - (props.form.state.page - 1) * props.form.itemsPerPage + props.index; + (props.form.state.page - 1n) * BigInt(props.form.itemsPerPage) + + BigInt(props.index); let item = { - ...props.form.state.customEmojis[pagedIndex], + ...props.form.state.customEmojis[Number(pagedIndex)], category: event.target.value, changed: true, }; - custom_emojis[pagedIndex] = item; + custom_emojis[Number(pagedIndex)] = item; props.form.setState({ customEmojis: custom_emojis }); } @@ -342,13 +344,14 @@ export class EmojiForm extends Component<any, EmojiFormState> { ) { let custom_emojis = [...props.form.state.customEmojis]; let pagedIndex = - (props.form.state.page - 1) * props.form.itemsPerPage + props.index; + (props.form.state.page - 1n) * BigInt(props.form.itemsPerPage) + + BigInt(props.index); let item = { - ...props.form.state.customEmojis[pagedIndex], + ...props.form.state.customEmojis[Number(pagedIndex)], shortcode: event.target.value, changed: true, }; - custom_emojis[pagedIndex] = item; + custom_emojis[Number(pagedIndex)] = item; props.form.setState({ customEmojis: custom_emojis }); } @@ -358,13 +361,14 @@ export class EmojiForm extends Component<any, EmojiFormState> { ) { let custom_emojis = [...props.form.state.customEmojis]; let pagedIndex = - (props.form.state.page - 1) * props.form.itemsPerPage + props.index; + (props.form.state.page - 1n) * BigInt(props.form.itemsPerPage) + + BigInt(props.index); let item = { - ...props.form.state.customEmojis[pagedIndex], + ...props.form.state.customEmojis[Number(pagedIndex)], image_url: props.overrideValue ?? event.target.value, changed: true, }; - custom_emojis[pagedIndex] = item; + custom_emojis[Number(pagedIndex)] = item; props.form.setState({ customEmojis: custom_emojis }); } @@ -374,13 +378,14 @@ export class EmojiForm extends Component<any, EmojiFormState> { ) { let custom_emojis = [...props.form.state.customEmojis]; let pagedIndex = - (props.form.state.page - 1) * props.form.itemsPerPage + props.index; + (props.form.state.page - 1n) * BigInt(props.form.itemsPerPage) + + BigInt(props.index); let item = { - ...props.form.state.customEmojis[pagedIndex], + ...props.form.state.customEmojis[Number(pagedIndex)], alt_text: event.target.value, changed: true, }; - custom_emojis[pagedIndex] = item; + custom_emojis[Number(pagedIndex)] = item; props.form.setState({ customEmojis: custom_emojis }); } @@ -390,13 +395,14 @@ export class EmojiForm extends Component<any, EmojiFormState> { ) { let custom_emojis = [...props.form.state.customEmojis]; let pagedIndex = - (props.form.state.page - 1) * props.form.itemsPerPage + props.index; + (props.form.state.page - 1n) * BigInt(props.form.itemsPerPage) + + BigInt(props.index); let item = { - ...props.form.state.customEmojis[pagedIndex], + ...props.form.state.customEmojis[Number(pagedIndex)], keywords: event.target.value, changed: true, }; - custom_emojis[pagedIndex] = item; + custom_emojis[Number(pagedIndex)] = item; props.form.setState({ customEmojis: custom_emojis }); } @@ -406,7 +412,8 @@ export class EmojiForm extends Component<any, EmojiFormState> { cv: CustomEmojiViewForm; }) { let pagedIndex = - (props.form.state.page - 1) * props.form.itemsPerPage + props.index; + (props.form.state.page - 1n) * BigInt(props.form.itemsPerPage) + + BigInt(props.index); if (props.cv.id != 0) { const deleteForm: DeleteCustomEmoji = { id: props.cv.id, @@ -415,7 +422,7 @@ export class EmojiForm extends Component<any, EmojiFormState> { WebSocketService.Instance.send(wsClient.deleteCustomEmoji(deleteForm)); } else { let custom_emojis = [...props.form.state.customEmojis]; - custom_emojis.splice(pagedIndex, 1); + custom_emojis.splice(Number(pagedIndex), 1); props.form.setState({ customEmojis: custom_emojis }); } } @@ -451,8 +458,9 @@ export class EmojiForm extends Component<any, EmojiFormState> { handleAddEmojiClick(form: EmojiForm, event: any) { event.preventDefault(); let custom_emojis = [...form.state.customEmojis]; - const page = - 1 + Math.floor(form.state.customEmojis.length / form.itemsPerPage); + const page = BigInt( + 1 + Math.floor(form.state.customEmojis.length / form.itemsPerPage) + ); let item: CustomEmojiViewForm = { id: 0, shortcode: "", diff --git a/src/shared/components/home/home.tsx b/src/shared/components/home/home.tsx index c23586a..0cd5b98 100644 --- a/src/shared/components/home/home.tsx +++ b/src/shared/components/home/home.tsx @@ -61,9 +61,6 @@ import { QueryParams, relTags, restoreScrollPosition, - routeDataTypeToEnum, - routeListingTypeToEnum, - routeSortTypeToEnum, saveCommentRes, saveScrollPosition, setIsoData, @@ -103,36 +100,27 @@ interface HomeProps { listingType: ListingType; dataType: DataType; sort: SortType; - page: number; + page: bigint; } -const getDataTypeFromQuery = (type?: string) => - routeDataTypeToEnum(type ?? "", DataType.Post); +function getDataTypeFromQuery(type?: string): DataType { + return type ? DataType[type] : DataType.Post; +} -function getListingTypeFromQuery(type?: string) { - const mui = UserService.Instance.myUserInfo; +function getListingTypeFromQuery(type?: string): ListingType { + const myListingType = + UserService.Instance.myUserInfo?.local_user_view?.local_user + ?.default_listing_type; - return routeListingTypeToEnum( - type ?? "", - mui - ? Object.values(ListingType)[ - mui.local_user_view.local_user.default_listing_type - ] - : ListingType.Local - ); + return type ? (type as ListingType) : myListingType ?? "Local"; } -function getSortTypeFromQuery(type?: string) { - const mui = UserService.Instance.myUserInfo; +function getSortTypeFromQuery(type?: string): SortType { + const mySortType = + UserService.Instance.myUserInfo?.local_user_view?.local_user + ?.default_sort_type; - return routeSortTypeToEnum( - type ?? "", - mui - ? Object.values(SortType)[ - mui.local_user_view.local_user.default_listing_type - ] - : SortType.Active - ); + return type ? (type as SortType) : mySortType ?? "Active"; } const getHomeQueryParams = () => @@ -145,8 +133,8 @@ const getHomeQueryParams = () => function fetchTrendingCommunities() { const listCommunitiesForm: ListCommunities = { - type_: ListingType.Local, - sort: SortType.Hot, + type_: "Local", + sort: "Hot", limit: trendingFetchLimit, auth: myAuth(false), }; @@ -222,15 +210,15 @@ function getRss(listingType: ListingType) { let rss: string | undefined = undefined; switch (listingType) { - case ListingType.All: { + case "All": { rss = `/feeds/all.xml?sort=${sort}`; break; } - case ListingType.Local: { + case "Local": { rss = `/feeds/local.xml?sort=${sort}`; break; } - case ListingType.Subscribed: { + case "Subscribed": { rss = auth ? `/feeds/front/${auth}.xml?sort=${sort}` : undefined; break; } @@ -336,7 +324,7 @@ export class Home extends Component<any, HomeState> { const type_ = getListingTypeFromQuery(listingType); const sort = getSortTypeFromQuery(urlSort); - const page = urlPage ? Number(urlPage) : 1; + const page = urlPage ? BigInt(urlPage) : 1n; const promises: Promise<any>[] = []; @@ -366,8 +354,8 @@ export class Home extends Component<any, HomeState> { } const trendingCommunitiesForm: ListCommunities = { - type_: ListingType.Local, - sort: SortType.Hot, + type_: "Local", + sort: "Hot", limit: trendingFetchLimit, auth, }; @@ -712,23 +700,23 @@ export class Home extends Component<any, HomeState> { i.setState({ subscribedCollapsed: !i.state.subscribedCollapsed }); } - handlePageChange(page: number) { + handlePageChange(page: bigint) { this.updateUrl({ page }); window.scrollTo(0, 0); } handleSortChange(val: SortType) { - this.updateUrl({ sort: val, page: 1 }); + this.updateUrl({ sort: val, page: 1n }); window.scrollTo(0, 0); } handleListingTypeChange(val: ListingType) { - this.updateUrl({ listingType: val, page: 1 }); + this.updateUrl({ listingType: val, page: 1n }); window.scrollTo(0, 0); } handleDataTypeChange(val: DataType) { - this.updateUrl({ dataType: val, page: 1 }); + this.updateUrl({ dataType: val, page: 1n }); window.scrollTo(0, 0); } @@ -777,21 +765,25 @@ export class Home extends Component<any, HomeState> { const { post_view } = wsJsonToRes<PostResponse>(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)) { + if ( + page === 1n && + 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 ListingType.Subscribed: { + 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 ListingType.Local: { + case "Local": { // If you're on the local view, only push it if its local shouldAddPost = post_view.post.local; break; @@ -885,7 +877,7 @@ export class Home extends Component<any, HomeState> { // If you're on subscribed, only push it if you're subscribed. const shouldAddComment = - listingType === ListingType.Subscribed + listingType === "Subscribed" ? UserService.Instance.myUserInfo?.follows.some( ({ community: { id } }) => id === comment_view.community.id ) diff --git a/src/shared/components/home/instances.tsx b/src/shared/components/home/instances.tsx index 0870f65..674374d 100644 --- a/src/shared/components/home/instances.tsx +++ b/src/shared/components/home/instances.tsx @@ -1,29 +1,79 @@ import { Component } from "inferno"; -import { GetSiteResponse } from "lemmy-js-client"; +import { + GetFederatedInstancesResponse, + GetSiteResponse, + Instance, + UserOperation, + wsJsonToRes, + wsUserOp, +} from "lemmy-js-client"; +import { Subscription } from "rxjs"; import { i18n } from "../../i18next"; -import { relTags, setIsoData } from "../../utils"; +import { InitialFetchRequest } from "../../interfaces"; +import { WebSocketService } from "../../services"; +import { + isBrowser, + relTags, + setIsoData, + toast, + wsClient, + wsSubscribe, +} from "../../utils"; import { HtmlTags } from "../common/html-tags"; interface InstancesState { siteRes: GetSiteResponse; + instancesRes?: GetFederatedInstancesResponse; + loading: boolean; } export class Instances extends Component<any, InstancesState> { private isoData = setIsoData(this.context); state: InstancesState = { siteRes: this.isoData.site_res, + loading: true, }; + private subscription?: Subscription; constructor(props: any, context: any) { super(props, context); + + this.parseMessage = this.parseMessage.bind(this); + this.subscription = wsSubscribe(this.parseMessage); + + // Only fetch the data if coming from another route + if (this.isoData.path == this.context.router.route.match.url) { + this.state = { + ...this.state, + instancesRes: this.isoData + .routeData[0] as GetFederatedInstancesResponse, + loading: false, + }; + } else { + WebSocketService.Instance.send(wsClient.getFederatedInstances({})); + } + } + + static fetchInitialData(req: InitialFetchRequest): Promise<any>[] { + let promises: Promise<any>[] = []; + + promises.push(req.client.getFederatedInstances({})); + + return promises; } get documentTitle(): string { return `${i18n.t("instances")} - ${this.state.siteRes.site_view.site.name}`; } + componentWillUnmount() { + if (isBrowser()) { + this.subscription?.unsubscribe(); + } + } + render() { - let federated_instances = this.state.siteRes.federated_instances; + let federated_instances = this.state.instancesRes?.federated_instances; return federated_instances ? ( <div className="container-lg"> <HtmlTags @@ -56,20 +106,47 @@ export class Instances extends Component<any, InstancesState> { ); } - itemList(items: string[]) { - let noneFound = <div>{i18n.t("none_found")}</div>; + itemList(items: Instance[]) { return items.length > 0 ? ( - <ul> - {items.map(i => ( - <li key={i}> - <a href={`https://${i}`} rel={relTags}> - {i} - </a> - </li> - ))} - </ul> + <div className="table-responsive"> + <table id="instances_table" className="table table-sm table-hover"> + <thead className="pointer"> + <tr> + <th>{i18n.t("name")}</th> + <th>{i18n.t("software")}</th> + <th>{i18n.t("version")}</th> + </tr> + </thead> + <tbody> + {items.map(i => ( + <tr key={i.domain}> + <td> + <a href={`https://${i.domain}`} rel={relTags}> + {i.domain} + </a> + </td> + <td>{i.software}</td> + <td>{i.version}</td> + </tr> + ))} + </tbody> + </table> + </div> ) : ( - noneFound + <div>{i18n.t("none_found")}</div> ); } + parseMessage(msg: any) { + let op = wsUserOp(msg); + console.log(msg); + if (msg.error) { + toast(i18n.t(msg.error), "danger"); + this.context.router.history.push("/"); + this.setState({ loading: false }); + return; + } else if (op == UserOperation.GetFederatedInstances) { + let data = wsJsonToRes<GetFederatedInstancesResponse>(msg); + this.setState({ loading: false, instancesRes: data }); + } + } } diff --git a/src/shared/components/home/login.tsx b/src/shared/components/home/login.tsx index dea6484..a536583 100644 --- a/src/shared/components/home/login.tsx +++ b/src/shared/components/home/login.tsx @@ -51,7 +51,7 @@ export class Login extends Component<any, State> { this.subscription = wsSubscribe(this.parseMessage); if (isBrowser()) { - WebSocketService.Instance.send(wsClient.getCaptcha()); + WebSocketService.Instance.send(wsClient.getCaptcha({})); } } diff --git a/src/shared/components/home/signup.tsx b/src/shared/components/home/signup.tsx index aecba9f..457b416 100644 --- a/src/shared/components/home/signup.tsx +++ b/src/shared/components/home/signup.tsx @@ -8,7 +8,6 @@ import { GetSiteResponse, LoginResponse, Register, - RegistrationMode, SiteView, UserOperation, wsJsonToRes, @@ -99,7 +98,7 @@ export class Signup extends Component<any, State> { this.subscription = wsSubscribe(this.parseMessage); if (isBrowser()) { - WebSocketService.Instance.send(wsClient.getCaptcha()); + WebSocketService.Instance.send(wsClient.getCaptcha({})); } } @@ -258,8 +257,7 @@ export class Signup extends Component<any, State> { </div> </div> - {siteView.local_site.registration_mode == - RegistrationMode.RequireApplication && ( + {siteView.local_site.registration_mode == "RequireApplication" && ( <> <div className="form-group row"> <div className="offset-sm-2 col-sm-10"> @@ -486,7 +484,7 @@ export class Signup extends Component<any, State> { handleRegenCaptcha(i: Signup) { i.audio = undefined; i.setState({ captchaPlaying: false }); - WebSocketService.Instance.send(wsClient.getCaptcha()); + WebSocketService.Instance.send(wsClient.getCaptcha({})); } handleCaptchaPlay(i: Signup) { diff --git a/src/shared/components/home/site-form.tsx b/src/shared/components/home/site-form.tsx index 0bd3c62..ec37af6 100644 --- a/src/shared/components/home/site-form.tsx +++ b/src/shared/components/home/site-form.tsx @@ -3,9 +3,9 @@ import { Prompt } from "inferno-router"; import { CreateSite, EditSite, + GetFederatedInstancesResponse, GetSiteResponse, ListingType, - RegistrationMode, } from "lemmy-js-client"; import { i18n } from "../../i18next"; import { WebSocketService } from "../../services"; @@ -23,6 +23,7 @@ import { MarkdownTextArea } from "../common/markdown-textarea"; interface SiteFormProps { siteRes: GetSiteResponse; + instancesRes?: GetFederatedInstancesResponse; showLocal?: boolean; } @@ -104,8 +105,14 @@ export class SiteForm extends Component<SiteFormProps, SiteFormState> { federation_worker_count: ls.federation_worker_count, captcha_enabled: ls.captcha_enabled, captcha_difficulty: ls.captcha_difficulty, - allowed_instances: this.props.siteRes.federated_instances?.allowed, - blocked_instances: this.props.siteRes.federated_instances?.blocked, + allowed_instances: + this.props.instancesRes?.federated_instances?.allowed.map( + i => i.domain + ), + blocked_instances: + this.props.instancesRes?.federated_instances?.blocked.map( + i => i.domain + ), auth: "TODO", }, }; @@ -295,20 +302,15 @@ export class SiteForm extends Component<SiteFormProps, SiteFormState> { )} className="custom-select w-auto" > - <option value={RegistrationMode.RequireApplication}> + <option value={"RequireApplication"}> {i18n.t("require_registration_application")} </option> - <option value={RegistrationMode.Open}> - {i18n.t("open_registration")} - </option> - <option value={RegistrationMode.Closed}> - {i18n.t("close_registration")} - </option> + <option value={"Open"}>{i18n.t("open_registration")}</option> + <option value={"Closed"}>{i18n.t("close_registration")}</option> </select> </div> </div> - {this.state.siteForm.registration_mode == - RegistrationMode.RequireApplication && ( + {this.state.siteForm.registration_mode == "RequireApplication" && ( <div className="form-group row"> <label className="col-12 col-form-label"> {i18n.t("application_questionnaire")} @@ -438,9 +440,7 @@ export class SiteForm extends Component<SiteFormProps, SiteFormState> { <div className="col-sm-9"> <ListingTypeSelect type_={ - ListingType[ - this.state.siteForm.default_post_listing_type ?? "Local" - ] + this.state.siteForm.default_post_listing_type ?? "Local" } showLocal showSubscribed={false} @@ -1256,12 +1256,7 @@ export class SiteForm extends Component<SiteFormProps, SiteFormState> { } handleDefaultPostListingTypeChange(val: ListingType) { - this.setState( - s => ( - (s.siteForm.default_post_listing_type = ListingType[ListingType[val]]), - s - ) - ); + this.setState(s => ((s.siteForm.default_post_listing_type = val), s)); } } diff --git a/src/shared/components/home/site-sidebar.tsx b/src/shared/components/home/site-sidebar.tsx index fbe3e2a..0592f93 100644 --- a/src/shared/components/home/site-sidebar.tsx +++ b/src/shared/components/home/site-sidebar.tsx @@ -1,6 +1,6 @@ import { Component, linkEvent } from "inferno"; import { Link } from "inferno-router"; -import { PersonViewSafe, Site, SiteAggregates } from "lemmy-js-client"; +import { PersonView, Site, SiteAggregates } from "lemmy-js-client"; import { i18n } from "../../i18next"; import { mdToHtml, numToSI } from "../../utils"; import { BannerIconHeader } from "../common/banner-icon-header"; @@ -11,7 +11,7 @@ interface SiteSidebarProps { site: Site; showLocal: boolean; counts?: SiteAggregates; - admins?: PersonViewSafe[]; + admins?: PersonView[]; online?: number; } @@ -84,7 +84,7 @@ export class SiteSidebar extends Component<SiteSidebarProps, SiteSidebarState> { ); } - admins(admins: PersonViewSafe[]) { + admins(admins: PersonView[]) { return ( <ul className="mt-1 list-inline small mb-0"> <li className="list-inline-item">{i18n.t("admins")}:</li> @@ -105,18 +105,18 @@ export class SiteSidebar extends Component<SiteSidebarProps, SiteSidebarState> { <li className="list-inline-item badge badge-secondary"> {i18n.t("number_online", { count: online, - formattedCount: numToSI(online), + formattedCount: numToSI(BigInt(online)), })} </li> <li className="list-inline-item badge badge-secondary pointer" data-tippy-content={i18n.t("active_users_in_the_last_day", { - count: counts.users_active_day, + count: Number(counts.users_active_day), formattedCount: numToSI(counts.users_active_day), })} > {i18n.t("number_of_users", { - count: counts.users_active_day, + count: Number(counts.users_active_day), formattedCount: numToSI(counts.users_active_day), })}{" "} / {i18n.t("day")} @@ -124,12 +124,12 @@ export class SiteSidebar extends Component<SiteSidebarProps, SiteSidebarState> { <li className="list-inline-item badge badge-secondary pointer" data-tippy-content={i18n.t("active_users_in_the_last_week", { - count: counts.users_active_week, - formattedCount: counts.users_active_week, + count: Number(counts.users_active_week), + formattedCount: numToSI(counts.users_active_week), })} > {i18n.t("number_of_users", { - count: counts.users_active_week, + count: Number(counts.users_active_week), formattedCount: numToSI(counts.users_active_week), })}{" "} / {i18n.t("week")} @@ -137,12 +137,12 @@ export class SiteSidebar extends Component<SiteSidebarProps, SiteSidebarState> { <li className="list-inline-item badge badge-secondary pointer" data-tippy-content={i18n.t("active_users_in_the_last_month", { - count: counts.users_active_month, - formattedCount: counts.users_active_month, + count: Number(counts.users_active_month), + formattedCount: numToSI(counts.users_active_month), })} > {i18n.t("number_of_users", { - count: counts.users_active_month, + count: Number(counts.users_active_month), formattedCount: numToSI(counts.users_active_month), })}{" "} / {i18n.t("month")} @@ -150,37 +150,37 @@ export class SiteSidebar extends Component<SiteSidebarProps, SiteSidebarState> { <li className="list-inline-item badge badge-secondary pointer" data-tippy-content={i18n.t("active_users_in_the_last_six_months", { - count: counts.users_active_half_year, - formattedCount: counts.users_active_half_year, + count: Number(counts.users_active_half_year), + formattedCount: numToSI(counts.users_active_half_year), })} > {i18n.t("number_of_users", { - count: counts.users_active_half_year, + count: Number(counts.users_active_half_year), formattedCount: numToSI(counts.users_active_half_year), })}{" "} / {i18n.t("number_of_months", { count: 6, formattedCount: 6 })} </li> <li className="list-inline-item badge badge-secondary"> {i18n.t("number_of_users", { - count: counts.users, + count: Number(counts.users), formattedCount: numToSI(counts.users), })} </li> <li className="list-inline-item badge badge-secondary"> {i18n.t("number_of_communities", { - count: counts.communities, + count: Number(counts.communities), formattedCount: numToSI(counts.communities), })} </li> <li className="list-inline-item badge badge-secondary"> {i18n.t("number_of_posts", { - count: counts.posts, + count: Number(counts.posts), formattedCount: numToSI(counts.posts), })} </li> <li className="list-inline-item badge badge-secondary"> {i18n.t("number_of_comments", { - count: counts.comments, + count: Number(counts.comments), formattedCount: numToSI(counts.comments), })} </li> diff --git a/src/shared/components/modlog.tsx b/src/shared/components/modlog.tsx index 93490b9..922afc0 100644 --- a/src/shared/components/modlog.tsx +++ b/src/shared/components/modlog.tsx @@ -26,7 +26,7 @@ import { ModRemovePostView, ModTransferCommunityView, ModlogActionType, - PersonSafe, + Person, UserOperation, wsJsonToRes, wsUserOp, @@ -86,7 +86,7 @@ type View = interface ModlogType { id: number; type_: ModlogActionType; - moderator?: PersonSafe; + moderator?: Person; view: View; when_: string; } @@ -111,23 +111,22 @@ interface ModlogState { } interface ModlogProps { - page: number; + page: bigint; userId?: number | null; modId?: number | null; actionType: ModlogActionType; } -const getActionFromString = (action?: string) => - action - ? ModlogActionType[action] ?? ModlogActionType.All - : ModlogActionType.All; +function getActionFromString(action?: string): ModlogActionType { + return action !== undefined ? (action as ModlogActionType) : "All"; +} const getModlogActionMapper = ( actionType: ModlogActionType, getAction: (view: View) => { id: number; when_: string } ) => - (view: View & { moderator?: PersonSafe; admin?: PersonSafe }): ModlogType => { + (view: View & { moderator?: Person; admin?: Person }): ModlogType => { const { id, when_ } = getAction(view); return { @@ -158,14 +157,14 @@ function buildCombined({ const combined = removed_posts .map( getModlogActionMapper( - ModlogActionType.ModRemovePost, + "ModRemovePost", ({ mod_remove_post }: ModRemovePostView) => mod_remove_post ) ) .concat( locked_posts.map( getModlogActionMapper( - ModlogActionType.ModLockPost, + "ModLockPost", ({ mod_lock_post }: ModLockPostView) => mod_lock_post ) ) @@ -173,7 +172,7 @@ function buildCombined({ .concat( featured_posts.map( getModlogActionMapper( - ModlogActionType.ModFeaturePost, + "ModFeaturePost", ({ mod_feature_post }: ModFeaturePostView) => mod_feature_post ) ) @@ -181,7 +180,7 @@ function buildCombined({ .concat( removed_comments.map( getModlogActionMapper( - ModlogActionType.ModRemoveComment, + "ModRemoveComment", ({ mod_remove_comment }: ModRemoveCommentView) => mod_remove_comment ) ) @@ -189,7 +188,7 @@ function buildCombined({ .concat( removed_communities.map( getModlogActionMapper( - ModlogActionType.ModRemoveCommunity, + "ModRemoveCommunity", ({ mod_remove_community }: ModRemoveCommunityView) => mod_remove_community ) @@ -198,7 +197,7 @@ function buildCombined({ .concat( banned_from_community.map( getModlogActionMapper( - ModlogActionType.ModBanFromCommunity, + "ModBanFromCommunity", ({ mod_ban_from_community }: ModBanFromCommunityView) => mod_ban_from_community ) @@ -207,7 +206,7 @@ function buildCombined({ .concat( added_to_community.map( getModlogActionMapper( - ModlogActionType.ModAddCommunity, + "ModAddCommunity", ({ mod_add_community }: ModAddCommunityView) => mod_add_community ) ) @@ -215,7 +214,7 @@ function buildCombined({ .concat( transferred_to_community.map( getModlogActionMapper( - ModlogActionType.ModTransferCommunity, + "ModTransferCommunity", ({ mod_transfer_community }: ModTransferCommunityView) => mod_transfer_community ) @@ -223,24 +222,18 @@ function buildCombined({ ) .concat( added.map( - getModlogActionMapper( - ModlogActionType.ModAdd, - ({ mod_add }: ModAddView) => mod_add - ) + getModlogActionMapper("ModAdd", ({ mod_add }: ModAddView) => mod_add) ) ) .concat( banned.map( - getModlogActionMapper( - ModlogActionType.ModBan, - ({ mod_ban }: ModBanView) => mod_ban - ) + getModlogActionMapper("ModBan", ({ mod_ban }: ModBanView) => mod_ban) ) ) .concat( admin_purged_persons.map( getModlogActionMapper( - ModlogActionType.AdminPurgePerson, + "AdminPurgePerson", ({ admin_purge_person }: AdminPurgePersonView) => admin_purge_person ) ) @@ -248,7 +241,7 @@ function buildCombined({ .concat( admin_purged_communities.map( getModlogActionMapper( - ModlogActionType.AdminPurgeCommunity, + "AdminPurgeCommunity", ({ admin_purge_community }: AdminPurgeCommunityView) => admin_purge_community ) @@ -257,7 +250,7 @@ function buildCombined({ .concat( admin_purged_posts.map( getModlogActionMapper( - ModlogActionType.AdminPurgePost, + "AdminPurgePost", ({ admin_purge_post }: AdminPurgePostView) => admin_purge_post ) ) @@ -265,7 +258,7 @@ function buildCombined({ .concat( admin_purged_comments.map( getModlogActionMapper( - ModlogActionType.AdminPurgeComment, + "AdminPurgeComment", ({ admin_purge_comment }: AdminPurgeCommentView) => admin_purge_comment ) @@ -280,7 +273,7 @@ function buildCombined({ function renderModlogType({ type_, view }: ModlogType) { switch (type_) { - case ModlogActionType.ModRemovePost: { + case "ModRemovePost": { const mrpv = view as ModRemovePostView; const { mod_remove_post: { reason, removed }, @@ -302,7 +295,7 @@ function renderModlogType({ type_, view }: ModlogType) { ); } - case ModlogActionType.ModLockPost: { + case "ModLockPost": { const { mod_lock_post: { locked }, post: { id, name }, @@ -318,7 +311,7 @@ function renderModlogType({ type_, view }: ModlogType) { ); } - case ModlogActionType.ModFeaturePost: { + case "ModFeaturePost": { const { mod_feature_post: { featured, is_featured_community }, post: { id, name }, @@ -334,7 +327,7 @@ function renderModlogType({ type_, view }: ModlogType) { </> ); } - case ModlogActionType.ModRemoveComment: { + case "ModRemoveComment": { const mrc = view as ModRemoveCommentView; const { mod_remove_comment: { reason, removed }, @@ -361,7 +354,7 @@ function renderModlogType({ type_, view }: ModlogType) { ); } - case ModlogActionType.ModRemoveCommunity: { + case "ModRemoveCommunity": { const mrco = view as ModRemoveCommunityView; const { mod_remove_community: { reason, expires, removed }, @@ -388,7 +381,7 @@ function renderModlogType({ type_, view }: ModlogType) { ); } - case ModlogActionType.ModBanFromCommunity: { + case "ModBanFromCommunity": { const mbfc = view as ModBanFromCommunityView; const { mod_ban_from_community: { reason, expires, banned }, @@ -420,7 +413,7 @@ function renderModlogType({ type_, view }: ModlogType) { ); } - case ModlogActionType.ModAddCommunity: { + case "ModAddCommunity": { const { mod_add_community: { removed }, modded_person, @@ -441,16 +434,12 @@ function renderModlogType({ type_, view }: ModlogType) { ); } - case ModlogActionType.ModTransferCommunity: { - const { - mod_transfer_community: { removed }, - community, - modded_person, - } = view as ModTransferCommunityView; + case "ModTransferCommunity": { + const { community, modded_person } = view as ModTransferCommunityView; return ( <> - <span>{removed ? "Removed " : "Transferred "}</span> + <span>Transferred</span> <span> <CommunityLink community={community} /> </span> @@ -462,7 +451,7 @@ function renderModlogType({ type_, view }: ModlogType) { ); } - case ModlogActionType.ModBan: { + case "ModBan": { const { mod_ban: { reason, expires, banned }, banned_person, @@ -488,7 +477,7 @@ function renderModlogType({ type_, view }: ModlogType) { ); } - case ModlogActionType.ModAdd: { + case "ModAdd": { const { mod_add: { removed }, modded_person, @@ -504,7 +493,7 @@ function renderModlogType({ type_, view }: ModlogType) { </> ); } - case ModlogActionType.AdminPurgePerson: { + case "AdminPurgePerson": { const { admin_purge_person: { reason }, } = view as AdminPurgePersonView; @@ -521,7 +510,7 @@ function renderModlogType({ type_, view }: ModlogType) { ); } - case ModlogActionType.AdminPurgeCommunity: { + case "AdminPurgeCommunity": { const { admin_purge_community: { reason }, } = view as AdminPurgeCommunityView; @@ -538,7 +527,7 @@ function renderModlogType({ type_, view }: ModlogType) { ); } - case ModlogActionType.AdminPurgePost: { + case "AdminPurgePost": { const { admin_purge_post: { reason }, community, @@ -557,7 +546,7 @@ function renderModlogType({ type_, view }: ModlogType) { ); } - case ModlogActionType.AdminPurgeComment: { + case "AdminPurgeComment": { const { admin_purge_comment: { reason }, post: { id, name }, @@ -641,7 +630,7 @@ async function createNewOptions({ if (text.length > 0) { newOptions.push( ...(await fetchUsers(text)).users - .slice(0, fetchLimit) + .slice(0, Number(fetchLimit)) .map<Choice>(personToChoice) ); } @@ -751,7 +740,7 @@ export class Modlog extends Component< return amAdmin() || amMod(this.state.communityMods); } - modOrAdminText(person?: PersonSafe): string { + modOrAdminText(person?: Person): string { return person && this.isoData.site_res.admins.some( ({ person: { id } }) => id === person.id @@ -814,35 +803,21 @@ export class Modlog extends Component< <option disabled aria-hidden="true"> {i18n.t("filter_by_action")} </option> - <option value={ModlogActionType.All}>{i18n.t("all")}</option> - <option value={ModlogActionType.ModRemovePost}> - Removing Posts - </option> - <option value={ModlogActionType.ModLockPost}> - Locking Posts - </option> - <option value={ModlogActionType.ModFeaturePost}> - Featuring Posts - </option> - <option value={ModlogActionType.ModRemoveComment}> - Removing Comments - </option> - <option value={ModlogActionType.ModRemoveCommunity}> - Removing Communities - </option> - <option value={ModlogActionType.ModBanFromCommunity}> + <option value={"All"}>{i18n.t("all")}</option> + <option value={"ModRemovePost"}>Removing Posts</option> + <option value={"ModLockPost"}>Locking Posts</option> + <option value={"ModFeaturePost"}>Featuring Posts</option> + <option value={"ModRemoveComment"}>Removing Comments</option> + <option value={"ModRemoveCommunity"}>Removing Communities</option> + <option value={"ModBanFromCommunity"}> Banning From Communities </option> - <option value={ModlogActionType.ModAddCommunity}> - Adding Mod to Community - </option> - <option value={ModlogActionType.ModTransferCommunity}> + <option value={"ModAddCommunity"}>Adding Mod to Community</option> + <option value={"ModTransferCommunity"}> Transferring Communities </option> - <option value={ModlogActionType.ModAdd}> - Adding Mod to Site - </option> - <option value={ModlogActionType.ModBan}>Banning From Site</option> + <option value={"ModAdd"}>Adding Mod to Site</option> + <option value={"ModBan"}>Banning From Site</option> </select> </div> <div className="form-row mb-2"> @@ -892,21 +867,21 @@ export class Modlog extends Component< handleFilterActionChange(i: Modlog, event: any) { i.updateUrl({ - actionType: ModlogActionType[event.target.value], - page: 1, + actionType: event.target.value as ModlogActionType, + page: 1n, }); } - handlePageChange(page: number) { + handlePageChange(page: bigint) { this.updateUrl({ page }); } handleUserChange(option: Choice) { - this.updateUrl({ userId: getIdFromString(option.value) ?? null, page: 1 }); + this.updateUrl({ userId: getIdFromString(option.value) ?? null, page: 1n }); } handleModChange(option: Choice) { - this.updateUrl({ modId: getIdFromString(option.value) ?? null, page: 1 }); + this.updateUrl({ modId: getIdFromString(option.value) ?? null, page: 1n }); } handleSearchUsers = debounce(async (text: string) => { diff --git a/src/shared/components/person/inbox.tsx b/src/shared/components/person/inbox.tsx index 692b9dd..10af488 100644 --- a/src/shared/components/person/inbox.tsx +++ b/src/shared/components/person/inbox.tsx @@ -84,7 +84,7 @@ interface InboxState { messages: PrivateMessageView[]; combined: ReplyType[]; sort: CommentSortType; - page: number; + page: bigint; siteRes: GetSiteResponse; loading: boolean; } @@ -99,8 +99,8 @@ export class Inbox extends Component<any, InboxState> { mentions: [], messages: [], combined: [], - sort: CommentSortType.New, - page: 1, + sort: "New", + page: 1n, siteRes: this.isoData.site_res, loading: true, }; @@ -471,33 +471,33 @@ export class Inbox extends Component<any, InboxState> { ); } - handlePageChange(page: number) { + handlePageChange(page: bigint) { this.setState({ page }); this.refetch(); } handleUnreadOrAllChange(i: Inbox, event: any) { - i.setState({ unreadOrAll: Number(event.target.value), page: 1 }); + i.setState({ unreadOrAll: Number(event.target.value), page: 1n }); i.refetch(); } handleMessageTypeChange(i: Inbox, event: any) { - i.setState({ messageType: Number(event.target.value), page: 1 }); + i.setState({ messageType: Number(event.target.value), page: 1n }); i.refetch(); } static fetchInitialData(req: InitialFetchRequest): Promise<any>[] { let promises: Promise<any>[] = []; - let sort = CommentSortType.New; + let sort: CommentSortType = "New"; let auth = req.auth; if (auth) { // It can be /u/me, or /username/1 let repliesForm: GetReplies = { - sort, + sort: "New", unread_only: true, - page: 1, + page: 1n, limit: fetchLimit, auth, }; @@ -506,7 +506,7 @@ export class Inbox extends Component<any, InboxState> { let personMentionsForm: GetPersonMentions = { sort, unread_only: true, - page: 1, + page: 1n, limit: fetchLimit, auth, }; @@ -514,7 +514,7 @@ export class Inbox extends Component<any, InboxState> { let privateMessagesForm: GetPrivateMessages = { unread_only: true, - page: 1, + page: 1n, limit: fetchLimit, auth, }; @@ -565,7 +565,7 @@ export class Inbox extends Component<any, InboxState> { } handleSortChange(val: CommentSortType) { - this.setState({ sort: val, page: 1 }); + this.setState({ sort: val, page: 1n }); this.refetch(); } @@ -579,7 +579,7 @@ export class Inbox extends Component<any, InboxState> { ); i.setState({ replies: [], mentions: [], messages: [] }); i.setState({ combined: i.buildCombined() }); - UserService.Instance.unreadInboxCountSub.next(0); + UserService.Instance.unreadInboxCountSub.next(0n); window.scrollTo(0, 0); i.setState(i.state); } @@ -588,9 +588,9 @@ export class Inbox extends Component<any, InboxState> { sendUnreadCount(read: boolean) { let urcs = UserService.Instance.unreadInboxCountSub; if (read) { - urcs.next(urcs.getValue() - 1); + urcs.next(urcs.getValue() - 1n); } else { - urcs.next(urcs.getValue() + 1); + urcs.next(urcs.getValue() + 1n); } } diff --git a/src/shared/components/person/password-change.tsx b/src/shared/components/person/password-change.tsx index 32ebad6..f3df971 100644 --- a/src/shared/components/person/password-change.tsx +++ b/src/shared/components/person/password-change.tsx @@ -2,7 +2,7 @@ import { Component, linkEvent } from "inferno"; import { GetSiteResponse, LoginResponse, - PasswordChange as PWordChange, + PasswordChangeAfterReset, UserOperation, wsJsonToRes, wsUserOp, @@ -147,7 +147,7 @@ export class PasswordChange extends Component<any, State> { let password_verify = i.state.form.password_verify; if (password && password_verify) { - let form: PWordChange = { + let form: PasswordChangeAfterReset = { token: i.state.form.token, password, password_verify, @@ -164,7 +164,7 @@ export class PasswordChange extends Component<any, State> { toast(i18n.t(msg.error), "danger"); this.setState({ loading: false }); return; - } else if (op == UserOperation.PasswordChange) { + } else if (op == UserOperation.PasswordChangeAfterReset) { let data = wsJsonToRes<LoginResponse>(msg); UserService.Instance.login(data); this.props.history.push("/"); diff --git a/src/shared/components/person/person-details.tsx b/src/shared/components/person/person-details.tsx index 450f6c5..910ea98 100644 --- a/src/shared/components/person/person-details.tsx +++ b/src/shared/components/person/person-details.tsx @@ -3,7 +3,7 @@ import { CommentView, GetPersonDetailsResponse, Language, - PersonViewSafe, + PersonView, PostView, SortType, } from "lemmy-js-client"; @@ -15,16 +15,16 @@ import { PostListing } from "../post/post-listing"; interface PersonDetailsProps { personRes: GetPersonDetailsResponse; - admins: PersonViewSafe[]; + admins: PersonView[]; allLanguages: Language[]; siteLanguages: number[]; - page: number; - limit: number; + page: bigint; + limit: bigint; sort: SortType; enableDownvotes: boolean; enableNsfw: boolean; view: PersonDetailsView; - onPageChange(page: number): number | any; + onPageChange(page: bigint): bigint | any; } enum ItemEnum { @@ -36,7 +36,7 @@ type ItemType = { type_: ItemEnum; view: CommentView | PostView; published: string; - score: number; + score: bigint; }; export class PersonDetails extends Component<PersonDetailsProps, any> { @@ -144,10 +144,10 @@ export class PersonDetails extends Component<PersonDetailsProps, any> { let combined = [...comments, ...posts]; // Sort it - if (this.props.sort === SortType.New) { + if (this.props.sort === "New") { combined.sort((a, b) => b.published.localeCompare(a.published)); } else { - combined.sort((a, b) => b.score - a.score); + combined.sort((a, b) => Number(b.score - a.score)); } return ( @@ -199,7 +199,7 @@ export class PersonDetails extends Component<PersonDetailsProps, any> { ); } - handlePageChange(val: number) { + handlePageChange(val: bigint) { this.props.onPageChange(val); } } diff --git a/src/shared/components/person/person-listing.tsx b/src/shared/components/person/person-listing.tsx index 6cf4ad1..f4121b3 100644 --- a/src/shared/components/person/person-listing.tsx +++ b/src/shared/components/person/person-listing.tsx @@ -1,12 +1,12 @@ import { Component } from "inferno"; import { Link } from "inferno-router"; -import { PersonSafe } from "lemmy-js-client"; +import { Person } from "lemmy-js-client"; import { hostname, isCakeDay, relTags, showAvatars } from "../../utils"; import { PictrsImage } from "../common/pictrs-image"; import { CakeDay } from "./cake-day"; interface PersonListingProps { - person: PersonSafe; + person: Person; realLink?: boolean; useApubName?: boolean; muted?: boolean; diff --git a/src/shared/components/person/profile.tsx b/src/shared/components/person/profile.tsx index 59ac95a..b38dae9 100644 --- a/src/shared/components/person/profile.tsx +++ b/src/shared/components/person/profile.tsx @@ -10,8 +10,8 @@ import { BlockPerson, BlockPersonResponse, CommentResponse, + Community, CommunityModeratorView, - CommunitySafe, GetPersonDetails, GetPersonDetailsResponse, GetSiteResponse, @@ -49,7 +49,6 @@ import { numToSI, relTags, restoreScrollPosition, - routeSortTypeToEnum, saveCommentRes, saveScrollPosition, setIsoData, @@ -82,23 +81,26 @@ interface ProfileState { interface ProfileProps { view: PersonDetailsView; sort: SortType; - page: number; + page: bigint; } -const getProfileQueryParams = () => - getQueryParams<ProfileProps>({ +function getProfileQueryParams() { + return getQueryParams<ProfileProps>({ view: getViewFromProps, page: getPageFromString, sort: getSortTypeFromQuery, }); +} -const getSortTypeFromQuery = (sort?: string): SortType => - sort ? routeSortTypeToEnum(sort, SortType.New) : SortType.New; +function getSortTypeFromQuery(sort?: string): SortType { + return sort ? (sort as SortType) : "New"; +} -const getViewFromProps = (view?: string): PersonDetailsView => - view +function getViewFromProps(view?: string): PersonDetailsView { + return view ? PersonDetailsView[view] ?? PersonDetailsView.Overview : PersonDetailsView.Overview; +} function toggleBlockPerson(recipientId: number, block: boolean) { const auth = myAuth(); @@ -122,7 +124,7 @@ const handleBlockPerson = (personId: number) => const getCommunitiesListing = ( translationKey: NoOptionI18nKeys, - communityViews?: { community: CommunitySafe }[] + communityViews?: { community: Community }[] ) => communityViews && communityViews.length > 0 && ( @@ -500,13 +502,13 @@ export class Profile extends Component< <ul className="list-inline mb-2"> <li className="list-inline-item badge badge-light"> {i18n.t("number_of_posts", { - count: pv.counts.post_count, + count: Number(pv.counts.post_count), formattedCount: numToSI(pv.counts.post_count), })} </li> <li className="list-inline-item badge badge-light"> {i18n.t("number_of_comments", { - count: pv.counts.comment_count, + count: Number(pv.counts.comment_count), formattedCount: numToSI(pv.counts.comment_count), })} </li> @@ -643,18 +645,18 @@ export class Profile extends Component< this.fetchUserData(); } - handlePageChange(page: number) { + handlePageChange(page: bigint) { this.updateUrl({ page }); } handleSortChange(sort: SortType) { - this.updateUrl({ sort, page: 1 }); + this.updateUrl({ sort, page: 1n }); } handleViewChange(i: Profile, event: any) { i.updateUrl({ view: PersonDetailsView[event.target.value], - page: 1, + page: 1n, }); } diff --git a/src/shared/components/person/registration-applications.tsx b/src/shared/components/person/registration-applications.tsx index 1816741..cd99bcc 100644 --- a/src/shared/components/person/registration-applications.tsx +++ b/src/shared/components/person/registration-applications.tsx @@ -37,7 +37,7 @@ interface RegistrationApplicationsState { listRegistrationApplicationsResponse?: ListRegistrationApplicationsResponse; siteRes: GetSiteResponse; unreadOrAll: UnreadOrAll; - page: number; + page: bigint; loading: boolean; } @@ -50,7 +50,7 @@ export class RegistrationApplications extends Component< state: RegistrationApplicationsState = { siteRes: this.isoData.site_res, unreadOrAll: UnreadOrAll.Unread, - page: 1, + page: 1n, loading: true, }; @@ -188,11 +188,11 @@ export class RegistrationApplications extends Component< } handleUnreadOrAllChange(i: RegistrationApplications, event: any) { - i.setState({ unreadOrAll: Number(event.target.value), page: 1 }); + i.setState({ unreadOrAll: Number(event.target.value), page: 1n }); i.refetch(); } - handlePageChange(page: number) { + handlePageChange(page: bigint) { this.setState({ page }); this.refetch(); } @@ -204,7 +204,7 @@ export class RegistrationApplications extends Component< if (auth) { let form: ListRegistrationApplications = { unread_only: true, - page: 1, + page: 1n, limit: fetchLimit, auth, }; @@ -254,7 +254,7 @@ export class RegistrationApplications extends Component< ); let uacs = UserService.Instance.unreadApplicationCountSub; // Minor bug, where if the application switches from deny to approve, the count will still go down - uacs.next(uacs.getValue() - 1); + uacs.next(uacs.getValue() - 1n); this.setState(this.state); } } diff --git a/src/shared/components/person/reports.tsx b/src/shared/components/person/reports.tsx index 0af56b5..8fc3081 100644 --- a/src/shared/components/person/reports.tsx +++ b/src/shared/components/person/reports.tsx @@ -75,7 +75,7 @@ interface ReportsState { messageType: MessageType; combined: ItemType[]; siteRes: GetSiteResponse; - page: number; + page: bigint; loading: boolean; } @@ -86,7 +86,7 @@ export class Reports extends Component<any, ReportsState> { unreadOrAll: UnreadOrAll.Unread, messageType: MessageType.All, combined: [], - page: 1, + page: 1n, siteRes: this.isoData.site_res, loading: true, }; @@ -422,18 +422,18 @@ export class Reports extends Component<any, ReportsState> { ); } - handlePageChange(page: number) { + handlePageChange(page: bigint) { this.setState({ page }); this.refetch(); } handleUnreadOrAllChange(i: Reports, event: any) { - i.setState({ unreadOrAll: Number(event.target.value), page: 1 }); + i.setState({ unreadOrAll: Number(event.target.value), page: 1n }); i.refetch(); } handleMessageTypeChange(i: Reports, event: any) { - i.setState({ messageType: Number(event.target.value), page: 1 }); + i.setState({ messageType: Number(event.target.value), page: 1n }); i.refetch(); } @@ -441,7 +441,7 @@ export class Reports extends Component<any, ReportsState> { let promises: Promise<any>[] = []; let unresolved_only = true; - let page = 1; + let page = 1n; let limit = fetchLimit; let auth = req.auth; @@ -553,9 +553,9 @@ export class Reports extends Component<any, ReportsState> { ); let urcs = UserService.Instance.unreadReportCountSub; if (data.post_report_view.post_report.resolved) { - urcs.next(urcs.getValue() - 1); + urcs.next(urcs.getValue() - 1n); } else { - urcs.next(urcs.getValue() + 1); + urcs.next(urcs.getValue() + 1n); } this.setState(this.state); } else if (op == UserOperation.ResolveCommentReport) { @@ -566,9 +566,9 @@ export class Reports extends Component<any, ReportsState> { ); let urcs = UserService.Instance.unreadReportCountSub; if (data.comment_report_view.comment_report.resolved) { - urcs.next(urcs.getValue() - 1); + urcs.next(urcs.getValue() - 1n); } else { - urcs.next(urcs.getValue() + 1); + urcs.next(urcs.getValue() + 1n); } this.setState(this.state); } else if (op == UserOperation.ResolvePrivateMessageReport) { @@ -579,9 +579,9 @@ export class Reports extends Component<any, ReportsState> { ); let urcs = UserService.Instance.unreadReportCountSub; if (data.private_message_report_view.private_message_report.resolved) { - urcs.next(urcs.getValue() - 1); + urcs.next(urcs.getValue() - 1n); } else { - urcs.next(urcs.getValue() + 1); + urcs.next(urcs.getValue() + 1n); } this.setState(this.state); } diff --git a/src/shared/components/person/settings.tsx b/src/shared/components/person/settings.tsx index 74a40c1..95b2590 100644 --- a/src/shared/components/person/settings.tsx +++ b/src/shared/components/person/settings.tsx @@ -62,8 +62,8 @@ interface SettingsState { saveUserSettingsForm: { show_nsfw?: boolean; theme?: string; - default_sort_type?: number; - default_listing_type?: number; + default_sort_type?: SortType; + default_listing_type?: ListingType; interface_language?: string; avatar?: string; banner?: string; @@ -650,9 +650,8 @@ export class Settings extends Component<any, SettingsState> { <div className="col-sm-9"> <ListingTypeSelect type_={ - Object.values(ListingType)[ - this.state.saveUserSettingsForm.default_listing_type ?? 1 - ] + this.state.saveUserSettingsForm.default_listing_type ?? + "Local" } showLocal={showLocal(this.isoData)} showSubscribed @@ -665,9 +664,7 @@ export class Settings extends Component<any, SettingsState> { <div className="col-sm-9"> <SortSelect sort={ - Object.values(SortType)[ - this.state.saveUserSettingsForm.default_sort_type ?? 0 - ] + this.state.saveUserSettingsForm.default_sort_type ?? "Active" } onChange={this.handleSortTypeChange} /> @@ -1096,22 +1093,12 @@ export class Settings extends Component<any, SettingsState> { } handleSortTypeChange(val: SortType) { - this.setState( - s => ( - (s.saveUserSettingsForm.default_sort_type = - Object.keys(SortType).indexOf(val)), - s - ) - ); + this.setState(s => ((s.saveUserSettingsForm.default_sort_type = val), s)); } handleListingTypeChange(val: ListingType) { this.setState( - s => ( - (s.saveUserSettingsForm.default_listing_type = - Object.keys(ListingType).indexOf(val)), - s - ) + s => ((s.saveUserSettingsForm.default_listing_type = val), s) ); } diff --git a/src/shared/components/person/verify-email.tsx b/src/shared/components/person/verify-email.tsx index 14231b8..61261bb 100644 --- a/src/shared/components/person/verify-email.tsx +++ b/src/shared/components/person/verify-email.tsx @@ -3,7 +3,6 @@ import { GetSiteResponse, UserOperation, VerifyEmail as VerifyEmailForm, - VerifyEmailResponse, wsJsonToRes, wsUserOp, } from "lemmy-js-client"; @@ -85,7 +84,7 @@ export class VerifyEmail extends Component<any, State> { this.props.history.push("/"); return; } else if (op == UserOperation.VerifyEmail) { - let data = wsJsonToRes<VerifyEmailResponse>(msg); + let data = wsJsonToRes(msg); if (data) { toast(i18n.t("email_verified")); this.props.history.push("/login"); diff --git a/src/shared/components/post/post-form.tsx b/src/shared/components/post/post-form.tsx index bcebc34..355a6ed 100644 --- a/src/shared/components/post/post-form.tsx +++ b/src/shared/components/post/post-form.tsx @@ -5,13 +5,10 @@ import { CreatePost, EditPost, Language, - ListingType, PostResponse, PostView, Search, SearchResponse, - SearchType, - SortType, UserOperation, wsJsonToRes, wsUserOp, @@ -516,10 +513,10 @@ export class PostForm extends Component<PostFormProps, PostFormState> { if (url && validURL(url)) { let form: Search = { q: url, - type_: SearchType.Url, - sort: SortType.TopAll, - listing_type: ListingType.All, - page: 1, + type_: "Url", + sort: "TopAll", + listing_type: "All", + page: 1n, limit: trendingFetchLimit, auth: myAuth(false), }; @@ -545,11 +542,11 @@ export class PostForm extends Component<PostFormProps, PostFormState> { if (q && q !== "") { let form: Search = { q, - type_: SearchType.Posts, - sort: SortType.TopAll, - listing_type: ListingType.All, + type_: "Posts", + sort: "TopAll", + listing_type: "All", community_id: this.state.form.community_id, - page: 1, + page: 1n, limit: trendingFetchLimit, auth: myAuth(false), }; @@ -687,9 +684,9 @@ export class PostForm extends Component<PostFormProps, PostFormState> { } else if (op == UserOperation.Search) { let data = wsJsonToRes<SearchResponse>(msg); - if (data.type_ == SearchType[SearchType.Posts]) { + if (data.type_ == "Posts") { this.setState({ suggestedPosts: data.posts }); - } else if (data.type_ == SearchType[SearchType.Url]) { + } else if (data.type_ == "Url") { this.setState({ crossPosts: data.posts }); } } diff --git a/src/shared/components/post/post-listing.tsx b/src/shared/components/post/post-listing.tsx index 34037aa..5152818 100644 --- a/src/shared/components/post/post-listing.tsx +++ b/src/shared/components/post/post-listing.tsx @@ -14,8 +14,7 @@ import { FeaturePost, Language, LockPost, - PersonViewSafe, - PostFeatureType, + PersonView, PostView, PurgePerson, PurgePost, @@ -81,16 +80,16 @@ interface PostListingState { showReportDialog: boolean; reportReason?: string; my_vote?: number; - score: number; - upvotes: number; - downvotes: number; + score: bigint; + upvotes: bigint; + downvotes: bigint; } interface PostListingProps { post_view: PostView; duplicates?: PostView[]; moderators?: CommunityModeratorView[]; - admins?: PersonViewSafe[]; + admins?: PersonView[]; allLanguages: Language[]; siteLanguages: number[]; showCommunity?: boolean; @@ -638,15 +637,15 @@ export class PostListing extends Component<PostListingProps, PostListingState> { <Link className="text-muted" title={i18n.t("number_of_comments", { - count: post_view.counts.comments, - formattedCount: post_view.counts.comments, + count: Number(post_view.counts.comments), + formattedCount: Number(post_view.counts.comments), })} to={`/post/${post_view.post.id}?scrollToComments=true`} > <Icon icon="message-square" classes="mr-1" inline /> <span className="mr-2"> {i18n.t("number_of_comments", { - count: post_view.counts.comments, + count: Number(post_view.counts.comments), formattedCount: numToSI(post_view.counts.comments), })} </span> @@ -660,9 +659,9 @@ export class PostListing extends Component<PostListingProps, PostListingState> { ); } - get unreadCount(): number | undefined { + get unreadCount(): bigint | undefined { let pv = this.props.post_view; - return pv.unread_comments == pv.counts.comments || pv.unread_comments == 0 + return pv.unread_comments == pv.counts.comments || pv.unread_comments == 0n ? undefined : pv.unread_comments; } @@ -699,7 +698,7 @@ export class PostListing extends Component<PostListingProps, PostListingState> { {showScores() && ( <span className={classNames("ml-2", { - invisible: this.state.downvotes === 0, + invisible: this.state.downvotes === 0n, })} > {numToSI(this.state.downvotes)} @@ -1319,19 +1318,19 @@ export class PostListing extends Component<PostListingProps, PostListingState> { if (myVote == 1) { this.setState({ - score: this.state.score - 1, - upvotes: this.state.upvotes - 1, + score: this.state.score - 1n, + upvotes: this.state.upvotes - 1n, }); } else if (myVote == -1) { this.setState({ - score: this.state.score + 2, - upvotes: this.state.upvotes + 1, - downvotes: this.state.downvotes - 1, + score: this.state.score + 2n, + upvotes: this.state.upvotes + 1n, + downvotes: this.state.downvotes - 1n, }); } else { this.setState({ - score: this.state.score + 1, - upvotes: this.state.upvotes + 1, + score: this.state.score + 1n, + upvotes: this.state.upvotes + 1n, }); } @@ -1362,19 +1361,19 @@ export class PostListing extends Component<PostListingProps, PostListingState> { if (myVote == 1) { this.setState({ - score: this.state.score - 2, - upvotes: this.state.upvotes - 1, - downvotes: this.state.downvotes + 1, + score: this.state.score - 2n, + upvotes: this.state.upvotes - 1n, + downvotes: this.state.downvotes + 1n, }); } else if (myVote == -1) { this.setState({ - score: this.state.score + 1, - downvotes: this.state.downvotes - 1, + score: this.state.score + 1n, + downvotes: this.state.downvotes - 1n, }); } else { this.setState({ - score: this.state.score - 1, - downvotes: this.state.downvotes + 1, + score: this.state.score - 1n, + downvotes: this.state.downvotes + 1n, }); } @@ -1551,7 +1550,7 @@ export class PostListing extends Component<PostListingProps, PostListingState> { if (auth) { let form: FeaturePost = { post_id: i.props.post_view.post.id, - feature_type: PostFeatureType.Local, + feature_type: "Local", featured: !i.props.post_view.post.featured_local, auth, }; @@ -1564,7 +1563,7 @@ export class PostListing extends Component<PostListingProps, PostListingState> { if (auth) { let form: FeaturePost = { post_id: i.props.post_view.post.id, - feature_type: PostFeatureType.Community, + feature_type: "Community", featured: !i.props.post_view.post.featured_community, auth, }; @@ -1784,18 +1783,18 @@ export class PostListing extends Component<PostListingProps, PostListingState> { get pointsTippy(): string { let points = i18n.t("number_of_points", { - count: this.state.score, - formattedCount: this.state.score, + count: Number(this.state.score), + formattedCount: Number(this.state.score), }); let upvotes = i18n.t("number_of_upvotes", { - count: this.state.upvotes, - formattedCount: this.state.upvotes, + count: Number(this.state.upvotes), + formattedCount: Number(this.state.upvotes), }); let downvotes = i18n.t("number_of_downvotes", { - count: this.state.downvotes, - formattedCount: this.state.downvotes, + count: Number(this.state.downvotes), + formattedCount: Number(this.state.downvotes), }); return `${points} ⢠${upvotes} ⢠${downvotes}`; diff --git a/src/shared/components/post/post-report.tsx b/src/shared/components/post/post-report.tsx index 2b1540e..5ef25b4 100644 --- a/src/shared/components/post/post-report.tsx +++ b/src/shared/components/post/post-report.tsx @@ -1,11 +1,6 @@ import { Component, linkEvent } from "inferno"; import { T } from "inferno-i18next-dess"; -import { - PostReportView, - PostView, - ResolvePostReport, - SubscribedType, -} from "lemmy-js-client"; +import { PostReportView, PostView, ResolvePostReport } from "lemmy-js-client"; import { i18n } from "../../i18next"; import { WebSocketService } from "../../services"; import { myAuth, wsClient } from "../../utils"; @@ -40,12 +35,12 @@ export class PostReport extends Component<PostReportProps, any> { community: r.community, creator_banned_from_community: r.creator_banned_from_community, counts: r.counts, - subscribed: SubscribedType.NotSubscribed, + subscribed: "NotSubscribed", saved: false, read: false, creator_blocked: false, my_vote: r.my_vote, - unread_comments: 0, + unread_comments: 0n, }; return ( diff --git a/src/shared/components/post/post.tsx b/src/shared/components/post/post.tsx index 2f8a208..eed5aad 100644 --- a/src/shared/components/post/post.tsx +++ b/src/shared/components/post/post.tsx @@ -6,7 +6,6 @@ import { BanFromCommunityResponse, BanPersonResponse, BlockPersonResponse, - CommentNode as CommentNodeI, CommentReportResponse, CommentResponse, CommentSortType, @@ -17,22 +16,23 @@ import { GetPost, GetPostResponse, GetSiteResponse, - ListingType, PostReportResponse, PostResponse, PostView, PurgeItemResponse, Search, SearchResponse, - SearchType, - SortType, UserOperation, wsJsonToRes, wsUserOp, } from "lemmy-js-client"; import { Subscription } from "rxjs"; import { i18n } from "../../i18next"; -import { CommentViewType, InitialFetchRequest } from "../../interfaces"; +import { + CommentNodeI, + CommentViewType, + InitialFetchRequest, +} from "../../interfaces"; import { UserService, WebSocketService } from "../../services"; import { buildCommentsTree, @@ -97,7 +97,7 @@ export class Post extends Component<any, PostState> { postId: getIdFromProps(this.props), commentId: getCommentIdFromProps(this.props), commentTree: [], - commentSort: CommentSortType[CommentSortType.Hot], + commentSort: "Hot", commentViewType: CommentViewType.Tree, scrolled: false, loading: true, @@ -174,7 +174,7 @@ export class Post extends Component<any, PostState> { parent_id: this.state.commentId, max_depth: commentTreeMaxDepth, sort: this.state.commentSort, - type_: ListingType.All, + type_: "All", saved_only: false, auth, }; @@ -186,10 +186,10 @@ export class Post extends Component<any, PostState> { if (q) { let form: Search = { q, - type_: SearchType.Url, - sort: SortType.TopAll, - listing_type: ListingType.All, - page: 1, + type_: "Url", + sort: "TopAll", + listing_type: "All", + page: 1n, limit: trendingFetchLimit, auth: myAuth(false), }; @@ -211,8 +211,8 @@ export class Post extends Component<any, PostState> { let commentsForm: GetComments = { max_depth: commentTreeMaxDepth, - sort: CommentSortType.Hot, - type_: ListingType.All, + sort: "Hot", + type_: "All", saved_only: false, auth, }; @@ -373,57 +373,53 @@ export class Post extends Component<any, PostState> { <div className="btn-group btn-group-toggle flex-wrap mr-3 mb-2"> <label className={`btn btn-outline-secondary pointer ${ - CommentSortType[this.state.commentSort] === CommentSortType.Hot && - "active" + this.state.commentSort === "Hot" && "active" }`} > {i18n.t("hot")} <input type="radio" - value={CommentSortType.Hot} - checked={this.state.commentSort === CommentSortType.Hot} + value={"Hot"} + checked={this.state.commentSort === "Hot"} onChange={linkEvent(this, this.handleCommentSortChange)} /> </label> <label className={`btn btn-outline-secondary pointer ${ - CommentSortType[this.state.commentSort] === CommentSortType.Top && - "active" + this.state.commentSort === "Top" && "active" }`} > {i18n.t("top")} <input type="radio" - value={CommentSortType.Top} - checked={this.state.commentSort === CommentSortType.Top} + value={"Top"} + checked={this.state.commentSort === "Top"} onChange={linkEvent(this, this.handleCommentSortChange)} /> </label> <label className={`btn btn-outline-secondary pointer ${ - CommentSortType[this.state.commentSort] === CommentSortType.New && - "active" + this.state.commentSort === "New" && "active" }`} > {i18n.t("new")} <input type="radio" - value={CommentSortType.New} - checked={this.state.commentSort === CommentSortType.New} + value={"New"} + checked={this.state.commentSort === "New"} onChange={linkEvent(this, this.handleCommentSortChange)} /> </label> <label className={`btn btn-outline-secondary pointer ${ - CommentSortType[this.state.commentSort] === CommentSortType.Old && - "active" + this.state.commentSort === "Old" && "active" }`} > {i18n.t("old")} <input type="radio" - value={CommentSortType.Old} - checked={this.state.commentSort === CommentSortType.Old} + value={"Old"} + checked={this.state.commentSort === "Old"} onChange={linkEvent(this, this.handleCommentSortChange)} /> </label> @@ -495,7 +491,7 @@ export class Post extends Component<any, PostState> { handleCommentSortChange(i: Post, event: any) { i.setState({ - commentSort: CommentSortType[event.target.value], + commentSort: event.target.value as CommentSortType, commentViewType: CommentViewType.Tree, commentsRes: undefined, postRes: undefined, @@ -508,7 +504,7 @@ export class Post extends Component<any, PostState> { if (comments) { i.setState({ commentViewType: Number(event.target.value), - commentSort: CommentSortType.New, + commentSort: "New", commentTree: buildCommentsTree(comments, !!i.state.commentId), }); } diff --git a/src/shared/components/private_message/create-private-message.tsx b/src/shared/components/private_message/create-private-message.tsx index e3aba7a..33bac43 100644 --- a/src/shared/components/private_message/create-private-message.tsx +++ b/src/shared/components/private_message/create-private-message.tsx @@ -3,7 +3,6 @@ import { GetPersonDetails, GetPersonDetailsResponse, GetSiteResponse, - SortType, UserOperation, wsJsonToRes, wsUserOp, @@ -73,7 +72,7 @@ export class CreatePrivateMessage extends Component< fetchPersonDetails() { let form: GetPersonDetails = { person_id: this.state.recipient_id, - sort: SortType.New, + sort: "New", saved_only: false, auth: myAuth(false), }; @@ -84,7 +83,7 @@ export class CreatePrivateMessage extends Component< let person_id = Number(req.path.split("/").pop()); let form: GetPersonDetails = { person_id, - sort: SortType.New, + sort: "New", saved_only: false, auth: req.auth, }; diff --git a/src/shared/components/private_message/private-message-form.tsx b/src/shared/components/private_message/private-message-form.tsx index 31dc292..ca93721 100644 --- a/src/shared/components/private_message/private-message-form.tsx +++ b/src/shared/components/private_message/private-message-form.tsx @@ -4,7 +4,7 @@ import { Prompt } from "inferno-router"; import { CreatePrivateMessage, EditPrivateMessage, - PersonSafe, + Person, PrivateMessageResponse, PrivateMessageView, UserOperation, @@ -29,7 +29,7 @@ import { MarkdownTextArea } from "../common/markdown-textarea"; import { PersonListing } from "../person/person-listing"; interface PrivateMessageFormProps { - recipient: PersonSafe; + recipient: Person; privateMessageView?: PrivateMessageView; // If a pm is given, that means this is an edit onCancel?(): any; onCreate?(message: PrivateMessageView): any; diff --git a/src/shared/components/private_message/private-message.tsx b/src/shared/components/private_message/private-message.tsx index f9b30a1..c3b94bb 100644 --- a/src/shared/components/private_message/private-message.tsx +++ b/src/shared/components/private_message/private-message.tsx @@ -3,7 +3,7 @@ import { CreatePrivateMessageReport, DeletePrivateMessage, MarkPrivateMessageAsRead, - PersonSafe, + Person, PrivateMessageView, } from "lemmy-js-client"; import { i18n } from "../../i18next"; @@ -57,7 +57,7 @@ export class PrivateMessage extends Component< render() { let message_view = this.props.private_message_view; - let otherPerson: PersonSafe = this.mine + let otherPerson: Person = this.mine ? message_view.recipient : message_view.creator; diff --git a/src/shared/components/search.tsx b/src/shared/components/search.tsx index c1f9ff4..94e9d29 100644 --- a/src/shared/components/search.tsx +++ b/src/shared/components/search.tsx @@ -12,7 +12,7 @@ import { ListCommunities, ListCommunitiesResponse, ListingType, - PersonViewSafe, + PersonView, PostResponse, PostView, ResolveObject, @@ -52,9 +52,6 @@ import { numToSI, personToChoice, restoreScrollPosition, - routeListingTypeToEnum, - routeSearchTypeToEnum, - routeSortTypeToEnum, saveScrollPosition, setIsoData, showLocal, @@ -80,7 +77,7 @@ interface SearchProps { listingType: ListingType; communityId?: number | null; creatorId?: number | null; - page: number; + page: bigint; } type FilterType = "creator" | "community"; @@ -101,22 +98,15 @@ interface SearchState { interface Combined { type_: string; - data: CommentView | PostView | CommunityView | PersonViewSafe; + data: CommentView | PostView | CommunityView | PersonView; published: string; } -const defaultSearchType = SearchType.All; -const defaultSortType = SortType.TopAll; -const defaultListingType = ListingType.All; +const defaultSearchType = "All"; +const defaultSortType = "TopAll"; +const defaultListingType = "All"; -const searchTypes = [ - SearchType.All, - SearchType.Comments, - SearchType.Posts, - SearchType.Communities, - SearchType.Users, - SearchType.Url, -]; +const searchTypes = ["All", "Comments", "Posts", "Communities", "Users", "Url"]; const getSearchQueryParams = () => getQueryParams<SearchProps>({ @@ -132,38 +122,49 @@ const getSearchQueryParams = () => const getSearchQueryFromQuery = (q?: string): string | undefined => q ? decodeURIComponent(q) : undefined; -const getSearchTypeFromQuery = (type_?: string): SearchType => - routeSearchTypeToEnum(type_ ?? "", defaultSearchType); +function getSearchTypeFromQuery(type_?: string): SearchType { + return type_ ? (type_ as SearchType) : defaultSearchType; +} -const getSortTypeFromQuery = (sort?: string): SortType => - routeSortTypeToEnum(sort ?? "", defaultSortType); +function getSortTypeFromQuery(sort?: string): SortType { + return sort ? (sort as SortType) : defaultSortType; +} -const getListingTypeFromQuery = (listingType?: string): ListingType => - routeListingTypeToEnum(listingType ?? "", defaultListingType); +function getListingTypeFromQuery(listingType?: string): ListingType { + return listingType ? (listingType as ListingType) : defaultListingType; +} -const postViewToCombined = (data: PostView): Combined => ({ - type_: "posts", - data, - published: data.post.published, -}); +function postViewToCombined(data: PostView): Combined { + return { + type_: "posts", + data, + published: data.post.published, + }; +} -const commentViewToCombined = (data: CommentView): Combined => ({ - type_: "comments", - data, - published: data.comment.published, -}); +function commentViewToCombined(data: CommentView): Combined { + return { + type_: "comments", + data, + published: data.comment.published, + }; +} -const communityViewToCombined = (data: CommunityView): Combined => ({ - type_: "communities", - data, - published: data.community.published, -}); +function communityViewToCombined(data: CommunityView): Combined { + return { + type_: "communities", + data, + published: data.community.published, + }; +} -const personViewSafeToCombined = (data: PersonViewSafe): Combined => ({ - type_: "users", - data, - published: data.person.published, -}); +function personViewSafeToCombined(data: PersonView): Combined { + return { + type_: "users", + data, + published: data.person.published, + }; +} const Filter = ({ filterType, @@ -212,26 +213,28 @@ const communityListing = ({ "number_of_subscribers" ); -const personListing = ({ person, counts: { comment_count } }: PersonViewSafe) => +const personListing = ({ person, counts: { comment_count } }: PersonView) => getListing( <PersonListing person={person} showApubName />, comment_count, "number_of_comments" ); -const getListing = ( +function getListing( listing: JSX.ElementClass, - count: number, + count: bigint, translationKey: "number_of_comments" | "number_of_subscribers" -) => ( - <> - <span>{listing}</span> - <span>{` - ${i18n.t(translationKey, { - count, - formattedCount: numToSI(count), - })}`}</span> - </> -); +) { + return ( + <> + <span>{listing}</span> + <span>{` - ${i18n.t(translationKey, { + count: Number(count), + formattedCount: numToSI(count), + })}`}</span> + </> + ); +} export class Search extends Component<any, SearchState> { private isoData = setIsoData(this.context); @@ -382,19 +385,20 @@ export class Search extends Component<any, SearchState> { type_: getSearchTypeFromQuery(type), sort: getSortTypeFromQuery(sort), listing_type: getListingTypeFromQuery(listingType), - page: getIdFromString(page), + page: getPageFromString(page), limit: fetchLimit, auth, }; - const resolveObjectForm: ResolveObject = { - q: query, - auth, - }; - if (query !== "") { promises.push(client.search(form)); - promises.push(client.resolveObject(resolveObjectForm)); + if (auth) { + const resolveObjectForm: ResolveObject = { + q: query, + auth, + }; + promises.push(client.resolveObject(resolveObjectForm)); + } } else { promises.push(Promise.resolve()); promises.push(Promise.resolve()); @@ -433,16 +437,16 @@ export class Search extends Component<any, SearchState> { displayResults(type: SearchType) { switch (type) { - case SearchType.All: + case "All": return this.all; - case SearchType.Comments: + case "Comments": return this.comments; - case SearchType.Posts: - case SearchType.Url: + case "Posts": + case "Url": return this.posts; - case SearchType.Communities: + case "Communities": return this.communities; - case SearchType.Users: + case "Users": return this.users; default: return <></>; @@ -582,17 +586,18 @@ export class Search extends Component<any, SearchState> { const { sort } = getSearchQueryParams(); // Sort it - if (sort === SortType.New) { + if (sort === "New") { combined.sort((a, b) => b.published.localeCompare(a.published)); } else { - combined.sort( - (a, b) => + combined.sort((a, b) => + Number( ((b.data as CommentView | PostView).counts.score | (b.data as CommunityView).counts.subscribers | - (b.data as PersonViewSafe).counts.comment_score) - - ((a.data as CommentView | PostView).counts.score | - (a.data as CommunityView).counts.subscribers | - (a.data as PersonViewSafe).counts.comment_score) + (b.data as PersonView).counts.comment_score) - + ((a.data as CommentView | PostView).counts.score | + (a.data as CommunityView).counts.subscribers | + (a.data as PersonView).counts.comment_score) + ) ); } @@ -642,7 +647,7 @@ export class Search extends Component<any, SearchState> { <div>{communityListing(i.data as CommunityView)}</div> )} {i.type_ === "users" && ( - <div>{personListing(i.data as PersonViewSafe)}</div> + <div>{personListing(i.data as PersonView)}</div> )} </div> </div> @@ -781,10 +786,15 @@ export class Search extends Component<any, SearchState> { auth, }; - const resolveObjectForm: ResolveObject = { - q, - auth, - }; + if (auth) { + const resolveObjectForm: ResolveObject = { + q, + auth, + }; + WebSocketService.Instance.send( + wsClient.resolveObject(resolveObjectForm) + ); + } this.setState({ searchResponse: undefined, @@ -793,7 +803,6 @@ export class Search extends Component<any, SearchState> { }); WebSocketService.Instance.send(wsClient.search(form)); - WebSocketService.Instance.send(wsClient.resolveObject(resolveObjectForm)); } } @@ -854,40 +863,40 @@ export class Search extends Component<any, SearchState> { }); handleSortChange(sort: SortType) { - this.updateUrl({ sort, page: 1 }); + this.updateUrl({ sort, page: 1n }); } handleTypeChange(i: Search, event: any) { - const type = SearchType[event.target.value]; + const type = event.target.value as SearchType; i.updateUrl({ type, - page: 1, + page: 1n, }); } - handlePageChange(page: number) { + handlePageChange(page: bigint) { this.updateUrl({ page }); } handleListingTypeChange(listingType: ListingType) { this.updateUrl({ listingType, - page: 1, + page: 1n, }); } handleCommunityFilterChange({ value }: Choice) { this.updateUrl({ communityId: getIdFromString(value) ?? null, - page: 1, + page: 1n, }); } handleCreatorFilterChange({ value }: Choice) { this.updateUrl({ creatorId: getIdFromString(value) ?? null, - page: 1, + page: 1n, }); } @@ -896,7 +905,7 @@ export class Search extends Component<any, SearchState> { i.updateUrl({ q: i.state.searchText, - page: 1, + page: 1n, }); } diff --git a/src/shared/interfaces.ts b/src/shared/interfaces.ts index aeb4678..30422af 100644 --- a/src/shared/interfaces.ts +++ b/src/shared/interfaces.ts @@ -1,4 +1,4 @@ -import { GetSiteResponse, LemmyHttp } from "lemmy-js-client"; +import { CommentView, GetSiteResponse, LemmyHttp } from "lemmy-js-client"; import type { ParsedQs } from "qs"; /** @@ -63,3 +63,9 @@ export enum PurgeType { Post, Comment, } + +export interface CommentNodeI { + comment_view: CommentView; + children: Array<CommentNodeI>; + depth: number; +} diff --git a/src/shared/routes.ts b/src/shared/routes.ts index ddaa874..b5c2818 100644 --- a/src/shared/routes.ts +++ b/src/shared/routes.ts @@ -130,6 +130,10 @@ export const routes: IRoutePropsWithFetch[] = [ path: `/verify_email/:token`, component: VerifyEmail, }, - { path: `/instances`, component: Instances }, + { + path: `/instances`, + component: Instances, + fetchInitialData: Instances.fetchInitialData, + }, { path: `/legal`, component: Legal }, ]; diff --git a/src/shared/services/UserService.ts b/src/shared/services/UserService.ts index 34a08b3..9928da5 100644 --- a/src/shared/services/UserService.ts +++ b/src/shared/services/UserService.ts @@ -22,12 +22,12 @@ export class UserService { private static _instance: UserService; public myUserInfo?: MyUserInfo; public jwtInfo?: JwtInfo; - public unreadInboxCountSub: BehaviorSubject<number> = - new BehaviorSubject<number>(0); - public unreadReportCountSub: BehaviorSubject<number> = - new BehaviorSubject<number>(0); - public unreadApplicationCountSub: BehaviorSubject<number> = - new BehaviorSubject<number>(0); + public unreadInboxCountSub: BehaviorSubject<bigint> = + new BehaviorSubject<bigint>(0n); + public unreadReportCountSub: BehaviorSubject<bigint> = + new BehaviorSubject<bigint>(0n); + public unreadApplicationCountSub: BehaviorSubject<bigint> = + new BehaviorSubject<bigint>(0n); private constructor() { this.setJwtInfo(); diff --git a/src/shared/utils.ts b/src/shared/utils.ts index 0a62292..da67b62 100644 --- a/src/shared/utils.ts +++ b/src/shared/utils.ts @@ -4,7 +4,6 @@ import { BlockCommunityResponse, BlockPersonResponse, Comment as CommentI, - CommentNode as CommentNodeI, CommentReportView, CommentSortType, CommentView, @@ -16,16 +15,15 @@ import { Language, LemmyHttp, LemmyWebsocket, - ListingType, - PersonSafe, - PersonViewSafe, + MyUserInfo, + Person, + PersonView, PostReportView, PostView, PrivateMessageReportView, PrivateMessageView, RegistrationApplicationView, Search, - SearchType, SortType, UploadImageResponse, } from "lemmy-js-client"; @@ -45,7 +43,7 @@ import tippy from "tippy.js"; import Toastify from "toastify-js"; import { httpBase } from "./env"; import { i18n, languages } from "./i18next"; -import { DataType, IsoData } from "./interfaces"; +import { CommentNodeI, DataType, IsoData } from "./interfaces"; import { UserService, WebSocketService } from "./services"; var Tribute: any; @@ -72,12 +70,12 @@ export const webArchiveUrl = "https://web.archive.org"; export const elementUrl = "https://element.io"; export const postRefetchSeconds: number = 60 * 1000; -export const fetchLimit = 40; -export const trendingFetchLimit = 6; +export const fetchLimit = 40n; +export const trendingFetchLimit = 6n; export const mentionDropdownFetchLimit = 10; export const commentTreeMaxDepth = 8; export const markdownFieldCharacterLimit = 50000; -export const maxUploadImages = 20; +export const maxUploadImages = 20n; export const concurrentImageUpload = 4; export const relTags = "noopener nofollow"; @@ -124,8 +122,8 @@ export function getIdFromString(id?: string): number | undefined { return id && id !== "0" && !Number.isNaN(Number(id)) ? Number(id) : undefined; } -export function getPageFromString(page?: string): number { - return page && !Number.isNaN(Number(page)) ? Number(page) : 1; +export function getPageFromString(page?: string): bigint { + return page && !Number.isNaN(Number(page)) ? BigInt(page) : BigInt(1); } export function randomStr( @@ -187,14 +185,14 @@ export function hotRankPost(post_view: PostView): number { return hotRank(post_view.counts.score, post_view.post.published); } -export function hotRank(score: number, timeStr: string): number { +export function hotRank(score: bigint, timeStr: string): number { // Rank = ScaleFactor * sign(Score) * log(1 + abs(Score)) / (Time + 2)^Gravity let date: Date = new Date(timeStr + "Z"); // Add Z to convert from UTC date let now: Date = new Date(); let hoursElapsed: number = (now.getTime() - date.getTime()) / 36e5; let rank = - (10000 * Math.log10(Math.max(1, 3 + score))) / + (10000 * Math.log10(Math.max(1, Number(3n + score)))) / Math.pow(hoursElapsed + 2, 1.8); // console.log(`Comment: ${comment.content}\nRank: ${rank}\nScore: ${comment.score}\nHours: ${hoursElapsed}`); @@ -214,14 +212,16 @@ export function mdToHtmlInline(text: string) { return { __html: md.renderInline(text) }; } -export function getUnixTime(text?: string): number | undefined { - return text ? new Date(text).getTime() / 1000 : undefined; +export function getUnixTime(text?: string): bigint | undefined { + return text ? BigInt(new Date(text).getTime() / 1000) : undefined; } -export function futureDaysToUnixTime(days?: number): number | undefined { +export function futureDaysToUnixTime(days?: number): bigint | undefined { return days - ? Math.trunc( - new Date(Date.now() + 1000 * 60 * 60 * 24 * days).getTime() / 1000 + ? BigInt( + Math.trunc( + new Date(Date.now() + 1000 * 60 * 60 * 24 * days).getTime() / 1000 + ) ) : undefined; } @@ -229,7 +229,7 @@ export function futureDaysToUnixTime(days?: number): number | undefined { export function canMod( creator_id: number, mods?: CommunityModeratorView[], - admins?: PersonViewSafe[], + admins?: PersonView[], myUserInfo = UserService.Instance.myUserInfo, onSelf = false ): boolean { @@ -257,7 +257,7 @@ export function canMod( export function canAdmin( creatorId: number, - admins?: PersonViewSafe[], + admins?: PersonView[], myUserInfo = UserService.Instance.myUserInfo, onSelf = false ): boolean { @@ -278,7 +278,7 @@ export function amMod( return myUserInfo ? isMod(myUserInfo.local_user_view.person.id, mods) : false; } -export function isAdmin(creatorId: number, admins?: PersonViewSafe[]): boolean { +export function isAdmin(creatorId: number, admins?: PersonView[]): boolean { return admins?.map(a => a.person.id).includes(creatorId) ?? false; } @@ -298,7 +298,7 @@ export function amCommunityCreator( export function amSiteCreator( creator_id: number, - admins?: PersonViewSafe[], + admins?: PersonView[], myUserInfo = UserService.Instance.myUserInfo ): boolean { let myId = myUserInfo?.local_user_view.person.id; @@ -342,42 +342,6 @@ export function capitalizeFirstLetter(str: string): string { return str.charAt(0).toUpperCase() + str.slice(1); } -export function routeSortTypeToEnum( - sort: string, - defaultValue: SortType -): SortType { - return SortType[sort] ?? defaultValue; -} - -export function listingTypeFromNum(type_: number): ListingType { - return Object.values(ListingType)[type_]; -} - -export function sortTypeFromNum(type_: number): SortType { - return Object.values(SortType)[type_]; -} - -export function routeListingTypeToEnum( - type: string, - defaultValue: ListingType -): ListingType { - return ListingType[type] ?? defaultValue; -} - -export function routeDataTypeToEnum( - type: string, - defaultValue: DataType -): DataType { - return DataType[type] ?? defaultValue; -} - -export function routeSearchTypeToEnum( - type: string, - defaultValue: SearchType -): SearchType { - return SearchType[type] ?? defaultValue; -} - export async function getSiteMetadata(url: string) { let form: GetSiteMetadata = { url }; let client = new LemmyHttp(httpBase); @@ -901,7 +865,7 @@ export function setupTippy() { interface PersonTribute { key: string; - view: PersonViewSafe; + view: PersonView; } async function personSearch(text: string): Promise<PersonTribute[]> { @@ -972,7 +936,7 @@ export function saveCommentRes(data: CommentView, comments?: CommentView[]) { export function updatePersonBlock( data: BlockPersonResponse, - myUserInfo = UserService.Instance.myUserInfo + myUserInfo: MyUserInfo | undefined = UserService.Instance.myUserInfo ) { let mui = myUserInfo; if (mui) { @@ -993,7 +957,7 @@ export function updatePersonBlock( export function updateCommunityBlock( data: BlockCommunityResponse, - myUserInfo = UserService.Instance.myUserInfo + myUserInfo: MyUserInfo | undefined = UserService.Instance.myUserInfo ) { let mui = myUserInfo; if (mui) { @@ -1124,19 +1088,19 @@ export function commentsToFlatNodes(comments: CommentView[]): CommentNodeI[] { export function convertCommentSortType(sort: SortType): CommentSortType { if ( - sort == SortType.TopAll || - sort == SortType.TopDay || - sort == SortType.TopWeek || - sort == SortType.TopMonth || - sort == SortType.TopYear + sort == "TopAll" || + sort == "TopDay" || + sort == "TopWeek" || + sort == "TopMonth" || + sort == "TopYear" ) { - return CommentSortType.Top; - } else if (sort == SortType.New) { - return CommentSortType.New; - } else if (sort == SortType.Hot || sort == SortType.Active) { - return CommentSortType.Hot; + return "Top"; + } else if (sort == "New") { + return "New"; + } else if (sort == "Hot" || sort == "Active") { + return "Hot"; } else { - return CommentSortType.Hot; + return "Hot"; } } @@ -1359,8 +1323,7 @@ export function restoreScrollPosition(context: any) { } export function showLocal(isoData: IsoData): boolean { - let linked = isoData.site_res.federated_instances?.linked; - return linked ? linked.length > 0 : false; + return isoData.site_res.site_view.local_site.federation_enabled; } export interface Choice { @@ -1382,7 +1345,7 @@ export function communityToChoice(cv: CommunityView): Choice { }; } -export function personToChoice(pvs: PersonViewSafe): Choice { +export function personToChoice(pvs: PersonView): Choice { return { value: pvs.person.id.toString(), label: personSelectName(pvs), @@ -1392,10 +1355,10 @@ export function personToChoice(pvs: PersonViewSafe): Choice { export async function fetchCommunities(q: string) { let form: Search = { q, - type_: SearchType.Communities, - sort: SortType.TopAll, - listing_type: ListingType.All, - page: 1, + type_: "Communities", + sort: "TopAll", + listing_type: "All", + page: 1n, limit: fetchLimit, auth: myAuth(false), }; @@ -1406,10 +1369,10 @@ export async function fetchCommunities(q: string) { export async function fetchUsers(q: string) { let form: Search = { q, - type_: SearchType.Users, - sort: SortType.TopAll, - listing_type: ListingType.All, - page: 1, + type_: "Users", + sort: "TopAll", + listing_type: "All", + page: 1n, limit: fetchLimit, auth: myAuth(false), }; @@ -1425,7 +1388,7 @@ export function communitySelectName(cv: CommunityView): string { export function personSelectName({ person: { display_name, name, local, actor_id }, -}: PersonViewSafe): string { +}: PersonView): string { const pName = display_name ?? name; return local ? pName : `${hostname(actor_id)}/${pName}`; } @@ -1444,11 +1407,11 @@ const SHORTNUM_SI_FORMAT = new Intl.NumberFormat("en-US", { compactDisplay: "short", }); -export function numToSI(value: number): string { +export function numToSI(value: bigint): string { return SHORTNUM_SI_FORMAT.format(value); } -export function isBanned(ps: PersonSafe): boolean { +export function isBanned(ps: Person): boolean { let expires = ps.ban_expires; // Add Z to convert from UTC date // TODO this check probably isn't necessary anymore @@ -1477,16 +1440,16 @@ export function enableNsfw(siteRes: GetSiteResponse): boolean { export function postToCommentSortType(sort: SortType): CommentSortType { switch (sort) { - case SortType.Active: - case SortType.Hot: - return CommentSortType.Hot; - case SortType.New: - case SortType.NewComments: - return CommentSortType.New; - case SortType.Old: - return CommentSortType.Old; + case "Active": + case "Hot": + return "Hot"; + case "New": + case "NewComments": + return "New"; + case "Old": + return "Old"; default: - return CommentSortType.Top; + return "Top"; } } @@ -1515,7 +1478,7 @@ export function canCreateCommunity( export function isPostBlocked( pv: PostView, - myUserInfo = UserService.Instance.myUserInfo + myUserInfo: MyUserInfo | undefined = UserService.Instance.myUserInfo ): boolean { return ( (myUserInfo?.community_blocks diff --git a/yarn.lock b/yarn.lock index 7e348f8..9fe3419 100644 --- a/yarn.lock +++ b/yarn.lock @@ -5581,10 +5581,10 @@ leac@^0.6.0: resolved "https://registry.yarnpkg.com/leac/-/leac-0.6.0.tgz#dcf136e382e666bd2475f44a1096061b70dc0912" integrity sha512-y+SqErxb8h7nE/fiEX07jsbuhrpO9lL8eca7/Y1nuWV2moNlXhyd59iDGcRf6moVyDMbmTNzL40SUyrFU/yDpg== -lemmy-js-client@0.17.2-rc.5: - version "0.17.2-rc.5" - resolved "https://registry.yarnpkg.com/lemmy-js-client/-/lemmy-js-client-0.17.2-rc.5.tgz#8dbfa01fc293d63d72d8294d5584d4e71c9c08be" - integrity sha512-B2VibqJvevVDiYK7yfMPZrx0GdC4XgpN2bgouzMgXZsn+HENALIAm5K+sZhD40/NCd69MglWTlYtFYg9d4YxOA== +lemmy-js-client@0.17.2-rc.14: + version "0.17.2-rc.14" + resolved "https://registry.yarnpkg.com/lemmy-js-client/-/lemmy-js-client-0.17.2-rc.14.tgz#2734c52a4216e4045c1b63ad0e4e302e72463d12" + integrity sha512-HERUQL3UChSjY1pLeyAJ/4dBS+YMEoq0MBUW3Q45s6GjcjSJyE3l5JKC6qlozyDX3oc462NNel/rP1/qNQRvZQ== dependencies: cross-fetch "^3.1.5" form-data "^4.0.0"