]> Untitled Git - lemmy-ui.git/commitdiff
Adding private message reporting. Fixes #782 (#806)
authorDessalines <dessalines@users.noreply.github.com>
Wed, 28 Sep 2022 12:50:47 +0000 (08:50 -0400)
committerGitHub <noreply@github.com>
Wed, 28 Sep 2022 12:50:47 +0000 (08:50 -0400)
package.json
src/shared/components/app/navbar.tsx
src/shared/components/community/sidebar.tsx
src/shared/components/home/site-sidebar.tsx
src/shared/components/modlog.tsx
src/shared/components/person/inbox.tsx
src/shared/components/person/reports.tsx
src/shared/components/private_message/private-message-report.tsx [new file with mode: 0644]
src/shared/components/private_message/private-message.tsx
src/shared/utils.ts
yarn.lock

index b3a41ab80b808428b105eba30cc4bd258ac2f58a..20188e9e5bc0bbc49f9a45496e95a1bd2af8e609 100644 (file)
@@ -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",
index dbf978e14535a48baf0c0049f59645041297103e..d6bc7727db2ccee4b036fd170209160cb766011c 100644 (file)
@@ -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({
index c723567789095b515368bf3a9241c63bc6ebe656..43e863c87c09172edee88aa640c51a0066c10d74 100644 (file)
@@ -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()
     );
   }
 
index d867c8d56913b1f60148ef1f1d0770dcc18d47bd..e8642c78366e8da22ed206a5adbdb84fad8d8e1b 100644 (file)
@@ -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
index 556d84a2bcc98e7cb6a660ace1ccd8ae10165324..4bbf8180679bf6f19899beae3e60d5901ccaf16b 100644 (file)
@@ -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 {
index 2ba6dce3131a51167041bba0f848167c597ff664..cfc4bd7e1f9d9f8b6b8f9f55090951d5f861ca12 100644 (file)
@@ -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"));
+      }
     }
   }
 
index ed1182fe2c1526727e4a5c9a5fa19ec55ced6cfa..85411cc3b4226a89279cc4b4f0355f200f26dd61 100644 (file)
@@ -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));
-
-    return [...comments, ...posts].sort((a, b) =>
+      .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, ...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);
     }
   }
 }
diff --git a/src/shared/components/private_message/private-message-report.tsx b/src/shared/components/private_message/private-message-report.tsx
new file mode 100644 (file)
index 0000000..3d6198c
--- /dev/null
@@ -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));
+  }
+}
index 436a07a53a482fa8188534bcd80249c92ebcc97f..b7d1bd1f7a164e40fc70d9eb0b2711004185c224 100644 (file)
@@ -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 });
   }
index 17fbd62bea6db84a70c30519b2599dd95a626704..d8703252fcbbda0fbc8917bedbc36fe917b88ecc 100644 (file)
@@ -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(
index 39d9488a82ba42fc2b63c4bfb19f644de0e1d5f1..7c3367070d38e273049396937f28439fa8348647 100644 (file)
--- a/yarn.lock
+++ b/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==