]> Untitled Git - lemmy-ui.git/blob - src/shared/components/home/site-sidebar.tsx
Fix I18 next circular reference
[lemmy-ui.git] / src / shared / components / home / site-sidebar.tsx
1 import { Component, linkEvent } from "inferno";
2 import { PersonView, Site, SiteAggregates } from "lemmy-js-client";
3 import { mdToHtml } from "../../markdown";
4 import { I18NextService } from "../../services";
5 import { Badges } from "../common/badges";
6 import { BannerIconHeader } from "../common/banner-icon-header";
7 import { Icon } from "../common/icon";
8 import { PersonListing } from "../person/person-listing";
9
10 interface SiteSidebarProps {
11   site: Site;
12   showLocal: boolean;
13   counts?: SiteAggregates;
14   admins?: PersonView[];
15   isMobile?: boolean;
16 }
17
18 interface SiteSidebarState {
19   collapsed: boolean;
20 }
21
22 export class SiteSidebar extends Component<SiteSidebarProps, SiteSidebarState> {
23   state: SiteSidebarState = {
24     collapsed: false,
25   };
26
27   constructor(props: any, context: any) {
28     super(props, context);
29   }
30
31   render() {
32     return (
33       <div className="site-sidebar accordion">
34         <section id="sidebarInfo" className="card border-secondary mb-3">
35           <header
36             className="card-header d-flex align-items-center"
37             id="sidebarInfoHeader"
38           >
39             {this.siteName()}
40             {!this.state.collapsed && (
41               <BannerIconHeader banner={this.props.site.banner} />
42             )}
43           </header>
44
45           {!this.state.collapsed && (
46             <div id="sidebarInfoBody" aria-labelledby="sidebarInfoHeader">
47               <div className="card-body">{this.siteInfo()}</div>
48             </div>
49           )}
50         </section>
51       </div>
52     );
53   }
54
55   siteName() {
56     return (
57       <>
58         <h5 className="mb-0 d-inline">{this.props.site.name}</h5>
59         {!this.props.isMobile && (
60           <button
61             type="button"
62             className="btn btn-sm"
63             onClick={linkEvent(this, this.handleCollapseSidebar)}
64             aria-label={
65               this.state.collapsed
66                 ? I18NextService.i18n.t("expand")
67                 : I18NextService.i18n.t("collapse")
68             }
69             data-tippy-content={
70               this.state.collapsed
71                 ? I18NextService.i18n.t("expand")
72                 : I18NextService.i18n.t("collapse")
73             }
74             data-bs-toggle="collapse"
75             data-bs-target="#sidebarInfoBody"
76             aria-expanded="true"
77             aria-controls="sidebarInfoBody"
78           >
79             {this.state.collapsed ? (
80               <Icon icon="plus-square" classes="icon-inline" />
81             ) : (
82               <Icon icon="minus-square" classes="icon-inline" />
83             )}
84           </button>
85         )}
86       </>
87     );
88   }
89
90   siteInfo() {
91     const site = this.props.site;
92     return (
93       <div>
94         {site.description && <h6>{site.description}</h6>}
95         {site.sidebar && this.siteSidebar(site.sidebar)}
96         {this.props.counts && <Badges counts={this.props.counts} />}
97         {this.props.admins && this.admins(this.props.admins)}
98       </div>
99     );
100   }
101
102   siteSidebar(sidebar: string) {
103     return (
104       <div className="md-div" dangerouslySetInnerHTML={mdToHtml(sidebar)} />
105     );
106   }
107
108   admins(admins: PersonView[]) {
109     return (
110       <ul className="mt-1 list-inline small mb-0">
111         <li className="list-inline-item">{I18NextService.i18n.t("admins")}:</li>
112         {admins.map(av => (
113           <li key={av.person.id} className="list-inline-item">
114             <PersonListing person={av.person} />
115           </li>
116         ))}
117       </ul>
118     );
119   }
120
121   handleCollapseSidebar(i: SiteSidebar) {
122     i.setState({ collapsed: !i.state.collapsed });
123   }
124 }