]> Untitled Git - lemmy.git/blobdiff - ui/src/components/post-listings.tsx
routes.api: fix get_captcha endpoint (#1135)
[lemmy.git] / ui / src / components / post-listings.tsx
index f5682a7e96ad88309ee8b0b814ab4d90dcdbead2..2c9b4a882663e4e154c6e406fbf11fd807c775aa 100644 (file)
@@ -1,16 +1,21 @@
 import { Component } from 'inferno';
 import { Link } from 'inferno-router';
-import { Post } from '../interfaces';
+import { Post, SortType } from 'lemmy-js-client';
+import { postSort } from '../utils';
 import { PostListing } from './post-listing';
+import { i18n } from '../i18next';
 import { T } from 'inferno-i18next';
 
 interface PostListingsProps {
   posts: Array<Post>;
   showCommunity?: boolean;
+  removeDuplicates?: boolean;
+  sort?: SortType;
+  enableDownvotes: boolean;
+  enableNsfw: boolean;
 }
 
 export class PostListings extends Component<PostListingsProps, any> {
-
   constructor(props: any, context: any) {
     super(props, context);
   }
@@ -18,14 +23,93 @@ export class PostListings extends Component<PostListingsProps, any> {
   render() {
     return (
       <div>
-        {this.props.posts.length > 0 ? this.props.posts.map(post => 
-          <PostListing post={post} showCommunity={this.props.showCommunity} />) : 
+        {this.props.posts.length > 0 ? (
+          this.outer().map(post => (
+            <>
+              <PostListing
+                post={post}
+                showCommunity={this.props.showCommunity}
+                enableDownvotes={this.props.enableDownvotes}
+                enableNsfw={this.props.enableNsfw}
+              />
+              <hr class="my-3" />
+            </>
+          ))
+        ) : (
           <>
-            <div><T i18nKey="no_posts">#</T></div>
-            {this.props.showCommunity !== undefined  && <div><T i18nKey="subscribe_to_communities">#<Link to="/communities">#</Link></T></div>}
+            <div>{i18n.t('no_posts')}</div>
+            {this.props.showCommunity !== undefined && (
+              <T i18nKey="subscribe_to_communities">
+                #<Link to="/communities">#</Link>
+              </T>
+            )}
           </>
-        }
+        )}
       </div>
-    )
+    );
+  }
+
+  outer(): Array<Post> {
+    let out = this.props.posts;
+    if (this.props.removeDuplicates) {
+      out = this.removeDuplicates(out);
+    }
+
+    if (this.props.sort !== undefined) {
+      postSort(out, this.props.sort, this.props.showCommunity == undefined);
+    }
+
+    return out;
+  }
+
+  removeDuplicates(posts: Array<Post>): Array<Post> {
+    // A map from post url to list of posts (dupes)
+    let urlMap = new Map<string, Array<Post>>();
+
+    // Loop over the posts, find ones with same urls
+    for (let post of posts) {
+      if (
+        post.url &&
+        !post.deleted &&
+        !post.removed &&
+        !post.community_deleted &&
+        !post.community_removed
+      ) {
+        if (!urlMap.get(post.url)) {
+          urlMap.set(post.url, [post]);
+        } else {
+          urlMap.get(post.url).push(post);
+        }
+      }
+    }
+
+    // Sort by oldest
+    // Remove the ones that have no length
+    for (let e of urlMap.entries()) {
+      if (e[1].length == 1) {
+        urlMap.delete(e[0]);
+      } else {
+        e[1].sort((a, b) => a.published.localeCompare(b.published));
+      }
+    }
+
+    for (let i = 0; i < posts.length; i++) {
+      let post = posts[i];
+      if (post.url) {
+        let found = urlMap.get(post.url);
+        if (found) {
+          // If its the oldest, add
+          if (post.id == found[0].id) {
+            post.duplicates = found.slice(1);
+          }
+          // Otherwise, delete it
+          else {
+            posts.splice(i--, 1);
+          }
+        }
+      }
+    }
+
+    return posts;
   }
 }