mirror of
https://github.com/outbackdingo/firezone.git
synced 2026-01-27 18:18:55 +00:00
Previously, we opted into the X11 GTK backend when rendering the GUI Client's window. This is causing issues on newer Linux distributions such as Fedora 43 where Wayland is now the only available compositor. Removing the X11 GTK requires us to draw our own CSDs such as titlebars and a close button. This PR does exactly that by adding a minimalistic title bar. To make better use of the space, we move the section headers into there. |Before|After| |---|---| |<img width="1900" height="1174" alt="Screenshot From 2025-11-11 11-14-11" src="https://github.com/user-attachments/assets/9439a69b-65ba-41d6-b1f8-4448e0f80728" />|<img width="1800" height="1000" alt="Screenshot From 2025-11-11 11-40-55" src="https://github.com/user-attachments/assets/7884b2cc-3d9c-4b47-9a1e-c6462aef36ab" />| |<img width="1900" height="1174" alt="Screenshot From 2025-11-11 11-14-16" src="https://github.com/user-attachments/assets/2cfea825-5c08-45a5-873c-5afcbc1dbf16" />|<img width="1800" height="1000" alt="Screenshot From 2025-11-11 11-40-58" src="https://github.com/user-attachments/assets/43ddd7c9-ce65-42f7-b972-28c6b172b70d" />| |<img width="1900" height="1174" alt="Screenshot From 2025-11-11 11-14-19" src="https://github.com/user-attachments/assets/446873a7-9023-4266-9377-ea7b8b4353ee" />|<img width="1800" height="1000" alt="Screenshot From 2025-11-11 11-41-01" src="https://github.com/user-attachments/assets/64439383-f33f-461d-9b4a-6b4138bd675b" />| |<img width="1900" height="1174" alt="Screenshot From 2025-11-11 11-14-22" src="https://github.com/user-attachments/assets/6c39e06c-1d77-471f-91f1-32a78b90a21c" />|<img width="1800" height="1000" alt="Screenshot From 2025-11-11 11-41-04" src="https://github.com/user-attachments/assets/b56912cb-9c85-4b5a-9295-dae6139b25c6" />| |<img width="1900" height="1174" alt="Screenshot From 2025-11-11 11-14-26" src="https://github.com/user-attachments/assets/5a5d638c-15bf-4523-8466-2e0977a03e22" />|<img width="1800" height="1000" alt="Screenshot From 2025-11-11 11-41-06" src="https://github.com/user-attachments/assets/ed169b52-ef86-4dc4-8f25-852da622eaa1" />|
137 lines
4.1 KiB
TypeScript
137 lines
4.1 KiB
TypeScript
import React, { useEffect, useId, useState } from "react";
|
|
import { Button, Label, ToggleSwitch } from "flowbite-react";
|
|
import { ManagedToggleSwitch, ManagedTextInput } from "./ManagedInput";
|
|
import { GeneralSettingsViewModel } from "../generated/bindings";
|
|
|
|
interface Props {
|
|
settings: GeneralSettingsViewModel | null;
|
|
saveSettings: (settings: GeneralSettingsViewModel) => void;
|
|
resetSettings: () => void;
|
|
}
|
|
|
|
export default function GeneralSettingsPage({
|
|
settings,
|
|
saveSettings,
|
|
resetSettings,
|
|
}: Props) {
|
|
// Local settings can be edited without affecting the global state.
|
|
const [localSettings, setLocalSettings] = useState<GeneralSettingsViewModel>(
|
|
settings ?? {
|
|
start_minimized: true,
|
|
account_slug: "",
|
|
connect_on_start: false,
|
|
start_on_login: false,
|
|
account_slug_is_managed: false,
|
|
connect_on_start_is_managed: false,
|
|
}
|
|
);
|
|
|
|
useEffect(() => {
|
|
setLocalSettings(
|
|
settings ?? {
|
|
start_minimized: true,
|
|
account_slug: "",
|
|
connect_on_start: false,
|
|
start_on_login: false,
|
|
account_slug_is_managed: false,
|
|
connect_on_start_is_managed: false,
|
|
}
|
|
);
|
|
}, [settings]);
|
|
|
|
const accountSlugInputId = useId();
|
|
const startMinimizedInputId = useId();
|
|
const startOnLoginInputId = useId();
|
|
const connectOnStartInputId = useId();
|
|
return (
|
|
<div className="container p-4">
|
|
<form
|
|
onSubmit={(e) => {
|
|
e.preventDefault();
|
|
saveSettings(localSettings);
|
|
}}
|
|
className="max-w flex flex-col gap-2"
|
|
>
|
|
<div>
|
|
<Label className="text-neutral-600" htmlFor={accountSlugInputId}>
|
|
Account slug
|
|
</Label>
|
|
<ManagedTextInput
|
|
name="account_slug"
|
|
id={accountSlugInputId}
|
|
managed={localSettings.account_slug_is_managed}
|
|
value={localSettings.account_slug}
|
|
onChange={(e) =>
|
|
setLocalSettings({
|
|
...localSettings,
|
|
account_slug: e.target.value,
|
|
})
|
|
}
|
|
/>
|
|
</div>
|
|
|
|
<div className="flex flex-col max-w-1/2 gap-4 mt-4">
|
|
<div className="flex justify-between items-center">
|
|
<Label className="text-neutral-600" htmlFor={startMinimizedInputId}>
|
|
Start minimized
|
|
</Label>
|
|
<ToggleSwitch
|
|
name="start_minimized"
|
|
id={startMinimizedInputId}
|
|
checked={localSettings.start_minimized}
|
|
onChange={(e) =>
|
|
setLocalSettings({
|
|
...localSettings,
|
|
start_minimized: e,
|
|
})
|
|
}
|
|
/>
|
|
</div>
|
|
|
|
<div className="flex justify-between items-center">
|
|
<Label className="text-neutral-600" htmlFor={startOnLoginInputId}>
|
|
Start on login
|
|
</Label>
|
|
<ToggleSwitch
|
|
name="start_on_login"
|
|
id={startOnLoginInputId}
|
|
checked={localSettings.start_on_login}
|
|
onChange={(e) =>
|
|
setLocalSettings({
|
|
...localSettings,
|
|
start_on_login: e,
|
|
})
|
|
}
|
|
/>
|
|
</div>
|
|
|
|
<div className="flex justify-between items-center">
|
|
<Label className="text-neutral-600" htmlFor={connectOnStartInputId}>
|
|
Connect on start
|
|
</Label>
|
|
<ManagedToggleSwitch
|
|
name="connect-on-start"
|
|
id={connectOnStartInputId}
|
|
managed={localSettings.connect_on_start_is_managed}
|
|
checked={localSettings.connect_on_start}
|
|
onChange={(e) =>
|
|
setLocalSettings({
|
|
...localSettings,
|
|
connect_on_start: e,
|
|
})
|
|
}
|
|
/>
|
|
</div>
|
|
</div>
|
|
|
|
<div className="flex justify-end gap-4 mt-4">
|
|
<Button type="reset" onClick={resetSettings} color="alternative">
|
|
Reset to Defaults
|
|
</Button>
|
|
<Button type="submit">Apply</Button>
|
|
</div>
|
|
</form>
|
|
</div>
|
|
);
|
|
}
|