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