]> Untitled Git - lemmy-ui.git/blob - src/shared/components/post-listings.tsx
First pass at v2_api
[lemmy-ui.git] / src / shared / components / post-listings.tsx
1 import { Component } from 'inferno';
2 import { Link } from 'inferno-router';
3 import { PostView, SortType } from 'lemmy-js-client';
4 import { postSort } from '../utils';
5 import { PostListing } from './post-listing';
6 import { i18n } from '../i18next';
7 import { T } from 'inferno-i18next';
8
9 interface PostListingsProps {
10   posts: PostView[];
11   showCommunity?: boolean;
12   removeDuplicates?: boolean;
13   sort?: SortType;
14   enableDownvotes: boolean;
15   enableNsfw: boolean;
16 }
17
18 export class PostListings extends Component<PostListingsProps, any> {
19   private duplicatesMap = new Map<number, PostView[]>();
20
21   constructor(props: any, context: any) {
22     super(props, context);
23   }
24
25   render() {
26     return (
27       <div>
28         {this.props.posts.length > 0 ? (
29           this.outer().map(post_view => (
30             <>
31               <PostListing
32                 post_view={post_view}
33                 duplicates={this.duplicatesMap.get(post_view.post.id)}
34                 showCommunity={this.props.showCommunity}
35                 enableDownvotes={this.props.enableDownvotes}
36                 enableNsfw={this.props.enableNsfw}
37               />
38               <hr class="my-3" />
39             </>
40           ))
41         ) : (
42           <>
43             <div>{i18n.t('no_posts')}</div>
44             {this.props.showCommunity !== undefined && (
45               <T i18nKey="subscribe_to_communities">
46                 #<Link to="/communities">#</Link>
47               </T>
48             )}
49           </>
50         )}
51       </div>
52     );
53   }
54
55   outer(): PostView[] {
56     let out = this.props.posts;
57     if (this.props.removeDuplicates) {
58       out = this.removeDuplicates(out);
59     }
60
61     if (this.props.sort !== undefined) {
62       postSort(out, this.props.sort, this.props.showCommunity == undefined);
63     }
64
65     return out;
66   }
67
68   removeDuplicates(posts: PostView[]): PostView[] {
69     // A map from post url to list of posts (dupes)
70     let urlMap = new Map<string, PostView[]>();
71
72     // Loop over the posts, find ones with same urls
73     for (let pv of posts) {
74       if (
75         pv.post.url &&
76         !pv.post.deleted &&
77         !pv.post.removed &&
78         !pv.community.deleted &&
79         !pv.community.removed
80       ) {
81         if (!urlMap.get(pv.post.url)) {
82           urlMap.set(pv.post.url, [pv]);
83         } else {
84           urlMap.get(pv.post.url).push(pv);
85         }
86       }
87     }
88
89     // Sort by oldest
90     // Remove the ones that have no length
91     for (let e of urlMap.entries()) {
92       if (e[1].length == 1) {
93         urlMap.delete(e[0]);
94       } else {
95         e[1].sort((a, b) => a.post.published.localeCompare(b.post.published));
96       }
97     }
98
99     for (let i = 0; i < posts.length; i++) {
100       let pv = posts[i];
101       if (pv.post.url) {
102         let found = urlMap.get(pv.post.url);
103         if (found) {
104           // If its the oldest, add
105           if (pv.post.id == found[0].post.id) {
106             this.duplicatesMap.set(pv.post.id, found.slice(1));
107           }
108           // Otherwise, delete it
109           else {
110             posts.splice(i--, 1);
111           }
112         }
113       }
114     }
115
116     return posts;
117   }
118 }