* 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.
-Subproject commit 007e53683768aeba63e9e4c179c1d240217bcee2
+Subproject commit 3bb45c26cb54325c3d8d605f4334447b9b78293a
"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",
</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")}
interface NavbarState {
expanded: boolean;
- unreadInboxCount: number;
- unreadReportCount: number;
- unreadApplicationCount: number;
+ unreadInboxCount: bigint;
+ unreadReportCount: bigint;
+ unreadApplicationCount: bigint;
showDropdown: boolean;
onSiteBanner?(url: string): any;
}
private unreadReportCountSub: Subscription;
private unreadApplicationCountSub: Subscription;
state: NavbarState = {
- unreadInboxCount: 0,
- unreadReportCount: 0,
- unreadApplicationCount: 0,
+ unreadInboxCount: 0n,
+ unreadReportCount: 0n,
+ unreadApplicationCount: 0n,
expanded: false,
showDropdown: false,
};
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),
})}
>
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),
})}
>
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
),
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),
})}
>
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),
})}
>
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
),
unreadReportCount:
data.post_reports +
data.comment_reports +
- (data.private_message_reports ?? 0),
+ (data.private_message_reports ?? 0n),
});
this.sendReportUnread();
} else if (op == UserOperation.GetUnreadRegistrationApplicationCount) {
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);
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);
import { T } from "inferno-i18next-dess";
import { Link } from "inferno-router";
import {
- CommentNode as CommentNodeI,
CommentResponse,
CreateComment,
EditComment,
wsUserOp,
} from "lemmy-js-client";
import { Subscription } from "rxjs";
+import { CommentNodeI } from "shared/interfaces";
import { i18n } from "../../i18next";
import { UserService, WebSocketService } from "../../services";
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,
} 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,
showReportDialog: boolean;
reportReason?: string;
my_vote?: number;
- score: number;
- upvotes: number;
- downvotes: number;
+ score: bigint;
+ upvotes: bigint;
+ downvotes: bigint;
readLoading: boolean;
saveLoading: boolean;
}
interface CommentNodeProps {
node: CommentNodeI;
moderators?: CommunityModeratorView[];
- admins?: PersonViewSafe[];
+ admins?: PersonView[];
noBorder?: boolean;
noIndent?: boolean;
viewOnly?: boolean;
<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)}
>
{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>
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,
});
}
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,
});
}
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,
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),
};
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}`;
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;
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";
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,
<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"
<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}
/>
<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")}
<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")}
if (files.length > maxUploadImages) {
toast(
i18n.t("too_many_images_upload", {
- count: maxUploadImages,
+ count: Number(maxUploadImages),
formattedCount: numToSI(maxUploadImages),
}),
"danger"
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> {
<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")}
}
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);
}
}
{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"
ListCommunities,
ListCommunitiesResponse,
ListingType,
- SortType,
- SubscribedType,
UserOperation,
wsJsonToRes,
wsUserOp,
isBrowser,
myAuth,
numToSI,
- routeListingTypeToEnum,
setIsoData,
showLocal,
toast,
import { Paginator } from "../common/paginator";
import { CommunityLink } from "./community-link";
-const communityLimit = 50;
+const communityLimit = 50n;
interface CommunitiesState {
listCommunitiesResponse?: ListCommunitiesResponse;
interface CommunitiesProps {
listingType: ListingType;
- page: number;
+ page: bigint;
}
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) {
const listCommunitiesForm: ListCommunities = {
type_: listingType,
- sort: SortType.TopMonth,
+ sort: "TopMonth",
limit: communityLimit,
page,
auth: myAuth(false),
{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(
{i18n.t("unsubscribe")}
</button>
)}
- {cv.subscribed === SubscribedType.NotSubscribed && (
+ {cv.subscribed === "NotSubscribed" && (
<button
className="btn btn-link d-inline-block"
onClick={linkEvent(
{i18n.t("subscribe")}
</button>
)}
- {cv.subscribed === SubscribedType.Pending && (
+ {cv.subscribed === "Pending" && (
<div className="text-warning d-inline-block">
{i18n.t("subscribe_pending")}
</div>
refetch();
}
- handlePageChange(page: number) {
+ handlePageChange(page: bigint) {
this.updateUrl({ page });
}
handleListingTypeChange(val: ListingType) {
this.updateUrl({
listingType: val,
- page: 1,
+ page: 1n,
});
}
}: InitialFetchRequest<QueryParams<CommunitiesProps>>): Promise<any>[] {
const listCommunitiesForm: ListCommunities = {
type_: getListingTypeFromQuery(listingType),
- sort: SortType.TopMonth,
+ sort: "TopMonth",
limit: communityLimit,
page: getPageFromString(page),
auth: auth,
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;
GetCommunityResponse,
GetPosts,
GetPostsResponse,
- ListingType,
PostReportResponse,
PostResponse,
PostView,
postToCommentSortType,
relTags,
restoreScrollPosition,
- routeDataTypeToEnum,
- routeSortTypeToEnum,
saveCommentRes,
saveScrollPosition,
setIsoData,
interface CommunityProps {
dataType: DataType;
sort: SortType;
- page: number;
+ page: bigint;
}
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<
page,
limit: fetchLimit,
sort,
- type_: ListingType.All,
+ type_: "All",
saved_only: false,
auth,
};
page,
limit: fetchLimit,
sort: postToCommentSortType(sort),
- type_: ListingType.All,
+ type_: "All",
saved_only: false,
auth,
};
);
}
- 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);
}
page,
limit: fetchLimit,
sort,
- type_: ListingType.All,
+ type_: "All",
community_name: name,
saved_only: false,
auth: myAuth(false),
page,
limit: fetchLimit,
sort: postToCommentSortType(sort),
- type_: ListingType.All,
+ type_: "All",
community_name: name,
saved_only: false,
auth: myAuth(false),
.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);
DeleteCommunity,
FollowCommunity,
Language,
- PersonViewSafe,
+ PersonView,
PurgeCommunity,
RemoveCommunity,
- SubscribedType,
} from "lemmy-js-client";
import { i18n } from "../../i18next";
import { UserService, WebSocketService } from "../../services";
interface SidebarProps {
community_view: CommunityView;
moderators: CommunityModeratorView[];
- admins: PersonViewSafe[];
+ admins: PersonView[];
allLanguages: Language[];
siteLanguages: number[];
communityLanguages?: number[];
<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)}
{i18n.t("joined")}
</button>
)}
- {subscribed === SubscribedType.Pending && (
+ {subscribed === "Pending" && (
<button
className="btn btn-warning mr-2"
onClick={linkEvent(this, this.handleUnsubscribe)}
<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")}
<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")}
<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")}
<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>
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)}
return (
<div className="mb-2">
- {community_view.subscribed == SubscribedType.NotSubscribed &&
+ {community_view.subscribed == "NotSubscribed" &&
(blocked ? (
<button
className="btn btn-danger btn-block"
import {
BannedPersonsResponse,
GetBannedPersons,
+ GetFederatedInstancesResponse,
GetSiteResponse,
- PersonViewSafe,
+ PersonView,
SiteResponse,
UserOperation,
wsJsonToRes,
interface AdminSettingsState {
siteRes: GetSiteResponse;
- banned: PersonViewSafe[];
+ instancesRes?: GetFederatedInstancesResponse;
+ banned: PersonView[];
loading: boolean;
leaveAdminTeamLoading: boolean;
currentTab: string;
this.state = {
...this.state,
banned: (this.isoData.routeData[0] as BannedPersonsResponse).banned,
+ instancesRes: this.isoData
+ .routeData[1] as GetFederatedInstancesResponse,
loading: false,
};
} else {
auth: cAuth,
})
);
+ WebSocketService.Instance.send(
+ wsClient.getFederatedInstances({ auth: cAuth })
+ );
}
}
}
if (auth) {
let bannedPersonsForm: GetBannedPersons = { auth };
promises.push(req.client.getBannedPersons(bannedPersonsForm));
+ promises.push(req.client.getFederatedInstances({ auth }));
}
return promises;
<div className="col-12 col-md-6">
<SiteForm
siteRes={this.state.siteRes}
+ instancesRes={this.state.instancesRes}
showLocal={showLocal(this.isoData)}
/>
</div>
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 });
}
}
}
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";
siteRes: GetSiteResponse;
customEmojis: CustomEmojiViewForm[];
loading: boolean;
- page: number;
+ page: bigint;
}
interface CustomEmojiViewForm {
alt_text: string;
keywords: string;
changed: boolean;
- page: number;
+ page: bigint;
}
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 = {};
<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)}>
else return i18n.t("custom_emoji_save_validation");
}
- handlePageChange(page: number) {
+ handlePageChange(page: bigint) {
this.setState({ page: page });
}
) {
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 });
}
) {
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 });
}
) {
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 });
}
) {
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 });
}
) {
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 });
}
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,
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 });
}
}
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: "",
QueryParams,
relTags,
restoreScrollPosition,
- routeDataTypeToEnum,
- routeListingTypeToEnum,
- routeSortTypeToEnum,
saveCommentRes,
saveScrollPosition,
setIsoData,
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 = () =>
function fetchTrendingCommunities() {
const listCommunitiesForm: ListCommunities = {
- type_: ListingType.Local,
- sort: SortType.Hot,
+ type_: "Local",
+ sort: "Hot",
limit: trendingFetchLimit,
auth: myAuth(false),
};
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;
}
const type_ = getListingTypeFromQuery(listingType);
const sort = getSortTypeFromQuery(urlSort);
- const page = urlPage ? Number(urlPage) : 1;
+ const page = urlPage ? BigInt(urlPage) : 1n;
const promises: Promise<any>[] = [];
}
const trendingCommunitiesForm: ListCommunities = {
- type_: ListingType.Local,
- sort: SortType.Hot,
+ type_: "Local",
+ sort: "Hot",
limit: trendingFetchLimit,
auth,
};
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);
}
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;
// 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
)
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
);
}
- 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 });
+ }
+ }
}
this.subscription = wsSubscribe(this.parseMessage);
if (isBrowser()) {
- WebSocketService.Instance.send(wsClient.getCaptcha());
+ WebSocketService.Instance.send(wsClient.getCaptcha({}));
}
}
GetSiteResponse,
LoginResponse,
Register,
- RegistrationMode,
SiteView,
UserOperation,
wsJsonToRes,
this.subscription = wsSubscribe(this.parseMessage);
if (isBrowser()) {
- WebSocketService.Instance.send(wsClient.getCaptcha());
+ WebSocketService.Instance.send(wsClient.getCaptcha({}));
}
}
</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">
handleRegenCaptcha(i: Signup) {
i.audio = undefined;
i.setState({ captchaPlaying: false });
- WebSocketService.Instance.send(wsClient.getCaptcha());
+ WebSocketService.Instance.send(wsClient.getCaptcha({}));
}
handleCaptchaPlay(i: Signup) {
import {
CreateSite,
EditSite,
+ GetFederatedInstancesResponse,
GetSiteResponse,
ListingType,
- RegistrationMode,
} from "lemmy-js-client";
import { i18n } from "../../i18next";
import { WebSocketService } from "../../services";
interface SiteFormProps {
siteRes: GetSiteResponse;
+ instancesRes?: GetFederatedInstancesResponse;
showLocal?: boolean;
}
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",
},
};
)}
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")}
<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}
}
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));
}
}
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";
site: Site;
showLocal: boolean;
counts?: SiteAggregates;
- admins?: PersonViewSafe[];
+ admins?: PersonView[];
online?: number;
}
);
}
- 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>
<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")}
<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")}
<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")}
<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>
ModRemovePostView,
ModTransferCommunityView,
ModlogActionType,
- PersonSafe,
+ Person,
UserOperation,
wsJsonToRes,
wsUserOp,
interface ModlogType {
id: number;
type_: ModlogActionType;
- moderator?: PersonSafe;
+ moderator?: Person;
view: View;
when_: string;
}
}
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 {
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
)
)
.concat(
featured_posts.map(
getModlogActionMapper(
- ModlogActionType.ModFeaturePost,
+ "ModFeaturePost",
({ mod_feature_post }: ModFeaturePostView) => mod_feature_post
)
)
.concat(
removed_comments.map(
getModlogActionMapper(
- ModlogActionType.ModRemoveComment,
+ "ModRemoveComment",
({ mod_remove_comment }: ModRemoveCommentView) => mod_remove_comment
)
)
.concat(
removed_communities.map(
getModlogActionMapper(
- ModlogActionType.ModRemoveCommunity,
+ "ModRemoveCommunity",
({ mod_remove_community }: ModRemoveCommunityView) =>
mod_remove_community
)
.concat(
banned_from_community.map(
getModlogActionMapper(
- ModlogActionType.ModBanFromCommunity,
+ "ModBanFromCommunity",
({ mod_ban_from_community }: ModBanFromCommunityView) =>
mod_ban_from_community
)
.concat(
added_to_community.map(
getModlogActionMapper(
- ModlogActionType.ModAddCommunity,
+ "ModAddCommunity",
({ mod_add_community }: ModAddCommunityView) => mod_add_community
)
)
.concat(
transferred_to_community.map(
getModlogActionMapper(
- ModlogActionType.ModTransferCommunity,
+ "ModTransferCommunity",
({ mod_transfer_community }: ModTransferCommunityView) =>
mod_transfer_community
)
)
.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
)
)
.concat(
admin_purged_communities.map(
getModlogActionMapper(
- ModlogActionType.AdminPurgeCommunity,
+ "AdminPurgeCommunity",
({ admin_purge_community }: AdminPurgeCommunityView) =>
admin_purge_community
)
.concat(
admin_purged_posts.map(
getModlogActionMapper(
- ModlogActionType.AdminPurgePost,
+ "AdminPurgePost",
({ admin_purge_post }: AdminPurgePostView) => admin_purge_post
)
)
.concat(
admin_purged_comments.map(
getModlogActionMapper(
- ModlogActionType.AdminPurgeComment,
+ "AdminPurgeComment",
({ admin_purge_comment }: AdminPurgeCommentView) =>
admin_purge_comment
)
function renderModlogType({ type_, view }: ModlogType) {
switch (type_) {
- case ModlogActionType.ModRemovePost: {
+ case "ModRemovePost": {
const mrpv = view as ModRemovePostView;
const {
mod_remove_post: { reason, removed },
);
}
- case ModlogActionType.ModLockPost: {
+ case "ModLockPost": {
const {
mod_lock_post: { locked },
post: { id, name },
);
}
- case ModlogActionType.ModFeaturePost: {
+ case "ModFeaturePost": {
const {
mod_feature_post: { featured, is_featured_community },
post: { id, name },
</>
);
}
- case ModlogActionType.ModRemoveComment: {
+ case "ModRemoveComment": {
const mrc = view as ModRemoveCommentView;
const {
mod_remove_comment: { reason, removed },
);
}
- case ModlogActionType.ModRemoveCommunity: {
+ case "ModRemoveCommunity": {
const mrco = view as ModRemoveCommunityView;
const {
mod_remove_community: { reason, expires, removed },
);
}
- case ModlogActionType.ModBanFromCommunity: {
+ case "ModBanFromCommunity": {
const mbfc = view as ModBanFromCommunityView;
const {
mod_ban_from_community: { reason, expires, banned },
);
}
- case ModlogActionType.ModAddCommunity: {
+ case "ModAddCommunity": {
const {
mod_add_community: { removed },
modded_person,
);
}
- 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>
);
}
- case ModlogActionType.ModBan: {
+ case "ModBan": {
const {
mod_ban: { reason, expires, banned },
banned_person,
);
}
- case ModlogActionType.ModAdd: {
+ case "ModAdd": {
const {
mod_add: { removed },
modded_person,
</>
);
}
- case ModlogActionType.AdminPurgePerson: {
+ case "AdminPurgePerson": {
const {
admin_purge_person: { reason },
} = view as AdminPurgePersonView;
);
}
- case ModlogActionType.AdminPurgeCommunity: {
+ case "AdminPurgeCommunity": {
const {
admin_purge_community: { reason },
} = view as AdminPurgeCommunityView;
);
}
- case ModlogActionType.AdminPurgePost: {
+ case "AdminPurgePost": {
const {
admin_purge_post: { reason },
community,
);
}
- case ModlogActionType.AdminPurgeComment: {
+ case "AdminPurgeComment": {
const {
admin_purge_comment: { reason },
post: { id, name },
if (text.length > 0) {
newOptions.push(
...(await fetchUsers(text)).users
- .slice(0, fetchLimit)
+ .slice(0, Number(fetchLimit))
.map<Choice>(personToChoice)
);
}
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
<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">
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) => {
messages: PrivateMessageView[];
combined: ReplyType[];
sort: CommentSortType;
- page: number;
+ page: bigint;
siteRes: GetSiteResponse;
loading: boolean;
}
mentions: [],
messages: [],
combined: [],
- sort: CommentSortType.New,
- page: 1,
+ sort: "New",
+ page: 1n,
siteRes: this.isoData.site_res,
loading: true,
};
);
}
- 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,
};
let personMentionsForm: GetPersonMentions = {
sort,
unread_only: true,
- page: 1,
+ page: 1n,
limit: fetchLimit,
auth,
};
let privateMessagesForm: GetPrivateMessages = {
unread_only: true,
- page: 1,
+ page: 1n,
limit: fetchLimit,
auth,
};
}
handleSortChange(val: CommentSortType) {
- this.setState({ sort: val, page: 1 });
+ this.setState({ sort: val, page: 1n });
this.refetch();
}
);
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);
}
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);
}
}
import {
GetSiteResponse,
LoginResponse,
- PasswordChange as PWordChange,
+ PasswordChangeAfterReset,
UserOperation,
wsJsonToRes,
wsUserOp,
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,
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("/");
CommentView,
GetPersonDetailsResponse,
Language,
- PersonViewSafe,
+ PersonView,
PostView,
SortType,
} from "lemmy-js-client";
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 {
type_: ItemEnum;
view: CommentView | PostView;
published: string;
- score: number;
+ score: bigint;
};
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 (
);
}
- handlePageChange(val: number) {
+ handlePageChange(val: bigint) {
this.props.onPageChange(val);
}
}
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;
BlockPerson,
BlockPersonResponse,
CommentResponse,
+ Community,
CommunityModeratorView,
- CommunitySafe,
GetPersonDetails,
GetPersonDetailsResponse,
GetSiteResponse,
numToSI,
relTags,
restoreScrollPosition,
- routeSortTypeToEnum,
saveCommentRes,
saveScrollPosition,
setIsoData,
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();
const getCommunitiesListing = (
translationKey: NoOptionI18nKeys,
- communityViews?: { community: CommunitySafe }[]
+ communityViews?: { community: Community }[]
) =>
communityViews &&
communityViews.length > 0 && (
<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>
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,
});
}
listRegistrationApplicationsResponse?: ListRegistrationApplicationsResponse;
siteRes: GetSiteResponse;
unreadOrAll: UnreadOrAll;
- page: number;
+ page: bigint;
loading: boolean;
}
state: RegistrationApplicationsState = {
siteRes: this.isoData.site_res,
unreadOrAll: UnreadOrAll.Unread,
- page: 1,
+ page: 1n,
loading: true,
};
}
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();
}
if (auth) {
let form: ListRegistrationApplications = {
unread_only: true,
- page: 1,
+ page: 1n,
limit: fetchLimit,
auth,
};
);
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);
}
}
messageType: MessageType;
combined: ItemType[];
siteRes: GetSiteResponse;
- page: number;
+ page: bigint;
loading: boolean;
}
unreadOrAll: UnreadOrAll.Unread,
messageType: MessageType.All,
combined: [],
- page: 1,
+ page: 1n,
siteRes: this.isoData.site_res,
loading: true,
};
);
}
- 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();
}
let promises: Promise<any>[] = [];
let unresolved_only = true;
- let page = 1;
+ let page = 1n;
let limit = fetchLimit;
let auth = req.auth;
);
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) {
);
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) {
);
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);
}
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;
<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
<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}
/>
}
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)
);
}
GetSiteResponse,
UserOperation,
VerifyEmail as VerifyEmailForm,
- VerifyEmailResponse,
wsJsonToRes,
wsUserOp,
} from "lemmy-js-client";
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");
CreatePost,
EditPost,
Language,
- ListingType,
PostResponse,
PostView,
Search,
SearchResponse,
- SearchType,
- SortType,
UserOperation,
wsJsonToRes,
wsUserOp,
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),
};
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),
};
} 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 });
}
}
FeaturePost,
Language,
LockPost,
- PersonViewSafe,
- PostFeatureType,
+ PersonView,
PostView,
PurgePerson,
PurgePost,
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;
<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>
);
}
- 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;
}
{showScores() && (
<span
className={classNames("ml-2", {
- invisible: this.state.downvotes === 0,
+ invisible: this.state.downvotes === 0n,
})}
>
{numToSI(this.state.downvotes)}
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,
});
}
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,
});
}
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,
};
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,
};
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}`;
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";
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 (
BanFromCommunityResponse,
BanPersonResponse,
BlockPersonResponse,
- CommentNode as CommentNodeI,
CommentReportResponse,
CommentResponse,
CommentSortType,
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,
postId: getIdFromProps(this.props),
commentId: getCommentIdFromProps(this.props),
commentTree: [],
- commentSort: CommentSortType[CommentSortType.Hot],
+ commentSort: "Hot",
commentViewType: CommentViewType.Tree,
scrolled: false,
loading: true,
parent_id: this.state.commentId,
max_depth: commentTreeMaxDepth,
sort: this.state.commentSort,
- type_: ListingType.All,
+ type_: "All",
saved_only: false,
auth,
};
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),
};
let commentsForm: GetComments = {
max_depth: commentTreeMaxDepth,
- sort: CommentSortType.Hot,
- type_: ListingType.All,
+ sort: "Hot",
+ type_: "All",
saved_only: false,
auth,
};
<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>
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,
if (comments) {
i.setState({
commentViewType: Number(event.target.value),
- commentSort: CommentSortType.New,
+ commentSort: "New",
commentTree: buildCommentsTree(comments, !!i.state.commentId),
});
}
GetPersonDetails,
GetPersonDetailsResponse,
GetSiteResponse,
- SortType,
UserOperation,
wsJsonToRes,
wsUserOp,
fetchPersonDetails() {
let form: GetPersonDetails = {
person_id: this.state.recipient_id,
- sort: SortType.New,
+ sort: "New",
saved_only: false,
auth: myAuth(false),
};
let person_id = Number(req.path.split("/").pop());
let form: GetPersonDetails = {
person_id,
- sort: SortType.New,
+ sort: "New",
saved_only: false,
auth: req.auth,
};
import {
CreatePrivateMessage,
EditPrivateMessage,
- PersonSafe,
+ Person,
PrivateMessageResponse,
PrivateMessageView,
UserOperation,
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;
CreatePrivateMessageReport,
DeletePrivateMessage,
MarkPrivateMessageAsRead,
- PersonSafe,
+ Person,
PrivateMessageView,
} from "lemmy-js-client";
import { i18n } from "../../i18next";
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;
ListCommunities,
ListCommunitiesResponse,
ListingType,
- PersonViewSafe,
+ PersonView,
PostResponse,
PostView,
ResolveObject,
numToSI,
personToChoice,
restoreScrollPosition,
- routeListingTypeToEnum,
- routeSearchTypeToEnum,
- routeSortTypeToEnum,
saveScrollPosition,
setIsoData,
showLocal,
listingType: ListingType;
communityId?: number | null;
creatorId?: number | null;
- page: number;
+ page: bigint;
}
type FilterType = "creator" | "community";
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>({
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,
"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);
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());
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 <></>;
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)
+ )
);
}
<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>
auth,
};
- const resolveObjectForm: ResolveObject = {
- q,
- auth,
- };
+ if (auth) {
+ const resolveObjectForm: ResolveObject = {
+ q,
+ auth,
+ };
+ WebSocketService.Instance.send(
+ wsClient.resolveObject(resolveObjectForm)
+ );
+ }
this.setState({
searchResponse: undefined,
});
WebSocketService.Instance.send(wsClient.search(form));
- WebSocketService.Instance.send(wsClient.resolveObject(resolveObjectForm));
}
}
});
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,
});
}
i.updateUrl({
q: i.state.searchText,
- page: 1,
+ page: 1n,
});
}
-import { GetSiteResponse, LemmyHttp } from "lemmy-js-client";
+import { CommentView, GetSiteResponse, LemmyHttp } from "lemmy-js-client";
import type { ParsedQs } from "qs";
/**
Post,
Comment,
}
+
+export interface CommentNodeI {
+ comment_view: CommentView;
+ children: Array<CommentNodeI>;
+ depth: number;
+}
path: `/verify_email/:token`,
component: VerifyEmail,
},
- { path: `/instances`, component: Instances },
+ {
+ path: `/instances`,
+ component: Instances,
+ fetchInitialData: Instances.fetchInitialData,
+ },
{ path: `/legal`, component: Legal },
];
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();
BlockCommunityResponse,
BlockPersonResponse,
Comment as CommentI,
- CommentNode as CommentNodeI,
CommentReportView,
CommentSortType,
CommentView,
Language,
LemmyHttp,
LemmyWebsocket,
- ListingType,
- PersonSafe,
- PersonViewSafe,
+ MyUserInfo,
+ Person,
+ PersonView,
PostReportView,
PostView,
PrivateMessageReportView,
PrivateMessageView,
RegistrationApplicationView,
Search,
- SearchType,
SortType,
UploadImageResponse,
} from "lemmy-js-client";
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;
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";
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(
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}`);
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;
}
export function canMod(
creator_id: number,
mods?: CommunityModeratorView[],
- admins?: PersonViewSafe[],
+ admins?: PersonView[],
myUserInfo = UserService.Instance.myUserInfo,
onSelf = false
): boolean {
export function canAdmin(
creatorId: number,
- admins?: PersonViewSafe[],
+ admins?: PersonView[],
myUserInfo = UserService.Instance.myUserInfo,
onSelf = false
): boolean {
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;
}
export function amSiteCreator(
creator_id: number,
- admins?: PersonViewSafe[],
+ admins?: PersonView[],
myUserInfo = UserService.Instance.myUserInfo
): boolean {
let myId = myUserInfo?.local_user_view.person.id;
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);
interface PersonTribute {
key: string;
- view: PersonViewSafe;
+ view: PersonView;
}
async function personSearch(text: string): Promise<PersonTribute[]> {
export function updatePersonBlock(
data: BlockPersonResponse,
- myUserInfo = UserService.Instance.myUserInfo
+ myUserInfo: MyUserInfo | undefined = UserService.Instance.myUserInfo
) {
let mui = myUserInfo;
if (mui) {
export function updateCommunityBlock(
data: BlockCommunityResponse,
- myUserInfo = UserService.Instance.myUserInfo
+ myUserInfo: MyUserInfo | undefined = UserService.Instance.myUserInfo
) {
let mui = myUserInfo;
if (mui) {
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";
}
}
}
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 {
};
}
-export function personToChoice(pvs: PersonViewSafe): Choice {
+export function personToChoice(pvs: PersonView): Choice {
return {
value: pvs.person.id.toString(),
label: personSelectName(pvs),
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),
};
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),
};
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}`;
}
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
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";
}
}
export function isPostBlocked(
pv: PostView,
- myUserInfo = UserService.Instance.myUserInfo
+ myUserInfo: MyUserInfo | undefined = UserService.Instance.myUserInfo
): boolean {
return (
(myUserInfo?.community_blocks
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"