]> Untitled Git - lemmy-ui.git/blob - src/shared/components/home/instances.tsx
Merge branch 'main' into patch-1
[lemmy-ui.git] / src / shared / components / home / instances.tsx
1 import { Component } from "inferno";
2 import {
3   GetFederatedInstancesResponse,
4   GetSiteResponse,
5   Instance,
6 } from "lemmy-js-client";
7 import { i18n } from "../../i18next";
8 import { InitialFetchRequest } from "../../interfaces";
9 import { FirstLoadService } from "../../services/FirstLoadService";
10 import { HttpService, RequestState } from "../../services/HttpService";
11 import { relTags, setIsoData } from "../../utils";
12 import { HtmlTags } from "../common/html-tags";
13 import { Spinner } from "../common/icon";
14
15 interface InstancesState {
16   instancesRes: RequestState<GetFederatedInstancesResponse>;
17   siteRes: GetSiteResponse;
18   isIsomorphic: boolean;
19 }
20
21 export class Instances extends Component<any, InstancesState> {
22   private isoData = setIsoData(this.context);
23   state: InstancesState = {
24     instancesRes: { state: "empty" },
25     siteRes: this.isoData.site_res,
26     isIsomorphic: false,
27   };
28
29   constructor(props: any, context: any) {
30     super(props, context);
31
32     // Only fetch the data if coming from another route
33     if (FirstLoadService.isFirstLoad) {
34       this.state = {
35         ...this.state,
36         instancesRes: this.isoData.routeData[0],
37         isIsomorphic: true,
38       };
39     }
40   }
41
42   async componentDidMount() {
43     if (!this.state.isIsomorphic) {
44       await this.fetchInstances();
45     }
46   }
47
48   async fetchInstances() {
49     this.setState({
50       instancesRes: { state: "loading" },
51     });
52
53     this.setState({
54       instancesRes: await HttpService.client.getFederatedInstances({}),
55     });
56   }
57
58   static fetchInitialData(
59     req: InitialFetchRequest
60   ): Promise<RequestState<any>>[] {
61     return [req.client.getFederatedInstances({})];
62   }
63
64   get documentTitle(): string {
65     return `${i18n.t("instances")} - ${this.state.siteRes.site_view.site.name}`;
66   }
67
68   renderInstances() {
69     switch (this.state.instancesRes.state) {
70       case "loading":
71         return (
72           <h5>
73             <Spinner large />
74           </h5>
75         );
76       case "success": {
77         const instances = this.state.instancesRes.data.federated_instances;
78         return instances ? (
79           <div className="row">
80             <div className="col-md-6">
81               <h5>{i18n.t("linked_instances")}</h5>
82               {this.itemList(instances.linked)}
83             </div>
84             {instances.allowed && instances.allowed.length > 0 && (
85               <div className="col-md-6">
86                 <h5>{i18n.t("allowed_instances")}</h5>
87                 {this.itemList(instances.allowed)}
88               </div>
89             )}
90             {instances.blocked && instances.blocked.length > 0 && (
91               <div className="col-md-6">
92                 <h5>{i18n.t("blocked_instances")}</h5>
93                 {this.itemList(instances.blocked)}
94               </div>
95             )}
96           </div>
97         ) : (
98           <></>
99         );
100       }
101     }
102   }
103
104   render() {
105     return (
106       <div className="container-lg">
107         <HtmlTags
108           title={this.documentTitle}
109           path={this.context.router.route.match.url}
110         />
111         {this.renderInstances()}
112       </div>
113     );
114   }
115
116   itemList(items: Instance[]) {
117     return items.length > 0 ? (
118       <div className="table-responsive">
119         <table id="instances_table" className="table table-sm table-hover">
120           <thead className="pointer">
121             <tr>
122               <th>{i18n.t("name")}</th>
123               <th>{i18n.t("software")}</th>
124               <th>{i18n.t("version")}</th>
125             </tr>
126           </thead>
127           <tbody>
128             {items.map(i => (
129               <tr key={i.domain}>
130                 <td>
131                   <a href={`https://${i.domain}`} rel={relTags}>
132                     {i.domain}
133                   </a>
134                 </td>
135                 <td>{i.software}</td>
136                 <td>{i.version}</td>
137               </tr>
138             ))}
139           </tbody>
140         </table>
141       </div>
142     ) : (
143       <div>{i18n.t("none_found")}</div>
144     );
145   }
146 }