]> Untitled Git - lemmy-ui.git/blobdiff - src/shared/components/community/community.tsx
Adding Community Language fixes. #783 (#868)
[lemmy-ui.git] / src / shared / components / community / community.tsx
index c5afe0efe33e848e6842c62de3be1d8f79cf9f85..7ce6099988d9c9a866a3906532ea4e0fac3d88ba 100644 (file)
@@ -29,7 +29,11 @@ import {
 } from "lemmy-js-client";
 import { Subscription } from "rxjs";
 import { i18n } from "../../i18next";
-import { DataType, InitialFetchRequest } from "../../interfaces";
+import {
+  CommentViewType,
+  DataType,
+  InitialFetchRequest,
+} from "../../interfaces";
 import { UserService, WebSocketService } from "../../services";
 import {
   auth,
@@ -45,7 +49,10 @@ import {
   getDataTypeFromProps,
   getPageFromProps,
   getSortTypeFromProps,
+  isPostBlocked,
   notifyPost,
+  nsfwCheck,
+  postToCommentSortType,
   relTags,
   restoreScrollPosition,
   saveCommentRes,
@@ -134,24 +141,27 @@ export class Community extends Component<any, State> {
 
     // Only fetch the data if coming from another route
     if (this.isoData.path == this.context.router.route.match.url) {
-      this.state.communityRes = Some(
-        this.isoData.routeData[0] as GetCommunityResponse
-      );
+      this.state = {
+        ...this.state,
+        communityRes: Some(this.isoData.routeData[0] as GetCommunityResponse),
+      };
       let postsRes = Some(this.isoData.routeData[1] as GetPostsResponse);
       let commentsRes = Some(this.isoData.routeData[2] as GetCommentsResponse);
 
-      postsRes.match({
-        some: pvs => (this.state.posts = pvs.posts),
-        none: void 0,
-      });
-      commentsRes.match({
-        some: cvs => (this.state.comments = cvs.comments),
-        none: void 0,
-      });
+      if (postsRes.isSome()) {
+        this.state = { ...this.state, posts: postsRes.unwrap().posts };
+      }
+
+      if (commentsRes.isSome()) {
+        this.state = { ...this.state, comments: commentsRes.unwrap().comments };
+      }
 
-      this.state.communityLoading = false;
-      this.state.postsLoading = false;
-      this.state.commentsLoading = false;
+      this.state = {
+        ...this.state,
+        communityLoading: false,
+        postsLoading: false,
+        commentsLoading: false,
+      };
     } else {
       this.fetchCommunity();
       this.fetchData();
@@ -233,9 +243,12 @@ export class Community extends Component<any, State> {
         community_id: None,
         page,
         limit: Some(fetchLimit),
-        sort,
+        max_depth: None,
+        sort: sort.map(postToCommentSortType),
         type_: Some(ListingType.All),
         saved_only: Some(false),
+        post_id: None,
+        parent_id: None,
         auth: req.auth,
       });
       promises.push(Promise.resolve());
@@ -259,18 +272,24 @@ export class Community extends Component<any, State> {
   get documentTitle(): string {
     return this.state.communityRes.match({
       some: res =>
-        this.state.siteRes.site_view.match({
-          some: siteView =>
-            `${res.community_view.community.title} - ${siteView.site.name}`,
-          none: "",
-        }),
+        `${res.community_view.community.title} - ${this.state.siteRes.site_view.site.name}`,
       none: "",
     });
   }
 
   render() {
+    // For some reason, this returns an empty vec if it matches the site langs
+    let communityLangs = this.state.communityRes.map(r => {
+      let langs = r.discussion_languages;
+      if (langs.length == 0) {
+        return this.state.siteRes.all_languages.map(l => l.id);
+      } else {
+        return langs;
+      }
+    });
+
     return (
-      <div class="container">
+      <div className="container-lg">
         {this.state.communityLoading ? (
           <h5>
             <Spinner large />
@@ -286,12 +305,12 @@ export class Community extends Component<any, State> {
                   image={res.community_view.community.icon}
                 />
 
-                <div class="row">
-                  <div class="col-12 col-md-8">
+                <div className="row">
+                  <div className="col-12 col-md-8">
                     {this.communityInfo()}
-                    <div class="d-block d-md-none">
+                    <div className="d-block d-md-none">
                       <button
-                        class="btn btn-secondary d-inline-block mb-2 mr-3"
+                        className="btn btn-secondary d-inline-block mb-2 mr-3"
                         onClick={linkEvent(this, this.handleShowSidebarMobile)}
                       >
                         {i18n.t("sidebar")}{" "}
@@ -312,6 +331,12 @@ export class Community extends Component<any, State> {
                             admins={this.state.siteRes.admins}
                             online={res.online}
                             enableNsfw={enableNsfw(this.state.siteRes)}
+                            editable
+                            allLanguages={this.state.siteRes.all_languages}
+                            siteLanguages={
+                              this.state.siteRes.discussion_languages
+                            }
+                            communityLanguages={communityLangs}
                           />
                           {!res.community_view.community.local &&
                             res.site.match({
@@ -336,13 +361,17 @@ export class Community extends Component<any, State> {
                       onChange={this.handlePageChange}
                     />
                   </div>
-                  <div class="d-none d-md-block col-md-4">
+                  <div className="d-none d-md-block col-md-4">
                     <Sidebar
                       community_view={res.community_view}
                       moderators={res.moderators}
                       admins={this.state.siteRes.admins}
                       online={res.online}
                       enableNsfw={enableNsfw(this.state.siteRes)}
+                      editable
+                      allLanguages={this.state.siteRes.all_languages}
+                      siteLanguages={this.state.siteRes.discussion_languages}
+                      communityLanguages={communityLangs}
                     />
                     {!res.community_view.community.local &&
                       res.site.match({
@@ -380,6 +409,8 @@ export class Community extends Component<any, State> {
           removeDuplicates
           enableDownvotes={enableDownvotes(this.state.siteRes)}
           enableNsfw={enableNsfw(this.state.siteRes)}
+          allLanguages={this.state.siteRes.all_languages}
+          siteLanguages={this.state.siteRes.discussion_languages}
         />
       )
     ) : this.state.commentsLoading ? (
@@ -389,12 +420,15 @@ export class Community extends Component<any, State> {
     ) : (
       <CommentNodes
         nodes={commentsToFlatNodes(this.state.comments)}
+        viewType={CommentViewType.Flat}
         noIndent
         showContext
         enableDownvotes={enableDownvotes(this.state.siteRes)}
         moderators={this.state.communityRes.map(r => r.moderators)}
         admins={Some(this.state.siteRes.admins)}
         maxCommentsShown={None}
+        allLanguages={this.state.siteRes.all_languages}
+        siteLanguages={this.state.siteRes.discussion_languages}
       />
     );
   }
@@ -404,9 +438,9 @@ export class Community extends Component<any, State> {
       .map(r => r.community_view.community)
       .match({
         some: community => (
-          <div class="mb-2">
+          <div className="mb-2">
             <BannerIconHeader banner={community.banner} icon={community.icon} />
-            <h5 class="mb-0 overflow-wrap-anywhere">{community.title}</h5>
+            <h5 className="mb-0 overflow-wrap-anywhere">{community.title}</h5>
             <CommunityLink
               community={community}
               realLink
@@ -425,14 +459,14 @@ export class Community extends Component<any, State> {
       communityRSSUrl(r.community_view.community.actor_id, this.state.sort)
     );
     return (
-      <div class="mb-3">
-        <span class="mr-3">
+      <div className="mb-3">
+        <span className="mr-3">
           <DataTypeSelect
             type_={this.state.dataType}
             onChange={this.handleDataTypeChange}
           />
         </span>
-        <span class="mr-2">
+        <span className="mr-2">
           <SortSelect sort={this.state.sort} onChange={this.handleSortChange} />
         </span>
         {communityRss.match({
@@ -466,8 +500,7 @@ export class Community extends Component<any, State> {
   }
 
   handleShowSidebarMobile(i: Community) {
-    i.state.showSidebarMobile = !i.state.showSidebarMobile;
-    i.setState(i.state);
+    i.setState({ showSidebarMobile: !i.state.showSidebarMobile });
   }
 
   updateUrl(paramUpdates: UrlParams) {
@@ -499,11 +532,14 @@ export class Community extends Component<any, State> {
       let form = new GetComments({
         page: Some(this.state.page),
         limit: Some(fetchLimit),
-        sort: Some(this.state.sort),
+        max_depth: None,
+        sort: Some(postToCommentSortType(this.state.sort)),
         type_: Some(ListingType.All),
         community_name: Some(this.state.communityName),
         community_id: None,
         saved_only: Some(false),
+        post_id: None,
+        parent_id: None,
         auth: auth(false).ok(),
       });
       WebSocketService.Instance.send(wsClient.getComments(form));
@@ -531,9 +567,7 @@ export class Community extends Component<any, State> {
       this.fetchData();
     } else if (op == UserOperation.GetCommunity) {
       let data = wsJsonToRes<GetCommunityResponse>(msg, GetCommunityResponse);
-      this.state.communityRes = Some(data);
-      this.state.communityLoading = false;
-      this.setState(this.state);
+      this.setState({ communityRes: Some(data), communityLoading: false });
       // TODO why is there no auth in this form?
       WebSocketService.Instance.send(
         wsClient.communityJoin({
@@ -547,7 +581,10 @@ export class Community extends Component<any, State> {
     ) {
       let data = wsJsonToRes<CommunityResponse>(msg, CommunityResponse);
       this.state.communityRes.match({
-        some: res => (res.community_view = data.community_view),
+        some: res => {
+          res.community_view = data.community_view;
+          res.discussion_languages = data.discussion_languages;
+        },
         none: void 0,
       });
       this.setState(this.state);
@@ -564,9 +601,7 @@ export class Community extends Component<any, State> {
       this.setState(this.state);
     } else if (op == UserOperation.GetPosts) {
       let data = wsJsonToRes<GetPostsResponse>(msg, GetPostsResponse);
-      this.state.posts = data.posts;
-      this.state.postsLoading = false;
-      this.setState(this.state);
+      this.setState({ posts: data.posts, postsLoading: false });
       restoreScrollPosition(this.context);
       setupTippy();
     } else if (
@@ -574,7 +609,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);
@@ -582,15 +617,24 @@ export class Community extends Component<any, State> {
       this.setState(this.state);
     } else if (op == UserOperation.CreatePost) {
       let data = wsJsonToRes<PostResponse>(msg, PostResponse);
-      this.state.posts.unshift(data.post_view);
+
+      let showPostNotifs = UserService.Instance.myUserInfo
+        .map(m => m.local_user_view.local_user.show_new_post_notifs)
+        .unwrapOr(false);
+
+      // Only push these if you're on the first page, you pass the nsfw check, and it isn't blocked
+      //
       if (
-        UserService.Instance.myUserInfo
-          .map(m => m.local_user_view.local_user.show_new_post_notifs)
-          .unwrapOr(false)
+        this.state.page == 1 &&
+        nsfwCheck(data.post_view) &&
+        !isPostBlocked(data.post_view)
       ) {
-        notifyPost(data.post_view, this.context.router);
+        this.state.posts.unshift(data.post_view);
+        if (showPostNotifs) {
+          notifyPost(data.post_view, this.context.router);
+        }
+        this.setState(this.state);
       }
-      this.setState(this.state);
     } else if (op == UserOperation.CreatePostLike) {
       let data = wsJsonToRes<PostResponse>(msg, PostResponse);
       createPostLikeFindRes(data.post_view, this.state.posts);
@@ -619,9 +663,7 @@ export class Community extends Component<any, State> {
       this.setState(this.state);
     } else if (op == UserOperation.GetComments) {
       let data = wsJsonToRes<GetCommentsResponse>(msg, GetCommentsResponse);
-      this.state.comments = data.comments;
-      this.state.commentsLoading = false;
-      this.setState(this.state);
+      this.setState({ comments: data.comments, commentsLoading: false });
     } else if (
       op == UserOperation.EditComment ||
       op == UserOperation.DeleteComment ||