Skip to content

Commit a3c4379

Browse files
committed
Delay before changing settings state
1 parent 6d23382 commit a3c4379

2 files changed

Lines changed: 35 additions & 12 deletions

File tree

src/programs/Settings/Settings.tsx

Lines changed: 29 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ import AppSideBar from "../../components/AppSideBar";
22
import { getPages } from "./settingsPageConfig";
33

44
import "./Settings.scss";
5-
import { HTMLInputTypeAttribute, useState } from "react";
5+
import React, { HTMLInputTypeAttribute, useRef, useState } from "react";
66
import useSystemSettings from "../../stores/systemSettingsStore";
77

88
interface SettingsSectionProps {
@@ -16,6 +16,12 @@ interface SettingsSectionProps {
1616
}
1717

1818
function SettingsSection(section: SettingsSectionProps) {
19+
// We'll keep the section value in local state for a short time
20+
// before updating global state with it. This will allow values which
21+
// are actively being input and at the time are technically "invalid"
22+
// to still be shown on the screen
23+
const updateStateDelay = useRef<NodeJS.Timeout | null>(null);
24+
const [value, setValue] = useState(section.currentValue);
1925
function getInputType(type: string): HTMLInputTypeAttribute {
2026
switch (type) {
2127
case "color":
@@ -26,6 +32,26 @@ function SettingsSection(section: SettingsSectionProps) {
2632
return "text";
2733
}
2834
}
35+
function handleChange(event: React.ChangeEvent<HTMLInputElement>) {
36+
setValue(event.currentTarget.value);
37+
updateStateDelay.current && clearTimeout(updateStateDelay.current);
38+
updateStateDelay.current = setTimeout(() => {
39+
const newValue = event.target.value;
40+
if (section.validValues && !section.validValues.includes(newValue)) {
41+
console.error("Not an allowed value");
42+
return;
43+
}
44+
45+
if (section.valueValidation) {
46+
console.error("Not a valid value");
47+
const error = section.valueValidation(newValue);
48+
if (error) return;
49+
}
50+
section.onValueChanged(newValue);
51+
}, 1000);
52+
}
53+
54+
console.log("value is ", value);
2955
return (
3056
<div className="settings__page-section">
3157
<h1 className="settings__page-section__title">{section.title}</h1>
@@ -35,11 +61,8 @@ function SettingsSection(section: SettingsSectionProps) {
3561
<input
3662
className="settings__page-section__value"
3763
type={getInputType(section.type)}
38-
value={String(section.currentValue)}
39-
onChange={(e) => {
40-
console.log("value changed to", e.currentTarget.value);
41-
section.onValueChanged(e.currentTarget.value);
42-
}}
64+
value={String(value)}
65+
onChange={handleChange}
4366
></input>
4467
</div>
4568
);

src/programs/Settings/settingsPageConfig.ts

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,10 @@
11
import { SystemSettingState } from "../../stores/systemSettingsStore";
22
import { SettingsPageProps } from "./Settings";
33

4+
function isHexColorCode(value: string) {
5+
return !!value.match("^#(?:[0-9a-fA-F]{3}){1,2}$");
6+
}
7+
48
export function getPages(
59
systemsSettings: SystemSettingState
610
): Record<string, SettingsPageProps> {
@@ -31,9 +35,7 @@ export function getPages(
3135
currentValue: systemsSettings.mainColor,
3236
type: "color",
3337
valueValidation: (value) =>
34-
value.match("^#(?:[0-9a-fA-F]{3}){1,2}$")
35-
? undefined
36-
: "Invalid HEX color code",
38+
isHexColorCode(value) ? undefined : "Invalid HEX color code",
3739
onValueChanged(value) {
3840
systemsSettings.setMainColor(value);
3941
},
@@ -45,9 +47,7 @@ export function getPages(
4547
currentValue: systemsSettings.accentColor,
4648
type: "color",
4749
valueValidation: (value) =>
48-
value.match("^#(?:[0-9a-fA-F]{3}){1,2}$")
49-
? undefined
50-
: "Invalid HEX color code",
50+
isHexColorCode(value) ? undefined : "Invalid HEX color code",
5151
onValueChanged(value) {
5252
systemsSettings.setAccentColor(value);
5353
},

0 commit comments

Comments
 (0)