131 lines
4.1 kB
1
import { useStateFromStores } from "@moonlight-mod/wp/discord/packages/flux";
2
import { MoonbaseSettingsStore } from "@moonlight-mod/wp/moonbase_stores";
3
import React from "@moonlight-mod/wp/react";
4
import { UpdateState } from "../../types";
5
import HelpMessage from "./HelpMessage";
6
import { MoonlightBranch } from "@moonlight-mod/types";
7
import MarkupUtils from "@moonlight-mod/wp/discord/modules/markup/MarkupUtils";
8
import Flex from "@moonlight-mod/wp/discord/uikit/Flex";
9
import {
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";
21
import MarkupClasses from "@moonlight-mod/wp/discord/modules/messages/web/Markup.css";
22
23
const logger = moonlight.getLogger("moonbase/ui/update");
24
25
const 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
32
function 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
69
export 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
}
132