mirror of
https://github.com/LemmyNet/lemmy-ui.git
synced 2024-12-23 03:11:25 +00:00
parent
333642e065
commit
dc62cab7e9
11 changed files with 353 additions and 75 deletions
|
@ -78,7 +78,7 @@
|
|||
"eslint-plugin-prettier": "^4.2.1",
|
||||
"husky": "^8.0.1",
|
||||
"import-sort-style-module": "^6.0.0",
|
||||
"lemmy-js-client": "0.17.0-rc.45",
|
||||
"lemmy-js-client": "0.17.0-rc.46",
|
||||
"lint-staged": "^13.0.3",
|
||||
"mini-css-extract-plugin": "^2.6.1",
|
||||
"node-fetch": "^2.6.1",
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
import { None, Some } from "@sniptt/monads";
|
||||
import { None } from "@sniptt/monads";
|
||||
import { Component, createRef, linkEvent, RefObject } from "inferno";
|
||||
import { NavLink } from "inferno-router";
|
||||
import {
|
||||
|
@ -209,7 +209,7 @@ export class Navbar extends Component<NavbarProps, NavbarState> {
|
|||
</li>
|
||||
</ul>
|
||||
)}
|
||||
{this.amAdmin && (
|
||||
{amAdmin() && (
|
||||
<ul className="navbar-nav ml-1">
|
||||
<li className="nav-item">
|
||||
<NavLink
|
||||
|
@ -298,7 +298,7 @@ export class Navbar extends Component<NavbarProps, NavbarState> {
|
|||
</li>
|
||||
</ul>
|
||||
<ul className="navbar-nav my-2">
|
||||
{this.amAdmin && (
|
||||
{amAdmin() && (
|
||||
<li className="nav-item">
|
||||
<NavLink
|
||||
to="/admin"
|
||||
|
@ -388,7 +388,7 @@ export class Navbar extends Component<NavbarProps, NavbarState> {
|
|||
</li>
|
||||
</ul>
|
||||
)}
|
||||
{this.amAdmin && (
|
||||
{amAdmin() && (
|
||||
<ul className="navbar-nav my-2">
|
||||
<li className="nav-item">
|
||||
<NavLink
|
||||
|
@ -525,10 +525,6 @@ export class Navbar extends Component<NavbarProps, NavbarState> {
|
|||
);
|
||||
}
|
||||
|
||||
get amAdmin(): boolean {
|
||||
return amAdmin(Some(this.props.siteRes.admins));
|
||||
}
|
||||
|
||||
handleToggleExpandNavbar(i: Navbar) {
|
||||
i.setState({ expanded: !i.state.expanded });
|
||||
}
|
||||
|
@ -605,7 +601,10 @@ export class Navbar extends Component<NavbarProps, NavbarState> {
|
|||
GetReportCountResponse
|
||||
);
|
||||
this.setState({
|
||||
unreadReportCount: data.post_reports + data.comment_reports,
|
||||
unreadReportCount:
|
||||
data.post_reports +
|
||||
data.comment_reports +
|
||||
data.private_message_reports.unwrapOr(0),
|
||||
});
|
||||
this.sendReportUnread();
|
||||
} else if (op == UserOperation.GetUnreadRegistrationApplicationCount) {
|
||||
|
@ -673,7 +672,7 @@ export class Navbar extends Component<NavbarProps, NavbarState> {
|
|||
});
|
||||
WebSocketService.Instance.send(wsClient.getReportCount(reportCountForm));
|
||||
|
||||
if (this.amAdmin) {
|
||||
if (amAdmin()) {
|
||||
console.log("Fetching applications...");
|
||||
|
||||
let applicationCountForm = new GetUnreadRegistrationApplicationCount({
|
||||
|
|
|
@ -420,7 +420,7 @@ export class Sidebar extends Component<SidebarProps, SidebarState> {
|
|||
)}
|
||||
</>
|
||||
)}
|
||||
{amAdmin(Some(this.props.admins)) && (
|
||||
{amAdmin() && (
|
||||
<li className="list-inline-item">
|
||||
{!this.props.community_view.community.removed ? (
|
||||
<button
|
||||
|
@ -600,7 +600,7 @@ export class Sidebar extends Component<SidebarProps, SidebarState> {
|
|||
return (
|
||||
!this.props.community_view.community.posting_restricted_to_mods ||
|
||||
amMod(Some(this.props.moderators)) ||
|
||||
amAdmin(Some(this.props.admins))
|
||||
amAdmin()
|
||||
);
|
||||
}
|
||||
|
||||
|
|
|
@ -113,7 +113,7 @@ export class SiteSidebar extends Component<SiteSidebarProps, SiteSidebarState> {
|
|||
|
||||
adminButtons() {
|
||||
return (
|
||||
amAdmin(this.props.admins) && (
|
||||
amAdmin() && (
|
||||
<ul className="list-inline mb-1 text-muted font-weight-bold">
|
||||
<li className="list-inline-item-action">
|
||||
<button
|
||||
|
|
|
@ -618,10 +618,7 @@ export class Modlog extends Component<any, ModlogState> {
|
|||
}
|
||||
|
||||
get amAdminOrMod(): boolean {
|
||||
return (
|
||||
amAdmin(Some(this.state.siteRes.admins)) ||
|
||||
amMod(this.state.communityMods)
|
||||
);
|
||||
return amAdmin() || amMod(this.state.communityMods);
|
||||
}
|
||||
|
||||
modOrAdminText(person: Option<PersonSafe>): string {
|
||||
|
|
|
@ -17,6 +17,7 @@ import {
|
|||
PersonMentionResponse,
|
||||
PersonMentionView,
|
||||
PostReportResponse,
|
||||
PrivateMessageReportResponse,
|
||||
PrivateMessageResponse,
|
||||
PrivateMessagesResponse,
|
||||
PrivateMessageView,
|
||||
|
@ -880,6 +881,14 @@ export class Inbox extends Component<any, InboxState> {
|
|||
if (data) {
|
||||
toast(i18n.t("report_created"));
|
||||
}
|
||||
} else if (op == UserOperation.CreatePrivateMessageReport) {
|
||||
let data = wsJsonToRes<PrivateMessageReportResponse>(
|
||||
msg,
|
||||
PrivateMessageReportResponse
|
||||
);
|
||||
if (data) {
|
||||
toast(i18n.t("report_created"));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -8,8 +8,12 @@ import {
|
|||
ListCommentReportsResponse,
|
||||
ListPostReports,
|
||||
ListPostReportsResponse,
|
||||
ListPrivateMessageReports,
|
||||
ListPrivateMessageReportsResponse,
|
||||
PostReportResponse,
|
||||
PostReportView,
|
||||
PrivateMessageReportResponse,
|
||||
PrivateMessageReportView,
|
||||
UserOperation,
|
||||
wsJsonToRes,
|
||||
wsUserOp,
|
||||
|
@ -19,6 +23,7 @@ import { i18n } from "../../i18next";
|
|||
import { InitialFetchRequest } from "../../interfaces";
|
||||
import { UserService, WebSocketService } from "../../services";
|
||||
import {
|
||||
amAdmin,
|
||||
auth,
|
||||
fetchLimit,
|
||||
isBrowser,
|
||||
|
@ -27,6 +32,7 @@ import {
|
|||
toast,
|
||||
updateCommentReportRes,
|
||||
updatePostReportRes,
|
||||
updatePrivateMessageReportRes,
|
||||
wsClient,
|
||||
wsSubscribe,
|
||||
} from "../../utils";
|
||||
|
@ -35,6 +41,7 @@ import { HtmlTags } from "../common/html-tags";
|
|||
import { Spinner } from "../common/icon";
|
||||
import { Paginator } from "../common/paginator";
|
||||
import { PostReport } from "../post/post-report";
|
||||
import { PrivateMessageReport } from "../private_message/private-message-report";
|
||||
|
||||
enum UnreadOrAll {
|
||||
Unread,
|
||||
|
@ -45,23 +52,26 @@ enum MessageType {
|
|||
All,
|
||||
CommentReport,
|
||||
PostReport,
|
||||
PrivateMessageReport,
|
||||
}
|
||||
|
||||
enum MessageEnum {
|
||||
CommentReport,
|
||||
PostReport,
|
||||
PrivateMessageReport,
|
||||
}
|
||||
|
||||
type ItemType = {
|
||||
id: number;
|
||||
type_: MessageEnum;
|
||||
view: CommentReportView | PostReportView;
|
||||
view: CommentReportView | PostReportView | PrivateMessageReportView;
|
||||
published: string;
|
||||
};
|
||||
|
||||
interface ReportsState {
|
||||
listCommentReportsResponse: Option<ListCommentReportsResponse>;
|
||||
listPostReportsResponse: Option<ListPostReportsResponse>;
|
||||
listPrivateMessageReportsResponse: Option<ListPrivateMessageReportsResponse>;
|
||||
unreadOrAll: UnreadOrAll;
|
||||
messageType: MessageType;
|
||||
combined: ItemType[];
|
||||
|
@ -74,12 +84,14 @@ export class Reports extends Component<any, ReportsState> {
|
|||
private isoData = setIsoData(
|
||||
this.context,
|
||||
ListCommentReportsResponse,
|
||||
ListPostReportsResponse
|
||||
ListPostReportsResponse,
|
||||
ListPrivateMessageReportsResponse
|
||||
);
|
||||
private subscription: Subscription;
|
||||
private emptyState: ReportsState = {
|
||||
listCommentReportsResponse: None,
|
||||
listPostReportsResponse: None,
|
||||
listPrivateMessageReportsResponse: None,
|
||||
unreadOrAll: UnreadOrAll.Unread,
|
||||
messageType: MessageType.All,
|
||||
combined: [],
|
||||
|
@ -113,6 +125,14 @@ export class Reports extends Component<any, ReportsState> {
|
|||
this.isoData.routeData[1] as ListPostReportsResponse
|
||||
),
|
||||
};
|
||||
if (amAdmin()) {
|
||||
this.state = {
|
||||
...this.state,
|
||||
listPrivateMessageReportsResponse: Some(
|
||||
this.isoData.routeData[2] as ListPrivateMessageReportsResponse
|
||||
),
|
||||
};
|
||||
}
|
||||
this.state = {
|
||||
...this.state,
|
||||
combined: this.buildCombined(),
|
||||
|
@ -166,6 +186,8 @@ export class Reports extends Component<any, ReportsState> {
|
|||
this.commentReports()}
|
||||
{this.state.messageType == MessageType.PostReport &&
|
||||
this.postReports()}
|
||||
{this.state.messageType == MessageType.PrivateMessageReport &&
|
||||
this.privateMessageReports()}
|
||||
<Paginator
|
||||
page={this.state.page}
|
||||
onChange={this.handlePageChange}
|
||||
|
@ -252,6 +274,26 @@ export class Reports extends Component<any, ReportsState> {
|
|||
/>
|
||||
{i18n.t("posts")}
|
||||
</label>
|
||||
{amAdmin() && (
|
||||
<label
|
||||
className={`btn btn-outline-secondary pointer
|
||||
${
|
||||
this.state.messageType == MessageType.PrivateMessageReport &&
|
||||
"active"
|
||||
}
|
||||
`}
|
||||
>
|
||||
<input
|
||||
type="radio"
|
||||
value={MessageType.PrivateMessageReport}
|
||||
checked={
|
||||
this.state.messageType == MessageType.PrivateMessageReport
|
||||
}
|
||||
onChange={linkEvent(this, this.handleMessageTypeChange)}
|
||||
/>
|
||||
{i18n.t("messages")}
|
||||
</label>
|
||||
)}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
@ -265,7 +307,7 @@ export class Reports extends Component<any, ReportsState> {
|
|||
);
|
||||
}
|
||||
|
||||
replyToReplyType(r: CommentReportView): ItemType {
|
||||
commentReportToItemType(r: CommentReportView): ItemType {
|
||||
return {
|
||||
id: r.comment_report.id,
|
||||
type_: MessageEnum.CommentReport,
|
||||
|
@ -274,7 +316,7 @@ export class Reports extends Component<any, ReportsState> {
|
|||
};
|
||||
}
|
||||
|
||||
mentionToReplyType(r: PostReportView): ItemType {
|
||||
postReportToItemType(r: PostReportView): ItemType {
|
||||
return {
|
||||
id: r.post_report.id,
|
||||
type_: MessageEnum.PostReport,
|
||||
|
@ -283,17 +325,31 @@ export class Reports extends Component<any, ReportsState> {
|
|||
};
|
||||
}
|
||||
|
||||
privateMessageReportToItemType(r: PrivateMessageReportView): ItemType {
|
||||
return {
|
||||
id: r.private_message_report.id,
|
||||
type_: MessageEnum.PrivateMessageReport,
|
||||
view: r,
|
||||
published: r.private_message_report.published,
|
||||
};
|
||||
}
|
||||
|
||||
buildCombined(): ItemType[] {
|
||||
let comments: ItemType[] = this.state.listCommentReportsResponse
|
||||
.map(r => r.comment_reports)
|
||||
.unwrapOr([])
|
||||
.map(r => this.replyToReplyType(r));
|
||||
.map(r => this.commentReportToItemType(r));
|
||||
let posts: ItemType[] = this.state.listPostReportsResponse
|
||||
.map(r => r.post_reports)
|
||||
.unwrapOr([])
|
||||
.map(r => this.mentionToReplyType(r));
|
||||
.map(r => this.postReportToItemType(r));
|
||||
let privateMessages: ItemType[] =
|
||||
this.state.listPrivateMessageReportsResponse
|
||||
.map(r => r.private_message_reports)
|
||||
.unwrapOr([])
|
||||
.map(r => this.privateMessageReportToItemType(r));
|
||||
|
||||
return [...comments, ...posts].sort((a, b) =>
|
||||
return [...comments, ...posts, ...privateMessages].sort((a, b) =>
|
||||
b.published.localeCompare(a.published)
|
||||
);
|
||||
}
|
||||
|
@ -306,6 +362,13 @@ export class Reports extends Component<any, ReportsState> {
|
|||
);
|
||||
case MessageEnum.PostReport:
|
||||
return <PostReport key={i.id} report={i.view as PostReportView} />;
|
||||
case MessageEnum.PrivateMessageReport:
|
||||
return (
|
||||
<PrivateMessageReport
|
||||
key={i.id}
|
||||
report={i.view as PrivateMessageReportView}
|
||||
/>
|
||||
);
|
||||
default:
|
||||
return <div />;
|
||||
}
|
||||
|
@ -356,6 +419,25 @@ export class Reports extends Component<any, ReportsState> {
|
|||
});
|
||||
}
|
||||
|
||||
privateMessageReports() {
|
||||
return this.state.listPrivateMessageReportsResponse.match({
|
||||
some: res => (
|
||||
<div>
|
||||
{res.private_message_reports.map(pmr => (
|
||||
<>
|
||||
<hr />
|
||||
<PrivateMessageReport
|
||||
key={pmr.private_message_report.id}
|
||||
report={pmr}
|
||||
/>
|
||||
</>
|
||||
))}
|
||||
</div>
|
||||
),
|
||||
none: <></>,
|
||||
});
|
||||
}
|
||||
|
||||
handlePageChange(page: number) {
|
||||
this.setState({ page });
|
||||
this.refetch();
|
||||
|
@ -400,6 +482,18 @@ export class Reports extends Component<any, ReportsState> {
|
|||
});
|
||||
promises.push(req.client.listPostReports(postReportsForm));
|
||||
|
||||
if (amAdmin()) {
|
||||
let privateMessageReportsForm = new ListPrivateMessageReports({
|
||||
unresolved_only,
|
||||
page,
|
||||
limit,
|
||||
auth,
|
||||
});
|
||||
promises.push(
|
||||
req.client.listPrivateMessageReports(privateMessageReportsForm)
|
||||
);
|
||||
}
|
||||
|
||||
return promises;
|
||||
}
|
||||
|
||||
|
@ -430,6 +524,18 @@ export class Reports extends Component<any, ReportsState> {
|
|||
auth: auth().unwrap(),
|
||||
});
|
||||
WebSocketService.Instance.send(wsClient.listPostReports(postReportsForm));
|
||||
|
||||
if (amAdmin()) {
|
||||
let privateMessageReportsForm = new ListPrivateMessageReports({
|
||||
unresolved_only,
|
||||
page,
|
||||
limit,
|
||||
auth: auth().unwrap(),
|
||||
});
|
||||
WebSocketService.Instance.send(
|
||||
wsClient.listPrivateMessageReports(privateMessageReportsForm)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
parseMessage(msg: any) {
|
||||
|
@ -460,6 +566,16 @@ export class Reports extends Component<any, ReportsState> {
|
|||
// this.sendUnreadCount();
|
||||
window.scrollTo(0, 0);
|
||||
setupTippy();
|
||||
} else if (op == UserOperation.ListPrivateMessageReports) {
|
||||
let data = wsJsonToRes<ListPrivateMessageReportsResponse>(
|
||||
msg,
|
||||
ListPrivateMessageReportsResponse
|
||||
);
|
||||
this.setState({ listPrivateMessageReportsResponse: Some(data) });
|
||||
this.setState({ combined: this.buildCombined(), loading: false });
|
||||
// this.sendUnreadCount();
|
||||
window.scrollTo(0, 0);
|
||||
setupTippy();
|
||||
} else if (op == UserOperation.ResolvePostReport) {
|
||||
let data = wsJsonToRes<PostReportResponse>(msg, PostReportResponse);
|
||||
updatePostReportRes(
|
||||
|
@ -488,6 +604,24 @@ export class Reports extends Component<any, ReportsState> {
|
|||
urcs.next(urcs.getValue() + 1);
|
||||
}
|
||||
this.setState(this.state);
|
||||
} else if (op == UserOperation.ResolvePrivateMessageReport) {
|
||||
let data = wsJsonToRes<PrivateMessageReportResponse>(
|
||||
msg,
|
||||
PrivateMessageReportResponse
|
||||
);
|
||||
updatePrivateMessageReportRes(
|
||||
data.private_message_report_view,
|
||||
this.state.listPrivateMessageReportsResponse
|
||||
.map(r => r.private_message_reports)
|
||||
.unwrapOr([])
|
||||
);
|
||||
let urcs = UserService.Instance.unreadReportCountSub;
|
||||
if (data.private_message_report_view.private_message_report.resolved) {
|
||||
urcs.next(urcs.getValue() - 1);
|
||||
} else {
|
||||
urcs.next(urcs.getValue() + 1);
|
||||
}
|
||||
this.setState(this.state);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,92 @@
|
|||
import { Component, linkEvent } from "inferno";
|
||||
import { T } from "inferno-i18next-dess";
|
||||
import {
|
||||
PrivateMessageReportView,
|
||||
ResolvePrivateMessageReport,
|
||||
} from "lemmy-js-client";
|
||||
import { i18n } from "../../i18next";
|
||||
import { WebSocketService } from "../../services";
|
||||
import { auth, mdToHtml, wsClient } from "../../utils";
|
||||
import { Icon } from "../common/icon";
|
||||
import { PersonListing } from "../person/person-listing";
|
||||
|
||||
interface Props {
|
||||
report: PrivateMessageReportView;
|
||||
}
|
||||
|
||||
export class PrivateMessageReport extends Component<Props, any> {
|
||||
constructor(props: any, context: any) {
|
||||
super(props, context);
|
||||
}
|
||||
|
||||
render() {
|
||||
let r = this.props.report;
|
||||
let pmr = r.private_message_report;
|
||||
let tippyContent = i18n.t(
|
||||
r.private_message_report.resolved ? "unresolve_report" : "resolve_report"
|
||||
);
|
||||
|
||||
return (
|
||||
<div>
|
||||
<div>
|
||||
{i18n.t("creator")}:{" "}
|
||||
<PersonListing person={r.private_message_creator} />
|
||||
</div>
|
||||
<div>
|
||||
{i18n.t("message")}:
|
||||
<div
|
||||
className="md-div"
|
||||
dangerouslySetInnerHTML={mdToHtml(pmr.original_pm_text)}
|
||||
/>
|
||||
</div>
|
||||
<div>
|
||||
{i18n.t("reporter")}: <PersonListing person={r.creator} />
|
||||
</div>
|
||||
<div>
|
||||
{i18n.t("reason")}: {pmr.reason}
|
||||
</div>
|
||||
{r.resolver.match({
|
||||
some: resolver => (
|
||||
<div>
|
||||
{pmr.resolved ? (
|
||||
<T i18nKey="resolved_by">
|
||||
#
|
||||
<PersonListing person={resolver} />
|
||||
</T>
|
||||
) : (
|
||||
<T i18nKey="unresolved_by">
|
||||
#
|
||||
<PersonListing person={resolver} />
|
||||
</T>
|
||||
)}
|
||||
</div>
|
||||
),
|
||||
none: <></>,
|
||||
})}
|
||||
<button
|
||||
className="btn btn-link btn-animate text-muted py-0"
|
||||
onClick={linkEvent(this, this.handleResolveReport)}
|
||||
data-tippy-content={tippyContent}
|
||||
aria-label={tippyContent}
|
||||
>
|
||||
<Icon
|
||||
icon="check"
|
||||
classes={`icon-inline ${
|
||||
pmr.resolved ? "text-success" : "text-danger"
|
||||
}`}
|
||||
/>
|
||||
</button>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
handleResolveReport(i: PrivateMessageReport) {
|
||||
let pmr = i.props.report.private_message_report;
|
||||
let form = new ResolvePrivateMessageReport({
|
||||
report_id: pmr.id,
|
||||
resolved: !pmr.resolved,
|
||||
auth: auth().unwrap(),
|
||||
});
|
||||
WebSocketService.Instance.send(wsClient.resolvePrivateMessageReport(form));
|
||||
}
|
||||
}
|
|
@ -1,10 +1,12 @@
|
|||
import { None, Some } from "@sniptt/monads/build";
|
||||
import { None, Option, Some } from "@sniptt/monads/build";
|
||||
import { Component, linkEvent } from "inferno";
|
||||
import {
|
||||
CreatePrivateMessageReport,
|
||||
DeletePrivateMessage,
|
||||
MarkPrivateMessageAsRead,
|
||||
PersonSafe,
|
||||
PrivateMessageView,
|
||||
toUndefined,
|
||||
} from "lemmy-js-client";
|
||||
import { i18n } from "../../i18next";
|
||||
import { UserService, WebSocketService } from "../../services";
|
||||
|
@ -19,6 +21,8 @@ interface PrivateMessageState {
|
|||
showEdit: boolean;
|
||||
collapsed: boolean;
|
||||
viewSource: boolean;
|
||||
showReportDialog: boolean;
|
||||
reportReason: Option<string>;
|
||||
}
|
||||
|
||||
interface PrivateMessageProps {
|
||||
|
@ -34,6 +38,8 @@ export class PrivateMessage extends Component<
|
|||
showEdit: false,
|
||||
collapsed: false,
|
||||
viewSource: false,
|
||||
showReportDialog: false,
|
||||
reportReason: None,
|
||||
};
|
||||
|
||||
constructor(props: any, context: any) {
|
||||
|
@ -140,6 +146,7 @@ export class PrivateMessage extends Component<
|
|||
/>
|
||||
</button>
|
||||
</li>
|
||||
<li className="list-inline-item">{this.reportButton}</li>
|
||||
<li className="list-inline-item">
|
||||
<button
|
||||
className="btn btn-link btn-animate text-muted"
|
||||
|
@ -209,6 +216,32 @@ export class PrivateMessage extends Component<
|
|||
</div>
|
||||
)}
|
||||
</div>
|
||||
{this.state.showReportDialog && (
|
||||
<form
|
||||
className="form-inline"
|
||||
onSubmit={linkEvent(this, this.handleReportSubmit)}
|
||||
>
|
||||
<label className="sr-only" htmlFor="pm-report-reason">
|
||||
{i18n.t("reason")}
|
||||
</label>
|
||||
<input
|
||||
type="text"
|
||||
id="pm-report-reason"
|
||||
className="form-control mr-2"
|
||||
placeholder={i18n.t("reason")}
|
||||
required
|
||||
value={toUndefined(this.state.reportReason)}
|
||||
onInput={linkEvent(this, this.handleReportReasonChange)}
|
||||
/>
|
||||
<button
|
||||
type="submit"
|
||||
className="btn btn-secondary"
|
||||
aria-label={i18n.t("create_report")}
|
||||
>
|
||||
{i18n.t("create_report")}
|
||||
</button>
|
||||
</form>
|
||||
)}
|
||||
{this.state.showReply && (
|
||||
<PrivateMessageForm
|
||||
recipient={otherPerson}
|
||||
|
@ -222,6 +255,19 @@ export class PrivateMessage extends Component<
|
|||
);
|
||||
}
|
||||
|
||||
get reportButton() {
|
||||
return (
|
||||
<button
|
||||
className="btn btn-link btn-animate text-muted py-0"
|
||||
onClick={linkEvent(this, this.handleShowReportDialog)}
|
||||
data-tippy-content={i18n.t("show_report_dialog")}
|
||||
aria-label={i18n.t("show_report_dialog")}
|
||||
>
|
||||
<Icon icon="flag" inline />
|
||||
</button>
|
||||
);
|
||||
}
|
||||
|
||||
get messageUnlessRemoved(): string {
|
||||
let message = this.props.private_message_view.private_message;
|
||||
return message.deleted ? `*${i18n.t("deleted")}*` : message.content;
|
||||
|
@ -266,6 +312,26 @@ export class PrivateMessage extends Component<
|
|||
i.setState({ viewSource: !i.state.viewSource });
|
||||
}
|
||||
|
||||
handleShowReportDialog(i: PrivateMessage) {
|
||||
i.setState({ showReportDialog: !i.state.showReportDialog });
|
||||
}
|
||||
|
||||
handleReportReasonChange(i: PrivateMessage, event: any) {
|
||||
i.setState({ reportReason: Some(event.target.value) });
|
||||
}
|
||||
|
||||
handleReportSubmit(i: PrivateMessage, event: any) {
|
||||
event.preventDefault();
|
||||
let form = new CreatePrivateMessageReport({
|
||||
private_message_id: i.props.private_message_view.private_message.id,
|
||||
reason: toUndefined(i.state.reportReason),
|
||||
auth: auth().unwrap(),
|
||||
});
|
||||
WebSocketService.Instance.send(wsClient.createPrivateMessageReport(form));
|
||||
|
||||
i.setState({ showReportDialog: false });
|
||||
}
|
||||
|
||||
handlePrivateMessageEdit() {
|
||||
this.setState({ showEdit: false });
|
||||
}
|
||||
|
|
|
@ -23,6 +23,7 @@ import {
|
|||
PersonViewSafe,
|
||||
PostReportView,
|
||||
PostView,
|
||||
PrivateMessageReportView,
|
||||
PrivateMessageView,
|
||||
RegistrationApplicationView,
|
||||
Search,
|
||||
|
@ -246,14 +247,10 @@ export function isAdmin(
|
|||
});
|
||||
}
|
||||
|
||||
export function amAdmin(
|
||||
admins: Option<PersonViewSafe[]>,
|
||||
myUserInfo = UserService.Instance.myUserInfo
|
||||
): boolean {
|
||||
return myUserInfo.match({
|
||||
some: mui => isAdmin(admins, mui.local_user_view.person.id),
|
||||
none: false,
|
||||
});
|
||||
export function amAdmin(myUserInfo = UserService.Instance.myUserInfo): boolean {
|
||||
return myUserInfo
|
||||
.map(mui => mui.local_user_view.person.admin)
|
||||
.unwrapOr(false);
|
||||
}
|
||||
|
||||
export function amCommunityCreator(
|
||||
|
@ -948,6 +945,7 @@ export function editPostRes(data: PostView, post: PostView) {
|
|||
}
|
||||
}
|
||||
|
||||
// TODO possible to make these generic?
|
||||
export function updatePostReportRes(
|
||||
data: PostReportView,
|
||||
reports: PostReportView[]
|
||||
|
@ -968,6 +966,18 @@ export function updateCommentReportRes(
|
|||
}
|
||||
}
|
||||
|
||||
export function updatePrivateMessageReportRes(
|
||||
data: PrivateMessageReportView,
|
||||
reports: PrivateMessageReportView[]
|
||||
) {
|
||||
let found = reports.find(
|
||||
c => c.private_message_report.id == data.private_message_report.id
|
||||
);
|
||||
if (found) {
|
||||
found.private_message_report = data.private_message_report;
|
||||
}
|
||||
}
|
||||
|
||||
export function updateRegistrationApplicationRes(
|
||||
data: RegistrationApplicationView,
|
||||
applications: RegistrationApplicationView[]
|
||||
|
@ -1448,11 +1458,14 @@ export function myFirstDiscussionLanguageId(
|
|||
);
|
||||
}
|
||||
|
||||
export function canCreateCommunity(siteRes: GetSiteResponse): boolean {
|
||||
export function canCreateCommunity(
|
||||
siteRes: GetSiteResponse,
|
||||
myUserInfo = UserService.Instance.myUserInfo
|
||||
): boolean {
|
||||
let adminOnly = siteRes.site_view
|
||||
.map(s => s.site.community_creation_admin_only)
|
||||
.unwrapOr(false);
|
||||
return !adminOnly || amAdmin(Some(siteRes.admins));
|
||||
return !adminOnly || amAdmin(myUserInfo);
|
||||
}
|
||||
|
||||
export function isPostBlocked(
|
||||
|
|
46
yarn.lock
46
yarn.lock
|
@ -2657,7 +2657,7 @@ debug@^4.1.0, debug@^4.1.1, debug@^4.3.2, debug@^4.3.4:
|
|||
dependencies:
|
||||
ms "2.1.2"
|
||||
|
||||
debuglog@*, debuglog@^1.0.1:
|
||||
debuglog@^1.0.1:
|
||||
version "1.0.1"
|
||||
resolved "https://registry.yarnpkg.com/debuglog/-/debuglog-1.0.1.tgz#aa24ffb9ac3df9a2351837cfb2d279360cd78492"
|
||||
integrity sha512-syBZ+rnAK3EgMsH2aYEOLUW7mZSY9Gb+0wUMCFsZvcmiz+HigA0LOcq/HoQqVuGG+EKykunc7QG2bzrponfaSw==
|
||||
|
@ -4165,7 +4165,7 @@ import-sort@^6.0.0:
|
|||
is-builtin-module "^3.0.0"
|
||||
resolve "^1.8.1"
|
||||
|
||||
imurmurhash@*, imurmurhash@^0.1.4:
|
||||
imurmurhash@^0.1.4:
|
||||
version "0.1.4"
|
||||
resolved "https://registry.yarnpkg.com/imurmurhash/-/imurmurhash-0.1.4.tgz#9218b9b2b928a238b13dc4fb6b6d576f231453ea"
|
||||
integrity sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==
|
||||
|
@ -4799,10 +4799,10 @@ lcid@^1.0.0:
|
|||
dependencies:
|
||||
invert-kv "^1.0.0"
|
||||
|
||||
lemmy-js-client@0.17.0-rc.45:
|
||||
version "0.17.0-rc.45"
|
||||
resolved "https://registry.yarnpkg.com/lemmy-js-client/-/lemmy-js-client-0.17.0-rc.45.tgz#903122b615d5dae10e65abffa1ee6b70b1a3e52c"
|
||||
integrity sha512-jPeeDwGgMQHt6rYJfO7lzHQQ63Ox75Ojdihs7DsCUjLOMygantCsM6BD0xtPs3/rYV09zbYeNizKxEjv/wBnRA==
|
||||
lemmy-js-client@0.17.0-rc.46:
|
||||
version "0.17.0-rc.46"
|
||||
resolved "https://registry.yarnpkg.com/lemmy-js-client/-/lemmy-js-client-0.17.0-rc.46.tgz#c2820821ca46394fd17d1045e54c00a04b15700c"
|
||||
integrity sha512-9HqKKsvToSB397ywXpl0jPa7KIhDaULWel0g35CgmfOkylvuTlpF8UZW20vMXr02Br9qvbRf0hRvi9s5uaji+Q==
|
||||
|
||||
levn@^0.4.1:
|
||||
version "0.4.1"
|
||||
|
@ -4967,11 +4967,6 @@ lockfile@^1.0.4:
|
|||
dependencies:
|
||||
signal-exit "^3.0.2"
|
||||
|
||||
lodash._baseindexof@*:
|
||||
version "3.1.0"
|
||||
resolved "https://registry.yarnpkg.com/lodash._baseindexof/-/lodash._baseindexof-3.1.0.tgz#fe52b53a1c6761e42618d654e4a25789ed61822c"
|
||||
integrity sha512-bSYo8Pc/f0qAkr8fPJydpJjtrHiSynYfYBjtANIgXv5xEf1WlTC63dIDlgu0s9dmTvzRu1+JJTxcIAHe+sH0FQ==
|
||||
|
||||
lodash._baseuniq@~4.6.0:
|
||||
version "4.6.0"
|
||||
resolved "https://registry.yarnpkg.com/lodash._baseuniq/-/lodash._baseuniq-4.6.0.tgz#0ebb44e456814af7905c6212fa2c9b2d51b841e8"
|
||||
|
@ -4980,33 +4975,11 @@ lodash._baseuniq@~4.6.0:
|
|||
lodash._createset "~4.0.0"
|
||||
lodash._root "~3.0.0"
|
||||
|
||||
lodash._bindcallback@*:
|
||||
version "3.0.1"
|
||||
resolved "https://registry.yarnpkg.com/lodash._bindcallback/-/lodash._bindcallback-3.0.1.tgz#e531c27644cf8b57a99e17ed95b35c748789392e"
|
||||
integrity sha512-2wlI0JRAGX8WEf4Gm1p/mv/SZ+jLijpj0jyaE/AXeuQphzCgD8ZQW4oSpoN8JAopujOFGU3KMuq7qfHBWlGpjQ==
|
||||
|
||||
lodash._cacheindexof@*:
|
||||
version "3.0.2"
|
||||
resolved "https://registry.yarnpkg.com/lodash._cacheindexof/-/lodash._cacheindexof-3.0.2.tgz#3dc69ac82498d2ee5e3ce56091bafd2adc7bde92"
|
||||
integrity sha512-S8dUjWr7SUT/X6TBIQ/OYoCHo1Stu1ZRy6uMUSKqzFnZp5G5RyQizSm6kvxD2Ewyy6AVfMg4AToeZzKfF99T5w==
|
||||
|
||||
lodash._createcache@*:
|
||||
version "3.1.2"
|
||||
resolved "https://registry.yarnpkg.com/lodash._createcache/-/lodash._createcache-3.1.2.tgz#56d6a064017625e79ebca6b8018e17440bdcf093"
|
||||
integrity sha512-ev5SP+iFpZOugyab/DEUQxUeZP5qyciVTlgQ1f4Vlw7VUcCD8fVnyIqVUEIaoFH9zjAqdgi69KiofzvVmda/ZQ==
|
||||
dependencies:
|
||||
lodash._getnative "^3.0.0"
|
||||
|
||||
lodash._createset@~4.0.0:
|
||||
version "4.0.3"
|
||||
resolved "https://registry.yarnpkg.com/lodash._createset/-/lodash._createset-4.0.3.tgz#0f4659fbb09d75194fa9e2b88a6644d363c9fe26"
|
||||
integrity sha512-GTkC6YMprrJZCYU3zcqZj+jkXkrXzq3IPBcF/fIPpNEAB4hZEtXU8zp/RwKOvZl43NUmwDbyRk3+ZTbeRdEBXA==
|
||||
|
||||
lodash._getnative@*, lodash._getnative@^3.0.0:
|
||||
version "3.9.1"
|
||||
resolved "https://registry.yarnpkg.com/lodash._getnative/-/lodash._getnative-3.9.1.tgz#570bc7dede46d61cdcde687d65d3eecbaa3aaff5"
|
||||
integrity sha512-RrL9VxMEPyDMHOd9uFbvMe8X55X16/cGM5IgOKgRElQZutpX89iS6vwl64duTV1/16w5JY7tuFNXqoekmh1EmA==
|
||||
|
||||
lodash._root@~3.0.0:
|
||||
version "3.0.1"
|
||||
resolved "https://registry.yarnpkg.com/lodash._root/-/lodash._root-3.0.1.tgz#fba1c4524c19ee9a5f8136b4609f017cf4ded692"
|
||||
|
@ -5032,11 +5005,6 @@ lodash.pick@^4.4.0:
|
|||
resolved "https://registry.yarnpkg.com/lodash.pick/-/lodash.pick-4.4.0.tgz#52f05610fff9ded422611441ed1fc123a03001b3"
|
||||
integrity sha512-hXt6Ul/5yWjfklSGvLQl8vM//l3FtyHZeuelpzK6mm99pNvN9yTDruNZPEJZD1oWrqo+izBmB7oUfWgcCX7s4Q==
|
||||
|
||||
lodash.restparam@*:
|
||||
version "3.6.1"
|
||||
resolved "https://registry.yarnpkg.com/lodash.restparam/-/lodash.restparam-3.6.1.tgz#936a4e309ef330a7645ed4145986c85ae5b20805"
|
||||
integrity sha512-L4/arjjuq4noiUJpt3yS6KIKDtJwNe2fIYgMqyYYKoeIfV1iEqvPwhCx23o+R9dzouGihDAPN1dTIRWa7zk8tw==
|
||||
|
||||
lodash.union@~4.6.0:
|
||||
version "4.6.0"
|
||||
resolved "https://registry.yarnpkg.com/lodash.union/-/lodash.union-4.6.0.tgz#48bb5088409f16f1821666641c44dd1aaae3cd88"
|
||||
|
@ -6725,7 +6693,7 @@ readable-stream@~1.1.10:
|
|||
isarray "0.0.1"
|
||||
string_decoder "~0.10.x"
|
||||
|
||||
readdir-scoped-modules@*, readdir-scoped-modules@^1.0.0:
|
||||
readdir-scoped-modules@^1.0.0:
|
||||
version "1.1.0"
|
||||
resolved "https://registry.yarnpkg.com/readdir-scoped-modules/-/readdir-scoped-modules-1.1.0.tgz#8d45407b4f870a0dcaebc0e28670d18e74514309"
|
||||
integrity sha512-asaikDeqAQg7JifRsZn1NJZXo9E+VwlyCfbkZhwyISinqk5zNS6266HS5kah6P0SaQKGF6SkNnZVHUzHFYxYDw==
|
||||
|
|
Loading…
Reference in a new issue