Skip to content

Commit afeb640

Browse files
authored
Adding Community Language fixes. #783 (#868)
* Partially done with language tagging. #783 * A few more updates.
1 parent 003b177 commit afeb640

33 files changed

+360
-131
lines changed

.prettierrc.js

-4
This file was deleted.

.prettierrc.json

+4
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
{
2+
"arrowParens": "avoid",
3+
"semi": true
4+
}

package.json

+7-7
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99
"build:prod": "webpack --mode=production",
1010
"clean": "yarn run rimraf dist",
1111
"dev": "yarn start",
12-
"lint": "node generate_translations.js && tsc --noEmit && eslint --report-unused-disable-directives --ext .js,.ts,.tsx src",
12+
"lint": "node generate_translations.js && tsc --noEmit && eslint --report-unused-disable-directives --ext .js,.ts,.tsx src && prettier --check 'src/**/*.tsx'",
1313
"prebuild:dev": "yarn clean && node generate_translations.js",
1414
"prebuild:prod": "yarn clean && node generate_translations.js",
1515
"prepare": "husky install",
@@ -38,16 +38,16 @@
3838
"express": "~4.18.1",
3939
"html-to-text": "^8.2.1",
4040
"i18next": "^21.8.14",
41-
"inferno": "^8.0.3",
42-
"inferno-create-element": "^8.0.3",
41+
"inferno": "^8.0.5",
42+
"inferno-create-element": "^8.0.5",
4343
"inferno-helmet": "^5.2.1",
44-
"inferno-hydrate": "^8.0.3",
44+
"inferno-hydrate": "^8.0.5",
4545
"inferno-i18next-dess": "0.0.2",
46-
"inferno-router": "^8.0.3",
47-
"inferno-server": "^8.0.3",
46+
"inferno-router": "^8.0.5",
47+
"inferno-server": "^8.0.5",
4848
"isomorphic-cookie": "^1.2.4",
4949
"jwt-decode": "^3.1.2",
50-
"lemmy-js-client": "0.17.0-rc.56",
50+
"lemmy-js-client": "0.17.0-rc.57",
5151
"markdown-it": "^13.0.1",
5252
"markdown-it-container": "^3.0.0",
5353
"markdown-it-footnote": "^3.0.3",

src/assets/css/main.css

+9-1
Original file line numberDiff line numberDiff line change
@@ -385,4 +385,12 @@ br.big {
385385
display: -webkit-box;
386386
-webkit-line-clamp: 3;
387387
-webkit-box-orient: vertical;
388-
}
388+
}
389+
390+
.lang-select-action {
391+
width: 100px;
392+
}
393+
394+
.lang-select-action:focus {
395+
width: auto;
396+
}

src/shared/components/comment/comment-form.tsx

+9-1
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@ interface CommentFormProps {
3535
focus?: boolean;
3636
onReplyCancel?(): any;
3737
allLanguages: Language[];
38+
siteLanguages: number[];
3839
}
3940

4041
interface CommentFormState {
@@ -81,7 +82,13 @@ export class CommentForm extends Component<CommentFormProps, CommentFormState> {
8182
let selectedLang = this.props.node
8283
.left()
8384
.map(n => n.comment_view.comment.language_id)
84-
.or(myFirstDiscussionLanguageId(UserService.Instance.myUserInfo));
85+
.or(
86+
myFirstDiscussionLanguageId(
87+
this.props.allLanguages,
88+
this.props.siteLanguages,
89+
UserService.Instance.myUserInfo
90+
)
91+
);
8592

8693
return (
8794
<div className="mb-3">
@@ -100,6 +107,7 @@ export class CommentForm extends Component<CommentFormProps, CommentFormState> {
100107
onReplyCancel={this.handleReplyCancel}
101108
placeholder={Some(i18n.t("comment_here"))}
102109
allLanguages={this.props.allLanguages}
110+
siteLanguages={this.props.siteLanguages}
103111
/>
104112
) : (
105113
<div className="alert alert-warning" role="alert">

src/shared/components/comment/comment-node.tsx

+4
Original file line numberDiff line numberDiff line change
@@ -104,6 +104,7 @@ interface CommentNodeProps {
104104
enableDownvotes: boolean;
105105
viewType: CommentViewType;
106106
allLanguages: Language[];
107+
siteLanguages: number[];
107108
hideImages?: boolean;
108109
}
109110

@@ -329,6 +330,7 @@ export class CommentNode extends Component<CommentNodeProps, CommentNodeState> {
329330
disabled={this.props.locked}
330331
focus
331332
allLanguages={this.props.allLanguages}
333+
siteLanguages={this.props.siteLanguages}
332334
/>
333335
)}
334336
{!this.state.showEdit && !this.state.collapsed && (
@@ -1015,6 +1017,7 @@ export class CommentNode extends Component<CommentNodeProps, CommentNodeState> {
10151017
disabled={this.props.locked}
10161018
focus
10171019
allLanguages={this.props.allLanguages}
1020+
siteLanguages={this.props.siteLanguages}
10181021
/>
10191022
)}
10201023
{!this.state.collapsed && node.children.length > 0 && (
@@ -1027,6 +1030,7 @@ export class CommentNode extends Component<CommentNodeProps, CommentNodeState> {
10271030
enableDownvotes={this.props.enableDownvotes}
10281031
viewType={this.props.viewType}
10291032
allLanguages={this.props.allLanguages}
1033+
siteLanguages={this.props.siteLanguages}
10301034
hideImages={this.props.hideImages}
10311035
/>
10321036
)}

src/shared/components/comment/comment-nodes.tsx

+2
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ interface CommentNodesProps {
2424
enableDownvotes?: boolean;
2525
viewType: CommentViewType;
2626
allLanguages: Language[];
27+
siteLanguages: number[];
2728
hideImages?: boolean;
2829
}
2930

@@ -55,6 +56,7 @@ export class CommentNodes extends Component<CommentNodesProps, any> {
5556
enableDownvotes={this.props.enableDownvotes}
5657
viewType={this.props.viewType}
5758
allLanguages={this.props.allLanguages}
59+
siteLanguages={this.props.siteLanguages}
5860
hideImages={this.props.hideImages}
5961
/>
6062
))}

src/shared/components/comment/comment-report.tsx

+1
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,7 @@ export class CommentReport extends Component<CommentReportProps, any> {
6565
viewOnly={true}
6666
showCommunity={true}
6767
allLanguages={[]}
68+
siteLanguages={[]}
6869
hideImages
6970
/>
7071
<div>

src/shared/components/common/language-select.tsx

+44-21
Original file line numberDiff line numberDiff line change
@@ -3,14 +3,19 @@ import classNames from "classnames";
33
import { Component, linkEvent } from "inferno";
44
import { Language } from "lemmy-js-client";
55
import { i18n } from "../../i18next";
6-
import { randomStr } from "../../utils";
6+
import { UserService } from "../../services/UserService";
7+
import { randomStr, selectableLanguages } from "../../utils";
78
import { Icon } from "./icon";
89

910
interface LanguageSelectProps {
1011
allLanguages: Language[];
12+
siteLanguages: number[];
1113
selectedLanguageIds: Option<number[]>;
1214
multiple: boolean;
1315
onChange(val: number[]): any;
16+
showAll?: boolean;
17+
showSite?: boolean;
18+
iconVersion?: boolean;
1419
}
1520

1621
export class LanguageSelect extends Component<LanguageSelectProps, any> {
@@ -42,9 +47,9 @@ export class LanguageSelect extends Component<LanguageSelectProps, any> {
4247
}
4348

4449
render() {
45-
let selectedLangs = this.props.selectedLanguageIds;
46-
47-
return (
50+
return this.props.iconVersion ? (
51+
this.selectBtn
52+
) : (
4853
<div className="form-group row">
4954
<label
5055
className={classNames("col-form-label", {
@@ -61,23 +66,7 @@ export class LanguageSelect extends Component<LanguageSelectProps, any> {
6166
"col-sm-10": !this.props.multiple,
6267
})}
6368
>
64-
<select
65-
className="form-control custom-select"
66-
id={this.id}
67-
onChange={linkEvent(this, this.handleLanguageChange)}
68-
aria-label="action"
69-
multiple={this.props.multiple}
70-
>
71-
{this.props.allLanguages.map(l => (
72-
<option
73-
key={l.id}
74-
value={l.id}
75-
selected={selectedLangs.unwrapOr([]).includes(l.id)}
76-
>
77-
{l.name}
78-
</option>
79-
))}
80-
</select>
69+
{this.selectBtn}
8170
{this.props.multiple && (
8271
<div className="input-group-append">
8372
<button
@@ -93,6 +82,40 @@ export class LanguageSelect extends Component<LanguageSelectProps, any> {
9382
);
9483
}
9584

85+
get selectBtn() {
86+
let selectedLangs = this.props.selectedLanguageIds;
87+
let filteredLangs = selectableLanguages(
88+
this.props.allLanguages,
89+
this.props.siteLanguages,
90+
this.props.showAll,
91+
this.props.showSite,
92+
UserService.Instance.myUserInfo
93+
);
94+
95+
return (
96+
<select
97+
className={classNames("lang-select-action", {
98+
"form-control custom-select": !this.props.iconVersion,
99+
"btn btn-sm text-muted": this.props.iconVersion,
100+
})}
101+
id={this.id}
102+
onChange={linkEvent(this, this.handleLanguageChange)}
103+
aria-label="action"
104+
multiple={this.props.multiple}
105+
>
106+
{filteredLangs.map(l => (
107+
<option
108+
key={l.id}
109+
value={l.id}
110+
selected={selectedLangs.unwrapOr([]).includes(l.id)}
111+
>
112+
{l.name}
113+
</option>
114+
))}
115+
</select>
116+
);
117+
}
118+
96119
handleLanguageChange(i: LanguageSelect, event: any) {
97120
let options: HTMLOptionElement[] = Array.from(event.target.options);
98121
let selected: number[] = options

src/shared/components/common/markdown-textarea.tsx

+12-12
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@ interface MarkdownTextAreaProps {
4141
languageId: Option<number>;
4242
}): any;
4343
allLanguages: Language[];
44+
siteLanguages: number[];
4445
}
4546

4647
interface MarkdownTextAreaState {
@@ -164,18 +165,6 @@ export class MarkdownTextArea extends Component<
164165
{i18n.t("body")}
165166
</label>
166167
</div>
167-
{this.props.showLanguage && (
168-
<div className="row justify-content-end">
169-
<div className="col-sm-8">
170-
<LanguageSelect
171-
allLanguages={this.props.allLanguages}
172-
selectedLanguageIds={this.state.languageId.map(Array.of)}
173-
multiple={false}
174-
onChange={this.handleLanguageChange}
175-
/>
176-
</div>
177-
</div>
178-
)}
179168
<div className="row">
180169
<div className="col-sm-12 d-flex flex-wrap">
181170
{this.props.buttonTitle.match({
@@ -215,6 +204,17 @@ export class MarkdownTextArea extends Component<
215204
)}
216205
{/* A flex expander */}
217206
<div className="flex-grow-1"></div>
207+
208+
{this.props.showLanguage && (
209+
<LanguageSelect
210+
iconVersion
211+
allLanguages={this.props.allLanguages}
212+
selectedLanguageIds={this.state.languageId.map(Array.of)}
213+
siteLanguages={this.props.siteLanguages}
214+
multiple={false}
215+
onChange={this.handleLanguageChange}
216+
/>
217+
)}
218218
<button
219219
className="btn btn-sm text-muted"
220220
data-tippy-content={i18n.t("bold")}

src/shared/components/common/registration-application.tsx

+1
Original file line numberDiff line numberDiff line change
@@ -102,6 +102,7 @@ export class RegistrationApplication extends Component<
102102
maxLength={None}
103103
hideNavigationWarnings
104104
allLanguages={[]}
105+
siteLanguages={[]}
105106
/>
106107
</div>
107108
</div>

src/shared/components/community/community-form.tsx

+24
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ import {
66
CommunityView,
77
CreateCommunity,
88
EditCommunity,
9+
Language,
910
toUndefined,
1011
UserOperation,
1112
wsJsonToRes,
@@ -23,10 +24,14 @@ import {
2324
} from "../../utils";
2425
import { Icon, Spinner } from "../common/icon";
2526
import { ImageUploadForm } from "../common/image-upload-form";
27+
import { LanguageSelect } from "../common/language-select";
2628
import { MarkdownTextArea } from "../common/markdown-textarea";
2729

2830
interface CommunityFormProps {
2931
community_view: Option<CommunityView>; // If a community is given, that means this is an edit
32+
allLanguages: Language[];
33+
siteLanguages: number[];
34+
communityLanguages: Option<number[]>;
3035
onCancel?(): any;
3136
onCreate?(community: CommunityView): any;
3237
onEdit?(community: CommunityView): any;
@@ -50,6 +55,7 @@ export class CommunityForm extends Component<
5055
name: undefined,
5156
title: undefined,
5257
description: None,
58+
discussion_languages: this.props.communityLanguages,
5359
nsfw: None,
5460
icon: None,
5561
banner: None,
@@ -73,6 +79,9 @@ export class CommunityForm extends Component<
7379
this.handleBannerUpload = this.handleBannerUpload.bind(this);
7480
this.handleBannerRemove = this.handleBannerRemove.bind(this);
7581

82+
this.handleDiscussionLanguageChange =
83+
this.handleDiscussionLanguageChange.bind(this);
84+
7685
this.parseMessage = this.parseMessage.bind(this);
7786
this.subscription = wsSubscribe(this.parseMessage);
7887

@@ -90,6 +99,7 @@ export class CommunityForm extends Component<
9099
posting_restricted_to_mods: Some(
91100
cv.community.posting_restricted_to_mods
92101
),
102+
discussion_languages: this.props.communityLanguages,
93103
auth: undefined,
94104
}),
95105
};
@@ -218,6 +228,7 @@ export class CommunityForm extends Component<
218228
maxLength={None}
219229
onContentChange={this.handleCommunityDescriptionChange}
220230
allLanguages={[]}
231+
siteLanguages={[]}
221232
/>
222233
</div>
223234
</div>
@@ -261,6 +272,14 @@ export class CommunityForm extends Component<
261272
</div>
262273
</div>
263274
</div>
275+
<LanguageSelect
276+
allLanguages={this.props.allLanguages}
277+
siteLanguages={this.props.siteLanguages}
278+
showSite
279+
selectedLanguageIds={this.state.communityForm.discussion_languages}
280+
multiple={true}
281+
onChange={this.handleDiscussionLanguageChange}
282+
/>
264283
<div className="form-group row">
265284
<div className="col-12">
266285
<button
@@ -308,6 +327,7 @@ export class CommunityForm extends Component<
308327
banner: cForm.banner,
309328
nsfw: cForm.nsfw,
310329
posting_restricted_to_mods: cForm.posting_restricted_to_mods,
330+
discussion_languages: cForm.discussion_languages,
311331
auth: cForm.auth,
312332
});
313333

@@ -368,6 +388,10 @@ export class CommunityForm extends Component<
368388
this.setState(s => ((s.communityForm.banner = Some("")), s));
369389
}
370390

391+
handleDiscussionLanguageChange(val: number[]) {
392+
this.setState(s => ((s.communityForm.discussion_languages = Some(val)), s));
393+
}
394+
371395
parseMessage(msg: any) {
372396
let op = wsUserOp(msg);
373397
console.log(msg);

0 commit comments

Comments
 (0)