+32
-1
packages/core-extensions/src/moonbase/index.tsx
+32
-1
packages/core-extensions/src/moonbase/index.tsx
···
1
-
import { ExtensionWebpackModule } from "@moonlight-mod/types";
1
+
import { ExtensionWebpackModule, Patch } from "@moonlight-mod/types";
2
+
3
+
export const patches: Patch[] = [
4
+
{
5
+
find: "window.DiscordErrors=",
6
+
replace: [
7
+
// replace reporting line with update status
8
+
{
9
+
match: /,(\(0,.\.jsx\))\("p",{children:.\.[a-zA-Z]+\.Messages.ERRORS_ACTION_TO_TAKE}\)/,
10
+
replacement: (_, createElement) =>
11
+
`,${createElement}(require("moonbase_crashScreen").UpdateText,{state:this.state,setState:this.setState.bind(this)})`
12
+
},
13
+
14
+
// wrap actions field to display error details
15
+
{
16
+
match: /action:(.),className:/,
17
+
replacement: (_, action) => `action:require("moonbase_crashScreen").wrapAction(${action},this.state),className:`
18
+
},
19
+
20
+
// add update button
21
+
{
22
+
match: /(?<=\.ERRORS_RELOAD}\),(\(0,.\.jsx\))\(.,{}\))/,
23
+
replacement: (_, createElement) =>
24
+
`,${createElement}(require("moonbase_crashScreen").UpdateButton,{state:this.state,setState:this.setState.bind(this)})`
25
+
}
26
+
]
27
+
}
28
+
];
2
29
3
30
export const webpackModules: Record<string, ExtensionWebpackModule> = {
4
31
stores: {
···
43
70
44
71
moonbase: {
45
72
dependencies: [{ ext: "moonbase", id: "stores" }]
73
+
},
74
+
75
+
crashScreen: {
76
+
dependencies: [{ id: "react" }]
46
77
}
47
78
};
+64
-1
packages/core-extensions/src/moonbase/style.css
+64
-1
packages/core-extensions/src/moonbase/style.css
···
3
3
--moonbase-fg: #fffba6;
4
4
}
5
5
6
-
.moonbase-settings > :first-child {
6
+
.moonbase-settings> :first-child {
7
7
margin-top: 0px;
8
8
}
9
9
···
53
53
flex-direction: row;
54
54
gap: 8px;
55
55
}
56
+
57
+
/* crash screen */
58
+
.moonbase-crash-wrapper>[class^="buttons_"] {
59
+
gap: 1rem;
60
+
}
61
+
62
+
.moonbase-crash-wrapper {
63
+
display: flex;
64
+
flex-direction: column;
65
+
align-items: center;
66
+
gap: 1rem;
67
+
max-height: 50%;
68
+
}
69
+
70
+
.moonbase-crash-details-wrapper {
71
+
overflow-y: scroll;
72
+
color: var(--text-normal);
73
+
background: var(--background-secondary);
74
+
border: 1px solid var(--background-tertiary);
75
+
border-radius: 4px;
76
+
padding: 0.5em;
77
+
78
+
&::-webkit-scrollbar {
79
+
width: 8px;
80
+
height: 8px;
81
+
}
82
+
83
+
&::-webkit-scrollbar-thumb {
84
+
background-clip: padding-box;
85
+
border: 2px solid transparent;
86
+
border-radius: 4px;
87
+
background-color: var(--scrollbar-thin-thumb);
88
+
min-height: 40px;
89
+
}
90
+
91
+
&::-webkit-scrollbar-track {
92
+
border: 2px solid var(--scrollbar-thin-track);
93
+
background-color: var(--scrollbar-thin-track);
94
+
border-color: var(--scrollbar-thin-track);
95
+
}
96
+
}
97
+
98
+
.moonbase-crash-details {
99
+
box-sizing: border-box;
100
+
padding: 0;
101
+
font-family: var(--font-code);
102
+
font-size: .75rem;
103
+
line-height: 1rem;
104
+
margin: 6px;
105
+
max-width: 50vw;
106
+
white-space: pre-wrap;
107
+
background-clip: border-box;
108
+
109
+
&>code {
110
+
font-size: .875rem;
111
+
line-height: 1.125rem;
112
+
text-indent: 0;
113
+
white-space: pre-wrap;
114
+
text-size-adjust: none;
115
+
display: block;
116
+
user-select: text;
117
+
}
118
+
}
+102
packages/core-extensions/src/moonbase/webpackModules/crashScreen.tsx
+102
packages/core-extensions/src/moonbase/webpackModules/crashScreen.tsx
···
1
+
import React from "@moonlight-mod/wp/react";
2
+
import * as Components from "@moonlight-mod/wp/discord/components/common/index";
3
+
import { useStateFromStores } from "@moonlight-mod/wp/discord/packages/flux";
4
+
import { MoonbaseSettingsStore } from "@moonlight-mod/wp/moonbase_stores";
5
+
6
+
const { Button, ButtonSizes } = Components;
7
+
8
+
const logger = moonlight.getLogger("moonbase/crashScreen");
9
+
10
+
type ErrorState = {
11
+
error: Error;
12
+
info: {
13
+
componentStack: string;
14
+
};
15
+
__moonlight_update?: UpdateState;
16
+
};
17
+
18
+
enum UpdateState {
19
+
Ready,
20
+
Working,
21
+
Installed,
22
+
Failed
23
+
}
24
+
25
+
const updateStrings: Record<UpdateState, string> = {
26
+
[UpdateState.Ready]: "A new version of moonlight is available.",
27
+
[UpdateState.Working]: "Updating moonlight...",
28
+
[UpdateState.Installed]: "Updated moonlight. Click Reload to apply changes.",
29
+
[UpdateState.Failed]: "Failed to update moonlight. Please use the installer."
30
+
};
31
+
const buttonStrings: Record<UpdateState, string> = {
32
+
[UpdateState.Ready]: "Update moonlight",
33
+
[UpdateState.Working]: "Updating moonlight...",
34
+
[UpdateState.Installed]: "",
35
+
[UpdateState.Failed]: "Update failed"
36
+
};
37
+
38
+
export function wrapAction(action: React.ReactNode, { error, info }: ErrorState) {
39
+
return (
40
+
<div className="moonbase-crash-wrapper">
41
+
{action}
42
+
<div className="moonbase-crash-details-wrapper">
43
+
<pre className="moonbase-crash-details">
44
+
<code>
45
+
{error.stack}
46
+
{"\n\nComponent stack:"}
47
+
{info.componentStack}
48
+
</code>
49
+
</pre>
50
+
</div>
51
+
</div>
52
+
);
53
+
}
54
+
55
+
export function UpdateText({ state, setState }: { state: ErrorState; setState: (state: ErrorState) => void }) {
56
+
if (!state.__moonlight_update) {
57
+
setState({
58
+
...state,
59
+
__moonlight_update: UpdateState.Ready
60
+
});
61
+
}
62
+
const newVersion = useStateFromStores([MoonbaseSettingsStore], () => MoonbaseSettingsStore.newVersion);
63
+
64
+
return newVersion == null ? null : (
65
+
<p>{state.__moonlight_update !== undefined ? updateStrings[state.__moonlight_update] : ""}</p>
66
+
);
67
+
}
68
+
69
+
export function UpdateButton({ state, setState }: { state: ErrorState; setState: (state: ErrorState) => void }) {
70
+
const newVersion = useStateFromStores([MoonbaseSettingsStore], () => MoonbaseSettingsStore.newVersion);
71
+
return newVersion == null ||
72
+
state.__moonlight_update === UpdateState.Installed ||
73
+
state.__moonlight_update === undefined ? null : (
74
+
<Button
75
+
size={ButtonSizes.LARGE}
76
+
disabled={state.__moonlight_update !== UpdateState.Ready}
77
+
onClick={() => {
78
+
setState({
79
+
...state,
80
+
__moonlight_update: UpdateState.Working
81
+
});
82
+
83
+
MoonbaseSettingsStore.updateMoonlight()
84
+
.then(() => {
85
+
setState({
86
+
...state,
87
+
__moonlight_update: UpdateState.Installed
88
+
});
89
+
})
90
+
.catch((e) => {
91
+
logger.error(e);
92
+
setState({
93
+
...state,
94
+
__moonlight_update: UpdateState.Failed
95
+
});
96
+
});
97
+
}}
98
+
>
99
+
{state.__moonlight_update !== undefined ? buttonStrings[state.__moonlight_update] : ""}
100
+
</Button>
101
+
);
102
+
}