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
This commit is contained in:
Anon 2022-11-20 10:08:44 -06:00 committed by GitHub
parent 36c1c1f262
commit e2a29a5bad
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
5 changed files with 107 additions and 5 deletions

View file

@ -47,7 +47,7 @@
"inferno-server": "^8.0.3", "inferno-server": "^8.0.3",
"isomorphic-cookie": "^1.2.4", "isomorphic-cookie": "^1.2.4",
"jwt-decode": "^3.1.2", "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": "^13.0.1",
"markdown-it-container": "^3.0.0", "markdown-it-container": "^3.0.0",
"markdown-it-footnote": "^3.0.3", "markdown-it-footnote": "^3.0.3",

View file

@ -50,9 +50,11 @@ import {
getDataTypeFromProps, getDataTypeFromProps,
getListingTypeFromProps, getListingTypeFromProps,
getPageFromProps, getPageFromProps,
getRandomFromList,
getSortTypeFromProps, getSortTypeFromProps,
isBrowser, isBrowser,
isPostBlocked, isPostBlocked,
mdToHtml,
notifyPost, notifyPost,
nsfwCheck, nsfwCheck,
postToCommentSortType, postToCommentSortType,
@ -94,6 +96,7 @@ interface HomeState {
showSidebarMobile: boolean; showSidebarMobile: boolean;
subscribedCollapsed: boolean; subscribedCollapsed: boolean;
loading: boolean; loading: boolean;
tagline: Option<string>;
} }
interface HomeProps { interface HomeProps {
@ -137,6 +140,7 @@ export class Home extends Component<any, HomeState> {
dataType: getDataTypeFromProps(this.props), dataType: getDataTypeFromProps(this.props),
sort: getSortTypeFromProps(this.props), sort: getSortTypeFromProps(this.props),
page: getPageFromProps(this.props), page: getPageFromProps(this.props),
tagline: None
}; };
constructor(props: any, context: any) { constructor(props: any, context: any) {
@ -170,10 +174,12 @@ export class Home extends Component<any, HomeState> {
wsClient.communityJoin({ community_id: 0 }) wsClient.communityJoin({ community_id: 0 })
); );
} }
const taglines = this.state.siteRes.taglines;
this.state = { this.state = {
...this.state, ...this.state,
trendingCommunities: trendingRes.communities, trendingCommunities: trendingRes.communities,
loading: false, loading: false,
tagline: taglines.map(tls => getRandomFromList(tls).content)
}; };
} else { } else {
this.fetchTrendingCommunities(); this.fetchTrendingCommunities();
@ -329,6 +335,10 @@ export class Home extends Component<any, HomeState> {
{this.state.siteRes.site_view.local_site.site_setup && ( {this.state.siteRes.site_view.local_site.site_setup && (
<div className="row"> <div className="row">
<main role="main" className="col-12 col-md-8"> <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> <div className="d-block d-md-none">{this.mobileView()}</div>
{this.posts()} {this.posts()}
</main> </main>

View file

@ -1,5 +1,5 @@
import { None, Option, Some } from "@sniptt/monads"; import { None, Option, Some } from "@sniptt/monads";
import { Component, linkEvent } from "inferno"; import { Component, InfernoMouseEvent, linkEvent } from "inferno";
import { Prompt } from "inferno-router"; import { Prompt } from "inferno-router";
import { import {
CreateSite, CreateSite,
@ -16,7 +16,7 @@ import {
fetchThemeList, fetchThemeList,
wsClient, wsClient,
} from "../../utils"; } from "../../utils";
import { Spinner } from "../common/icon"; import { Icon, Spinner } from "../common/icon";
import { ImageUploadForm } from "../common/image-upload-form"; import { ImageUploadForm } from "../common/image-upload-form";
import { LanguageSelect } from "../common/language-select"; import { LanguageSelect } from "../common/language-select";
import { ListingTypeSelect } from "../common/listing-type-select"; import { ListingTypeSelect } from "../common/listing-type-select";
@ -78,6 +78,7 @@ export class SiteForm extends Component<SiteFormProps, SiteFormState> {
captcha_difficulty: None, captcha_difficulty: None,
allowed_instances: None, allowed_instances: None,
blocked_instances: None, blocked_instances: None,
taglines: None,
auth: undefined, auth: undefined,
}), }),
loading: false, loading: false,
@ -159,6 +160,7 @@ export class SiteForm extends Component<SiteFormProps, SiteFormState> {
blocked_instances: this.props.siteRes.federated_instances.andThen( blocked_instances: this.props.siteRes.federated_instances.andThen(
f => f.blocked f => f.blocked
), ),
taglines: this.props.siteRes.taglines.map(x => x.map(y => y.content)),
auth: undefined, auth: undefined,
}), }),
}; };
@ -1032,6 +1034,57 @@ export class SiteForm extends Component<SiteFormProps, SiteFormState> {
/> />
</div> </div>
</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="form-group row">
<div className="col-12"> <div className="col-12">
<button <button
@ -1058,7 +1111,6 @@ export class SiteForm extends Component<SiteFormProps, SiteFormState> {
event.preventDefault(); event.preventDefault();
i.setState({ loading: true }); i.setState({ loading: true });
i.setState(s => ((s.siteForm.auth = auth().unwrap()), s)); i.setState(s => ((s.siteForm.auth = auth().unwrap()), s));
if (i.props.siteRes.site_view.local_site.site_setup) { if (i.props.siteRes.site_view.local_site.site_setup) {
WebSocketService.Instance.send(wsClient.editSite(i.state.siteForm)); WebSocketService.Instance.send(wsClient.editSite(i.state.siteForm));
} else { } else {
@ -1141,6 +1193,42 @@ export class SiteForm extends Component<SiteFormProps, SiteFormState> {
this.setState(s => ((s.siteForm.legal_information = Some(val)), s)); 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) { handleSiteApplicationQuestionChange(val: string) {
this.setState(s => ((s.siteForm.application_question = Some(val)), s)); this.setState(s => ((s.siteForm.application_question = Some(val)), s));
} }

View file

@ -1525,3 +1525,7 @@ export function nsfwCheck(
.unwrapOr(false)) .unwrapOr(false))
); );
} }
export function getRandomFromList<T>(list : T[]) : T{
return list[Math.floor(Math.random() * list.length)];
}