this repo has no description
1import WebpackRequire from "@moonlight-mod/types/discord/require";
2import {
3 DangerIconSVG,
4 DownloadIconSVG,
5 ExtensionState,
6 TrashIconSVG
7} from "../../types";
8import { ExtensionLoadSource } from "@moonlight-mod/types";
9import info from "./info";
10import settings from "./settings";
11
12export enum ExtensionPage {
13 Info,
14 Description,
15 Settings
16}
17
18export default (require: typeof WebpackRequire) => {
19 const React = require("common_react");
20 const spacepack = require("spacepack_spacepack").spacepack;
21 const CommonComponents = require("common_components");
22 const Flux = require("common_flux");
23
24 const { ExtensionInfo } = info(require);
25 const Settings = settings(require);
26 const { MoonbaseSettingsStore } =
27 require("moonbase_stores") as typeof import("../../webpackModules/stores");
28
29 const UserProfileClasses = spacepack.findByCode(
30 "tabBarContainer",
31 "topSection"
32 )[0].exports;
33
34 const DownloadIcon =
35 spacepack.findByCode(DownloadIconSVG)[0].exports.DownloadIcon;
36 const TrashIcon = spacepack.findByCode(TrashIconSVG)[0].exports.default;
37 const DangerIcon =
38 spacepack.findByCode(DangerIconSVG)[0].exports.CircleExclamationPointIcon;
39
40 const PanelButton =
41 spacepack.findByCode("Masks.PANEL_BUTTON")[0].exports.default;
42
43 return function ExtensionCard({ id }: { id: string }) {
44 const [tab, setTab] = React.useState(ExtensionPage.Info);
45 const [restartNeeded, setRestartNeeded] = React.useState(false);
46
47 const { ext, enabled, busy, update } = Flux.useStateFromStores(
48 [MoonbaseSettingsStore],
49 () => {
50 return {
51 ext: MoonbaseSettingsStore.getExtension(id),
52 enabled: MoonbaseSettingsStore.getExtensionEnabled(id),
53 busy: MoonbaseSettingsStore.busy,
54 update: MoonbaseSettingsStore.getExtensionUpdate(id)
55 };
56 }
57 );
58
59 // Why it work like that :sob:
60 if (ext == null) return <></>;
61
62 const {
63 Card,
64 CardClasses,
65 Flex,
66 Text,
67 MarkdownParser,
68 Switch,
69 TabBar,
70 Button
71 } = CommonComponents;
72
73 const tagline = ext.manifest?.meta?.tagline;
74 const settings = ext.manifest?.settings;
75 const description = ext.manifest?.meta?.description;
76
77 return (
78 <Card editable={true} className={CardClasses.card}>
79 <div className={CardClasses.cardHeader}>
80 <Flex direction={Flex.Direction.VERTICAL}>
81 <Flex direction={Flex.Direction.HORIZONTAL}>
82 <Text variant="text-md/semibold">
83 {ext.manifest?.meta?.name ?? ext.id}
84 </Text>
85 </Flex>
86
87 {tagline != null && (
88 <Text variant="text-sm/normal">
89 {MarkdownParser.parse(tagline)}
90 </Text>
91 )}
92 </Flex>
93
94 <Flex
95 direction={Flex.Direction.HORIZONTAL}
96 align={Flex.Align.END}
97 justify={Flex.Justify.END}
98 >
99 {ext.state === ExtensionState.NotDownloaded ? (
100 <Button
101 color={Button.Colors.BRAND}
102 submitting={busy}
103 onClick={() => {
104 MoonbaseSettingsStore.installExtension(id);
105 }}
106 >
107 Install
108 </Button>
109 ) : (
110 <div
111 // too lazy to learn how <Flex /> works lmao
112 style={{
113 display: "flex",
114 alignItems: "center",
115 gap: "1rem"
116 }}
117 >
118 {ext.source.type === ExtensionLoadSource.Normal && (
119 <PanelButton
120 icon={TrashIcon}
121 tooltipText="Delete"
122 onClick={() => {
123 MoonbaseSettingsStore.deleteExtension(id);
124 }}
125 />
126 )}
127
128 {update !== null && (
129 <PanelButton
130 icon={DownloadIcon}
131 tooltipText="Update"
132 onClick={() => {
133 MoonbaseSettingsStore.installExtension(id);
134 }}
135 />
136 )}
137
138 {restartNeeded && (
139 <PanelButton
140 icon={() => (
141 <DangerIcon
142 color={CommonComponents.tokens.colors.STATUS_DANGER}
143 />
144 )}
145 onClick={() => window.location.reload()}
146 tooltipText="You will need to reload/restart your client for this extension to work properly."
147 />
148 )}
149
150 <Switch
151 checked={enabled}
152 onChange={() => {
153 setRestartNeeded(true);
154 MoonbaseSettingsStore.setExtensionEnabled(id, !enabled);
155 }}
156 />
157 </div>
158 )}
159 </Flex>
160 </div>
161
162 <div className={UserProfileClasses.body}>
163 {(description != null || settings != null) && (
164 <div
165 className={UserProfileClasses.tabBarContainer}
166 style={{
167 padding: "0 10px"
168 }}
169 >
170 <TabBar
171 selectedItem={tab}
172 type="top"
173 onItemSelect={setTab}
174 className={UserProfileClasses.tabBar}
175 >
176 <TabBar.Item
177 className={UserProfileClasses.tabBarItem}
178 id={ExtensionPage.Info}
179 >
180 Info
181 </TabBar.Item>
182
183 {description != null && (
184 <TabBar.Item
185 className={UserProfileClasses.tabBarItem}
186 id={ExtensionPage.Description}
187 >
188 Description
189 </TabBar.Item>
190 )}
191
192 {settings != null && (
193 <TabBar.Item
194 className={UserProfileClasses.tabBarItem}
195 id={ExtensionPage.Settings}
196 >
197 Settings
198 </TabBar.Item>
199 )}
200 </TabBar>
201 </div>
202 )}
203
204 <Flex
205 justify={Flex.Justify.START}
206 wrap={Flex.Wrap.WRAP}
207 style={{
208 padding: "16px 16px"
209 }}
210 >
211 {tab === ExtensionPage.Info && <ExtensionInfo ext={ext} />}
212 {tab === ExtensionPage.Description && (
213 <Text variant="text-md/normal">
214 {MarkdownParser.parse(description ?? "*No description*")}
215 </Text>
216 )}
217 {tab === ExtensionPage.Settings && <Settings ext={ext} />}
218 </Flex>
219 </div>
220 </Card>
221 );
222 };
223};