]> Untitled Git - lemmy-ui.git/commitdiff
Add FeaturedPost Support (#873)
authorAnon <makotech222@users.noreply.github.com>
Wed, 14 Dec 2022 15:03:18 +0000 (09:03 -0600)
committerGitHub <noreply@github.com>
Wed, 14 Dec 2022 15:03:18 +0000 (10:03 -0500)
lemmy-translations
package.json
src/shared/components/community/community.tsx
src/shared/components/home/home.tsx
src/shared/components/modlog.tsx
src/shared/components/person/profile.tsx
src/shared/components/post/post-listing.tsx
src/shared/components/post/post.tsx
src/shared/utils.ts

index 46f4b3e8676c23d4a8100ce78330eceed7bcf053..a2f59fcbf7529a1f7dd5cda894381ef2000b9ef5 160000 (submodule)
@@ -1 +1 @@
-Subproject commit 46f4b3e8676c23d4a8100ce78330eceed7bcf053
+Subproject commit a2f59fcbf7529a1f7dd5cda894381ef2000b9ef5
index fa93364d6eee2ef0ef2feed6ede49d6eb2cd7d09..002db3f5d2d984b4f433e6f911126ffbcf611b2b 100644 (file)
@@ -47,7 +47,7 @@
     "inferno-server": "^8.0.3",
     "isomorphic-cookie": "^1.2.4",
     "jwt-decode": "^3.1.2",
-    "lemmy-js-client": "0.17.0-rc.54",
+    "lemmy-js-client": "0.17.0-rc.56",
     "markdown-it": "^13.0.1",
     "markdown-it-container": "^3.0.0",
     "markdown-it-footnote": "^3.0.3",
index af0f7e6aaa515f3b928acb3592c9b85cbec5c0fd..77c01d62ad053559b6680390a91bde914388c86a 100644 (file)
@@ -584,7 +584,7 @@ export class Community extends Component<any, State> {
       op == UserOperation.DeletePost ||
       op == UserOperation.RemovePost ||
       op == UserOperation.LockPost ||
-      op == UserOperation.StickyPost ||
+      op == UserOperation.FeaturePost ||
       op == UserOperation.SavePost
     ) {
       let data = wsJsonToRes<PostResponse>(msg, PostResponse);
index 3e5f47181b7d078bb7c4f3da412cb0650da01cbb..877837bef4ad3dc7371801e97d4777f3cd57ab42 100644 (file)
@@ -140,7 +140,7 @@ export class Home extends Component<any, HomeState> {
     dataType: getDataTypeFromProps(this.props),
     sort: getSortTypeFromProps(this.props),
     page: getPageFromProps(this.props),
-    tagline: None
+    tagline: None,
   };
 
   constructor(props: any, context: any) {
@@ -179,7 +179,7 @@ export class Home extends Component<any, HomeState> {
         ...this.state,
         trendingCommunities: trendingRes.communities,
         loading: false,
-        tagline: taglines.map(tls => getRandomFromList(tls).content)
+        tagline: taglines.map(tls => getRandomFromList(tls).content),
       };
     } else {
       this.fetchTrendingCommunities();
@@ -336,7 +336,12 @@ export class Home extends Component<any, HomeState> {
           <div className="row">
             <main role="main" className="col-12 col-md-8">
               {this.state.tagline.match({
-                some: tagline => <div id="tagline" dangerouslySetInnerHTML={mdToHtml(tagline)}></div>,
+                some: tagline => (
+                  <div
+                    id="tagline"
+                    dangerouslySetInnerHTML={mdToHtml(tagline)}
+                  ></div>
+                ),
                 none: <></>,
               })}
               <div className="d-block d-md-none">{this.mobileView()}</div>
@@ -804,7 +809,7 @@ export class Home extends Component<any, HomeState> {
       op == UserOperation.DeletePost ||
       op == UserOperation.RemovePost ||
       op == UserOperation.LockPost ||
-      op == UserOperation.StickyPost ||
+      op == UserOperation.FeaturePost ||
       op == UserOperation.SavePost
     ) {
       let data = wsJsonToRes<PostResponse>(msg, PostResponse);
index e097d97214d5846ef6d382ff203d8190c2380caa..95e0cc86358c827b4f1dfcde9721e3a35d91e980 100644 (file)
@@ -16,12 +16,12 @@ import {
   ModAddView,
   ModBanFromCommunityView,
   ModBanView,
+  ModFeaturePostView,
   ModLockPostView,
   ModlogActionType,
   ModRemoveCommentView,
   ModRemoveCommunityView,
   ModRemovePostView,
-  ModStickyPostView,
   ModTransferCommunityView,
   PersonSafe,
   toUndefined,
@@ -61,7 +61,7 @@ type ModlogType = {
   view:
     | ModRemovePostView
     | ModLockPostView
-    | ModStickyPostView
+    | ModFeaturePostView
     | ModRemoveCommentView
     | ModRemoveCommunityView
     | ModBanFromCommunityView
@@ -182,12 +182,12 @@ export class Modlog extends Component<any, ModlogState> {
       when_: r.mod_lock_post.when_,
     }));
 
-    let stickied_posts: ModlogType[] = res.stickied_posts.map(r => ({
-      id: r.mod_sticky_post.id,
-      type_: ModlogActionType.ModStickyPost,
+    let featured_posts: ModlogType[] = res.featured_posts.map(r => ({
+      id: r.mod_feature_post.id,
+      type_: ModlogActionType.ModFeaturePost,
       view: r,
       moderator: r.moderator,
-      when_: r.mod_sticky_post.when_,
+      when_: r.mod_feature_post.when_,
     }));
 
     let removed_comments: ModlogType[] = res.removed_comments.map(r => ({
@@ -287,7 +287,7 @@ export class Modlog extends Component<any, ModlogState> {
 
     combined.push(...removed_posts);
     combined.push(...locked_posts);
-    combined.push(...stickied_posts);
+    combined.push(...featured_posts);
     combined.push(...removed_comments);
     combined.push(...removed_communities);
     combined.push(...banned_from_community);
@@ -344,18 +344,21 @@ export class Modlog extends Component<any, ModlogState> {
           </>
         );
       }
-      case ModlogActionType.ModStickyPost: {
-        let mspv = i.view as ModStickyPostView;
+      case ModlogActionType.ModFeaturePost: {
+        let mspv = i.view as ModFeaturePostView;
         return (
           <>
             <span>
-              {mspv.mod_sticky_post.stickied.unwrapOr(false)
-                ? "Stickied "
-                : "Unstickied "}
+              {mspv.mod_feature_post.featured ? "Featured " : "Unfeatured "}
             </span>
             <span>
               Post <Link to={`/post/${mspv.post.id}`}>{mspv.post.name}</Link>
             </span>
+            <span>
+              {mspv.mod_feature_post.is_featured_community
+                ? " In Community"
+                : " In Local"}
+            </span>
           </>
         );
       }
@@ -679,8 +682,8 @@ export class Modlog extends Component<any, ModlogState> {
                   <option value={ModlogActionType.ModLockPost}>
                     Locking Posts
                   </option>
-                  <option value={ModlogActionType.ModStickyPost}>
-                    Stickying Posts
+                  <option value={ModlogActionType.ModFeaturePost}>
+                    Featuring Posts
                   </option>
                   <option value={ModlogActionType.ModRemoveComment}>
                     Removing Comments
index 7f677f2a8260a225b6f2db8b94a31b9b2022b261..986f9fd9ddab74eca1bec369e92d5dc1e860f0eb 100644 (file)
@@ -864,7 +864,7 @@ export class Profile extends Component<any, ProfileState> {
       op == UserOperation.DeletePost ||
       op == UserOperation.RemovePost ||
       op == UserOperation.LockPost ||
-      op == UserOperation.StickyPost ||
+      op == UserOperation.FeaturePost ||
       op == UserOperation.SavePost
     ) {
       let data = wsJsonToRes<PostResponse>(msg, PostResponse);
index 4a1966caac83535f20e9b4b9e77b371620cd9ea0..efb237bb128e9b48fcda0e245d4ae9fc327d5b1e 100644 (file)
@@ -12,15 +12,16 @@ import {
   CreatePostLike,
   CreatePostReport,
   DeletePost,
+  FeaturePost,
   Language,
   LockPost,
   PersonViewSafe,
+  PostFeatureType,
   PostView,
   PurgePerson,
   PurgePost,
   RemovePost,
   SavePost,
-  StickyPost,
   toUndefined,
   TransferCommunity,
 } from "lemmy-js-client";
@@ -29,6 +30,7 @@ import { i18n } from "../../i18next";
 import { BanType, PurgeType } from "../../interfaces";
 import { UserService, WebSocketService } from "../../services";
 import {
+  amAdmin,
   amCommunityCreator,
   auth,
   canAdmin,
@@ -452,7 +454,11 @@ export class PostListing extends Component<PostListingProps, PostListingState> {
     let post = this.props.post_view.post;
     return (
       <Link
-        className={!post.stickied ? "text-body" : "text-primary"}
+        className={
+          !post.featured_community && !post.featured_local
+            ? "text-body"
+            : "text-primary"
+        }
         to={`/post/${post.id}`}
         title={i18n.t("comments")}
       >
@@ -470,7 +476,11 @@ export class PostListing extends Component<PostListingProps, PostListingState> {
             some: url =>
               this.props.showBody ? (
                 <a
-                  className={!post.stickied ? "text-body" : "text-primary"}
+                  className={
+                    !post.featured_community && !post.featured_local
+                      ? "text-body"
+                      : "text-primary"
+                  }
                   href={url}
                   title={url}
                   rel={relTags}
@@ -517,14 +527,22 @@ export class PostListing extends Component<PostListingProps, PostListingState> {
               <Icon icon="lock" classes="icon-inline text-danger" />
             </small>
           )}
-          {post.stickied && (
+          {post.featured_community && (
             <small
               className="unselectable pointer ml-2 text-muted font-italic"
-              data-tippy-content={i18n.t("stickied")}
+              data-tippy-content={i18n.t("featured")}
             >
               <Icon icon="pin" classes="icon-inline text-primary" />
             </small>
           )}
+          {post.featured_local && (
+            <small
+              className="unselectable pointer ml-2 text-muted font-italic"
+              data-tippy-content={i18n.t("featured")}
+            >
+              <Icon icon="pin" classes="icon-inline text-secondary" />
+            </small>
+          )}
           {post.nsfw && (
             <small className="ml-2 text-muted font-italic">
               {i18n.t("nsfw")}
@@ -617,7 +635,7 @@ export class PostListing extends Component<PostListingProps, PostListingState> {
             {this.canModOnSelf_ && (
               <>
                 {this.lockButton}
-                {this.stickyButton}
+                {this.featureButton}
               </>
             )}
             {(this.canMod_ || this.canAdmin_) && <>{this.modRemoveButton}</>}
@@ -854,22 +872,48 @@ export class PostListing extends Component<PostListingProps, PostListingState> {
     );
   }
 
-  get stickyButton() {
-    let stickied = this.props.post_view.post.stickied;
-    let label = stickied ? i18n.t("unsticky") : i18n.t("sticky");
+  get featureButton() {
+    const featured_community = this.props.post_view.post.featured_community;
+    const label_community = featured_community
+      ? i18n.t("unfeature_from_community")
+      : i18n.t("feature_in_community");
+
+    const is_admin = amAdmin();
+    const featured_local = this.props.post_view.post.featured_local;
+    const label_local = featured_local
+      ? i18n.t("unfeature_from_local")
+      : i18n.t("feature_in_local");
     return (
-      <button
-        className="btn btn-link btn-animate text-muted py-0"
-        onClick={linkEvent(this, this.handleModSticky)}
-        data-tippy-content={label}
-        aria-label={label}
-      >
-        <Icon
-          icon="pin"
-          classes={classNames({ "text-success": stickied })}
-          inline
-        />
-      </button>
+      <span>
+        <button
+          className="btn btn-link btn-animate text-muted py-0 pl-0"
+          onClick={() => this.handleModFeaturePost(this, true)}
+          data-tippy-content={label_community}
+          aria-label={label_community}
+        >
+          <Icon
+            icon="pin"
+            classes={classNames({ "text-success": featured_community })}
+            inline
+          />{" "}
+          Community
+        </button>
+        {is_admin && (
+          <button
+            className="btn btn-link btn-animate text-muted py-0"
+            onClick={() => this.handleModFeaturePost(this, false)}
+            data-tippy-content={label_local}
+            aria-label={label_local}
+          >
+            <Icon
+              icon="pin"
+              classes={classNames({ "text-success": featured_local })}
+              inline
+            />{" "}
+            Local
+          </button>
+        )}
+      </span>
     );
   }
 
@@ -1491,13 +1535,18 @@ export class PostListing extends Component<PostListingProps, PostListingState> {
     WebSocketService.Instance.send(wsClient.lockPost(form));
   }
 
-  handleModSticky(i: PostListing) {
-    let form = new StickyPost({
+  handleModFeaturePost(i: PostListing, is_community: boolean) {
+    let form = new FeaturePost({
       post_id: i.props.post_view.post.id,
-      stickied: !i.props.post_view.post.stickied,
+      featured: is_community
+        ? !i.props.post_view.post.featured_community
+        : !i.props.post_view.post.featured_local,
+      feature_type: is_community
+        ? PostFeatureType.Community
+        : PostFeatureType.Local,
       auth: auth().unwrap(),
     });
-    WebSocketService.Instance.send(wsClient.stickyPost(form));
+    WebSocketService.Instance.send(wsClient.featurePost(form));
   }
 
   handleModBanFromCommunityShow(i: PostListing) {
index 0fd25e2eed0ea05388385c16b54c14ee2efe24a8..50f0e449ae81211472b87b8a2eb3800a3e11d7cb 100644 (file)
@@ -755,7 +755,7 @@ export class Post extends Component<any, PostState> {
       op == UserOperation.DeletePost ||
       op == UserOperation.RemovePost ||
       op == UserOperation.LockPost ||
-      op == UserOperation.StickyPost ||
+      op == UserOperation.FeaturePost ||
       op == UserOperation.SavePost
     ) {
       let data = wsJsonToRes<PostResponse>(msg, PostResponse);
index 26b5168dad37c4afdc4819d4e3985d101aecba42..d541df065bd8912c0bbb24cddc3b9328b016ac58 100644 (file)
@@ -968,7 +968,8 @@ export function editPostRes(data: PostView, post: PostView) {
     post.post.nsfw = data.post.nsfw;
     post.post.deleted = data.post.deleted;
     post.post.removed = data.post.removed;
-    post.post.stickied = data.post.stickied;
+    post.post.featured_community = data.post.featured_community;
+    post.post.featured_local = data.post.featured_local;
     post.post.body = data.post.body;
     post.post.locked = data.post.locked;
     post.saved = data.saved;
@@ -1526,6 +1527,6 @@ export function nsfwCheck(
   );
 }
 
-export function getRandomFromList<T>(list : T[]) : T{
+export function getRandomFromList<T>(list: T[]): T {
   return list[Math.floor(Math.random() * list.length)];
 }