]> Untitled Git - lemmy.git/commitdiff
Refactoring thumbnails. Fixes #564
authorDessalines <tyhou13@gmx.com>
Sat, 29 Feb 2020 18:03:41 +0000 (13:03 -0500)
committerDessalines <tyhou13@gmx.com>
Sat, 29 Feb 2020 18:03:41 +0000 (13:03 -0500)
- Adding a default discussion thumbnail
- Adding a cropping max-height, and consistent width.
- Getting rid of hover overlays, in favor of top right content-type icon.

ui/assets/css/main.css
ui/src/components/post-listing.tsx
ui/src/components/symbols.tsx

index 048f687ec1ce0a5c97dece0a6e85a70d4ee62b12..fd51c59484eef0f1114568ad30ebce17f56da49e 100644 (file)
@@ -131,8 +131,13 @@ blockquote {
 }
 
 .thumbnail {
-  max-height: 62px;
-  max-width: 400px;
+  object-fit: cover;
+  max-height: 80px;
+  width: 100%;
+}
+
+svg.thumbnail {
+  height: 40px;
 }
 
 .no-s-hows {
@@ -188,6 +193,16 @@ hr {
   border: unset;
 }
 
+.mini-overlay {
+  position: absolute;
+  top: 0;
+  right: 0;
+  padding: 2px;
+  background: rgba(0,0,0,.4);
+  border-bottom-left-radius: 0.25rem !important;
+  border-top-right-radius: 0.25rem !important;
+}
+
 .link-overlay:hover {
   transition: .1s;
   opacity: 1;
index a77021584e2da6a660500de66596fda5b836c30f..90a8b7a11d62b011e7941e816a23994bf7813dda 100644 (file)
@@ -121,9 +121,12 @@ export class PostListing extends Component<PostListingProps, PostListingState> {
 
   render() {
     return (
-      <div class="row">
+      <div class="">
         {!this.state.showEdit ? (
-          this.listing()
+          <>
+            {this.listing()}
+            {this.body()}
+          </>
         ) : (
           <div class="col-12">
             <PostForm
@@ -137,23 +140,105 @@ export class PostListing extends Component<PostListingProps, PostListingState> {
     );
   }
 
-  imgThumbnail() {
+  body() {
+    return (
+      <div class="row">
+        <div class="col-12">
+          {this.state.url && this.props.showBody && this.state.iframely && (
+            <IFramelyCard iframely={this.state.iframely} />
+          )}
+          {this.props.showBody && this.props.post.body && (
+            <>
+              {this.state.viewSource ? (
+                <pre>{this.props.post.body}</pre>
+              ) : (
+                <div
+                  className="md-div"
+                  dangerouslySetInnerHTML={mdToHtml(this.props.post.body)}
+                />
+              )}
+            </>
+          )}
+        </div>
+      </div>
+    );
+  }
+
+  imgThumb() {
     let post = this.props.post;
     return (
-      <object
+      <img
         className={`img-fluid thumbnail rounded ${(post.nsfw ||
           post.community_nsfw) &&
           'img-blur'}`}
-        data={imageThumbnailer(this.state.thumbnail)}
-      ></object>
+        src={imageThumbnailer(this.state.thumbnail)}
+      />
     );
   }
 
+  thumbnail() {
+    let post = this.props.post;
+
+    if (isImage(this.state.url)) {
+      return (
+        <span
+          class="text-body pointer"
+          title={i18n.t('expand_here')}
+          onClick={linkEvent(this, this.handleImageExpandClick)}
+        >
+          {this.imgThumb()}
+          <svg class="icon mini-overlay">
+            <use xlinkHref="#icon-image"></use>
+          </svg>
+        </span>
+      );
+    } else if (this.state.thumbnail) {
+      return (
+        <a
+          className="text-body"
+          href={this.state.url}
+          target="_blank"
+          title={this.state.url}
+        >
+          {this.imgThumb()}
+          <svg class="icon mini-overlay">
+            <use xlinkHref="#icon-external-link"></use>
+          </svg>
+        </a>
+      );
+    } else if (this.state.url && !this.state.thumbnail) {
+      return (
+        <a
+          className="text-body"
+          href={this.state.url}
+          target="_blank"
+          title={this.state.url}
+        >
+          <svg class="icon thumbnail">
+            <use xlinkHref="#icon-external-link"></use>
+          </svg>
+        </a>
+      );
+    } else {
+      return (
+        <Link
+          className="text-body"
+          to={`/post/${post.id}`}
+          title={i18n.t('comments')}
+        >
+          <svg class="icon thumbnail">
+            <use xlinkHref="#icon-bubble2"></use>
+          </svg>
+        </Link>
+      );
+    }
+  }
+
   listing() {
     let post = this.props.post;
     return (
-      <div class="listing col-12">
-        <div className={`vote-bar mr-2 float-left small text-center`}>
+      <div class="row">
+        <div className={`vote-bar col-1 pr-0 small text-center`}>
           <button
             className={`vote-animate btn btn-link p-0 ${
               this.state.my_vote == 1 ? 'text-info' : 'text-muted'
@@ -178,32 +263,9 @@ export class PostListing extends Component<PostListingProps, PostListingState> {
             </button>
           )}
         </div>
-        {this.state.thumbnail && !this.state.imageExpanded && (
-          <div class="mx-2 mt-1 float-left position-relative">
-            {isImage(this.state.url) ? (
-              <span
-                class="text-body pointer"
-                title={i18n.t('expand_here')}
-                onClick={linkEvent(this, this.handleImageExpandClick)}
-              >
-                {this.imgThumbnail()}
-                <svg class="icon thumbnail rounded link-overlay hover-link">
-                  <use xlinkHref="#icon-image"></use>
-                </svg>
-              </span>
-            ) : (
-              <a
-                className="text-body"
-                href={this.state.url}
-                target="_blank"
-                title={this.state.url}
-              >
-                {this.imgThumbnail()}
-                <svg class="icon thumbnail rounded link-overlay hover-link">
-                  <use xlinkHref="#icon-external-link"></use>
-                </svg>
-              </a>
-            )}
+        {!this.state.imageExpanded && (
+          <div class="col-2 pr-0 mt-1">
+            <div class="position-relative">{this.thumbnail()}</div>
           </div>
         )}
         {this.state.url && isVideo(this.state.url) && (
@@ -212,501 +274,505 @@ export class PostListing extends Component<PostListingProps, PostListingState> {
             muted
             loop
             controls
-            class="mx-2 mt-1 float-left"
+            class="col-2 pr-0 mt-1"
             height="100"
             width="150"
           >
             <source src={this.state.url} type="video/mp4" />
           </video>
         )}
-        <div className="ml-4">
-          <div className="post-title">
-            <h5 className="mb-0 d-inline">
-              {this.props.showBody && this.state.url ? (
-                <a
-                  className="text-body"
-                  href={this.state.url}
-                  target="_blank"
-                  title={this.state.url}
-                >
-                  {post.name}
-                </a>
-              ) : (
-                <Link
-                  className="text-body"
-                  to={`/post/${post.id}`}
-                  title={i18n.t('comments')}
-                >
-                  {post.name}
-                </Link>
-              )}
-            </h5>
-            {this.state.url &&
-              !(
-                new URL(this.state.url).hostname == window.location.hostname
-              ) && (
-                <small class="d-inline-block">
-                  <a
-                    className="ml-2 text-muted font-italic"
-                    href={this.state.url}
-                    target="_blank"
-                    title={this.state.url}
-                  >
-                    {new URL(this.state.url).hostname}
-                    <svg class="ml-1 icon">
-                      <use xlinkHref="#icon-external-link"></use>
-                    </svg>
-                  </a>
-                </small>
-              )}
-            {this.state.thumbnail && (
-              <>
-                {!this.state.imageExpanded ? (
-                  <span
-                    class="text-monospace pointer ml-2 text-muted small"
-                    title={i18n.t('expand_here')}
-                    onClick={linkEvent(this, this.handleImageExpandClick)}
-                  >
-                    [+]
-                  </span>
-                ) : (
-                  <span>
-                    <span
-                      class="text-monospace pointer ml-2 text-muted small"
-                      onClick={linkEvent(this, this.handleImageExpandClick)}
+        <div class="col-9">
+          <div class="row">
+            <div className="col-12">
+              <div className="post-title">
+                <h5 className="mb-0 d-inline">
+                  {this.props.showBody && this.state.url ? (
+                    <a
+                      className="text-body"
+                      href={this.state.url}
+                      target="_blank"
+                      title={this.state.url}
                     >
-                      [-]
-                    </span>
-                    <div>
+                      {post.name}
+                    </a>
+                  ) : (
+                    <Link
+                      className="text-body"
+                      to={`/post/${post.id}`}
+                      title={i18n.t('comments')}
+                    >
+                      {post.name}
+                    </Link>
+                  )}
+                </h5>
+                {this.state.url &&
+                  !(
+                    new URL(this.state.url).hostname == window.location.hostname
+                  ) && (
+                    <small class="d-inline-block">
+                      <a
+                        className="ml-2 text-muted font-italic"
+                        href={this.state.url}
+                        target="_blank"
+                        title={this.state.url}
+                      >
+                        {new URL(this.state.url).hostname}
+                        <svg class="ml-1 icon">
+                          <use xlinkHref="#icon-external-link"></use>
+                        </svg>
+                      </a>
+                    </small>
+                  )}
+                {this.state.thumbnail && (
+                  <>
+                    {!this.state.imageExpanded ? (
                       <span
-                        class="pointer"
+                        class="text-monospace pointer ml-2 text-muted small"
+                        title={i18n.t('expand_here')}
                         onClick={linkEvent(this, this.handleImageExpandClick)}
                       >
-                        <object
-                          class="img-fluid img-expanded"
-                          data={this.state.thumbnail}
+                        [+]
+                      </span>
+                    ) : (
+                      <span>
+                        <span
+                          class="text-monospace pointer ml-2 text-muted small"
+                          onClick={linkEvent(this, this.handleImageExpandClick)}
                         >
-                          <svg class="icon thumbnail rounded placeholder">
-                            <use xlinkHref="#icon-external-link"></use>
-                          </svg>
-                        </object>
+                          [-]
+                        </span>
+                        <div>
+                          <span
+                            class="pointer"
+                            onClick={linkEvent(
+                              this,
+                              this.handleImageExpandClick
+                            )}
+                          >
+                            <img
+                              class="img-fluid img-expanded"
+                              src={this.state.thumbnail}
+                            />
+                          </span>
+                        </div>
                       </span>
-                    </div>
-                  </span>
+                    )}
+                  </>
                 )}
-              </>
-            )}
-            {post.removed && (
-              <small className="ml-2 text-muted font-italic">
-                {i18n.t('removed')}
-              </small>
-            )}
-            {post.deleted && (
-              <small className="ml-2 text-muted font-italic">
-                {i18n.t('deleted')}
-              </small>
-            )}
-            {post.locked && (
-              <small className="ml-2 text-muted font-italic">
-                {i18n.t('locked')}
-              </small>
-            )}
-            {post.stickied && (
-              <small className="ml-2 text-muted font-italic">
-                {i18n.t('stickied')}
-              </small>
-            )}
-            {post.nsfw && (
-              <small className="ml-2 text-muted font-italic">
-                {i18n.t('nsfw')}
-              </small>
-            )}
-          </div>
-        </div>
-        <div className="details ml-4">
-          <ul class="list-inline mb-0 text-muted small">
-            <li className="list-inline-item">
-              <span>{i18n.t('by')} </span>
-              <Link className="text-info" to={`/u/${post.creator_name}`}>
-                {post.creator_avatar && showAvatars() && (
-                  <img
-                    height="32"
-                    width="32"
-                    src={pictshareAvatarThumbnail(post.creator_avatar)}
-                    class="rounded-circle mr-1"
-                  />
+                {post.removed && (
+                  <small className="ml-2 text-muted font-italic">
+                    {i18n.t('removed')}
+                  </small>
                 )}
-                <span>{post.creator_name}</span>
-              </Link>
-              {this.isMod && (
-                <span className="mx-1 badge badge-light">{i18n.t('mod')}</span>
-              )}
-              {this.isAdmin && (
-                <span className="mx-1 badge badge-light">
-                  {i18n.t('admin')}
-                </span>
-              )}
-              {(post.banned_from_community || post.banned) && (
-                <span className="mx-1 badge badge-danger">
-                  {i18n.t('banned')}
-                </span>
-              )}
-              {this.props.showCommunity && (
-                <span>
-                  <span> {i18n.t('to')} </span>
-                  <Link to={`/c/${post.community_name}`}>
-                    {post.community_name}
+                {post.deleted && (
+                  <small className="ml-2 text-muted font-italic">
+                    {i18n.t('deleted')}
+                  </small>
+                )}
+                {post.locked && (
+                  <small className="ml-2 text-muted font-italic">
+                    {i18n.t('locked')}
+                  </small>
+                )}
+                {post.stickied && (
+                  <small className="ml-2 text-muted font-italic">
+                    {i18n.t('stickied')}
+                  </small>
+                )}
+                {post.nsfw && (
+                  <small className="ml-2 text-muted font-italic">
+                    {i18n.t('nsfw')}
+                  </small>
+                )}
+              </div>
+            </div>
+          </div>
+          <div class="row">
+            <div className="details col-12">
+              <ul class="list-inline mb-0 text-muted small">
+                <li className="list-inline-item">
+                  <span>{i18n.t('by')} </span>
+                  <Link className="text-info" to={`/u/${post.creator_name}`}>
+                    {post.creator_avatar && showAvatars() && (
+                      <img
+                        height="32"
+                        width="32"
+                        src={pictshareAvatarThumbnail(post.creator_avatar)}
+                        class="rounded-circle mr-1"
+                      />
+                    )}
+                    <span>{post.creator_name}</span>
                   </Link>
-                </span>
-              )}
-            </li>
-            <li className="list-inline-item">
-              <span>
-                <MomentTime data={post} />
-              </span>
-            </li>
-            <li className="list-inline-item">
-              <span>
-                (<span className="text-info">+{this.state.upvotes}</span>
-                <span> | </span>
-                <span className="text-danger">-{this.state.downvotes}</span>
-                <span>) </span>
-              </span>
-            </li>
-            <li className="list-inline-item">
-              <Link className="text-muted" to={`/post/${post.id}`}>
-                {i18n.t('number_of_comments', {
-                  count: post.number_of_comments,
-                })}
-              </Link>
-            </li>
-          </ul>
-          <ul class="list-inline mb-1 text-muted small">
-            {this.props.post.duplicates && (
-              <>
-                <li className="list-inline-item mr-2">
-                  {i18n.t('cross_posted_to')}
-                </li>
-                {this.props.post.duplicates.map(post => (
-                  <li className="list-inline-item mr-2">
-                    <Link to={`/post/${post.id}`}>{post.community_name}</Link>
-                  </li>
-                ))}
-              </>
-            )}
-          </ul>
-          <ul class="list-inline mb-1 text-muted small font-weight-bold">
-            {UserService.Instance.user && (
-              <>
-                {this.props.showBody && (
-                  <>
-                    <li className="list-inline-item mr-2">
-                      <span
-                        class="pointer"
-                        onClick={linkEvent(this, this.handleSavePostClick)}
-                      >
-                        {post.saved ? i18n.t('unsave') : i18n.t('save')}
-                      </span>
-                    </li>
-                    <li className="list-inline-item mr-2">
-                      <Link
-                        className="text-muted"
-                        to={`/create_post${this.crossPostParams}`}
-                      >
-                        {i18n.t('cross_post')}
+                  {this.isMod && (
+                    <span className="mx-1 badge badge-light">
+                      {i18n.t('mod')}
+                    </span>
+                  )}
+                  {this.isAdmin && (
+                    <span className="mx-1 badge badge-light">
+                      {i18n.t('admin')}
+                    </span>
+                  )}
+                  {(post.banned_from_community || post.banned) && (
+                    <span className="mx-1 badge badge-danger">
+                      {i18n.t('banned')}
+                    </span>
+                  )}
+                  {this.props.showCommunity && (
+                    <span>
+                      <span> {i18n.t('to')} </span>
+                      <Link to={`/c/${post.community_name}`}>
+                        {post.community_name}
                       </Link>
-                    </li>
-                  </>
-                )}
-                {this.myPost && this.props.showBody && (
+                    </span>
+                  )}
+                </li>
+                <li className="list-inline-item">
+                  <span>
+                    <MomentTime data={post} />
+                  </span>
+                </li>
+                <li className="list-inline-item">
+                  <span>
+                    (<span className="text-info">+{this.state.upvotes}</span>
+                    <span> | </span>
+                    <span className="text-danger">-{this.state.downvotes}</span>
+                    <span>) </span>
+                  </span>
+                </li>
+                <li className="list-inline-item">
+                  <Link className="text-muted" to={`/post/${post.id}`}>
+                    {i18n.t('number_of_comments', {
+                      count: post.number_of_comments,
+                    })}
+                  </Link>
+                </li>
+              </ul>
+              <ul class="list-inline mb-1 text-muted small">
+                {this.props.post.duplicates && (
                   <>
-                    <li className="list-inline-item">
-                      <span
-                        class="pointer"
-                        onClick={linkEvent(this, this.handleEditClick)}
-                      >
-                        {i18n.t('edit')}
-                      </span>
-                    </li>
                     <li className="list-inline-item mr-2">
-                      <span
-                        class="pointer"
-                        onClick={linkEvent(this, this.handleDeleteClick)}
-                      >
-                        {!post.deleted ? i18n.t('delete') : i18n.t('restore')}
-                      </span>
+                      {i18n.t('cross_posted_to')}
                     </li>
+                    {this.props.post.duplicates.map(post => (
+                      <li className="list-inline-item mr-2">
+                        <Link to={`/post/${post.id}`}>
+                          {post.community_name}
+                        </Link>
+                      </li>
+                    ))}
                   </>
                 )}
-                {this.canModOnSelf && (
+              </ul>
+              <ul class="list-inline mb-1 text-muted small font-weight-bold">
+                {UserService.Instance.user && (
                   <>
-                    <li className="list-inline-item">
-                      <span
-                        class="pointer"
-                        onClick={linkEvent(this, this.handleModLock)}
-                      >
-                        {post.locked ? i18n.t('unlock') : i18n.t('lock')}
-                      </span>
-                    </li>
-                    <li className="list-inline-item">
-                      <span
-                        class="pointer"
-                        onClick={linkEvent(this, this.handleModSticky)}
-                      >
-                        {post.stickied ? i18n.t('unsticky') : i18n.t('sticky')}
-                      </span>
-                    </li>
-                  </>
-                )}
-                {/* Mods can ban from community, and appoint as mods to community */}
-                {(this.canMod || this.canAdmin) && (
-                  <li className="list-inline-item">
-                    {!post.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>
+                    {this.props.showBody && (
+                      <>
+                        <li className="list-inline-item mr-2">
+                          <span
+                            class="pointer"
+                            onClick={linkEvent(this, this.handleSavePostClick)}
+                          >
+                            {post.saved ? i18n.t('unsave') : i18n.t('save')}
+                          </span>
+                        </li>
+                        <li className="list-inline-item mr-2">
+                          <Link
+                            className="text-muted"
+                            to={`/create_post${this.crossPostParams}`}
+                          >
+                            {i18n.t('cross_post')}
+                          </Link>
+                        </li>
+                      </>
                     )}
-                  </li>
-                )}
-                {this.canMod && (
-                  <>
-                    {!this.isMod && (
+                    {this.myPost && this.props.showBody && (
+                      <>
+                        <li className="list-inline-item">
+                          <span
+                            class="pointer"
+                            onClick={linkEvent(this, this.handleEditClick)}
+                          >
+                            {i18n.t('edit')}
+                          </span>
+                        </li>
+                        <li className="list-inline-item mr-2">
+                          <span
+                            class="pointer"
+                            onClick={linkEvent(this, this.handleDeleteClick)}
+                          >
+                            {!post.deleted
+                              ? i18n.t('delete')
+                              : i18n.t('restore')}
+                          </span>
+                        </li>
+                      </>
+                    )}
+                    {this.canModOnSelf && (
+                      <>
+                        <li className="list-inline-item">
+                          <span
+                            class="pointer"
+                            onClick={linkEvent(this, this.handleModLock)}
+                          >
+                            {post.locked ? i18n.t('unlock') : i18n.t('lock')}
+                          </span>
+                        </li>
+                        <li className="list-inline-item">
+                          <span
+                            class="pointer"
+                            onClick={linkEvent(this, this.handleModSticky)}
+                          >
+                            {post.stickied
+                              ? i18n.t('unsticky')
+                              : i18n.t('sticky')}
+                          </span>
+                        </li>
+                      </>
+                    )}
+                    {/* Mods can ban from community, and appoint as mods to community */}
+                    {(this.canMod || this.canAdmin) && (
                       <li className="list-inline-item">
-                        {!post.banned_from_community ? (
+                        {!post.removed ? (
                           <span
                             class="pointer"
-                            onClick={linkEvent(
-                              this,
-                              this.handleModBanFromCommunityShow
-                            )}
+                            onClick={linkEvent(this, this.handleModRemoveShow)}
                           >
-                            {i18n.t('ban')}
+                            {i18n.t('remove')}
                           </span>
                         ) : (
                           <span
                             class="pointer"
                             onClick={linkEvent(
                               this,
-                              this.handleModBanFromCommunitySubmit
+                              this.handleModRemoveSubmit
                             )}
                           >
-                            {i18n.t('unban')}
+                            {i18n.t('restore')}
                           </span>
                         )}
                       </li>
                     )}
-                    {!post.banned_from_community && (
-                      <li className="list-inline-item">
-                        <span
-                          class="pointer"
-                          onClick={linkEvent(
-                            this,
-                            this.handleAddModToCommunity
-                          )}
-                        >
-                          {this.isMod
-                            ? i18n.t('remove_as_mod')
-                            : i18n.t('appoint_as_mod')}
-                        </span>
-                      </li>
-                    )}
-                  </>
-                )}
-                {/* Community creators and admins can transfer community to another mod */}
-                {(this.amCommunityCreator || this.canAdmin) && this.isMod && (
-                  <li className="list-inline-item">
-                    {!this.state.showConfirmTransferCommunity ? (
-                      <span
-                        class="pointer"
-                        onClick={linkEvent(
-                          this,
-                          this.handleShowConfirmTransferCommunity
-                        )}
-                      >
-                        {i18n.t('transfer_community')}
-                      </span>
-                    ) : (
+                    {this.canMod && (
                       <>
-                        <span class="d-inline-block mr-1">
-                          {i18n.t('are_you_sure')}
-                        </span>
-                        <span
-                          class="pointer d-inline-block mr-1"
-                          onClick={linkEvent(
-                            this,
-                            this.handleTransferCommunity
-                          )}
-                        >
-                          {i18n.t('yes')}
-                        </span>
-                        <span
-                          class="pointer d-inline-block"
-                          onClick={linkEvent(
-                            this,
-                            this.handleCancelShowConfirmTransferCommunity
-                          )}
-                        >
-                          {i18n.t('no')}
-                        </span>
+                        {!this.isMod && (
+                          <li className="list-inline-item">
+                            {!post.banned_from_community ? (
+                              <span
+                                class="pointer"
+                                onClick={linkEvent(
+                                  this,
+                                  this.handleModBanFromCommunityShow
+                                )}
+                              >
+                                {i18n.t('ban')}
+                              </span>
+                            ) : (
+                              <span
+                                class="pointer"
+                                onClick={linkEvent(
+                                  this,
+                                  this.handleModBanFromCommunitySubmit
+                                )}
+                              >
+                                {i18n.t('unban')}
+                              </span>
+                            )}
+                          </li>
+                        )}
+                        {!post.banned_from_community && (
+                          <li className="list-inline-item">
+                            <span
+                              class="pointer"
+                              onClick={linkEvent(
+                                this,
+                                this.handleAddModToCommunity
+                              )}
+                            >
+                              {this.isMod
+                                ? i18n.t('remove_as_mod')
+                                : i18n.t('appoint_as_mod')}
+                            </span>
+                          </li>
+                        )}
                       </>
                     )}
-                  </li>
-                )}
-                {/* Admins can ban from all, and appoint other admins */}
-                {this.canAdmin && (
-                  <>
-                    {!this.isAdmin && (
+                    {/* Community creators and admins can transfer community to another mod */}
+                    {(this.amCommunityCreator || this.canAdmin) && this.isMod && (
                       <li className="list-inline-item">
-                        {!post.banned ? (
+                        {!this.state.showConfirmTransferCommunity ? (
                           <span
                             class="pointer"
-                            onClick={linkEvent(this, this.handleModBanShow)}
+                            onClick={linkEvent(
+                              this,
+                              this.handleShowConfirmTransferCommunity
+                            )}
                           >
-                            {i18n.t('ban_from_site')}
+                            {i18n.t('transfer_community')}
                           </span>
                         ) : (
+                          <>
+                            <span class="d-inline-block mr-1">
+                              {i18n.t('are_you_sure')}
+                            </span>
+                            <span
+                              class="pointer d-inline-block mr-1"
+                              onClick={linkEvent(
+                                this,
+                                this.handleTransferCommunity
+                              )}
+                            >
+                              {i18n.t('yes')}
+                            </span>
+                            <span
+                              class="pointer d-inline-block"
+                              onClick={linkEvent(
+                                this,
+                                this.handleCancelShowConfirmTransferCommunity
+                              )}
+                            >
+                              {i18n.t('no')}
+                            </span>
+                          </>
+                        )}
+                      </li>
+                    )}
+                    {/* Admins can ban from all, and appoint other admins */}
+                    {this.canAdmin && (
+                      <>
+                        {!this.isAdmin && (
+                          <li className="list-inline-item">
+                            {!post.banned ? (
+                              <span
+                                class="pointer"
+                                onClick={linkEvent(this, this.handleModBanShow)}
+                              >
+                                {i18n.t('ban_from_site')}
+                              </span>
+                            ) : (
+                              <span
+                                class="pointer"
+                                onClick={linkEvent(
+                                  this,
+                                  this.handleModBanSubmit
+                                )}
+                              >
+                                {i18n.t('unban_from_site')}
+                              </span>
+                            )}
+                          </li>
+                        )}
+                        {!post.banned && (
+                          <li className="list-inline-item">
+                            <span
+                              class="pointer"
+                              onClick={linkEvent(this, this.handleAddAdmin)}
+                            >
+                              {this.isAdmin
+                                ? i18n.t('remove_as_admin')
+                                : i18n.t('appoint_as_admin')}
+                            </span>
+                          </li>
+                        )}
+                      </>
+                    )}
+                    {/* Site Creator can transfer to another admin */}
+                    {this.amSiteCreator && this.isAdmin && (
+                      <li className="list-inline-item">
+                        {!this.state.showConfirmTransferSite ? (
                           <span
                             class="pointer"
-                            onClick={linkEvent(this, this.handleModBanSubmit)}
+                            onClick={linkEvent(
+                              this,
+                              this.handleShowConfirmTransferSite
+                            )}
                           >
-                            {i18n.t('unban_from_site')}
+                            {i18n.t('transfer_site')}
                           </span>
+                        ) : (
+                          <>
+                            <span class="d-inline-block mr-1">
+                              {i18n.t('are_you_sure')}
+                            </span>
+                            <span
+                              class="pointer d-inline-block mr-1"
+                              onClick={linkEvent(this, this.handleTransferSite)}
+                            >
+                              {i18n.t('yes')}
+                            </span>
+                            <span
+                              class="pointer d-inline-block"
+                              onClick={linkEvent(
+                                this,
+                                this.handleCancelShowConfirmTransferSite
+                              )}
+                            >
+                              {i18n.t('no')}
+                            </span>
+                          </>
                         )}
                       </li>
                     )}
-                    {!post.banned && (
-                      <li className="list-inline-item">
-                        <span
-                          class="pointer"
-                          onClick={linkEvent(this, this.handleAddAdmin)}
-                        >
-                          {this.isAdmin
-                            ? i18n.t('remove_as_admin')
-                            : i18n.t('appoint_as_admin')}
-                        </span>
-                      </li>
-                    )}
                   </>
                 )}
-                {/* Site Creator can transfer to another admin */}
-                {this.amSiteCreator && this.isAdmin && (
+                {this.props.showBody && post.body && (
                   <li className="list-inline-item">
-                    {!this.state.showConfirmTransferSite ? (
-                      <span
-                        class="pointer"
-                        onClick={linkEvent(
-                          this,
-                          this.handleShowConfirmTransferSite
-                        )}
-                      >
-                        {i18n.t('transfer_site')}
-                      </span>
-                    ) : (
-                      <>
-                        <span class="d-inline-block mr-1">
-                          {i18n.t('are_you_sure')}
-                        </span>
-                        <span
-                          class="pointer d-inline-block mr-1"
-                          onClick={linkEvent(this, this.handleTransferSite)}
-                        >
-                          {i18n.t('yes')}
-                        </span>
-                        <span
-                          class="pointer d-inline-block"
-                          onClick={linkEvent(
-                            this,
-                            this.handleCancelShowConfirmTransferSite
-                          )}
-                        >
-                          {i18n.t('no')}
-                        </span>
-                      </>
-                    )}
+                    <span
+                      className="pointer"
+                      onClick={linkEvent(this, this.handleViewSource)}
+                    >
+                      {i18n.t('view_source')}
+                    </span>
                   </li>
                 )}
-              </>
-            )}
-            {this.props.showBody && post.body && (
-              <li className="list-inline-item">
-                <span
-                  className="pointer"
-                  onClick={linkEvent(this, this.handleViewSource)}
+              </ul>
+              {this.state.showRemoveDialog && (
+                <form
+                  class="form-inline"
+                  onSubmit={linkEvent(this, this.handleModRemoveSubmit)}
                 >
-                  {i18n.t('view_source')}
-                </span>
-              </li>
-            )}
-          </ul>
-          {this.state.url && this.props.showBody && this.state.iframely && (
-            <IFramelyCard iframely={this.state.iframely} />
-          )}
-          {this.state.showRemoveDialog && (
-            <form
-              class="form-inline"
-              onSubmit={linkEvent(this, this.handleModRemoveSubmit)}
-            >
-              <input
-                type="text"
-                class="form-control mr-2"
-                placeholder={i18n.t('reason')}
-                value={this.state.removeReason}
-                onInput={linkEvent(this, this.handleModRemoveReasonChange)}
-              />
-              <button type="submit" class="btn btn-secondary">
-                {i18n.t('remove_post')}
-              </button>
-            </form>
-          )}
-          {this.state.showBanDialog && (
-            <form onSubmit={linkEvent(this, this.handleModBanBothSubmit)}>
-              <div class="form-group row">
-                <label class="col-form-label" htmlFor="post-listing-reason">
-                  {i18n.t('reason')}
-                </label>
-                <input
-                  type="text"
-                  id="post-listing-reason"
-                  class="form-control mr-2"
-                  placeholder={i18n.t('reason')}
-                  value={this.state.banReason}
-                  onInput={linkEvent(this, this.handleModBanReasonChange)}
-                />
-              </div>
-              {/* TODO hold off on expires until later */}
-              {/* <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.banExpires} onInput={linkEvent(this, this.handleModBanExpiresChange)} /> */}
-              {/* </div> */}
-              <div class="form-group row">
-                <button type="submit" class="btn btn-secondary">
-                  {i18n.t('ban')} {post.creator_name}
-                </button>
-              </div>
-            </form>
-          )}
-          {this.props.showBody && post.body && (
-            <>
-              {this.state.viewSource ? (
-                <pre>{post.body}</pre>
-              ) : (
-                <div
-                  className="md-div"
-                  dangerouslySetInnerHTML={mdToHtml(post.body)}
-                />
+                  <input
+                    type="text"
+                    class="form-control mr-2"
+                    placeholder={i18n.t('reason')}
+                    value={this.state.removeReason}
+                    onInput={linkEvent(this, this.handleModRemoveReasonChange)}
+                  />
+                  <button type="submit" class="btn btn-secondary">
+                    {i18n.t('remove_post')}
+                  </button>
+                </form>
               )}
-            </>
-          )}
+              {this.state.showBanDialog && (
+                <form onSubmit={linkEvent(this, this.handleModBanBothSubmit)}>
+                  <div class="form-group row">
+                    <label class="col-form-label" htmlFor="post-listing-reason">
+                      {i18n.t('reason')}
+                    </label>
+                    <input
+                      type="text"
+                      id="post-listing-reason"
+                      class="form-control mr-2"
+                      placeholder={i18n.t('reason')}
+                      value={this.state.banReason}
+                      onInput={linkEvent(this, this.handleModBanReasonChange)}
+                    />
+                  </div>
+                  {/* TODO hold off on expires until later */}
+                  {/* <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.banExpires} onInput={linkEvent(this, this.handleModBanExpiresChange)} /> */}
+                  {/* </div> */}
+                  <div class="form-group row">
+                    <button type="submit" class="btn btn-secondary">
+                      {i18n.t('ban')} {post.creator_name}
+                    </button>
+                  </div>
+                </form>
+              )}
+            </div>
+          </div>
         </div>
       </div>
     );
index 559a970723c2b6a339c520857ac342b76e8b3a90..db1f7b5f541a242a46d4a1e0bf03564c0176ce8d 100644 (file)
@@ -15,6 +15,10 @@ export class Symbols extends Component<any, any> {
         xmlnsXlink="http://www.w3.org/1999/xlink"
       >
         <defs>
+          <symbol id="icon-bubble2" viewBox="0 0 32 32">
+            <title>bubble2</title>
+            <path d="M16 6c-1.717 0-3.375 0.271-4.928 0.804-1.46 0.502-2.76 1.211-3.863 2.108-2.069 1.681-3.209 3.843-3.209 6.088 0 1.259 0.35 2.481 1.039 3.63 0.711 1.185 1.781 2.268 3.093 3.133 0.949 0.625 1.587 1.623 1.755 2.747 0.056 0.375 0.091 0.753 0.105 1.129 0.233-0.194 0.461-0.401 0.684-0.624 0.755-0.755 1.774-1.172 2.828-1.172 0.168 0 0.336 0.011 0.505 0.032 0.655 0.083 1.325 0.126 1.99 0.126 1.717 0 3.375-0.271 4.928-0.804 1.46-0.502 2.76-1.211 3.863-2.108 2.069-1.681 3.209-3.843 3.209-6.088s-1.14-4.407-3.209-6.088c-1.104-0.897-2.404-1.606-3.863-2.108-1.553-0.534-3.211-0.804-4.928-0.804zM16 2v0c8.837 0 16 5.82 16 13s-7.163 13-16 13c-0.849 0-1.682-0.054-2.495-0.158-3.437 3.437-7.539 4.053-11.505 4.144v-0.841c2.142-1.049 4-2.961 4-5.145 0-0.305-0.024-0.604-0.068-0.897-3.619-2.383-5.932-6.024-5.932-10.103 0-7.18 7.163-13 16-13z"></path>
+          </symbol>
           <symbol id="icon-image" viewBox="0 0 32 32">
             <title>image</title>
             <path d="M29.996 4c0.001 0.001 0.003 0.002 0.004 0.004v23.993c-0.001 0.001-0.002 0.003-0.004 0.004h-27.993c-0.001-0.001-0.003-0.002-0.004-0.004v-23.993c0.001-0.001 0.002-0.003 0.004-0.004h27.993zM30 2h-28c-1.1 0-2 0.9-2 2v24c0 1.1 0.9 2 2 2h28c1.1 0 2-0.9 2-2v-24c0-1.1-0.9-2-2-2v0z"></path>