]> Untitled Git - lemmy-ui.git/blobdiff - src/shared/components/post/post-listing.tsx
Merge remote-tracking branch 'lemmy/main' into fix/wider-max-width-1536
[lemmy-ui.git] / src / shared / components / post / post-listing.tsx
index 8e0cc28cfd7a3de620f87a07e990a4a01424adbf..eca56605235e1310dc80a144061be8fc55f0e642 100644 (file)
@@ -43,7 +43,12 @@ import {
   TransferCommunity,
 } from "lemmy-js-client";
 import { relTags } from "../../config";
-import { BanType, PostFormParams, PurgeType } from "../../interfaces";
+import {
+  BanType,
+  PostFormParams,
+  PurgeType,
+  VoteContentType,
+} from "../../interfaces";
 import { mdNoImages, mdToHtml, mdToHtmlInline } from "../../markdown";
 import { I18NextService, UserService } from "../../services";
 import { setupTippy } from "../../tippy";
@@ -242,12 +247,13 @@ export class PostListing extends Component<PostListingProps, PostListingState> {
             </a>
           </div>
           <div className="my-2 d-block d-sm-none">
-            <a
-              className="d-inline-block"
+            <button
+              type="button"
+              className="p-0 border-0 bg-transparent d-inline-block"
               onClick={linkEvent(this, this.handleImageExpandClick)}
             >
               <PictrsImage src={this.imageSrc} />
-            </a>
+            </button>
           </div>
         </>
       );
@@ -256,6 +262,7 @@ export class PostListing extends Component<PostListingProps, PostListingState> {
     const { post } = this.postView;
     const { url } = post;
 
+    // if direct video link
     if (url && isVideo(url)) {
       return (
         <div className="embed-responsive mt-3">
@@ -266,6 +273,20 @@ export class PostListing extends Component<PostListingProps, PostListingState> {
       );
     }
 
+    // if embedded video link
+    if (url && post.embed_video_url) {
+      return (
+        <div className="ratio ratio-16x9">
+          <iframe
+            allowFullScreen
+            className="post-metadata-iframe"
+            src={post.embed_video_url}
+            title={post.embed_title}
+          ></iframe>
+        </div>
+      );
+    }
+
     return <></>;
   }
 
@@ -332,7 +353,7 @@ export class PostListing extends Component<PostListingProps, PostListingState> {
         </a>
       );
     } else if (url) {
-      if (!this.props.hideImage && isVideo(url)) {
+      if ((!this.props.hideImage && isVideo(url)) || post.embed_video_url) {
         return (
           <a
             className="text-body"
@@ -376,7 +397,7 @@ export class PostListing extends Component<PostListingProps, PostListingState> {
     const post_view = this.postView;
     return (
       <span className="small">
-        <PersonListing person={post_view.creator} />
+        <PersonListing person={post_view.creator} muted={true} />
         {this.creatorIsMod_ && (
           <span className="mx-1 badge text-bg-light">
             {I18NextService.i18n.t("mod")}
@@ -423,8 +444,8 @@ export class PostListing extends Component<PostListingProps, PostListingState> {
       <Link
         className={`d-inline ${
           !post.featured_community && !post.featured_local
-            ? "text-body"
-            : "text-primary"
+            ? "link-dark"
+            : "link-primary"
         }`}
         to={`/post/${post.id}`}
         title={I18NextService.i18n.t("comments")}
@@ -449,8 +470,8 @@ export class PostListing extends Component<PostListingProps, PostListingState> {
               <a
                 className={
                   !post.featured_community && !post.featured_local
-                    ? "text-body"
-                    : "text-primary"
+                    ? "link-dark"
+                    : "link-primary"
                 }
                 href={url}
                 title={url}
@@ -483,7 +504,7 @@ export class PostListing extends Component<PostListingProps, PostListingState> {
           )}
           {post.deleted && (
             <small
-              className="unselectable pointer ms-2 text-muted font-italic"
+              className="unselectable pointer ms-2 text-muted fst-italic"
               data-tippy-content={I18NextService.i18n.t("deleted")}
             >
               <Icon icon="trash" classes="icon-inline text-danger" />
@@ -491,7 +512,7 @@ export class PostListing extends Component<PostListingProps, PostListingState> {
           )}
           {post.locked && (
             <small
-              className="unselectable pointer ms-2 text-muted font-italic"
+              className="unselectable pointer ms-2 text-muted fst-italic"
               data-tippy-content={I18NextService.i18n.t("locked")}
             >
               <Icon icon="lock" classes="icon-inline text-danger" />
@@ -499,7 +520,7 @@ export class PostListing extends Component<PostListingProps, PostListingState> {
           )}
           {post.featured_community && (
             <small
-              className="unselectable pointer ms-2 text-muted font-italic"
+              className="unselectable pointer ms-2 text-muted fst-italic"
               data-tippy-content={I18NextService.i18n.t(
                 "featured_in_community"
               )}
@@ -510,7 +531,7 @@ export class PostListing extends Component<PostListingProps, PostListingState> {
           )}
           {post.featured_local && (
             <small
-              className="unselectable pointer ms-2 text-muted font-italic"
+              className="unselectable pointer ms-2 text-muted fst-italic"
               data-tippy-content={I18NextService.i18n.t("featured_in_local")}
               aria-label={I18NextService.i18n.t("featured_in_local")}
             >
@@ -533,10 +554,10 @@ export class PostListing extends Component<PostListingProps, PostListingState> {
     const url = post.url;
 
     return (
-      <p className="d-flex text-muted align-items-center gap-1 small m-0">
+      <p className="small m-0">
         {url && !(hostname(url) === getExternalHost()) && (
           <a
-            className="text-muted font-italic"
+            className="fst-italic link-dark link-opacity-75 link-opacity-100-hover"
             href={url}
             title={url}
             rel={relTags}
@@ -598,9 +619,9 @@ export class PostListing extends Component<PostListingProps, PostListingState> {
         )}
         {mobile && !this.props.viewOnly && (
           <VoteButtonsCompact
+            voteContentType={VoteContentType.Post}
             id={this.postView.post.id}
             onVote={this.props.onPostVote}
-            postListing={this}
             enableDownvotes={this.props.enableDownvotes}
             counts={this.postView.counts}
             my_vote={this.postView.my_vote}
@@ -661,13 +682,16 @@ export class PostListing extends Component<PostListingProps, PostListingState> {
             data-tippy-content={I18NextService.i18n.t("more")}
             data-bs-toggle="dropdown"
             aria-expanded="false"
-            aria-controls="advancedButtonsDropdown"
+            aria-controls={`advancedButtonsDropdown${post.id}`}
             aria-label={I18NextService.i18n.t("more")}
           >
             <Icon icon="more-vertical" inline />
           </button>
 
-          <ul className="dropdown-menu" id="advancedButtonsDropdown">
+          <ul
+            className="dropdown-menu"
+            id={`advancedButtonsDropdown${post.id}`}
+          >
             {!this.myPost ? (
               <>
                 <li>{this.reportButton}</li>
@@ -717,9 +741,12 @@ export class PostListing extends Component<PostListingProps, PostListingState> {
         <Icon icon="message-square" classes="me-1" inline />
         {post_view.counts.comments}
         {this.unreadCount && (
-          <span className="text-muted fst-italic">
-            ({this.unreadCount} {I18NextService.i18n.t("new")})
-          </span>
+          <>
+            {" "}
+            <span className="fst-italic">
+              ({this.unreadCount} {I18NextService.i18n.t("new")})
+            </span>
+          </>
         )}
       </Link>
     );
@@ -1208,12 +1235,12 @@ export class PostListing extends Component<PostListingProps, PostListingState> {
                 value={this.state.banReason}
                 onInput={linkEvent(this, this.handleModBanReasonChange)}
               />
-              <label className="col-form-label" htmlFor={`mod-ban-expires`}>
+              <label className="col-form-label" htmlFor="mod-ban-expires">
                 {I18NextService.i18n.t("expires")}
               </label>
               <input
                 type="number"
-                id={`mod-ban-expires`}
+                id="mod-ban-expires"
                 className="form-control me-2"
                 placeholder={I18NextService.i18n.t("number_of_days")}
                 value={this.state.banExpireDays}
@@ -1380,21 +1407,23 @@ export class PostListing extends Component<PostListingProps, PostListingState> {
         <div className="d-none d-sm-block">
           <article className="row post-container">
             {!this.props.viewOnly && (
-              <VoteButtons
-                id={this.postView.post.id}
-                onVote={this.props.onPostVote}
-                postListing={this}
-                enableDownvotes={this.props.enableDownvotes}
-                counts={this.postView.counts}
-                my_vote={this.postView.my_vote}
-              />
+              <div className="col flex-grow-0">
+                <VoteButtons
+                  voteContentType={VoteContentType.Post}
+                  id={this.postView.post.id}
+                  onVote={this.props.onPostVote}
+                  enableDownvotes={this.props.enableDownvotes}
+                  counts={this.postView.counts}
+                  my_vote={this.postView.my_vote}
+                />
+              </div>
             )}
-            <div className="col-sm-2 pe-0 post-media">
-              <div className="">{this.thumbnail()}</div>
-            </div>
-            <div className="col-12 col-sm-9">
+            <div className="col flex-grow-1">
               <div className="row">
-                <div className="col-12">
+                <div className="col-sm-3 col-lg-2 pe-0 post-media">
+                  <div className="">{this.thumbnail()}</div>
+                </div>
+                <div className="col-12 col-sm-9 col-lg-10">
                   {this.postTitleLine()}
                   {this.createdLine()}
                   {this.showBodyPreview()}