1
Fork 0

Add save status changes to the username colors setting.

This commit is contained in:
Bauke 2023-09-14 13:24:06 +02:00
parent d69283f8a8
commit 45d9f03b50
Signed by: Bauke
GPG Key ID: C1C0F29952BCF558
2 changed files with 53 additions and 16 deletions

View File

@ -16,6 +16,7 @@ type State = {
usernameColors: UsernameColorsData; usernameColors: UsernameColorsData;
usernameColorsToRemove: UsernameColorsData; usernameColorsToRemove: UsernameColorsData;
randomizeChecked: Value<boolean>; randomizeChecked: Value<boolean>;
unsavedUsernameColorIds: Set<number>;
}; };
export class UsernameColorsSetting extends Component<SettingProps, State> { export class UsernameColorsSetting extends Component<SettingProps, State> {
@ -27,6 +28,7 @@ export class UsernameColorsSetting extends Component<SettingProps, State> {
usernameColors: undefined!, usernameColors: undefined!,
usernameColorsToRemove: [], usernameColorsToRemove: [],
randomizeChecked: undefined!, randomizeChecked: undefined!,
unsavedUsernameColorIds: new Set(),
}; };
} }
@ -38,11 +40,11 @@ export class UsernameColorsSetting extends Component<SettingProps, State> {
} }
addNewColor = async () => { addNewColor = async () => {
const {usernameColors, unsavedUsernameColorIds} = this.state;
let id = 1; let id = 1;
if (this.state.usernameColors.length > 0) { if (usernameColors.length > 0) {
id = id =
this.state.usernameColors.sort((a, b) => b.value.id - a.value.id)[0] usernameColors.sort((a, b) => b.value.id - a.value.id)[0].value.id + 1;
.value.id + 1;
} }
const newColor = await createValueUsernamecolor({ const newColor = await createValueUsernamecolor({
@ -50,24 +52,32 @@ export class UsernameColorsSetting extends Component<SettingProps, State> {
id, id,
username: "", username: "",
}); });
unsavedUsernameColorIds.add(id);
this.state.usernameColors.push(newColor); this.state.usernameColors.push(newColor);
this.setState({ this.setState({
usernameColors: this.state.usernameColors, usernameColors,
unsavedUsernameColorIds,
}); });
}; };
removeColor = async (targetId: number) => { removeColor = async (targetId: number) => {
const targetIndex = this.state.usernameColors.findIndex( const {usernameColors, usernameColorsToRemove, unsavedUsernameColorIds} =
this.state;
const targetIndex = usernameColors.findIndex(
({value}) => value.id === targetId, ({value}) => value.id === targetId,
); );
const usernameColorsToRemove = this.state.usernameColorsToRemove; if (targetIndex === -1) {
usernameColorsToRemove.push( log(`Tried to remove unknown UsernameColor ID: ${targetId}`);
...this.state.usernameColors.splice(targetIndex, 1), return;
); }
usernameColorsToRemove.push(...usernameColors.splice(targetIndex, 1));
unsavedUsernameColorIds.add(targetId);
this.setState({ this.setState({
usernameColors: this.state.usernameColors, usernameColors,
usernameColorsToRemove, usernameColorsToRemove,
unsavedUsernameColorIds,
}); });
}; };
@ -80,7 +90,10 @@ export class UsernameColorsSetting extends Component<SettingProps, State> {
await usernameColor.save(); await usernameColor.save();
} }
this.setState({usernameColorsToRemove: []}); this.setState({
usernameColorsToRemove: [],
unsavedUsernameColorIds: new Set(),
});
}; };
togglePreview = async () => { togglePreview = async () => {
@ -115,6 +128,7 @@ export class UsernameColorsSetting extends Component<SettingProps, State> {
}; };
onInput = (event: Event, id: number, key: "color" | "username") => { onInput = (event: Event, id: number, key: "color" | "username") => {
const {unsavedUsernameColorIds} = this.state;
const colorIndex = this.state.usernameColors.findIndex( const colorIndex = this.state.usernameColors.findIndex(
({value}) => value.id === id, ({value}) => value.id === id,
); );
@ -125,11 +139,17 @@ export class UsernameColorsSetting extends Component<SettingProps, State> {
const newValue = (event.target as HTMLInputElement).value; const newValue = (event.target as HTMLInputElement).value;
this.state.usernameColors[colorIndex].value[key] = newValue; this.state.usernameColors[colorIndex].value[key] = newValue;
unsavedUsernameColorIds.add(id);
this.setState({usernameColors: this.state.usernameColors}); this.setState({usernameColors: this.state.usernameColors});
}; };
render() { render() {
const {previewChecked, usernameColors, randomizeChecked} = this.state; const {
previewChecked,
usernameColors,
randomizeChecked,
unsavedUsernameColorIds,
} = this.state;
if (usernameColors === undefined) { if (usernameColors === undefined) {
return; return;
} }
@ -156,8 +176,15 @@ export class UsernameColorsSetting extends Component<SettingProps, State> {
await this.removeColor(id); await this.removeColor(id);
}; };
const hasUnsavedChanges = unsavedUsernameColorIds.has(id)
? "unsaved-changes"
: "";
return ( return (
<div class="username-colors-editor" key={id}> <div
class={`has-save-status username-colors-editor ${hasUnsavedChanges}`}
key={id}
>
<input <input
style={style} style={style}
placeholder="Username(s)" placeholder="Username(s)"
@ -177,6 +204,9 @@ export class UsernameColorsSetting extends Component<SettingProps, State> {
); );
}); });
const anyUnsavedChanges =
unsavedUsernameColorIds.size > 0 ? "unsaved-changes" : "";
return ( return (
<Setting {...this.props}> <Setting {...this.props}>
<p class="info"> <p class="info">
@ -199,8 +229,11 @@ export class UsernameColorsSetting extends Component<SettingProps, State> {
Toggle Preview Toggle Preview
</button> </button>
<button class="button" onClick={this.saveChanges}> <button
Save Changes class={`button save-button ${anyUnsavedChanges}`}
onClick={this.saveChanges}
>
Save Changes{anyUnsavedChanges.length > 0 ? "*" : ""}
</button> </button>
<ul class="checkbox-list"> <ul class="checkbox-list">

View File

@ -111,6 +111,10 @@
display: grid; display: grid;
gap: 8px; gap: 8px;
grid-template-columns: repeat(3, 1fr); grid-template-columns: repeat(3, 1fr);
.save-button.unsaved-changes {
background-color: var(--yellow);
}
} }
.username-colors-editor { .username-colors-editor {
@ -121,7 +125,7 @@
input { input {
background-color: var(--background-primary); background-color: var(--background-primary);
border: 1px solid var(--blue); border: 1px solid var(--save-status-color);
color: var(--foreground); color: var(--foreground);
padding: 8px; padding: 8px;
} }