]> Untitled Git - lemmy.git/commitdiff
Some more prettifying, cleaning up community and main.tsx
authorDessalines <tyhou13@gmx.com>
Wed, 29 Jul 2020 04:23:24 +0000 (00:23 -0400)
committerDessalines <tyhou13@gmx.com>
Wed, 29 Jul 2020 04:23:24 +0000 (00:23 -0400)
ui/src/components/community.tsx
ui/src/components/data-type-select.tsx
ui/src/components/inbox.tsx
ui/src/components/listing-type-select.tsx
ui/src/components/main.tsx
ui/src/components/post-listing.tsx
ui/src/components/post.tsx
ui/src/components/search.tsx
ui/src/components/sidebar.tsx
ui/src/components/sort-select.tsx
ui/src/components/user.tsx

index e1e747ae4b9476206044295ffda3359445564613..23f725e7c929b957072fc73fbb032c4106e98a3c 100644 (file)
@@ -187,7 +187,6 @@ export class Community extends Component<any, State> {
     return (
       <div class="container">
         <Helmet title={this.documentTitle} />
-        {this.selects()}
         {this.state.loading ? (
           <h5>
             <svg class="icon icon-spinner spin">
@@ -197,19 +196,7 @@ export class Community extends Component<any, State> {
         ) : (
           <div class="row">
             <div class="col-12 col-md-8">
-              <h5>
-                {this.state.community.title}
-                {this.state.community.removed && (
-                  <small className="ml-2 text-muted font-italic">
-                    {i18n.t('removed')}
-                  </small>
-                )}
-                {this.state.community.nsfw && (
-                  <small className="ml-2 text-muted font-italic">
-                    {i18n.t('nsfw')}
-                  </small>
-                )}
-              </h5>
+              {this.selects()}
               {this.listings()}
               {this.paginator()}
             </div>
index faa7a460cd859fcd9eccc63a411106c69c2e6286..c3e1fc60573d8b3c697542ccc6899940cc9839d0 100644 (file)
@@ -33,7 +33,7 @@ export class DataTypeSelect extends Component<
 
   render() {
     return (
-      <div class="btn-group btn-group-toggle">
+      <div class="btn-group btn-group-toggle flex-wrap mb-2">
         <label
           className={`pointer btn btn-outline-secondary 
             ${this.state.type_ == DataType.Post && 'active'}
index 5fe8a650f7b04040c8f7727a0516931ba27e0d8a..1c94032b384a53a648149446966504ce233dcc8c 100644 (file)
@@ -171,7 +171,7 @@ export class Inbox extends Component<any, InboxState> {
 
   unreadOrAllRadios() {
     return (
-      <div class="btn-group btn-group-toggle">
+      <div class="btn-group btn-group-toggle flex-wrap mb-2">
         <label
           className={`btn btn-outline-secondary pointer
             ${this.state.unreadOrAll == UnreadOrAll.Unread && 'active'}
@@ -204,7 +204,7 @@ export class Inbox extends Component<any, InboxState> {
 
   messageTypeRadios() {
     return (
-      <div class="btn-group btn-group-toggle">
+      <div class="btn-group btn-group-toggle flex-wrap mb-2">
         <label
           className={`btn btn-outline-secondary pointer 
             ${this.state.messageType == MessageType.All && 'active'}
index 62af7148398ac629958fc8585383f942a835cdc8..6bdf457c402a487c80475fe1e46b18e295863d0c 100644 (file)
@@ -34,7 +34,7 @@ export class ListingTypeSelect extends Component<
 
   render() {
     return (
-      <div class="btn-group btn-group-toggle">
+      <div class="btn-group btn-group-toggle flex-wrap mb-2">
         <label
           className={`btn btn-outline-secondary 
             ${this.state.type_ == ListingType.Subscribed && 'active'}
index 6bf69b8e6b959163dfa6fb4d1c8f4e38aa4ebb19..2466e5fae4f01c67ced7193b154eec7d62e9f177 100644 (file)
@@ -194,63 +194,52 @@ export class Main extends Component<any, MainState> {
           <main role="main" class="col-12 col-md-8">
             {this.posts()}
           </main>
-          <aside class="col-12 col-md-4">{this.my_sidebar()}</aside>
+          <aside class="col-12 col-md-4">{this.mySidebar()}</aside>
         </div>
       </div>
     );
   }
 
-  my_sidebar() {
+  mySidebar() {
     return (
       <div>
         {!this.state.loading && (
           <div>
             <div class="card bg-transparent border-secondary mb-3">
+              <div class="card-header bg-transparent border-secondary">
+                {this.siteName()}
+                {this.adminButtons()}
+              </div>
               <div class="card-body">
                 {this.trendingCommunities()}
-                {UserService.Instance.user &&
-                  this.state.subscribedCommunities.length > 0 && (
-                    <div>
-                      <h5>
-                        <T i18nKey="subscribed_to_communities">
-                          #
-                          <Link class="text-body" to="/communities">
-                            #
-                          </Link>
-                        </T>
-                      </h5>
-                      <ul class="list-inline">
-                        {this.state.subscribedCommunities.map(community => (
-                          <li class="list-inline-item">
-                            <CommunityLink
-                              community={{
-                                name: community.community_name,
-                                id: community.community_id,
-                                local: community.community_local,
-                                actor_id: community.community_actor_id,
-                              }}
-                            />
-                          </li>
-                        ))}
-                      </ul>
-                    </div>
-                  )}
-                <Link
-                  class="btn btn-secondary btn-block"
-                  to="/create_community"
-                >
-                  {i18n.t('create_a_community')}
-                </Link>
+                {this.createCommunityButton()}
+                {/*
+                {this.subscribedCommunities()}
+                */}
               </div>
             </div>
-            {this.sidebar()}
-            {this.landing()}
+
+            <div class="card bg-transparent border-secondary mb-3">
+              <div class="card-body">{this.sidebar()}</div>
+            </div>
+
+            <div class="card bg-transparent border-secondary">
+              <div class="card-body">{this.landing()}</div>
+            </div>
           </div>
         )}
       </div>
     );
   }
 
+  createCommunityButton() {
+    return (
+      <Link class="btn btn-secondary btn-block" to="/create_community">
+        {i18n.t('create_a_community')}
+      </Link>
+    );
+  }
+
   trendingCommunities() {
     return (
       <div>
@@ -273,6 +262,38 @@ export class Main extends Component<any, MainState> {
     );
   }
 
+  subscribedCommunities() {
+    return (
+      UserService.Instance.user &&
+      this.state.subscribedCommunities.length > 0 && (
+        <div>
+          <h5>
+            <T i18nKey="subscribed_to_communities">
+              #
+              <Link class="text-body" to="/communities">
+                #
+              </Link>
+            </T>
+          </h5>
+          <ul class="list-inline">
+            {this.state.subscribedCommunities.map(community => (
+              <li class="list-inline-item">
+                <CommunityLink
+                  community={{
+                    name: community.community_name,
+                    id: community.community_id,
+                    local: community.community_local,
+                    actor_id: community.community_actor_id,
+                  }}
+                />
+              </li>
+            ))}
+          </ul>
+        </div>
+      )
+    );
+  }
+
   sidebar() {
     return (
       <div>
@@ -305,136 +326,147 @@ export class Main extends Component<any, MainState> {
   siteInfo() {
     return (
       <div>
-        <div class="card bg-transparent border-secondary mb-3">
-          <div class="card-body">
-            <h5 class="mb-0">{`${this.state.siteRes.site.name}`}</h5>
-            {this.canAdmin && (
-              <ul class="list-inline mb-1 text-muted font-weight-bold">
-                <li className="list-inline-item-action">
-                  <span
-                    class="pointer"
-                    onClick={linkEvent(this, this.handleEditClick)}
-                    data-tippy-content={i18n.t('edit')}
-                  >
-                    <svg class="icon icon-inline">
-                      <use xlinkHref="#icon-edit"></use>
-                    </svg>
-                  </span>
-                </li>
-              </ul>
-            )}
-            <ul class="my-2 list-inline">
-              {/*
+        {this.state.siteRes.site.description && this.siteDescription()}
+        {this.badges()}
+        {this.admins()}
+      </div>
+    );
+  }
+
+  siteName() {
+    return <h5 class="mb-0">{`${this.state.siteRes.site.name}`}</h5>;
+  }
+
+  admins() {
+    return (
+      <ul class="mt-1 list-inline small mb-0">
+        <li class="list-inline-item">{i18n.t('admins')}:</li>
+        {this.state.siteRes.admins.map(admin => (
+          <li class="list-inline-item">
+            <UserListing
+              user={{
+                name: admin.name,
+                avatar: admin.avatar,
+                local: admin.local,
+                actor_id: admin.actor_id,
+                id: admin.id,
+              }}
+            />
+          </li>
+        ))}
+      </ul>
+    );
+  }
+
+  badges() {
+    return (
+      <ul class="my-2 list-inline">
+        {/*
               <li className="list-inline-item badge badge-light">
                 {i18n.t('number_online', { count: this.state.siteRes.online })}
               </li>
               */}
-              <li className="list-inline-item badge badge-light">
-                {i18n.t('number_of_users', {
-                  count: this.state.siteRes.site.number_of_users,
-                })}
-              </li>
-              <li className="list-inline-item badge badge-light">
-                {i18n.t('number_of_communities', {
-                  count: this.state.siteRes.site.number_of_communities,
-                })}
-              </li>
-              <li className="list-inline-item badge badge-light">
-                {i18n.t('number_of_posts', {
-                  count: this.state.siteRes.site.number_of_posts,
-                })}
-              </li>
-              <li className="list-inline-item badge badge-light">
-                {i18n.t('number_of_comments', {
-                  count: this.state.siteRes.site.number_of_comments,
-                })}
-              </li>
-              <li className="list-inline-item">
-                <Link className="badge badge-light" to="/modlog">
-                  {i18n.t('modlog')}
-                </Link>
-              </li>
-            </ul>
-            <ul class="mt-1 list-inline small mb-0">
-              <li class="list-inline-item">{i18n.t('admins')}:</li>
-              {this.state.siteRes.admins.map(admin => (
-                <li class="list-inline-item">
-                  <UserListing
-                    user={{
-                      name: admin.name,
-                      avatar: admin.avatar,
-                      local: admin.local,
-                      actor_id: admin.actor_id,
-                      id: admin.id,
-                    }}
-                  />
-                </li>
-              ))}
-            </ul>
-          </div>
-        </div>
-        {this.state.siteRes.site.description && (
-          <div class="card bg-transparent border-secondary mb-3">
-            <div class="card-body">
-              <div
-                className="md-div"
-                dangerouslySetInnerHTML={mdToHtml(
-                  this.state.siteRes.site.description
-                )}
-              />
-            </div>
-          </div>
-        )}
-      </div>
+        <li className="list-inline-item badge badge-light">
+          {i18n.t('number_of_users', {
+            count: this.state.siteRes.site.number_of_users,
+          })}
+        </li>
+        <li className="list-inline-item badge badge-light">
+          {i18n.t('number_of_communities', {
+            count: this.state.siteRes.site.number_of_communities,
+          })}
+        </li>
+        <li className="list-inline-item badge badge-light">
+          {i18n.t('number_of_posts', {
+            count: this.state.siteRes.site.number_of_posts,
+          })}
+        </li>
+        <li className="list-inline-item badge badge-light">
+          {i18n.t('number_of_comments', {
+            count: this.state.siteRes.site.number_of_comments,
+          })}
+        </li>
+        <li className="list-inline-item">
+          <Link className="badge badge-light" to="/modlog">
+            {i18n.t('modlog')}
+          </Link>
+        </li>
+      </ul>
+    );
+  }
+
+  adminButtons() {
+    return (
+      this.canAdmin && (
+        <ul class="list-inline mb-1 text-muted font-weight-bold">
+          <li className="list-inline-item-action">
+            <span
+              class="pointer"
+              onClick={linkEvent(this, this.handleEditClick)}
+              data-tippy-content={i18n.t('edit')}
+            >
+              <svg class="icon icon-inline">
+                <use xlinkHref="#icon-edit"></use>
+              </svg>
+            </span>
+          </li>
+        </ul>
+      )
+    );
+  }
+
+  siteDescription() {
+    return (
+      <div
+        className="md-div"
+        dangerouslySetInnerHTML={mdToHtml(this.state.siteRes.site.description)}
+      />
     );
   }
 
   landing() {
     return (
-      <div class="card bg-transparent border-secondary">
-        <div class="card-body">
-          <h5>
-            {i18n.t('powered_by')}
-            <svg class="icon mx-2">
-              <use xlinkHref="#icon-mouse">#</use>
-            </svg>
-            <a href={repoUrl}>
-              Lemmy<sup>beta</sup>
+      <>
+        <h5>
+          {i18n.t('powered_by')}
+          <svg class="icon mx-2">
+            <use xlinkHref="#icon-mouse">#</use>
+          </svg>
+          <a href={repoUrl}>
+            Lemmy<sup>beta</sup>
+          </a>
+        </h5>
+        <p class="mb-0">
+          <T i18nKey="landing_0">
+            #
+            <a href="https://en.wikipedia.org/wiki/Social_network_aggregation">
+              #
             </a>
-          </h5>
-          <p class="mb-0">
-            <T i18nKey="landing_0">
+            <a href="https://en.wikipedia.org/wiki/Fediverse">#</a>
+            <br class="big"></br>
+            <code>#</code>
+            <br></br>
+            <b>#</b>
+            <br class="big"></br>
+            <a href={repoUrl}>#</a>
+            <br class="big"></br>
+            <a href="https://www.rust-lang.org">#</a>
+            <a href="https://actix.rs/">#</a>
+            <a href="https://infernojs.org">#</a>
+            <a href="https://www.typescriptlang.org/">#</a>
+            <br class="big"></br>
+            <a href="https://github.com/LemmyNet/lemmy/graphs/contributors?type=a">
               #
-              <a href="https://en.wikipedia.org/wiki/Social_network_aggregation">
-                #
-              </a>
-              <a href="https://en.wikipedia.org/wiki/Fediverse">#</a>
-              <br class="big"></br>
-              <code>#</code>
-              <br></br>
-              <b>#</b>
-              <br class="big"></br>
-              <a href={repoUrl}>#</a>
-              <br class="big"></br>
-              <a href="https://www.rust-lang.org">#</a>
-              <a href="https://actix.rs/">#</a>
-              <a href="https://infernojs.org">#</a>
-              <a href="https://www.typescriptlang.org/">#</a>
-              <br class="big"></br>
-              <a href="https://github.com/LemmyNet/lemmy/graphs/contributors?type=a">
-                #
-              </a>
-            </T>
-          </p>
-        </div>
-      </div>
+            </a>
+          </T>
+        </p>
+      </>
     );
   }
 
   posts() {
     return (
       <div class="main-content-wrapper">
-        {this.selects()}
         {this.state.loading ? (
           <h5>
             <svg class="icon icon-spinner spin">
@@ -443,6 +475,7 @@ export class Main extends Component<any, MainState> {
           </h5>
         ) : (
           <div>
+            {this.selects()}
             {this.listings()}
             {this.paginator()}
           </div>
index 2d432bac6831b5f2c0aabcd86a4fd3b705848e9d..4271d3c169116001d9e09897b83366b77800ab0b 100644 (file)
@@ -312,7 +312,7 @@ export class PostListing extends Component<PostListingProps, PostListingState> {
           <div class="row">
             <div className="col-12">
               <div className="post-title">
-                <h5 className="mb-0 d-inline">
+                <h5 className="mb-1 d-inline-block">
                   {this.props.showBody && post.url ? (
                     <a
                       className="text-body"
@@ -434,7 +434,7 @@ export class PostListing extends Component<PostListingProps, PostListingState> {
           </div>
           <div class="row">
             <div className="details col-12">
-              <ul class="list-inline mb-0 text-muted small">
+              <ul class="list-inline mb-1 text-muted small">
                 <li className="list-inline-item">
                   <span>{i18n.t('by')} </span>
                   <UserListing
@@ -501,9 +501,27 @@ export class PostListing extends Component<PostListingProps, PostListingState> {
                     </li>
                   </>
                 )}
-                <li className="list-inline-item">•</li>
+              </ul>
+              <ul class="list-inline mb-1 text-muted small">
+                <li className="list-inline-item">
+                  <Link
+                    className="text-muted"
+                    title={i18n.t('number_of_comments', {
+                      count: post.number_of_comments,
+                    })}
+                    to={`/post/${post.id}`}
+                  >
+                    <svg class="mr-1 icon icon-inline">
+                      <use xlinkHref="#icon-message-square"></use>
+                    </svg>
+                    {i18n.t('number_of_comments', {
+                      count: post.number_of_comments,
+                    })}
+                  </Link>
+                </li>
                 {this.state.upvotes !== this.state.score && (
                   <>
+                    <li className="list-inline-item">•</li>
                     <span
                       class="unselectable pointer mr-2"
                       data-tippy-content={this.pointsTippy}
@@ -525,23 +543,8 @@ export class PostListing extends Component<PostListingProps, PostListingState> {
                         </span>
                       </li>
                     </span>
-                    <li className="list-inline-item">•</li>
                   </>
                 )}
-                <li className="list-inline-item">
-                  <Link
-                    className="text-muted"
-                    title={i18n.t('number_of_comments', {
-                      count: post.number_of_comments,
-                    })}
-                    to={`/post/${post.id}`}
-                  >
-                    <svg class="mr-1 icon icon-inline">
-                      <use xlinkHref="#icon-message-square"></use>
-                    </svg>
-                    {post.number_of_comments}
-                  </Link>
-                </li>
               </ul>
               {this.props.post.duplicates && (
                 <ul class="list-inline mb-1 small text-muted">
index 4f483b9ad80799b05b517892ddbb3a10a1ef30f9..801fd90db588ea15b5e1cfb53b4e3c6e40533e30 100644 (file)
@@ -232,7 +232,7 @@ export class Post extends Component<any, PostState> {
   sortRadios() {
     return (
       <>
-        <div class="btn-group btn-group-toggle mr-3 mb-2">
+        <div class="btn-group btn-group-toggle flex-wrap mr-3 mb-2">
           <label
             className={`btn btn-outline-secondary pointer ${
               this.state.commentSort === CommentSortType.Hot && 'active'
@@ -286,7 +286,7 @@ export class Post extends Component<any, PostState> {
             />
           </label>
         </div>
-        <div class="btn-group btn-group-toggle mb-2">
+        <div class="btn-group btn-group-toggle flex-wrap mb-2">
           <label
             className={`btn btn-outline-secondary pointer ${
               this.state.commentViewType === CommentViewType.Chat && 'active'
index 751c700790ade738662afc0ec93d303d393730b2..11429fb2e263070a127be26e2926676aeeca3ea6 100644 (file)
@@ -196,14 +196,14 @@ export class Search extends Component<any, SearchState> {
       >
         <input
           type="text"
-          class="form-control mr-2"
+          class="form-control mr-2 mb-2"
           value={this.state.searchText}
           placeholder={`${i18n.t('search')}...`}
           onInput={linkEvent(this, this.handleQChange)}
           required
           minLength={3}
         />
-        <button type="submit" class="btn btn-secondary mr-2">
+        <button type="submit" class="btn btn-secondary mr-2 mb-2">
           {this.state.loading ? (
             <svg class="icon icon-spinner spin">
               <use xlinkHref="#icon-spinner"></use>
@@ -222,7 +222,7 @@ export class Search extends Component<any, SearchState> {
         <select
           value={this.state.type_}
           onChange={linkEvent(this, this.handleTypeChange)}
-          class="custom-select w-auto"
+          class="custom-select w-auto mb-2"
         >
           <option disabled>{i18n.t('type')}</option>
           <option value={SearchType.All}>{i18n.t('all')}</option>
index 8e50865e448f0416c772599e91a0bafd63265702..ddf0bef66f781710d3bd17b9cef2969fdb76c175 100644 (file)
@@ -9,7 +9,7 @@ import {
   UserView,
 } from '../interfaces';
 import { WebSocketService, UserService } from '../services';
-import { mdToHtml, getUnixTime, hostname } from '../utils';
+import { mdToHtml, getUnixTime } from '../utils';
 import { CommunityForm } from './community-form';
 import { UserListing } from './user-listing';
 import { CommunityLink } from './community-link';
@@ -63,208 +63,247 @@ export class Sidebar extends Component<SidebarProps, SidebarState> {
   }
 
   sidebar() {
-    let community = this.props.community;
-    let name_: string, link: string;
-
-    if (community.local) {
-      name_ = community.name;
-      link = `/c/${community.name}`;
-    } else {
-      name_ = `${community.name}@${hostname(community.actor_id)}`;
-      link = community.actor_id;
-    }
     return (
       <div>
+        <div class="card bg-transparent border-secondary mb-3">
+          <div class="card-header bg-transparent border-secondary">
+            {this.communityTitle()}
+            {this.adminButtons()}
+          </div>
+          <div class="card-body">{this.subscribes()}</div>
+        </div>
         <div class="card bg-transparent border-secondary mb-3">
           <div class="card-body">
-            <h5 className="mb-0">
-              <span>{community.title}</span>
-              {community.removed && (
-                <small className="ml-2 text-muted font-italic">
-                  {i18n.t('removed')}
-                </small>
-              )}
-              {community.deleted && (
-                <small className="ml-2 text-muted font-italic">
-                  {i18n.t('deleted')}
-                </small>
-              )}
-            </h5>
-            <CommunityLink community={community} realLink />
-            <ul class="list-inline mb-1 text-muted font-weight-bold">
-              {this.canMod && (
-                <>
-                  <li className="list-inline-item-action">
-                    <span
-                      class="pointer"
-                      onClick={linkEvent(this, this.handleEditClick)}
-                      data-tippy-content={i18n.t('edit')}
-                    >
-                      <svg class="icon icon-inline">
-                        <use xlinkHref="#icon-edit"></use>
-                      </svg>
-                    </span>
-                  </li>
-                  {this.amCreator && (
-                    <li className="list-inline-item-action">
-                      <span
-                        class="pointer"
-                        onClick={linkEvent(this, this.handleDeleteClick)}
-                        data-tippy-content={
-                          !community.deleted
-                            ? i18n.t('delete')
-                            : i18n.t('restore')
-                        }
-                      >
-                        <svg
-                          class={`icon icon-inline ${
-                            community.deleted && 'text-danger'
-                          }`}
-                        >
-                          <use xlinkHref="#icon-trash"></use>
-                        </svg>
-                      </span>
-                    </li>
-                  )}
-                </>
-              )}
-              {this.canAdmin && (
-                <li className="list-inline-item">
-                  {!this.props.community.removed ? (
-                    <span
-                      class="pointer"
-                      onClick={linkEvent(this, this.handleModRemoveShow)}
-                    >
-                      {i18n.t('remove')}
-                    </span>
-                  ) : (
-                    <span
-                      class="pointer"
-                      onClick={linkEvent(this, this.handleModRemoveSubmit)}
-                    >
-                      {i18n.t('restore')}
-                    </span>
-                  )}
-                </li>
-              )}
-            </ul>
-            {this.state.showRemoveDialog && (
-              <form onSubmit={linkEvent(this, this.handleModRemoveSubmit)}>
-                <div class="form-group row">
-                  <label class="col-form-label" htmlFor="remove-reason">
-                    {i18n.t('reason')}
-                  </label>
-                  <input
-                    type="text"
-                    id="remove-reason"
-                    class="form-control mr-2"
-                    placeholder={i18n.t('optional')}
-                    value={this.state.removeReason}
-                    onInput={linkEvent(this, this.handleModRemoveReasonChange)}
-                  />
-                </div>
-                {/* TODO hold off on expires for now */}
-                {/* <div class="form-group row"> */}
-                {/*   <label class="col-form-label">Expires</label> */}
-                {/*   <input type="date" class="form-control mr-2" placeholder={i18n.t('expires')} value={this.state.removeExpires} onInput={linkEvent(this, this.handleModRemoveExpiresChange)} /> */}
-                {/* </div> */}
-                <div class="form-group row">
-                  <button type="submit" class="btn btn-secondary">
-                    {i18n.t('remove_community')}
-                  </button>
-                </div>
-              </form>
-            )}
-            <ul class="my-1 list-inline">
-              {/*
+            {this.description()}
+            {this.badges()}
+            {this.mods()}
+          </div>
+        </div>
+      </div>
+    );
+  }
+
+  communityTitle() {
+    let community = this.props.community;
+    return (
+      <h5 className="mb-2">
+        <span>{community.title}</span>
+        {community.removed && (
+          <small className="ml-2 text-muted font-italic">
+            {i18n.t('removed')}
+          </small>
+        )}
+        {community.deleted && (
+          <small className="ml-2 text-muted font-italic">
+            {i18n.t('deleted')}
+          </small>
+        )}
+        {community.nsfw && (
+          <small className="ml-2 text-muted font-italic">
+            {i18n.t('nsfw')}
+          </small>
+        )}
+      </h5>
+    );
+  }
+
+  badges() {
+    let community = this.props.community;
+    return (
+      <ul class="my-1 list-inline">
+        {/*
               <li className="list-inline-item badge badge-light">
                 {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>
-              <li className="list-inline-item badge badge-light">
-                {i18n.t('number_of_posts', {
-                  count: community.number_of_posts,
-                })}
-              </li>
-              <li className="list-inline-item badge badge-light">
-                {i18n.t('number_of_comments', {
-                  count: community.number_of_comments,
-                })}
-              </li>
-              <li className="list-inline-item">
-                <Link className="badge badge-light" to="/communities">
-                  {community.category_name}
-                </Link>
-              </li>
-              <li className="list-inline-item">
-                <Link
-                  className="badge badge-light"
-                  to={`/modlog/community/${this.props.community.id}`}
+        <li className="list-inline-item badge badge-light">
+          {i18n.t('number_of_subscribers', {
+            count: community.number_of_subscribers,
+          })}
+        </li>
+        <li className="list-inline-item badge badge-light">
+          {i18n.t('number_of_posts', {
+            count: community.number_of_posts,
+          })}
+        </li>
+        <li className="list-inline-item badge badge-light">
+          {i18n.t('number_of_comments', {
+            count: community.number_of_comments,
+          })}
+        </li>
+        <li className="list-inline-item">
+          <Link className="badge badge-light" to="/communities">
+            {community.category_name}
+          </Link>
+        </li>
+        <li className="list-inline-item">
+          <Link
+            className="badge badge-light"
+            to={`/modlog/community/${this.props.community.id}`}
+          >
+            {i18n.t('modlog')}
+          </Link>
+        </li>
+        <li className="list-inline-item badge badge-light">
+          <CommunityLink community={community} realLink />
+        </li>
+      </ul>
+    );
+  }
+
+  mods() {
+    return (
+      <ul class="list-inline small">
+        <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,
+                avatar: mod.avatar,
+                id: mod.user_id,
+                local: mod.user_local,
+                actor_id: mod.user_actor_id,
+              }}
+            />
+          </li>
+        ))}
+      </ul>
+    );
+  }
+
+  subscribes() {
+    let community = this.props.community;
+    return (
+      <div class="d-flex flex-wrap">
+        <Link
+          class={`btn btn-secondary flex-fill mr-2 mb-2 ${
+            community.deleted || community.removed ? 'no-click' : ''
+          }`}
+          to={`/create_post?community=${community.name}`}
+        >
+          {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>
+        ) : (
+          <a
+            class="btn btn-secondary flex-fill mb-2"
+            href="#"
+            onClick={linkEvent(community.id, this.handleSubscribe)}
+          >
+            {i18n.t('subscribe')}
+          </a>
+        )}
+      </div>
+    );
+  }
+
+  description() {
+    let community = this.props.community;
+    return (
+      community.description && (
+        <div
+          className="md-div"
+          dangerouslySetInnerHTML={mdToHtml(community.description)}
+        />
+      )
+    );
+  }
+
+  adminButtons() {
+    let community = this.props.community;
+    return (
+      <>
+        <ul class="list-inline mb-1 text-muted font-weight-bold">
+          {this.canMod && (
+            <>
+              <li className="list-inline-item-action">
+                <span
+                  class="pointer"
+                  onClick={linkEvent(this, this.handleEditClick)}
+                  data-tippy-content={i18n.t('edit')}
                 >
-                  {i18n.t('modlog')}
-                </Link>
+                  <svg class="icon icon-inline">
+                    <use xlinkHref="#icon-edit"></use>
+                  </svg>
+                </span>
               </li>
-            </ul>
-            <ul class="list-inline small">
-              <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,
-                      avatar: mod.avatar,
-                      id: mod.user_id,
-                      local: mod.user_local,
-                      actor_id: mod.user_actor_id,
-                    }}
-                  />
+              {this.amCreator && (
+                <li className="list-inline-item-action">
+                  <span
+                    class="pointer"
+                    onClick={linkEvent(this, this.handleDeleteClick)}
+                    data-tippy-content={
+                      !community.deleted ? i18n.t('delete') : i18n.t('restore')
+                    }
+                  >
+                    <svg
+                      class={`icon icon-inline ${
+                        community.deleted && 'text-danger'
+                      }`}
+                    >
+                      <use xlinkHref="#icon-trash"></use>
+                    </svg>
+                  </span>
                 </li>
-              ))}
-            </ul>
-            {/* TODO the to= needs to be able to handle community_ids as well, since they're federated */}
-            <Link
-              class={`btn btn-secondary btn-block mb-3 ${
-                (community.deleted || community.removed) && 'no-click'
-              }`}
-              to={`/create_post?community=${community.name}`}
-            >
-              {i18n.t('create_a_post')}
-            </Link>
-            <div>
-              {community.subscribed ? (
-                <button
-                  class="btn btn-secondary btn-block"
-                  onClick={linkEvent(community.id, this.handleUnsubscribe)}
+              )}
+            </>
+          )}
+          {this.canAdmin && (
+            <li className="list-inline-item">
+              {!this.props.community.removed ? (
+                <span
+                  class="pointer"
+                  onClick={linkEvent(this, this.handleModRemoveShow)}
                 >
-                  {i18n.t('unsubscribe')}
-                </button>
+                  {i18n.t('remove')}
+                </span>
               ) : (
-                <button
-                  class="btn btn-secondary btn-block"
-                  onClick={linkEvent(community.id, this.handleSubscribe)}
+                <span
+                  class="pointer"
+                  onClick={linkEvent(this, this.handleModRemoveSubmit)}
                 >
-                  {i18n.t('subscribe')}
-                </button>
+                  {i18n.t('restore')}
+                </span>
               )}
-            </div>
-          </div>
-        </div>
-        {community.description && (
-          <div class="card bg-transparent border-secondary">
-            <div class="card-body">
-              <div
-                className="md-div"
-                dangerouslySetInnerHTML={mdToHtml(community.description)}
+            </li>
+          )}
+        </ul>
+        {this.state.showRemoveDialog && (
+          <form onSubmit={linkEvent(this, this.handleModRemoveSubmit)}>
+            <div class="form-group row">
+              <label class="col-form-label" htmlFor="remove-reason">
+                {i18n.t('reason')}
+              </label>
+              <input
+                type="text"
+                id="remove-reason"
+                class="form-control mr-2"
+                placeholder={i18n.t('optional')}
+                value={this.state.removeReason}
+                onInput={linkEvent(this, this.handleModRemoveReasonChange)}
               />
             </div>
-          </div>
+            {/* TODO hold off on expires for now */}
+            {/* <div class="form-group row"> */}
+            {/*   <label class="col-form-label">Expires</label> */}
+            {/*   <input type="date" class="form-control mr-2" placeholder={i18n.t('expires')} value={this.state.removeExpires} onInput={linkEvent(this, this.handleModRemoveExpiresChange)} /> */}
+            {/* </div> */}
+            <div class="form-group row">
+              <button type="submit" class="btn btn-secondary">
+                {i18n.t('remove_community')}
+              </button>
+            </div>
+          </form>
         )}
-      </div>
+      </>
     );
   }
 
@@ -293,6 +332,7 @@ export class Sidebar extends Component<SidebarProps, SidebarState> {
   }
 
   handleUnsubscribe(communityId: number) {
+    event.preventDefault();
     let form: FollowCommunityForm = {
       community_id: communityId,
       follow: false,
@@ -301,6 +341,7 @@ export class Sidebar extends Component<SidebarProps, SidebarState> {
   }
 
   handleSubscribe(communityId: number) {
+    event.preventDefault();
     let form: FollowCommunityForm = {
       community_id: communityId,
       follow: true,
index 23069d3e3c468b63acb90149fb27078ca0961b33..12dcb4cb6e629722a5807f88f26aba157b1bef7d 100644 (file)
@@ -35,7 +35,7 @@ export class SortSelect extends Component<SortSelectProps, SortSelectState> {
         <select
           value={this.state.sort}
           onChange={linkEvent(this, this.handleSortChange)}
-          class="custom-select w-auto mr-2"
+          class="custom-select w-auto mr-2 mb-2"
         >
           <option disabled>{i18n.t('sort_type')}</option>
           {!this.props.hideHot && (
index 7a706235f4d26c817fbacb8ea53b8f2fa65b0973..03b8b8a4f3fa4cb28a74ccbe5cc23214408f52d3 100644 (file)
@@ -274,7 +274,7 @@ export class User extends Component<any, UserState> {
 
   viewRadios() {
     return (
-      <div class="btn-group btn-group-toggle">
+      <div class="btn-group btn-group-toggle flex-wrap mb-2">
         <label
           className={`btn btn-outline-secondary pointer 
             ${this.state.view == UserDetailsView.Overview && 'active'}