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