1 import { selectableLanguages } from "@utils/app";
2 import { randomStr } from "@utils/helpers";
3 import classNames from "classnames";
4 import { Component, linkEvent } from "inferno";
5 import { Language } from "lemmy-js-client";
6 import { i18n } from "../../i18next";
7 import { UserService } from "../../services/UserService";
8 import { Icon } from "./icon";
10 interface LanguageSelectProps {
11 allLanguages: Language[];
12 siteLanguages: number[];
13 selectedLanguageIds?: number[];
15 onChange(val: number[]): any;
18 iconVersion?: boolean;
20 showLanguageWarning?: boolean;
23 export class LanguageSelect extends Component<LanguageSelectProps, any> {
24 private id = `language-select-${randomStr()}`;
26 constructor(props: any, context: any) {
27 super(props, context);
31 this.setSelectedValues();
34 // Necessary because there is no HTML way to set selected for multiple in value=
36 const ids = this.props.selectedLanguageIds?.map(toString);
38 const select = (document.getElementById(this.id) as HTMLSelectElement)
40 for (let i = 0; i < select.length; i++) {
42 if (ids.includes(o.value)) {
50 return this.props.iconVersion ? (
53 <div className="language-select">
54 {this.props.multiple && this.props.showLanguageWarning && (
55 <div className="alert alert-warning" role="alert">
56 {i18n.t("undetermined_language_warning")}
59 <div className="mb-3 row">
61 className={classNames(
63 `col-sm-${this.props.multiple ? 3 : 2}`
67 {i18n.t(this.props.multiple ? "language_plural" : "language")}
70 className={classNames(`col-sm-${this.props.multiple ? 9 : 10}`, {
71 "input-group": this.props.multiple,
75 {this.props.multiple && (
77 className="btn btn-outline-secondary"
78 onClick={linkEvent(this, this.handleDeselectAll)}
90 const selectedLangs = this.props.selectedLanguageIds;
91 const filteredLangs = selectableLanguages(
92 this.props.allLanguages,
93 this.props.siteLanguages,
96 UserService.Instance.myUserInfo
101 className={classNames("form-select w-auto", {
102 "d-inline-block": !this.props.iconVersion,
105 onChange={linkEvent(this, this.handleLanguageChange)}
106 aria-label={i18n.t("language_select_placeholder")}
107 multiple={this.props.multiple}
108 disabled={this.props.disabled}
110 {!this.props.multiple && (
111 <option selected disabled hidden>
112 {i18n.t("language_select_placeholder")}
115 {filteredLangs.map(l => (
119 selected={selectedLangs?.includes(l.id)}
128 handleLanguageChange(i: LanguageSelect, event: any) {
129 const options: HTMLOptionElement[] = Array.from(event.target.options);
130 const selected: number[] = options
131 .filter(o => o.selected)
132 .map(o => Number(o.value));
134 i.props.onChange(selected);
137 handleDeselectAll(i: LanguageSelect, event: any) {
138 event.preventDefault();
139 i.props.onChange([]);