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