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