]> Untitled Git - lemmy-ui.git/blobdiff - src/shared/components/post/post-listing.tsx
use badge-muted
[lemmy-ui.git] / src / shared / components / post / post-listing.tsx
index 4b8d072bf4f9e0061c3af2e7913e054f3e1a8d72..137ded9e80626b20ab5b81d264301ec1161df1af 100644 (file)
@@ -14,8 +14,7 @@ import {
   FeaturePost,
   Language,
   LockPost,
-  PersonViewSafe,
-  PostFeatureType,
+  PersonView,
   PostView,
   PurgePerson,
   PurgePost,
@@ -23,9 +22,9 @@ import {
   SavePost,
   TransferCommunity,
 } from "lemmy-js-client";
-import { externalHost } from "../../env";
+import { getExternalHost, getHttpBase } from "../../env";
 import { i18n } from "../../i18next";
-import { BanType, PurgeType } from "../../interfaces";
+import { BanType, PostFormParams, PurgeType } from "../../interfaces";
 import { UserService, WebSocketService } from "../../services";
 import {
   amAdmin,
@@ -33,6 +32,7 @@ import {
   amMod,
   canAdmin,
   canMod,
+  canShare,
   futureDaysToUnixTime,
   hostname,
   isAdmin,
@@ -47,6 +47,7 @@ import {
   numToSI,
   relTags,
   setupTippy,
+  share,
   showScores,
   wsClient,
 } from "../../utils";
@@ -90,7 +91,7 @@ interface PostListingProps {
   post_view: PostView;
   duplicates?: PostView[];
   moderators?: CommunityModeratorView[];
-  admins?: PersonViewSafe[];
+  admins?: PersonView[];
   allLanguages: Language[];
   siteLanguages: number[];
   showCommunity?: boolean;
@@ -147,7 +148,8 @@ export class PostListing extends Component<PostListingProps, PostListingState> {
   }
 
   render() {
-    let post = this.props.post_view.post;
+    const post = this.props.post_view.post;
+
     return (
       <div className="post-listing">
         {!this.state.showEdit ? (
@@ -325,23 +327,16 @@ export class PostListing extends Component<PostListingProps, PostListingState> {
           <PersonListing person={post_view.creator} />
 
           {this.creatorIsMod_ && (
-            <span className="mx-1 badge badge-light">{i18n.t("mod")}</span>
+            <span className="mx-1 badge badge-muted">{i18n.t("mod")}</span>
           )}
           {this.creatorIsAdmin_ && (
-            <span className="mx-1 badge badge-light">{i18n.t("admin")}</span>
+            <span className="mx-1 badge badge-muted">{i18n.t("admin")}</span>
           )}
           {post_view.creator.bot_account && (
-            <span className="mx-1 badge badge-light">
+            <span className="mx-1 badge badge-muted">
               {i18n.t("bot_account").toLowerCase()}
             </span>
           )}
-          {(post_view.creator_banned_from_community ||
-            isBanned(post_view.creator)) && (
-            <span className="mx-1 badge badge-danger">{i18n.t("banned")}</span>
-          )}
-          {post_view.creator_blocked && (
-            <span className="mx-1 badge badge-danger">{"blocked"}</span>
-          )}
           {this.props.showCommunity && (
             <span>
               <span className="mx-1"> {i18n.t("to")} </span>
@@ -349,8 +344,17 @@ export class PostListing extends Component<PostListingProps, PostListingState> {
             </span>
           )}
         </li>
+        {post_view.post.language_id !== 0 && (
+          <span className="mx-1 badge badge-muted">
+            {
+              this.props.allLanguages.find(
+                lang => lang.id === post_view.post.language_id
+              )?.name
+            }
+          </span>
+        )}
         <li className="list-inline-item">•</li>
-        {url && !(hostname(url) == externalHost) && (
+        {url && !(hostname(url) === getExternalHost()) && (
           <>
             <li className="list-inline-item">
               <a
@@ -567,9 +571,19 @@ export class PostListing extends Component<PostListingProps, PostListingState> {
 
   commentsLine(mobile = false) {
     let post = this.props.post_view.post;
+
     return (
       <div className="d-flex justify-content-start flex-wrap text-muted font-weight-bold mb-1">
         {this.commentsButton}
+        {canShare() && (
+          <button
+            className="btn btn-link"
+            onClick={linkEvent(this, this.handleShare)}
+            type="button"
+          >
+            <Icon icon="share" inline />
+          </button>
+        )}
         {!post.local && (
           <a
             className="btn btn-link btn-animate text-muted py-0"
@@ -637,15 +651,15 @@ export class PostListing extends Component<PostListingProps, PostListingState> {
         <Link
           className="text-muted"
           title={i18n.t("number_of_comments", {
-            count: post_view.counts.comments,
-            formattedCount: post_view.counts.comments,
+            count: Number(post_view.counts.comments),
+            formattedCount: Number(post_view.counts.comments),
           })}
           to={`/post/${post_view.post.id}?scrollToComments=true`}
         >
           <Icon icon="message-square" classes="mr-1" inline />
           <span className="mr-2">
             {i18n.t("number_of_comments", {
-              count: post_view.counts.comments,
+              count: Number(post_view.counts.comments),
               formattedCount: numToSI(post_view.counts.comments),
             })}
           </span>
@@ -734,7 +748,14 @@ export class PostListing extends Component<PostListingProps, PostListingState> {
     return (
       <Link
         className="btn btn-link btn-animate text-muted py-0"
-        to={`/create_post${this.crossPostParams}`}
+        to={{
+          /* Empty string properties are required to satisfy type*/
+          pathname: "/create_post",
+          state: { ...this.crossPostParams },
+          hash: "",
+          key: "",
+          search: "",
+        }}
         title={i18n.t("cross_post")}
       >
         <Icon icon="copy" inline />
@@ -1399,6 +1420,15 @@ export class PostListing extends Component<PostListingProps, PostListingState> {
     this.setState({ showEdit: false });
   }
 
+  handleShare(i: PostListing) {
+    const { name, body, id } = i.props.post_view.post;
+    share({
+      title: name,
+      text: body?.slice(0, 50),
+      url: `${getHttpBase()}/post/${id}`,
+    });
+  }
+
   handleShowReportDialog(i: PostListing) {
     i.setState({ showReportDialog: !i.state.showReportDialog });
   }
@@ -1461,18 +1491,22 @@ export class PostListing extends Component<PostListingProps, PostListingState> {
     }
   }
 
-  get crossPostParams(): string {
-    let post = this.props.post_view.post;
-    let params = `?title=${encodeURIComponent(post.name)}`;
+  get crossPostParams(): PostFormParams {
+    const queryParams: PostFormParams = {};
+    const { name, url } = this.props.post_view.post;
+
+    queryParams.name = name;
 
-    if (post.url) {
-      params += `&url=${encodeURIComponent(post.url)}`;
+    if (url) {
+      queryParams.url = url;
     }
-    let crossPostBody = this.crossPostBody();
+
+    const crossPostBody = this.crossPostBody();
     if (crossPostBody) {
-      params += `&body=${encodeURIComponent(crossPostBody)}`;
+      queryParams.body = crossPostBody;
     }
-    return params;
+
+    return queryParams;
   }
 
   crossPostBody(): string | undefined {
@@ -1539,7 +1573,7 @@ export class PostListing extends Component<PostListingProps, PostListingState> {
     if (auth) {
       let form: FeaturePost = {
         post_id: i.props.post_view.post.id,
-        feature_type: PostFeatureType.Local,
+        feature_type: "Local",
         featured: !i.props.post_view.post.featured_local,
         auth,
       };
@@ -1552,7 +1586,7 @@ export class PostListing extends Component<PostListingProps, PostListingState> {
     if (auth) {
       let form: FeaturePost = {
         post_id: i.props.post_view.post.id,
-        feature_type: PostFeatureType.Community,
+        feature_type: "Community",
         featured: !i.props.post_view.post.featured_community,
         auth,
       };
@@ -1772,18 +1806,18 @@ export class PostListing extends Component<PostListingProps, PostListingState> {
 
   get pointsTippy(): string {
     let points = i18n.t("number_of_points", {
-      count: this.state.score,
-      formattedCount: this.state.score,
+      count: Number(this.state.score),
+      formattedCount: Number(this.state.score),
     });
 
     let upvotes = i18n.t("number_of_upvotes", {
-      count: this.state.upvotes,
-      formattedCount: this.state.upvotes,
+      count: Number(this.state.upvotes),
+      formattedCount: Number(this.state.upvotes),
     });
 
     let downvotes = i18n.t("number_of_downvotes", {
-      count: this.state.downvotes,
-      formattedCount: this.state.downvotes,
+      count: Number(this.state.downvotes),
+      formattedCount: Number(this.state.downvotes),
     });
 
     return `${points} • ${upvotes} • ${downvotes}`;