this repo has no description
1import { useStateFromStores } from "@moonlight-mod/wp/discord/packages/flux";
2import { MoonbaseSettingsStore } from "@moonlight-mod/wp/moonbase_stores";
3import React from "@moonlight-mod/wp/react";
4import { UpdateState } from "../../types";
5import HelpMessage from "./HelpMessage";
6import { MoonlightBranch } from "@moonlight-mod/types";
7import MarkupUtils from "@moonlight-mod/wp/discord/modules/markup/MarkupUtils";
8import Flex from "@moonlight-mod/wp/discord/uikit/Flex";
9import {
10 ThemeDarkIcon,
11 Button,
12 Text,
13 ModalRoot,
14 ModalSize,
15 ModalContent,
16 ModalHeader,
17 Heading,
18 ModalCloseButton,
19 openModal
20} from "@moonlight-mod/wp/discord/components/common/index";
21import MarkupClasses from "@moonlight-mod/wp/discord/modules/messages/web/Markup.css";
22
23const logger = moonlight.getLogger("moonbase/ui/update");
24
25const strings: Record<UpdateState, string> = {
26 [UpdateState.Ready]: "A new version of moonlight is available.",
27 [UpdateState.Working]: "Updating moonlight...",
28 [UpdateState.Installed]: "Updated. Restart Discord to apply changes.",
29 [UpdateState.Failed]: "Failed to update moonlight. Please use the installer instead."
30};
31
32function MoonlightChangelog({
33 changelog,
34 version,
35 transitionState,
36 onClose
37}: {
38 changelog: string;
39 version: string;
40 transitionState: number | null;
41 onClose: () => void;
42}) {
43 return (
44 <ModalRoot transitionState={transitionState} size={ModalSize.DYNAMIC}>
45 <ModalHeader>
46 <Flex.Child grow={1} shrink={1}>
47 <Heading variant="heading-lg/semibold">moonlight</Heading>
48 <Text variant="text-xs/normal">{version}</Text>
49 </Flex.Child>
50
51 <Flex.Child grow={0}>
52 <ModalCloseButton onClick={onClose} />
53 </Flex.Child>
54 </ModalHeader>
55
56 <ModalContent>
57 <Text variant="text-md/normal" className={MarkupClasses.markup} style={{ padding: "1rem" }}>
58 {MarkupUtils.parse(changelog, true, {
59 allowHeading: true,
60 allowList: true,
61 allowLinks: true
62 })}
63 </Text>
64 </ModalContent>
65 </ModalRoot>
66 );
67}
68
69export default function Update() {
70 const [state, setState] = React.useState(UpdateState.Ready);
71 const newVersion = useStateFromStores([MoonbaseSettingsStore], () => MoonbaseSettingsStore.newVersion);
72
73 if (newVersion == null) return null;
74
75 return (
76 <HelpMessage text={strings[state]} className="moonbase-update-section" icon={ThemeDarkIcon}>
77 <div className="moonbase-help-message-buttons">
78 {moonlight.branch === MoonlightBranch.STABLE && (
79 <Button
80 look={Button.Looks.OUTLINED}
81 color={Button.Colors.CUSTOM}
82 size={Button.Sizes.TINY}
83 onClick={() => {
84 fetch(`https://raw.githubusercontent.com/moonlight-mod/moonlight/refs/tags/${newVersion}/CHANGELOG.md`)
85 .then((r) => r.text())
86 .then((changelog) =>
87 openModal((modalProps) => {
88 return <MoonlightChangelog {...modalProps} changelog={changelog} version={newVersion} />;
89 })
90 );
91 }}
92 >
93 View changelog
94 </Button>
95 )}
96
97 {state === UpdateState.Installed && (
98 <Button
99 look={Button.Looks.OUTLINED}
100 color={Button.Colors.CUSTOM}
101 size={Button.Sizes.TINY}
102 onClick={() => {
103 MoonbaseSettingsStore.restartDiscord();
104 }}
105 >
106 Restart Discord
107 </Button>
108 )}
109
110 <Button
111 look={Button.Looks.OUTLINED}
112 color={Button.Colors.CUSTOM}
113 size={Button.Sizes.TINY}
114 disabled={state !== UpdateState.Ready}
115 onClick={() => {
116 setState(UpdateState.Working);
117
118 MoonbaseSettingsStore.updateMoonlight()
119 .then(() => setState(UpdateState.Installed))
120 .catch((e) => {
121 logger.error(e);
122 setState(UpdateState.Failed);
123 });
124 }}
125 >
126 Update
127 </Button>
128 </div>
129 </HelpMessage>
130 );
131}