From e2a29a5bada0a00c998c2b57e2d99098bc793b4b Mon Sep 17 00:00:00 2001
From: Anon <makotech222@users.noreply.github.com>
Date: Sun, 20 Nov 2022 10:08:44 -0600
Subject: [PATCH] Add Taglines support (#854)

* Add Taglines support

* Fix issue with deletion not rendering properly.

* Address PR comments

* Missed alllanguages

* Cleanup tagline match

* Update js client

* Move taglines to siteres

* Only show taglines editor after site setup

* Update js client
---
 package.json                             |  2 +-
 src/assets/css/main.css                  |  2 +-
 src/shared/components/home/home.tsx      | 10 +++
 src/shared/components/home/site-form.tsx | 94 +++++++++++++++++++++++-
 src/shared/utils.ts                      |  4 +
 5 files changed, 107 insertions(+), 5 deletions(-)

diff --git a/package.json b/package.json
index e95b361..83bc271 100644
--- a/package.json
+++ b/package.json
@@ -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.51",
+    "lemmy-js-client": "0.17.0-rc.53",
     "markdown-it": "^13.0.1",
     "markdown-it-container": "^3.0.0",
     "markdown-it-footnote": "^3.0.3",
diff --git a/src/assets/css/main.css b/src/assets/css/main.css
index b5a33af..a2a2a65 100644
--- a/src/assets/css/main.css
+++ b/src/assets/css/main.css
@@ -385,4 +385,4 @@ br.big {
   display: -webkit-box;
   -webkit-line-clamp: 3;
   -webkit-box-orient: vertical;
-}
+}
\ No newline at end of file
diff --git a/src/shared/components/home/home.tsx b/src/shared/components/home/home.tsx
index 08176bb..3e5f471 100644
--- a/src/shared/components/home/home.tsx
+++ b/src/shared/components/home/home.tsx
@@ -50,9 +50,11 @@ import {
   getDataTypeFromProps,
   getListingTypeFromProps,
   getPageFromProps,
+  getRandomFromList,
   getSortTypeFromProps,
   isBrowser,
   isPostBlocked,
+  mdToHtml,
   notifyPost,
   nsfwCheck,
   postToCommentSortType,
@@ -94,6 +96,7 @@ interface HomeState {
   showSidebarMobile: boolean;
   subscribedCollapsed: boolean;
   loading: boolean;
+  tagline: Option<string>;
 }
 
 interface HomeProps {
@@ -137,6 +140,7 @@ export class Home extends Component<any, HomeState> {
     dataType: getDataTypeFromProps(this.props),
     sort: getSortTypeFromProps(this.props),
     page: getPageFromProps(this.props),
+    tagline: None
   };
 
   constructor(props: any, context: any) {
@@ -170,10 +174,12 @@ export class Home extends Component<any, HomeState> {
           wsClient.communityJoin({ community_id: 0 })
         );
       }
+      const taglines = this.state.siteRes.taglines;
       this.state = {
         ...this.state,
         trendingCommunities: trendingRes.communities,
         loading: false,
+        tagline: taglines.map(tls => getRandomFromList(tls).content)
       };
     } else {
       this.fetchTrendingCommunities();
@@ -329,6 +335,10 @@ export class Home extends Component<any, HomeState> {
         {this.state.siteRes.site_view.local_site.site_setup && (
           <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>,
+                none: <></>,
+              })}
               <div className="d-block d-md-none">{this.mobileView()}</div>
               {this.posts()}
             </main>
diff --git a/src/shared/components/home/site-form.tsx b/src/shared/components/home/site-form.tsx
index 982afd5..c418f20 100644
--- a/src/shared/components/home/site-form.tsx
+++ b/src/shared/components/home/site-form.tsx
@@ -1,5 +1,5 @@
 import { None, Option, Some } from "@sniptt/monads";
-import { Component, linkEvent } from "inferno";
+import { Component, InfernoMouseEvent, linkEvent } from "inferno";
 import { Prompt } from "inferno-router";
 import {
   CreateSite,
@@ -16,7 +16,7 @@ import {
   fetchThemeList,
   wsClient,
 } from "../../utils";
-import { Spinner } from "../common/icon";
+import { Icon, Spinner } from "../common/icon";
 import { ImageUploadForm } from "../common/image-upload-form";
 import { LanguageSelect } from "../common/language-select";
 import { ListingTypeSelect } from "../common/listing-type-select";
@@ -78,6 +78,7 @@ export class SiteForm extends Component<SiteFormProps, SiteFormState> {
       captcha_difficulty: None,
       allowed_instances: None,
       blocked_instances: None,
+      taglines: None,
       auth: undefined,
     }),
     loading: false,
@@ -159,6 +160,7 @@ export class SiteForm extends Component<SiteFormProps, SiteFormState> {
         blocked_instances: this.props.siteRes.federated_instances.andThen(
           f => f.blocked
         ),
+        taglines: this.props.siteRes.taglines.map(x => x.map(y => y.content)),
         auth: undefined,
       }),
     };
@@ -1032,6 +1034,57 @@ export class SiteForm extends Component<SiteFormProps, SiteFormState> {
               />
             </div>
           </div>
+          {siteSetup && <div className="form-group row">
+            <h5 className="col-12">{i18n.t("taglines")}</h5>
+            <div className="table-responsive col-12">
+              <table id="taglines_table" className="table table-sm table-hover">
+                <thead className="pointer"></thead>
+                <tbody>
+                  {this.state.siteForm.taglines
+                    .unwrapOr([])
+                    .map((cv, index) => (
+                      <tr key={index}>
+                        <td>
+                          <MarkdownTextArea
+                            initialContent={Some(cv)}
+                            initialLanguageId={None}
+                            placeholder={None}
+                            buttonTitle={None}
+                            maxLength={None}
+                            onContentChange={s =>
+                              this.handleTaglineChange(this, index, s)
+                            }
+                            hideNavigationWarnings
+                            allLanguages={this.props.siteRes.all_languages}
+                          />
+                        </td>
+                        <td className="text-right">
+                          <button
+                            className="btn btn-link btn-animate text-muted"
+                            onClick={e =>
+                              this.handleDeleteTaglineClick(this, index, e)
+                            }
+                            data-tippy-content={i18n.t("delete")}
+                            aria-label={i18n.t("delete")}
+                          >
+                            <Icon
+                              icon="trash"
+                              classes={`icon-inline text-danger`}
+                            />
+                          </button>
+                        </td>
+                      </tr>
+                    ))}
+                </tbody>
+              </table>
+              <button
+                className="btn btn-sm btn-secondary mr-2"
+                onClick={e => this.handleAddTaglineClick(this, e)}
+              >
+                {i18n.t("add_tagline")}
+              </button>
+            </div>
+          </div>}
           <div className="form-group row">
             <div className="col-12">
               <button
@@ -1058,7 +1111,6 @@ export class SiteForm extends Component<SiteFormProps, SiteFormState> {
     event.preventDefault();
     i.setState({ loading: true });
     i.setState(s => ((s.siteForm.auth = auth().unwrap()), s));
-
     if (i.props.siteRes.site_view.local_site.site_setup) {
       WebSocketService.Instance.send(wsClient.editSite(i.state.siteForm));
     } else {
@@ -1141,6 +1193,42 @@ export class SiteForm extends Component<SiteFormProps, SiteFormState> {
     this.setState(s => ((s.siteForm.legal_information = Some(val)), s));
   }
 
+  handleTaglineChange(i: SiteForm, index: number, val: string) {
+    i.state.siteForm.taglines.match({
+      some: tls => { tls[index] = val; },
+      none: void 0
+    });
+    i.setState(i.state);
+  }
+
+  handleDeleteTaglineClick(
+    i: SiteForm,
+    index: number,
+    event: InfernoMouseEvent<HTMLButtonElement>
+  ) {
+    event.preventDefault();
+    if (i.state.siteForm.taglines.isSome()){
+      let taglines = i.state.siteForm.taglines.unwrap();
+      taglines.splice(index, 1);
+      i.state.siteForm.taglines = None; // force rerender of table rows
+      i.setState(i.state);
+      i.state.siteForm.taglines = Some(taglines);
+      i.setState(i.state);
+    }
+  }
+
+  handleAddTaglineClick(
+    i: SiteForm,
+    event: InfernoMouseEvent<HTMLButtonElement>
+  ) {
+    event.preventDefault();
+    if (i.state.siteForm.taglines.isNone()){
+      i.state.siteForm.taglines = Some([]);
+    }
+    i.state.siteForm.taglines.unwrap().push("");
+    i.setState(i.state);
+  }
+
   handleSiteApplicationQuestionChange(val: string) {
     this.setState(s => ((s.siteForm.application_question = Some(val)), s));
   }
diff --git a/src/shared/utils.ts b/src/shared/utils.ts
index 54536b8..26b5168 100644
--- a/src/shared/utils.ts
+++ b/src/shared/utils.ts
@@ -1525,3 +1525,7 @@ export function nsfwCheck(
         .unwrapOr(false))
   );
 }
+
+export function getRandomFromList<T>(list : T[]) : T{
+  return list[Math.floor(Math.random() * list.length)];
+}
-- 
2.44.1