Skip to content

Commit c98592a

Browse files
feat(ui): Enhance EDID settings with loading state (#691)
* feat(ui): Enhance EDID settings with loading state and Fieldset component * fix(ui): Improve notifications and adjust styling in custom EDID component * fix(ui): specify JsonRpcResponse type
1 parent 8fbad01 commit c98592a

File tree

1 file changed

+91
-72
lines changed

1 file changed

+91
-72
lines changed

ui/src/routes/devices.$id.settings.video.tsx

Lines changed: 91 additions & 72 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,16 @@
1-
import { useState, useEffect } from "react";
1+
import { useEffect, useState } from "react";
22

33
import { Button } from "@/components/Button";
44
import { TextAreaWithLabel } from "@/components/TextArea";
55
import { JsonRpcResponse, useJsonRpc } from "@/hooks/useJsonRpc";
66
import { SettingsPageHeader } from "@components/SettingsPageheader";
77
import { useSettingsStore } from "@/hooks/stores";
8-
9-
import notifications from "../notifications";
10-
import { SelectMenuBasic } from "../components/SelectMenuBasic";
8+
import { SelectMenuBasic } from "@components/SelectMenuBasic";
9+
import Fieldset from "@components/Fieldset";
10+
import notifications from "@/notifications";
1111

1212
import { SettingsItem } from "./devices.$id.settings";
13+
1314
const defaultEdid =
1415
"00ffffffffffff0052620188008888881c150103800000780a0dc9a05747982712484c00000001010101010101010101010101010101023a801871382d40582c4500c48e2100001e011d007251d01e206e285500c48e2100001e000000fc00543734392d6648443732300a20000000fd00147801ff1d000a202020202020017b";
1516
const edids = [
@@ -50,21 +51,27 @@ export default function SettingsVideoRoute() {
5051
const [streamQuality, setStreamQuality] = useState("1");
5152
const [customEdidValue, setCustomEdidValue] = useState<string | null>(null);
5253
const [edid, setEdid] = useState<string | null>(null);
54+
const [edidLoading, setEdidLoading] = useState(false);
5355

5456
// Video enhancement settings from store
5557
const {
56-
videoSaturation, setVideoSaturation,
57-
videoBrightness, setVideoBrightness,
58-
videoContrast, setVideoContrast
58+
videoSaturation,
59+
setVideoSaturation,
60+
videoBrightness,
61+
setVideoBrightness,
62+
videoContrast,
63+
setVideoContrast,
5964
} = useSettingsStore();
6065

6166
useEffect(() => {
67+
setEdidLoading(true);
6268
send("getStreamQualityFactor", {}, (resp: JsonRpcResponse) => {
6369
if ("error" in resp) return;
6470
setStreamQuality(String(resp.result));
6571
});
6672

6773
send("getEDID", {}, (resp: JsonRpcResponse) => {
74+
setEdidLoading(false);
6875
if ("error" in resp) {
6976
notifications.error(`Failed to get EDID: ${resp.error.data || "Unknown error"}`);
7077
return;
@@ -89,28 +96,36 @@ export default function SettingsVideoRoute() {
8996
}, [send]);
9097

9198
const handleStreamQualityChange = (factor: string) => {
92-
send("setStreamQualityFactor", { factor: Number(factor) }, (resp: JsonRpcResponse) => {
93-
if ("error" in resp) {
94-
notifications.error(
95-
`Failed to set stream quality: ${resp.error.data || "Unknown error"}`,
96-
);
97-
return;
98-
}
99+
send(
100+
"setStreamQualityFactor",
101+
{ factor: Number(factor) },
102+
(resp: JsonRpcResponse) => {
103+
if ("error" in resp) {
104+
notifications.error(
105+
`Failed to set stream quality: ${resp.error.data || "Unknown error"}`,
106+
);
107+
return;
108+
}
99109

100-
notifications.success(`Stream quality set to ${streamQualityOptions.find(x => x.value === factor)?.label}`);
101-
setStreamQuality(factor);
102-
});
110+
notifications.success(
111+
`Stream quality set to ${streamQualityOptions.find(x => x.value === factor)?.label}`,
112+
);
113+
setStreamQuality(factor);
114+
},
115+
);
103116
};
104117

105118
const handleEDIDChange = (newEdid: string) => {
119+
setEdidLoading(true);
106120
send("setEDID", { edid: newEdid }, (resp: JsonRpcResponse) => {
121+
setEdidLoading(false);
107122
if ("error" in resp) {
108123
notifications.error(`Failed to set EDID: ${resp.error.data || "Unknown error"}`);
109124
return;
110125
}
111126

112127
notifications.success(
113-
`EDID set successfully to ${edids.find(x => x.value === newEdid)?.label}`,
128+
`EDID set successfully to ${edids.find(x => x.value === newEdid)?.label ?? "the custom EDID"}`,
114129
);
115130
// Update the EDID value in the UI
116131
setEdid(newEdid);
@@ -158,7 +173,7 @@ export default function SettingsVideoRoute() {
158173
step="0.1"
159174
value={videoSaturation}
160175
onChange={e => setVideoSaturation(parseFloat(e.target.value))}
161-
className="w-32 h-2 bg-gray-200 rounded-lg appearance-none cursor-pointer dark:bg-gray-700"
176+
className="h-2 w-32 cursor-pointer appearance-none rounded-lg bg-gray-200 dark:bg-gray-700"
162177
/>
163178
</SettingsItem>
164179

@@ -173,7 +188,7 @@ export default function SettingsVideoRoute() {
173188
step="0.1"
174189
value={videoBrightness}
175190
onChange={e => setVideoBrightness(parseFloat(e.target.value))}
176-
className="w-32 h-2 bg-gray-200 rounded-lg appearance-none cursor-pointer dark:bg-gray-700"
191+
className="h-2 w-32 cursor-pointer appearance-none rounded-lg bg-gray-200 dark:bg-gray-700"
177192
/>
178193
</SettingsItem>
179194

@@ -188,7 +203,7 @@ export default function SettingsVideoRoute() {
188203
step="0.1"
189204
value={videoContrast}
190205
onChange={e => setVideoContrast(parseFloat(e.target.value))}
191-
className="w-32 h-2 bg-gray-200 rounded-lg appearance-none cursor-pointer dark:bg-gray-700"
206+
className="h-2 w-32 cursor-pointer appearance-none rounded-lg bg-gray-200 dark:bg-gray-700"
192207
/>
193208
</SettingsItem>
194209

@@ -205,60 +220,64 @@ export default function SettingsVideoRoute() {
205220
/>
206221
</div>
207222
</div>
208-
209-
<SettingsItem
210-
title="EDID"
211-
description="Adjust the EDID settings for the display"
212-
>
213-
<SelectMenuBasic
214-
size="SM"
215-
label=""
216-
fullWidth
217-
value={customEdidValue ? "custom" : edid || "asd"}
218-
onChange={e => {
219-
if (e.target.value === "custom") {
220-
setEdid("custom");
221-
setCustomEdidValue("");
222-
} else {
223-
setCustomEdidValue(null);
224-
handleEDIDChange(e.target.value as string);
225-
}
226-
}}
227-
options={[...edids, { value: "custom", label: "Custom" }]}
228-
/>
229-
</SettingsItem>
230-
{customEdidValue !== null && (
231-
<>
232-
<SettingsItem
233-
title="Custom EDID"
234-
description="EDID details video mode compatibility. Default settings works in most cases, but unique UEFI/BIOS might need adjustments."
235-
/>
236-
<TextAreaWithLabel
237-
label="EDID File"
238-
placeholder="00F..."
239-
rows={3}
240-
value={customEdidValue}
241-
onChange={e => setCustomEdidValue(e.target.value)}
223+
<Fieldset disabled={edidLoading} className="space-y-2">
224+
<SettingsItem
225+
title="EDID"
226+
description="Adjust the EDID settings for the display"
227+
loading={edidLoading}
228+
>
229+
<SelectMenuBasic
230+
size="SM"
231+
label=""
232+
fullWidth
233+
value={customEdidValue ? "custom" : edid || "asd"}
234+
onChange={e => {
235+
if (e.target.value === "custom") {
236+
setEdid("custom");
237+
setCustomEdidValue("");
238+
} else {
239+
setCustomEdidValue(null);
240+
handleEDIDChange(e.target.value as string);
241+
}
242+
}}
243+
options={[...edids, { value: "custom", label: "Custom" }]}
242244
/>
243-
<div className="flex justify-start gap-x-2">
244-
<Button
245-
size="SM"
246-
theme="primary"
247-
text="Set Custom EDID"
248-
onClick={() => handleEDIDChange(customEdidValue)}
245+
</SettingsItem>
246+
{customEdidValue !== null && (
247+
<>
248+
<SettingsItem
249+
title="Custom EDID"
250+
description="EDID details video mode compatibility. Default settings works in most cases, but unique UEFI/BIOS might need adjustments."
249251
/>
250-
<Button
251-
size="SM"
252-
theme="light"
253-
text="Restore to default"
254-
onClick={() => {
255-
setCustomEdidValue(null);
256-
handleEDIDChange(defaultEdid);
257-
}}
252+
<TextAreaWithLabel
253+
label="EDID File"
254+
placeholder="00F..."
255+
rows={3}
256+
value={customEdidValue}
257+
onChange={e => setCustomEdidValue(e.target.value)}
258258
/>
259-
</div>
260-
</>
261-
)}
259+
<div className="flex justify-start gap-x-2">
260+
<Button
261+
size="SM"
262+
theme="primary"
263+
text="Set Custom EDID"
264+
loading={edidLoading}
265+
onClick={() => handleEDIDChange(customEdidValue)}
266+
/>
267+
<Button
268+
size="SM"
269+
theme="light"
270+
text="Restore to default"
271+
loading={edidLoading}
272+
onClick={() => {
273+
setCustomEdidValue(null);
274+
handleEDIDChange(defaultEdid);
275+
}}
276+
/>
277+
</div>
278+
</>
279+
)}
280+
</Fieldset>
262281
</div>
263282
</div>
264283
</div>

0 commit comments

Comments
 (0)