From c6e3a4213a1f97152979969fd50088e567f894bc Mon Sep 17 00:00:00 2001 From: Dessalines Date: Thu, 22 Sep 2022 11:14:58 -0400 Subject: [PATCH] Hide create community (#787) * Adding post and comment language tagging. Fixes #771 * Hiding create community button. Fixes #754 --- lemmy-translations | 2 +- package.json | 2 +- src/shared/components/app/navbar.tsx | 10 +- .../components/comment/comment-form.tsx | 28 ++++- .../components/comment/comment-node.tsx | 6 + .../components/comment/comment-nodes.tsx | 3 + .../components/comment/comment-report.tsx | 1 + .../components/common/language-select.tsx | 109 ++++++++++++++++++ .../components/common/markdown-textarea.tsx | 38 +++++- .../common/registration-application.tsx | 2 + .../components/community/community-form.tsx | 2 + src/shared/components/community/community.tsx | 2 + src/shared/components/home/home.tsx | 6 +- src/shared/components/home/signup.tsx | 2 + src/shared/components/home/site-form.tsx | 6 + src/shared/components/person/inbox.tsx | 4 + .../components/person/person-details.tsx | 6 + src/shared/components/person/profile.tsx | 1 + src/shared/components/person/settings.tsx | 40 +++++-- src/shared/components/post/create-post.tsx | 1 + src/shared/components/post/metadata-card.tsx | 4 +- src/shared/components/post/post-form.tsx | 26 +++++ src/shared/components/post/post-listing.tsx | 3 + src/shared/components/post/post-listings.tsx | 4 +- src/shared/components/post/post-report.tsx | 1 + src/shared/components/post/post.tsx | 4 + .../private_message/private-message-form.tsx | 2 + src/shared/components/search.tsx | 4 + src/shared/utils.ts | 30 ++++- yarn.lock | 8 +- 30 files changed, 321 insertions(+), 36 deletions(-) create mode 100644 src/shared/components/common/language-select.tsx diff --git a/lemmy-translations b/lemmy-translations index 7ac48ae9..05fb028e 160000 --- a/lemmy-translations +++ b/lemmy-translations @@ -1 +1 @@ -Subproject commit 7ac48ae98271b3b573e28c90b87f9704492e0b62 +Subproject commit 05fb028e8b85de9e7e9d516abb1ebb8a01aad060 diff --git a/package.json b/package.json index 903974e9..f7cd0480 100644 --- a/package.json +++ b/package.json @@ -78,7 +78,7 @@ "eslint-plugin-prettier": "^4.2.1", "husky": "^8.0.1", "import-sort-style-module": "^6.0.0", - "lemmy-js-client": "0.17.0-rc.43", + "lemmy-js-client": "0.17.0-rc.44", "lint-staged": "^13.0.3", "mini-css-extract-plugin": "^2.6.1", "node-fetch": "^2.6.1", diff --git a/src/shared/components/app/navbar.tsx b/src/shared/components/app/navbar.tsx index 34500353..dbf978e1 100644 --- a/src/shared/components/app/navbar.tsx +++ b/src/shared/components/app/navbar.tsx @@ -21,6 +21,7 @@ import { UserService, WebSocketService } from "../../services"; import { amAdmin, auth, + canCreateCommunity, donateLemmyUrl, isBrowser, notifyComment, @@ -274,7 +275,7 @@ export class Navbar extends Component { {i18n.t("create_post")} - {this.canCreateCommunity && ( + {canCreateCommunity(this.props.siteRes) && (
  • { return amAdmin(Some(this.props.siteRes.admins)); } - get canCreateCommunity(): boolean { - let adminOnly = this.props.siteRes.site_view - .map(s => s.site.community_creation_admin_only) - .unwrapOr(false); - return !adminOnly || this.amAdmin; - } - handleToggleExpandNavbar(i: Navbar) { i.setState({ expanded: !i.state.expanded }); } diff --git a/src/shared/components/comment/comment-form.tsx b/src/shared/components/comment/comment-form.tsx index d91e86c1..d9630fda 100644 --- a/src/shared/components/comment/comment-form.tsx +++ b/src/shared/components/comment/comment-form.tsx @@ -7,6 +7,7 @@ import { CommentResponse, CreateComment, EditComment, + Language, UserOperation, wsJsonToRes, wsUserOp, @@ -17,6 +18,7 @@ import { UserService, WebSocketService } from "../../services"; import { auth, capitalizeFirstLetter, + myFirstDiscussionLanguageId, wsClient, wsSubscribe, } from "../../utils"; @@ -32,6 +34,7 @@ interface CommentFormProps { disabled?: boolean; focus?: boolean; onReplyCancel?(): any; + allLanguages: Language[]; } interface CommentFormState { @@ -74,11 +77,19 @@ export class CommentForm extends Component { this.props.edit ? Some(node.comment_view.comment.content) : None, right: () => None, }); + + let selectedLang = this.props.node + .left() + .map(n => n.comment_view.comment.language_id) + .or(myFirstDiscussionLanguageId(UserService.Instance.myUserInfo)); + return (
    {UserService.Instance.myUserInfo.isSome() ? ( { onSubmit={this.handleCommentSubmit} onReplyCancel={this.handleReplyCancel} placeholder={Some(i18n.t("comment_here"))} + allLanguages={this.props.allLanguages} /> ) : (
    @@ -104,27 +116,34 @@ export class CommentForm extends Component { ); } - handleCommentSubmit(msg: { val: string; formId: string }) { + handleCommentSubmit(msg: { + val: Option; + formId: string; + languageId: Option; + }) { let content = msg.val; + let language_id = msg.languageId; this.setState({ formId: Some(msg.formId) }); this.props.node.match({ left: node => { if (this.props.edit) { let form = new EditComment({ - content: Some(content), + content, distinguished: None, form_id: this.state.formId, comment_id: node.comment_view.comment.id, + language_id, auth: auth().unwrap(), }); WebSocketService.Instance.send(wsClient.editComment(form)); } else { let form = new CreateComment({ - content, + content: content.unwrap(), form_id: this.state.formId, post_id: node.comment_view.post.id, parent_id: Some(node.comment_view.comment.id), + language_id, auth: auth().unwrap(), }); WebSocketService.Instance.send(wsClient.createComment(form)); @@ -132,10 +151,11 @@ export class CommentForm extends Component { }, right: postId => { let form = new CreateComment({ - content, + content: content.unwrap(), form_id: this.state.formId, post_id: postId, parent_id: None, + language_id, auth: auth().unwrap(), }); WebSocketService.Instance.send(wsClient.createComment(form)); diff --git a/src/shared/components/comment/comment-node.tsx b/src/shared/components/comment/comment-node.tsx index f5fc6981..6d1621c1 100644 --- a/src/shared/components/comment/comment-node.tsx +++ b/src/shared/components/comment/comment-node.tsx @@ -17,6 +17,7 @@ import { DeleteComment, EditComment, GetComments, + Language, ListingType, MarkCommentReplyAsRead, MarkPersonMentionAsRead, @@ -101,6 +102,7 @@ interface CommentNodeProps { showCommunity?: boolean; enableDownvotes: boolean; viewType: CommentViewType; + allLanguages: Language[]; } export class CommentNode extends Component { @@ -324,6 +326,7 @@ export class CommentNode extends Component { onReplyCancel={this.handleReplyCancel} disabled={this.props.locked} focus + allLanguages={this.props.allLanguages} /> )} {!this.state.showEdit && !this.state.collapsed && ( @@ -1007,6 +1010,7 @@ export class CommentNode extends Component { onReplyCancel={this.handleReplyCancel} disabled={this.props.locked} focus + allLanguages={this.props.allLanguages} /> )} {!this.state.collapsed && node.children.length > 0 && ( @@ -1018,6 +1022,7 @@ export class CommentNode extends Component { maxCommentsShown={None} enableDownvotes={this.props.enableDownvotes} viewType={this.props.viewType} + allLanguages={this.props.allLanguages} /> )} {/* A collapsed clearfix */} @@ -1264,6 +1269,7 @@ export class CommentNode extends Component { form_id: None, // TODO not sure about this content: None, distinguished: Some(!comment.distinguished), + language_id: Some(comment.language_id), auth: auth().unwrap(), }); WebSocketService.Instance.send(wsClient.editComment(form)); diff --git a/src/shared/components/comment/comment-nodes.tsx b/src/shared/components/comment/comment-nodes.tsx index f9484c2d..70810589 100644 --- a/src/shared/components/comment/comment-nodes.tsx +++ b/src/shared/components/comment/comment-nodes.tsx @@ -3,6 +3,7 @@ import { Component } from "inferno"; import { CommentNode as CommentNodeI, CommunityModeratorView, + Language, PersonViewSafe, } from "lemmy-js-client"; import { CommentViewType } from "../../interfaces"; @@ -22,6 +23,7 @@ interface CommentNodesProps { showCommunity?: boolean; enableDownvotes?: boolean; viewType: CommentViewType; + allLanguages: Language[]; } export class CommentNodes extends Component { @@ -51,6 +53,7 @@ export class CommentNodes extends Component { showCommunity={this.props.showCommunity} enableDownvotes={this.props.enableDownvotes} viewType={this.props.viewType} + allLanguages={this.props.allLanguages} /> ))}
    diff --git a/src/shared/components/comment/comment-report.tsx b/src/shared/components/comment/comment-report.tsx index a2d2b10c..f72f8a6a 100644 --- a/src/shared/components/comment/comment-report.tsx +++ b/src/shared/components/comment/comment-report.tsx @@ -64,6 +64,7 @@ export class CommentReport extends Component { enableDownvotes={true} viewOnly={true} showCommunity={true} + allLanguages={[]} />
    {i18n.t("reporter")}: diff --git a/src/shared/components/common/language-select.tsx b/src/shared/components/common/language-select.tsx new file mode 100644 index 00000000..746fea4a --- /dev/null +++ b/src/shared/components/common/language-select.tsx @@ -0,0 +1,109 @@ +import { Option } from "@sniptt/monads"; +import classNames from "classnames"; +import { Component, linkEvent } from "inferno"; +import { Language } from "lemmy-js-client"; +import { i18n } from "../../i18next"; +import { randomStr } from "../../utils"; +import { Icon } from "./icon"; + +interface LanguageSelectProps { + allLanguages: Language[]; + selectedLanguageIds: Option; + multiple: boolean; + onChange(val: number[]): any; +} + +export class LanguageSelect extends Component { + private id = `language-select-${randomStr()}`; + + constructor(props: any, context: any) { + super(props, context); + } + + componentDidMount() { + this.setSelectedValues(); + } + + // Necessary because there is no HTML way to set selected for multiple in value= + setSelectedValues() { + this.props.selectedLanguageIds.map(toString).match({ + some: ids => { + var select = (document.getElementById(this.id) as HTMLSelectElement) + .options; + for (let i = 0; i < select.length; i++) { + let o = select[i]; + if (ids.includes(o.value)) { + o.selected = true; + } + } + }, + none: void 0, + }); + } + + render() { + let selectedLangs = this.props.selectedLanguageIds; + + return ( +
    + +
    + + {this.props.multiple && ( +
    + +
    + )} +
    +
    + ); + } + + handleLanguageChange(i: LanguageSelect, event: any) { + let options: HTMLOptionElement[] = Array.from(event.target.options); + let selected: number[] = options + .filter(o => o.selected) + .map(o => Number(o.value)); + + i.props.onChange(selected); + } + + handleDeselectAll(i: LanguageSelect, event: any) { + event.preventDefault(); + i.props.onChange([]); + } +} diff --git a/src/shared/components/common/markdown-textarea.tsx b/src/shared/components/common/markdown-textarea.tsx index b3374847..69bcd6df 100644 --- a/src/shared/components/common/markdown-textarea.tsx +++ b/src/shared/components/common/markdown-textarea.tsx @@ -2,7 +2,7 @@ import { None, Option, Some } from "@sniptt/monads"; import autosize from "autosize"; import { Component, linkEvent } from "inferno"; import { Prompt } from "inferno-router"; -import { toUndefined } from "lemmy-js-client"; +import { Language, toUndefined } from "lemmy-js-client"; import { pictrsUri } from "../../env"; import { i18n } from "../../i18next"; import { UserService } from "../../services"; @@ -18,9 +18,11 @@ import { toast, } from "../../utils"; import { Icon, Spinner } from "./icon"; +import { LanguageSelect } from "./language-select"; interface MarkdownTextAreaProps { initialContent: Option; + initialLanguageId: Option; placeholder: Option; buttonTitle: Option; maxLength: Option; @@ -28,14 +30,21 @@ interface MarkdownTextAreaProps { focus?: boolean; disabled?: boolean; finished?: boolean; + showLanguage?: boolean; hideNavigationWarnings?: boolean; onContentChange?(val: string): any; onReplyCancel?(): any; - onSubmit?(msg: { val: string; formId: string }): any; + onSubmit?(msg: { + val: Option; + formId: string; + languageId: Option; + }): any; + allLanguages: Language[]; } interface MarkdownTextAreaState { content: Option; + languageId: Option; previewMode: boolean; loading: boolean; imageLoading: boolean; @@ -50,6 +59,7 @@ export class MarkdownTextArea extends Component< private tribute: any; private emptyState: MarkdownTextAreaState = { content: this.props.initialContent, + languageId: this.props.initialLanguageId, previewMode: false, loading: false, imageLoading: false, @@ -58,6 +68,8 @@ export class MarkdownTextArea extends Component< constructor(props: any, context: any) { super(props, context); + this.handleLanguageChange = this.handleLanguageChange.bind(this); + if (isBrowser()) { this.tribute = setupTribute(); } @@ -149,6 +161,18 @@ export class MarkdownTextArea extends Component< {i18n.t("body")}
    + {this.props.showLanguage && ( +
    +
    + +
    +
    + )}
    {this.props.buttonTitle.match({ @@ -394,10 +418,18 @@ export class MarkdownTextArea extends Component< i.setState({ previewMode: !i.state.previewMode }); } + handleLanguageChange(val: number[]) { + this.setState({ languageId: Some(val[0]) }); + } + handleSubmit(i: MarkdownTextArea, event: any) { event.preventDefault(); i.setState({ loading: true }); - let msg = { val: toUndefined(i.state.content), formId: i.formId }; + let msg = { + val: i.state.content, + formId: i.formId, + languageId: i.state.languageId, + }; i.props.onSubmit(msg); } diff --git a/src/shared/components/common/registration-application.tsx b/src/shared/components/common/registration-application.tsx index cac317ee..07fbf203 100644 --- a/src/shared/components/common/registration-application.tsx +++ b/src/shared/components/common/registration-application.tsx @@ -95,11 +95,13 @@ export class RegistrationApplication extends Component<
    diff --git a/src/shared/components/community/community-form.tsx b/src/shared/components/community/community-form.tsx index 8f70f36f..db7cff08 100644 --- a/src/shared/components/community/community-form.tsx +++ b/src/shared/components/community/community-form.tsx @@ -212,10 +212,12 @@ export class CommunityForm extends Component<
    diff --git a/src/shared/components/community/community.tsx b/src/shared/components/community/community.tsx index 5c3746e1..a509df15 100644 --- a/src/shared/components/community/community.tsx +++ b/src/shared/components/community/community.tsx @@ -391,6 +391,7 @@ export class Community extends Component { removeDuplicates enableDownvotes={enableDownvotes(this.state.siteRes)} enableNsfw={enableNsfw(this.state.siteRes)} + allLanguages={this.state.siteRes.all_languages} /> ) ) : this.state.commentsLoading ? ( @@ -407,6 +408,7 @@ export class Community extends Component { moderators={this.state.communityRes.map(r => r.moderators)} admins={Some(this.state.siteRes.admins)} maxCommentsShown={None} + allLanguages={this.state.siteRes.all_languages} /> ); } diff --git a/src/shared/components/home/home.tsx b/src/shared/components/home/home.tsx index 69de7a85..3761998e 100644 --- a/src/shared/components/home/home.tsx +++ b/src/shared/components/home/home.tsx @@ -38,6 +38,7 @@ import { import { UserService, WebSocketService } from "../../services"; import { auth, + canCreateCommunity, commentsToFlatNodes, createCommentLikeRes, createPostLikeFindRes, @@ -430,7 +431,8 @@ export class Home extends Component {
    {this.trendingCommunities()} - {this.createCommunityButton()} + {canCreateCommunity(this.state.siteRes) && + this.createCommunityButton()} {this.exploreCommunitiesButton()}
    @@ -579,6 +581,7 @@ export class Home extends Component { removeDuplicates enableDownvotes={enableDownvotes(this.state.siteRes)} enableNsfw={enableNsfw(this.state.siteRes)} + allLanguages={this.state.siteRes.all_languages} /> ) : ( { showCommunity showContext enableDownvotes={enableDownvotes(this.state.siteRes)} + allLanguages={this.state.siteRes.all_languages} /> ); } diff --git a/src/shared/components/home/signup.tsx b/src/shared/components/home/signup.tsx index d7dc2a27..aa40aa0c 100644 --- a/src/shared/components/home/signup.tsx +++ b/src/shared/components/home/signup.tsx @@ -295,11 +295,13 @@ export class Signup extends Component {
    diff --git a/src/shared/components/home/site-form.tsx b/src/shared/components/home/site-form.tsx index 4f275cfd..74eef0a3 100644 --- a/src/shared/components/home/site-form.tsx +++ b/src/shared/components/home/site-form.tsx @@ -212,11 +212,13 @@ export class SiteForm extends Component {
    @@ -227,11 +229,13 @@ export class SiteForm extends Component {
    @@ -243,11 +247,13 @@ export class SiteForm extends Component {
    diff --git a/src/shared/components/person/inbox.tsx b/src/shared/components/person/inbox.tsx index 858364f9..2ba6dce3 100644 --- a/src/shared/components/person/inbox.tsx +++ b/src/shared/components/person/inbox.tsx @@ -398,6 +398,7 @@ export class Inbox extends Component { showCommunity showContext enableDownvotes={enableDownvotes(this.state.siteRes)} + allLanguages={this.state.siteRes.all_languages} /> ); case ReplyEnum.Mention: @@ -420,6 +421,7 @@ export class Inbox extends Component { showCommunity showContext enableDownvotes={enableDownvotes(this.state.siteRes)} + allLanguages={this.state.siteRes.all_languages} /> ); case ReplyEnum.Message: @@ -452,6 +454,7 @@ export class Inbox extends Component { showCommunity showContext enableDownvotes={enableDownvotes(this.state.siteRes)} + allLanguages={this.state.siteRes.all_languages} /> ); @@ -473,6 +476,7 @@ export class Inbox extends Component { showCommunity showContext enableDownvotes={enableDownvotes(this.state.siteRes)} + allLanguages={this.state.siteRes.all_languages} /> ))} diff --git a/src/shared/components/person/person-details.tsx b/src/shared/components/person/person-details.tsx index 8eaa5f0a..e228cbdf 100644 --- a/src/shared/components/person/person-details.tsx +++ b/src/shared/components/person/person-details.tsx @@ -3,6 +3,7 @@ import { Component } from "inferno"; import { CommentView, GetPersonDetailsResponse, + Language, PersonViewSafe, PostView, SortType, @@ -16,6 +17,7 @@ import { PostListing } from "../post/post-listing"; interface PersonDetailsProps { personRes: GetPersonDetailsResponse; admins: PersonViewSafe[]; + allLanguages: Language[]; page: number; limit: number; sort: SortType; @@ -99,6 +101,7 @@ export class PersonDetails extends Component { showCommunity showContext enableDownvotes={this.props.enableDownvotes} + allLanguages={this.props.allLanguages} /> ); } @@ -114,6 +117,7 @@ export class PersonDetails extends Component { showCommunity enableDownvotes={this.props.enableDownvotes} enableNsfw={this.props.enableNsfw} + allLanguages={this.props.allLanguages} /> ); } @@ -171,6 +175,7 @@ export class PersonDetails extends Component { showCommunity showContext enableDownvotes={this.props.enableDownvotes} + allLanguages={this.props.allLanguages} /> ); @@ -189,6 +194,7 @@ export class PersonDetails extends Component { moderators={None} enableDownvotes={this.props.enableDownvotes} enableNsfw={this.props.enableNsfw} + allLanguages={this.props.allLanguages} />
    diff --git a/src/shared/components/person/profile.tsx b/src/shared/components/person/profile.tsx index 0a8e4c09..b9387284 100644 --- a/src/shared/components/person/profile.tsx +++ b/src/shared/components/person/profile.tsx @@ -283,6 +283,7 @@ export class Profile extends Component { enableNsfw={enableNsfw(this.state.siteRes)} view={this.state.view} onPageChange={this.handlePageChange} + allLanguages={this.state.siteRes.all_languages} /> diff --git a/src/shared/components/person/settings.tsx b/src/shared/components/person/settings.tsx index 838c1ec1..e6d8896f 100644 --- a/src/shared/components/person/settings.tsx +++ b/src/shared/components/person/settings.tsx @@ -54,6 +54,7 @@ import { import { HtmlTags } from "../common/html-tags"; 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"; import { MarkdownTextArea } from "../common/markdown-textarea"; import { SortSelect } from "../common/sort-select"; @@ -99,7 +100,8 @@ export class Settings extends Component { default_sort_type: None, default_listing_type: None, theme: None, - lang: None, + interface_language: None, + discussion_languages: None, avatar: None, banner: None, display_name: None, @@ -140,6 +142,8 @@ export class Settings extends Component { this.handleSortTypeChange = this.handleSortTypeChange.bind(this); this.handleListingTypeChange = this.handleListingTypeChange.bind(this); this.handleBioChange = this.handleBioChange.bind(this); + this.handleDiscussionLanguageChange = + this.handleDiscussionLanguageChange.bind(this); this.handleAvatarUpload = this.handleAvatarUpload.bind(this); this.handleAvatarRemove = this.handleAvatarRemove.bind(this); @@ -163,7 +167,7 @@ export class Settings extends Component { theme: Some(luv.local_user.theme ? luv.local_user.theme : "browser"), default_sort_type: Some(luv.local_user.default_sort_type), default_listing_type: Some(luv.local_user.default_listing_type), - lang: Some(luv.local_user.lang), + interface_language: Some(luv.local_user.interface_language), avatar: luv.person.avatar, banner: luv.person.banner, display_name: luv.person.display_name, @@ -479,6 +483,8 @@ export class Settings extends Component { } saveUserSettingsHtmlForm() { + let selectedLangs = this.state.saveUserSettingsForm.discussion_languages; + return ( <>
    {i18n.t("settings")}
    @@ -509,11 +515,13 @@ export class Settings extends Component {
    @@ -578,17 +586,19 @@ export class Settings extends Component {
    +
    diff --git a/src/shared/components/post/metadata-card.tsx b/src/shared/components/post/metadata-card.tsx index a3b5b75e..4dc68fdf 100644 --- a/src/shared/components/post/metadata-card.tsx +++ b/src/shared/components/post/metadata-card.tsx @@ -72,7 +72,7 @@ export class MetadataCard extends Component< ), none: <>, })} - {post.embed_html.isSome() && ( + {post.embed_video_url.isSome() && (