]> Untitled Git - lemmy-ui.git/blob - src/shared/components/common/language-select.tsx
Adding Community Language fixes. #783 (#868)
[lemmy-ui.git] / src / shared / components / common / language-select.tsx
1 import { Option } from "@sniptt/monads";
2 import classNames from "classnames";
3 import { Component, linkEvent } from "inferno";
4 import { Language } from "lemmy-js-client";
5 import { i18n } from "../../i18next";
6 import { UserService } from "../../services/UserService";
7 import { randomStr, selectableLanguages } from "../../utils";
8 import { Icon } from "./icon";
9
10 interface LanguageSelectProps {
11   allLanguages: Language[];
12   siteLanguages: number[];
13   selectedLanguageIds: Option<number[]>;
14   multiple: boolean;
15   onChange(val: number[]): any;
16   showAll?: boolean;
17   showSite?: boolean;
18   iconVersion?: boolean;
19 }
20
21 export class LanguageSelect extends Component<LanguageSelectProps, any> {
22   private id = `language-select-${randomStr()}`;
23
24   constructor(props: any, context: any) {
25     super(props, context);
26   }
27
28   componentDidMount() {
29     this.setSelectedValues();
30   }
31
32   // Necessary because there is no HTML way to set selected for multiple in value=
33   setSelectedValues() {
34     this.props.selectedLanguageIds.map(toString).match({
35       some: ids => {
36         var select = (document.getElementById(this.id) as HTMLSelectElement)
37           .options;
38         for (let i = 0; i < select.length; i++) {
39           let o = select[i];
40           if (ids.includes(o.value)) {
41             o.selected = true;
42           }
43         }
44       },
45       none: void 0,
46     });
47   }
48
49   render() {
50     return this.props.iconVersion ? (
51       this.selectBtn
52     ) : (
53       <div className="form-group row">
54         <label
55           className={classNames("col-form-label", {
56             "col-sm-3": this.props.multiple,
57             "col-sm-2": !this.props.multiple,
58           })}
59           htmlFor={this.id}
60         >
61           {i18n.t(this.props.multiple ? "language_plural" : "language")}
62         </label>
63         <div
64           className={classNames("input-group", {
65             "col-sm-9": this.props.multiple,
66             "col-sm-10": !this.props.multiple,
67           })}
68         >
69           {this.selectBtn}
70           {this.props.multiple && (
71             <div className="input-group-append">
72               <button
73                 className="input-group-text"
74                 onClick={linkEvent(this, this.handleDeselectAll)}
75               >
76                 <Icon icon="x" />
77               </button>
78             </div>
79           )}
80         </div>
81       </div>
82     );
83   }
84
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
119   handleLanguageChange(i: LanguageSelect, event: any) {
120     let options: HTMLOptionElement[] = Array.from(event.target.options);
121     let selected: number[] = options
122       .filter(o => o.selected)
123       .map(o => Number(o.value));
124
125     i.props.onChange(selected);
126   }
127
128   handleDeselectAll(i: LanguageSelect, event: any) {
129     event.preventDefault();
130     i.props.onChange([]);
131   }
132 }