this repo has no description
1import React from "@moonlight-mod/wp/react"; 2import * as Components from "@moonlight-mod/wp/discord/components/common/index"; 3import { useStateFromStores, useStateFromStoresObject } from "@moonlight-mod/wp/discord/packages/flux"; 4import spacepack from "@moonlight-mod/wp/spacepack_spacepack"; 5import { MoonbaseSettingsStore } from "@moonlight-mod/wp/moonbase_stores"; 6import { RepositoryManifest, UpdateState } from "../types"; 7 8const { Button, TabBar } = Components; 9const TabBarClasses = spacepack.findByCode(/\.exports={tabBar:"tabBar_[a-z0-9]+",tabBarItem:"tabBarItem_[a-z0-9]+"}/)[0] 10 .exports; 11 12const logger = moonlight.getLogger("moonbase/crashScreen"); 13 14type ErrorState = { 15 error: Error; 16 info: { 17 componentStack: string; 18 }; 19 __moonlight_update?: UpdateState; 20}; 21 22type WrapperProps = { 23 action: React.ReactNode; 24 state: ErrorState; 25}; 26 27type UpdateCardProps = { 28 id: number; 29 ext: { 30 version: string; 31 download: string; 32 updateManifest: RepositoryManifest; 33 }; 34}; 35 36const updateStrings: Record<UpdateState, string> = { 37 [UpdateState.Ready]: "A new version of moonlight is available.", 38 [UpdateState.Working]: "Updating moonlight...", 39 [UpdateState.Installed]: "Updated moonlight. Click Reload to apply changes.", 40 [UpdateState.Failed]: "Failed to update moonlight. Please use the installer." 41}; 42const buttonStrings: Record<UpdateState, string> = { 43 [UpdateState.Ready]: "Update moonlight", 44 [UpdateState.Working]: "Updating moonlight...", 45 [UpdateState.Installed]: "", 46 [UpdateState.Failed]: "Update failed" 47}; 48const extensionButtonStrings: Record<UpdateState, string> = { 49 [UpdateState.Ready]: "Update", 50 [UpdateState.Working]: "Updating...", 51 [UpdateState.Installed]: "Updated", 52 [UpdateState.Failed]: "Update failed" 53}; 54 55function ExtensionUpdateCard({ id, ext }: UpdateCardProps) { 56 const [state, setState] = React.useState(UpdateState.Ready); 57 const installed = useStateFromStores([MoonbaseSettingsStore], () => MoonbaseSettingsStore.getExtension(id), [id]); 58 59 return ( 60 <div className="moonbase-crash-extensionCard"> 61 <div className="moonbase-crash-extensionCard-meta"> 62 <div className="moonbase-crash-extensionCard-title"> 63 {ext.updateManifest.meta?.name ?? ext.updateManifest.id} 64 </div> 65 <div className="moonbase-crash-extensionCard-version">{`v${installed?.manifest?.version ?? "???"} -> v${ 66 ext.version 67 }`}</div> 68 </div> 69 <div className="moonbase-crash-extensionCard-button"> 70 <Button 71 color={Button.Colors.GREEN} 72 disabled={state !== UpdateState.Ready} 73 onClick={() => { 74 setState(UpdateState.Working); 75 MoonbaseSettingsStore.installExtension(id) 76 .then(() => setState(UpdateState.Installed)) 77 .catch(() => setState(UpdateState.Failed)); 78 }} 79 > 80 {extensionButtonStrings[state]} 81 </Button> 82 </div> 83 </div> 84 ); 85} 86 87export function wrapAction({ action, state }: WrapperProps) { 88 const [tab, setTab] = React.useState("crash"); 89 90 const { updates, updateCount } = useStateFromStoresObject([MoonbaseSettingsStore], () => { 91 const { updates } = MoonbaseSettingsStore; 92 return { 93 updates: Object.entries(updates), 94 updateCount: Object.keys(updates).length 95 }; 96 }); 97 98 return ( 99 <div className="moonbase-crash-wrapper"> 100 {action} 101 <TabBar 102 className={`${TabBarClasses.tabBar} moonbase-crash-tabs`} 103 type="top" 104 selectedItem={tab} 105 onItemSelect={(v) => setTab(v)} 106 > 107 <TabBar.Item className={TabBarClasses.tabBarItem} id="crash"> 108 Crash Details 109 </TabBar.Item> 110 <TabBar.Item className={TabBarClasses.tabBarItem} id="extensions" disabled={updateCount === 0}> 111 {`Extension Updates (${updateCount})`} 112 </TabBar.Item> 113 </TabBar> 114 {tab === "crash" ? ( 115 <div className="moonbase-crash-details-wrapper"> 116 <pre className="moonbase-crash-details"> 117 <code> 118 {state.error.stack} 119 {"\n\nComponent stack:"} 120 {state.info.componentStack} 121 </code> 122 </pre> 123 </div> 124 ) : null} 125 {tab === "extensions" ? ( 126 <div className="moonbase-crash-extensions"> 127 {updates.map(([id, ext]) => ( 128 <ExtensionUpdateCard id={Number(id)} ext={ext} /> 129 ))} 130 </div> 131 ) : null} 132 </div> 133 ); 134} 135 136export function UpdateText({ state, setState }: { state: ErrorState; setState: (state: ErrorState) => void }) { 137 if (!state.__moonlight_update) { 138 setState({ 139 ...state, 140 __moonlight_update: UpdateState.Ready 141 }); 142 } 143 const newVersion = useStateFromStores([MoonbaseSettingsStore], () => MoonbaseSettingsStore.newVersion); 144 145 return newVersion == null ? null : ( 146 <p>{state.__moonlight_update !== undefined ? updateStrings[state.__moonlight_update] : ""}</p> 147 ); 148} 149 150export function UpdateButton({ state, setState }: { state: ErrorState; setState: (state: ErrorState) => void }) { 151 const newVersion = useStateFromStores([MoonbaseSettingsStore], () => MoonbaseSettingsStore.newVersion); 152 return newVersion == null || 153 state.__moonlight_update === UpdateState.Installed || 154 state.__moonlight_update === undefined ? null : ( 155 <Button 156 size={Button.Sizes.LARGE} 157 disabled={state.__moonlight_update !== UpdateState.Ready} 158 onClick={() => { 159 setState({ 160 ...state, 161 __moonlight_update: UpdateState.Working 162 }); 163 164 MoonbaseSettingsStore.updateMoonlight() 165 .then(() => { 166 setState({ 167 ...state, 168 __moonlight_update: UpdateState.Installed 169 }); 170 }) 171 .catch((e) => { 172 logger.error(e); 173 setState({ 174 ...state, 175 __moonlight_update: UpdateState.Failed 176 }); 177 }); 178 }} 179 > 180 {state.__moonlight_update !== undefined ? buttonStrings[state.__moonlight_update] : ""} 181 </Button> 182 ); 183}