]> Untitled Git - lemmy-ui.git/blobdiff - src/shared/components/sidebar.tsx
Remove categories
[lemmy-ui.git] / src / shared / components / sidebar.tsx
index 34cc8b3a4f89cd68bccaf8115e4f9a6d0cc6708b..47de96da8f903e5461c5d0e092d89c0b4bfa57e5 100644 (file)
@@ -1,26 +1,27 @@
-import { Component, linkEvent } from 'inferno';
-import { Link } from 'inferno-router';
+import { Component, linkEvent } from "inferno";
+import { Link } from "inferno-router";
 import {
-  Community,
-  CommunityUser,
-  FollowCommunityForm,
-  DeleteCommunityForm,
-  RemoveCommunityForm,
-  UserView,
-  AddModToCommunityForm,
-} from 'lemmy-js-client';
-import { WebSocketService, UserService } from '../services';
-import { mdToHtml, getUnixTime } from '../utils';
-import { CommunityForm } from './community-form';
-import { UserListing } from './user-listing';
-import { CommunityLink } from './community-link';
-import { BannerIconHeader } from './banner-icon-header';
-import { i18n } from '../i18next';
+  CommunityView,
+  CommunityModeratorView,
+  FollowCommunity,
+  DeleteCommunity,
+  RemoveCommunity,
+  UserViewSafe,
+  AddModToCommunity,
+} from "lemmy-js-client";
+import { WebSocketService, UserService } from "../services";
+import { mdToHtml, getUnixTime, wsClient, authField } from "../utils";
+import { CommunityForm } from "./community-form";
+import { UserListing } from "./user-listing";
+import { CommunityLink } from "./community-link";
+import { BannerIconHeader } from "./banner-icon-header";
+import { Icon } from "./icon";
+import { i18n } from "../i18next";
 
 interface SidebarProps {
-  community: Community;
-  moderators: CommunityUser[];
-  admins: UserView[];
+  community_view: CommunityView;
+  moderators: CommunityModeratorView[];
+  admins: UserViewSafe[];
   online: number;
   enableNsfw: boolean;
   showIcon?: boolean;
@@ -57,7 +58,7 @@ export class Sidebar extends Component<SidebarProps, SidebarState> {
           this.sidebar()
         ) : (
           <CommunityForm
-            community={this.props.community}
+            community_view={this.props.community_view}
             onEdit={this.handleEditCommunity}
             onCancel={this.handleEditCancel}
             enableNsfw={this.props.enableNsfw}
@@ -70,14 +71,15 @@ export class Sidebar extends Component<SidebarProps, SidebarState> {
   sidebar() {
     return (
       <div>
-        <div class="card bg-transparent border-secondary mb-3">
-          <div class="card-header bg-transparent border-secondary">
+        <div class="card border-secondary mb-3">
+          <div class="card-body">
             {this.communityTitle()}
             {this.adminButtons()}
+            {this.subscribe()}
+            {this.createPost()}
           </div>
-          <div class="card-body">{this.subscribes()}</div>
         </div>
-        <div class="card bg-transparent border-secondary mb-3">
+        <div class="card border-secondary mb-3">
           <div class="card-body">
             {this.description()}
             {this.badges()}
@@ -89,27 +91,38 @@ export class Sidebar extends Component<SidebarProps, SidebarState> {
   }
 
   communityTitle() {
-    let community = this.props.community;
+    let community = this.props.community_view.community;
+    let subscribed = this.props.community_view.subscribed;
     return (
       <div>
         <h5 className="mb-0">
           {this.props.showIcon && (
             <BannerIconHeader icon={community.icon} banner={community.banner} />
           )}
-          <span>{community.title}</span>
+          <span class="mr-2">{community.title}</span>
+          {subscribed && (
+            <a
+              class="btn btn-secondary btn-sm mr-2"
+              href="#"
+              onClick={linkEvent(community.id, this.handleUnsubscribe)}
+            >
+              <Icon icon="check" classes="icon-inline text-success mr-1" />
+              {i18n.t("joined")}
+            </a>
+          )}
           {community.removed && (
-            <small className="ml-2 text-muted font-italic">
-              {i18n.t('removed')}
+            <small className="mr-2 text-muted font-italic">
+              {i18n.t("removed")}
             </small>
           )}
           {community.deleted && (
-            <small className="ml-2 text-muted font-italic">
-              {i18n.t('deleted')}
+            <small className="mr-2 text-muted font-italic">
+              {i18n.t("deleted")}
             </small>
           )}
           {community.nsfw && (
-            <small className="ml-2 text-muted font-italic">
-              {i18n.t('nsfw')}
+            <small className="mr-2 text-muted font-italic">
+              {i18n.t("nsfw")}
             </small>
           )}
         </h5>
@@ -125,43 +138,82 @@ export class Sidebar extends Component<SidebarProps, SidebarState> {
   }
 
   badges() {
-    let community = this.props.community;
+    let community_view = this.props.community_view;
+    let counts = community_view.counts;
     return (
       <ul class="my-1 list-inline">
-        <li className="list-inline-item badge badge-light">
-          {i18n.t('number_online', { count: this.props.online })}
+        <li className="list-inline-item badge badge-secondary">
+          {i18n.t("number_online", { count: this.props.online })}
         </li>
-        <li className="list-inline-item badge badge-light">
-          {i18n.t('number_of_subscribers', {
-            count: community.number_of_subscribers,
-          })}
+        <li
+          className="list-inline-item badge badge-secondary pointer"
+          data-tippy-content={`${i18n.t("number_of_users", {
+            count: counts.users_active_day,
+          })} ${i18n.t("active_in_the_last")} ${i18n.t("day")}`}
+        >
+          {i18n.t("number_of_users", {
+            count: counts.users_active_day,
+          })}{" "}
+          / {i18n.t("day")}
+        </li>
+        <li
+          className="list-inline-item badge badge-secondary pointer"
+          data-tippy-content={`${i18n.t("number_of_users", {
+            count: counts.users_active_week,
+          })} ${i18n.t("active_in_the_last")} ${i18n.t("week")}`}
+        >
+          {i18n.t("number_of_users", {
+            count: counts.users_active_week,
+          })}{" "}
+          / {i18n.t("week")}
+        </li>
+        <li
+          className="list-inline-item badge badge-secondary pointer"
+          data-tippy-content={`${i18n.t("number_of_users", {
+            count: counts.users_active_month,
+          })} ${i18n.t("active_in_the_last")} ${i18n.t("month")}`}
+        >
+          {i18n.t("number_of_users", {
+            count: counts.users_active_month,
+          })}{" "}
+          / {i18n.t("month")}
+        </li>
+        <li
+          className="list-inline-item badge badge-secondary pointer"
+          data-tippy-content={`${i18n.t("number_of_users", {
+            count: counts.users_active_half_year,
+          })} ${i18n.t("active_in_the_last")} ${i18n.t("number_of_months", {
+            count: 6,
+          })}`}
+        >
+          {i18n.t("number_of_users", {
+            count: counts.users_active_half_year,
+          })}{" "}
+          / {i18n.t("number_of_months", { count: 6 })}
         </li>
-        <li className="list-inline-item badge badge-light">
-          {i18n.t('number_of_posts', {
-            count: community.number_of_posts,
+        <li className="list-inline-item badge badge-secondary">
+          {i18n.t("number_of_subscribers", {
+            count: counts.subscribers,
           })}
         </li>
-        <li className="list-inline-item badge badge-light">
-          {i18n.t('number_of_comments', {
-            count: community.number_of_comments,
+        <li className="list-inline-item badge badge-secondary">
+          {i18n.t("number_of_posts", {
+            count: counts.posts,
           })}
         </li>
-        <li className="list-inline-item">
-          <Link className="badge badge-light" to="/communities">
-            {community.category_name}
-          </Link>
+        <li className="list-inline-item badge badge-secondary">
+          {i18n.t("number_of_comments", {
+            count: counts.comments,
+          })}
         </li>
         <li className="list-inline-item">
           <Link
-            className="badge badge-light"
-            to={`/modlog/community/${this.props.community.id}`}
+            className="badge badge-secondary"
+            to={`/modlog/community/${this.props.community_view.community.id}`}
           >
-            {i18n.t('modlog')}
+            {i18n.t("modlog")}
           </Link>
         </li>
-        <li className="list-inline-item badge badge-light">
-          <CommunityLink community={community} realLink />
-        </li>
       </ul>
     );
   }
@@ -169,52 +221,48 @@ export class Sidebar extends Component<SidebarProps, SidebarState> {
   mods() {
     return (
       <ul class="list-inline small">
-        <li class="list-inline-item">{i18n.t('mods')}: </li>
+        <li class="list-inline-item">{i18n.t("mods")}: </li>
         {this.props.moderators.map(mod => (
           <li class="list-inline-item">
-            <UserListing
-              user={{
-                name: mod.user_name,
-                preferred_username: mod.user_preferred_username,
-                avatar: mod.avatar,
-                id: mod.user_id,
-                local: mod.user_local,
-                actor_id: mod.user_actor_id,
-              }}
-            />
+            <UserListing user={mod.moderator} />
           </li>
         ))}
       </ul>
     );
   }
 
-  subscribes() {
-    let community = this.props.community;
+  createPost() {
+    let community_view = this.props.community_view;
     return (
-      <div class="d-flex flex-wrap">
+      community_view.subscribed && (
         <Link
-          class={`btn btn-secondary flex-fill mr-2 mb-2 ${
-            community.deleted || community.removed ? 'no-click' : ''
+          className={`btn btn-secondary btn-block mb-2 ${
+            community_view.community.deleted || community_view.community.removed
+              ? "no-click"
+              : ""
           }`}
-          to={`/create_post?community=${community.name}`}
+          to={`/create_post?community_id=${community_view.community.id}`}
         >
-          {i18n.t('create_a_post')}
+          {i18n.t("create_a_post")}
         </Link>
-        {community.subscribed ? (
-          <a
-            class="btn btn-secondary flex-fill mb-2"
-            href="#"
-            onClick={linkEvent(community.id, this.handleUnsubscribe)}
-          >
-            {i18n.t('unsubscribe')}
-          </a>
-        ) : (
+      )
+    );
+  }
+
+  subscribe() {
+    let community_view = this.props.community_view;
+    return (
+      <div class="mb-2">
+        {!community_view.subscribed && (
           <a
-            class="btn btn-secondary flex-fill mb-2"
+            class="btn btn-secondary btn-block"
             href="#"
-            onClick={linkEvent(community.id, this.handleSubscribe)}
+            onClick={linkEvent(
+              community_view.community.id,
+              this.handleSubscribe
+            )}
           >
-            {i18n.t('subscribe')}
+            {i18n.t("subscribe")}
           </a>
         )}
       </div>
@@ -222,19 +270,19 @@ export class Sidebar extends Component<SidebarProps, SidebarState> {
   }
 
   description() {
-    let community = this.props.community;
+    let description = this.props.community_view.community.description;
     return (
-      community.description && (
+      description && (
         <div
           className="md-div"
-          dangerouslySetInnerHTML={mdToHtml(community.description)}
+          dangerouslySetInnerHTML={mdToHtml(description)}
         />
       )
     );
   }
 
   adminButtons() {
-    let community = this.props.community;
+    let community_view = this.props.community_view;
     return (
       <>
         <ul class="list-inline mb-1 text-muted font-weight-bold">
@@ -242,13 +290,13 @@ export class Sidebar extends Component<SidebarProps, SidebarState> {
             <>
               <li className="list-inline-item-action">
                 <span
+                  role="button"
                   class="pointer"
                   onClick={linkEvent(this, this.handleEditClick)}
-                  data-tippy-content={i18n.t('edit')}
+                  data-tippy-content={i18n.t("edit")}
+                  aria-label={i18n.t("edit")}
                 >
-                  <svg class="icon icon-inline">
-                    <use xlinkHref="#icon-edit"></use>
-                  </svg>
+                  <Icon icon="edit" classes="icon-inline" />
                 </span>
               </li>
               {!this.amCreator &&
@@ -256,36 +304,39 @@ export class Sidebar extends Component<SidebarProps, SidebarState> {
                   <li className="list-inline-item-action">
                     <span
                       class="pointer"
+                      role="button"
                       onClick={linkEvent(
                         this,
                         this.handleShowConfirmLeaveModTeamClick
                       )}
                     >
-                      {i18n.t('leave_mod_team')}
+                      {i18n.t("leave_mod_team")}
                     </span>
                   </li>
                 ) : (
                   <>
                     <li className="list-inline-item-action">
-                      {i18n.t('are_you_sure')}
+                      {i18n.t("are_you_sure")}
                     </li>
                     <li className="list-inline-item-action">
                       <span
                         class="pointer"
+                        role="button"
                         onClick={linkEvent(this, this.handleLeaveModTeamClick)}
                       >
-                        {i18n.t('yes')}
+                        {i18n.t("yes")}
                       </span>
                     </li>
                     <li className="list-inline-item-action">
                       <span
                         class="pointer"
+                        role="button"
                         onClick={linkEvent(
                           this,
                           this.handleCancelLeaveModTeamClick
                         )}
                       >
-                        {i18n.t('no')}
+                        {i18n.t("no")}
                       </span>
                     </li>
                   </>
@@ -296,16 +347,22 @@ export class Sidebar extends Component<SidebarProps, SidebarState> {
                     class="pointer"
                     onClick={linkEvent(this, this.handleDeleteClick)}
                     data-tippy-content={
-                      !community.deleted ? i18n.t('delete') : i18n.t('restore')
+                      !community_view.community.deleted
+                        ? i18n.t("delete")
+                        : i18n.t("restore")
+                    }
+                    aria-label={
+                      !community_view.community.deleted
+                        ? i18n.t("delete")
+                        : i18n.t("restore")
                     }
                   >
-                    <svg
-                      class={`icon icon-inline ${
-                        community.deleted && 'text-danger'
+                    <Icon
+                      icon="trash"
+                      classes={`icon-inline ${
+                        community_view.community.deleted && "text-danger"
                       }`}
-                    >
-                      <use xlinkHref="#icon-trash"></use>
-                    </svg>
+                    />
                   </span>
                 </li>
               )}
@@ -313,19 +370,21 @@ export class Sidebar extends Component<SidebarProps, SidebarState> {
           )}
           {this.canAdmin && (
             <li className="list-inline-item">
-              {!this.props.community.removed ? (
+              {!this.props.community_view.community.removed ? (
                 <span
                   class="pointer"
+                  role="button"
                   onClick={linkEvent(this, this.handleModRemoveShow)}
                 >
-                  {i18n.t('remove')}
+                  {i18n.t("remove")}
                 </span>
               ) : (
                 <span
                   class="pointer"
+                  role="button"
                   onClick={linkEvent(this, this.handleModRemoveSubmit)}
                 >
-                  {i18n.t('restore')}
+                  {i18n.t("restore")}
                 </span>
               )}
             </li>
@@ -335,13 +394,13 @@ export class Sidebar extends Component<SidebarProps, SidebarState> {
           <form onSubmit={linkEvent(this, this.handleModRemoveSubmit)}>
             <div class="form-group row">
               <label class="col-form-label" htmlFor="remove-reason">
-                {i18n.t('reason')}
+                {i18n.t("reason")}
               </label>
               <input
                 type="text"
                 id="remove-reason"
                 class="form-control mr-2"
-                placeholder={i18n.t('optional')}
+                placeholder={i18n.t("optional")}
                 value={this.state.removeReason}
                 onInput={linkEvent(this, this.handleModRemoveReasonChange)}
               />
@@ -353,7 +412,7 @@ export class Sidebar extends Component<SidebarProps, SidebarState> {
             {/* </div> */}
             <div class="form-group row">
               <button type="submit" class="btn btn-secondary">
-                {i18n.t('remove_community')}
+                {i18n.t("remove_community")}
               </button>
             </div>
           </form>
@@ -377,13 +436,14 @@ export class Sidebar extends Component<SidebarProps, SidebarState> {
     this.setState(this.state);
   }
 
-  handleDeleteClick(i: Sidebar) {
+  handleDeleteClick(i: Sidebar, event: any) {
     event.preventDefault();
-    let deleteForm: DeleteCommunityForm = {
-      edit_id: i.props.community.id,
-      deleted: !i.props.community.deleted,
+    let deleteForm: DeleteCommunity = {
+      community_id: i.props.community_view.community.id,
+      deleted: !i.props.community_view.community.deleted,
+      auth: authField(),
     };
-    WebSocketService.Instance.deleteCommunity(deleteForm);
+    WebSocketService.Instance.send(wsClient.deleteCommunity(deleteForm));
   }
 
   handleShowConfirmLeaveModTeamClick(i: Sidebar) {
@@ -392,12 +452,13 @@ export class Sidebar extends Component<SidebarProps, SidebarState> {
   }
 
   handleLeaveModTeamClick(i: Sidebar) {
-    let form: AddModToCommunityForm = {
+    let form: AddModToCommunity = {
       user_id: UserService.Instance.user.id,
-      community_id: i.props.community.id,
+      community_id: i.props.community_view.community.id,
       added: false,
+      auth: authField(),
     };
-    WebSocketService.Instance.addModToCommunity(form);
+    WebSocketService.Instance.send(wsClient.addModToCommunity(form));
     i.state.showConfirmLeaveModTeam = false;
     i.setState(i.state);
   }
@@ -407,33 +468,35 @@ export class Sidebar extends Component<SidebarProps, SidebarState> {
     i.setState(i.state);
   }
 
-  handleUnsubscribe(communityId: number) {
+  handleUnsubscribe(communityId: number, event: any) {
     event.preventDefault();
-    let form: FollowCommunityForm = {
+    let form: FollowCommunity = {
       community_id: communityId,
       follow: false,
+      auth: authField(),
     };
-    WebSocketService.Instance.followCommunity(form);
+    WebSocketService.Instance.send(wsClient.followCommunity(form));
   }
 
-  handleSubscribe(communityId: number) {
+  handleSubscribe(communityId: number, event: any) {
     event.preventDefault();
-    let form: FollowCommunityForm = {
+    let form: FollowCommunity = {
       community_id: communityId,
       follow: true,
+      auth: authField(),
     };
-    WebSocketService.Instance.followCommunity(form);
+    WebSocketService.Instance.send(wsClient.followCommunity(form));
   }
 
   private get amCreator(): boolean {
-    return this.props.community.creator_id == UserService.Instance.user.id;
+    return this.props.community_view.creator.id == UserService.Instance.user.id;
   }
 
   get canMod(): boolean {
     return (
       UserService.Instance.user &&
       this.props.moderators
-        .map(m => m.user_id)
+        .map(m => m.moderator.id)
         .includes(UserService.Instance.user.id)
     );
   }
@@ -441,7 +504,9 @@ export class Sidebar extends Component<SidebarProps, SidebarState> {
   get canAdmin(): boolean {
     return (
       UserService.Instance.user &&
-      this.props.admins.map(a => a.id).includes(UserService.Instance.user.id)
+      this.props.admins
+        .map(a => a.user.id)
+        .includes(UserService.Instance.user.id)
     );
   }
 
@@ -461,15 +526,16 @@ export class Sidebar extends Component<SidebarProps, SidebarState> {
     i.setState(i.state);
   }
 
-  handleModRemoveSubmit(i: Sidebar) {
+  handleModRemoveSubmit(i: Sidebar, event: any) {
     event.preventDefault();
-    let removeForm: RemoveCommunityForm = {
-      edit_id: i.props.community.id,
-      removed: !i.props.community.removed,
+    let removeForm: RemoveCommunity = {
+      community_id: i.props.community_view.community.id,
+      removed: !i.props.community_view.community.removed,
       reason: i.state.removeReason,
       expires: getUnixTime(i.state.removeExpires),
+      auth: authField(),
     };
-    WebSocketService.Instance.removeCommunity(removeForm);
+    WebSocketService.Instance.send(wsClient.removeCommunity(removeForm));
 
     i.state.showRemoveDialog = false;
     i.setState(i.state);