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