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