-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 { UserService } from "../../services/UserService";
+import { randomStr, selectableLanguages } from "../../utils";
import { Icon } from "./icon";
interface LanguageSelectProps {
allLanguages: Language[];
- selectedLanguageIds: Option<number[]>;
- multiple: boolean;
+ siteLanguages: number[];
+ selectedLanguageIds?: number[];
+ multiple?: boolean;
onChange(val: number[]): any;
+ showAll?: boolean;
+ showSite?: boolean;
+ iconVersion?: boolean;
+ disabled?: boolean;
+ showLanguageWarning?: boolean;
}
export class LanguageSelect extends Component<LanguageSelectProps, any> {
// 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;
- }
+ const ids = this.props.selectedLanguageIds?.map(toString);
+ if (ids) {
+ const select = (document.getElementById(this.id) as HTMLSelectElement)
+ .options;
+ for (let i = 0; i < select.length; i++) {
+ const o = select[i];
+ if (ids.includes(o.value)) {
+ o.selected = true;
}
- },
- none: void 0,
- });
+ }
+ }
}
render() {
- let selectedLangs = this.props.selectedLanguageIds;
-
- return (
- <div className="form-group row">
- <label
- className={classNames("col-form-label", {
- "col-sm-3": this.props.multiple,
- "col-sm-2": !this.props.multiple,
- })}
- htmlFor={this.id}
- >
- {i18n.t(this.props.multiple ? "language_plural" : "language")}
- </label>
- <div
- className={classNames("input-group", {
- "col-sm-9": this.props.multiple,
- "col-sm-10": !this.props.multiple,
- })}
- >
- <select
- className="form-control custom-select"
- id={this.id}
- onChange={linkEvent(this, this.handleLanguageChange)}
- aria-label="action"
- multiple={this.props.multiple}
+ return this.props.iconVersion ? (
+ this.selectBtn
+ ) : (
+ <div className="language-select">
+ {this.props.multiple && this.props.showLanguageWarning && (
+ <div className="alert alert-warning" role="alert">
+ {i18n.t("undetermined_language_warning")}
+ </div>
+ )}
+ <div className="mb-3 row">
+ <label
+ className={classNames(
+ "col-form-label",
+ `col-sm-${this.props.multiple ? 3 : 2}`
+ )}
+ htmlFor={this.id}
>
- {this.props.allLanguages.map(l => (
- <option
- key={l.id}
- value={l.id}
- selected={selectedLangs.unwrapOr([]).includes(l.id)}
- >
- {l.name}
- </option>
- ))}
- </select>
- {this.props.multiple && (
- <div className="input-group-append">
+ {i18n.t(this.props.multiple ? "language_plural" : "language")}
+ </label>
+ <div
+ className={classNames(
+ "input-group",
+ `col-sm-${this.props.multiple ? 9 : 10}`
+ )}
+ >
+ {this.selectBtn}
+ {this.props.multiple && (
<button
- className="input-group-text"
+ className="btn btn-outline-secondary"
onClick={linkEvent(this, this.handleDeselectAll)}
>
<Icon icon="x" />
</button>
- </div>
- )}
+ )}
+ </div>
</div>
</div>
);
}
+ get selectBtn() {
+ const selectedLangs = this.props.selectedLanguageIds;
+ const filteredLangs = selectableLanguages(
+ this.props.allLanguages,
+ this.props.siteLanguages,
+ this.props.showAll,
+ this.props.showSite,
+ UserService.Instance.myUserInfo
+ );
+
+ return (
+ <select
+ className={classNames("form-select w-auto", {
+ "d-inline-block": !this.props.iconVersion,
+ })}
+ id={this.id}
+ onChange={linkEvent(this, this.handleLanguageChange)}
+ aria-label={i18n.t("language_select_placeholder")}
+ multiple={this.props.multiple}
+ disabled={this.props.disabled}
+ >
+ {!this.props.multiple && (
+ <option selected disabled hidden>
+ {i18n.t("language_select_placeholder")}
+ </option>
+ )}
+ {filteredLangs.map(l => (
+ <option
+ key={l.id}
+ value={l.id}
+ selected={selectedLangs?.includes(l.id)}
+ >
+ {l.name}
+ </option>
+ ))}
+ </select>
+ );
+ }
+
handleLanguageChange(i: LanguageSelect, event: any) {
- let options: HTMLOptionElement[] = Array.from(event.target.options);
- let selected: number[] = options
+ const options: HTMLOptionElement[] = Array.from(event.target.options);
+ const selected: number[] = options
.filter(o => o.selected)
.map(o => Number(o.value));