1 import classNames from "classnames";
2 import { Component, linkEvent } from "inferno";
3 import { Language } from "lemmy-js-client";
4 import { i18n } from "../../i18next";
5 import { UserService } from "../../services/UserService";
6 import { randomStr, selectableLanguages } from "../../utils";
7 import { Icon } from "./icon";
9 interface LanguageSelectProps {
10 allLanguages: Language[];
11 siteLanguages: number[];
12 selectedLanguageIds?: number[];
14 onChange(val: number[]): any;
17 iconVersion?: boolean;
21 export class LanguageSelect extends Component<LanguageSelectProps, any> {
22 private id = `language-select-${randomStr()}`;
24 constructor(props: any, context: any) {
25 super(props, context);
29 this.setSelectedValues();
32 // Necessary because there is no HTML way to set selected for multiple in value=
34 const ids = this.props.selectedLanguageIds?.map(toString);
36 const select = (document.getElementById(this.id) as HTMLSelectElement)
38 for (let i = 0; i < select.length; i++) {
40 if (ids.includes(o.value)) {
48 return this.props.iconVersion ? (
52 {this.props.multiple && (
53 <div className="alert alert-warning" role="alert">
54 {i18n.t("undetermined_language_warning")}
57 <div className="form-group row">
59 className={classNames(
61 `col-sm-${this.props.multiple ? 3 : 2}`
65 {i18n.t(this.props.multiple ? "language_plural" : "language")}
68 className={classNames(
70 `col-sm-${this.props.multiple ? 9 : 10}`
74 {this.props.multiple && (
75 <div className="input-group-append">
77 className="input-group-text"
78 onClick={linkEvent(this, this.handleDeselectAll)}
91 const selectedLangs = this.props.selectedLanguageIds;
92 const filteredLangs = selectableLanguages(
93 this.props.allLanguages,
94 this.props.siteLanguages,
97 UserService.Instance.myUserInfo
102 className={classNames(
103 "lang-select-action",
104 this.props.iconVersion
105 ? "btn btn-sm text-muted"
106 : "form-control custom-select"
109 onChange={linkEvent(this, this.handleLanguageChange)}
110 aria-label={i18n.t("language_select_placeholder")}
111 multiple={this.props.multiple}
112 disabled={this.props.disabled}
114 {!this.props.multiple && (
115 <option selected disabled hidden>
116 {i18n.t("language_select_placeholder")}
119 {filteredLangs.map(l => (
123 selected={selectedLangs?.includes(l.id)}
132 handleLanguageChange(i: LanguageSelect, event: any) {
133 const options: HTMLOptionElement[] = Array.from(event.target.options);
134 const selected: number[] = options
135 .filter(o => o.selected)
136 .map(o => Number(o.value));
138 i.props.onChange(selected);
141 handleDeselectAll(i: LanguageSelect, event: any) {
142 event.preventDefault();
143 i.props.onChange([]);