From 8a9437e9b33752115fdb373596dbd12e6cd56096 Mon Sep 17 00:00:00 2001 From: Mathias Wagner Date: Wed, 11 Jun 2025 20:21:47 +0200 Subject: [PATCH] feat: add theme toggle option to Dropdown component with dark/light mode support --- client/public/assets/locales/en.json | 4 ++++ .../components/Dropdown/DropdownComponent.jsx | 14 +++++++++++++- 2 files changed, 17 insertions(+), 1 deletion(-) diff --git a/client/public/assets/locales/en.json b/client/public/assets/locales/en.json index c9be9fe7..31893f9c 100644 --- a/client/public/assets/locales/en.json +++ b/client/public/assets/locales/en.json @@ -60,6 +60,10 @@ "pause_tests": "Pause tests", "resume_tests": "Resume tests", "language": "Change language", + "light_mode": "Light mode", + "dark_mode": "Dark mode", + "theme_switched_light": "Switched to light mode", + "theme_switched_dark": "Switched to dark mode", "info": "About the project", "provider": "About the provider", "integrations": "Integrations" diff --git a/client/src/common/components/Dropdown/DropdownComponent.jsx b/client/src/common/components/Dropdown/DropdownComponent.jsx index 278689be..ae8668db 100644 --- a/client/src/common/components/Dropdown/DropdownComponent.jsx +++ b/client/src/common/components/Dropdown/DropdownComponent.jsx @@ -13,11 +13,16 @@ import { faPlay, faWandMagicSparkles, faCheck, - faExclamationTriangle, faSliders, faHardDrive + faExclamationTriangle, + faSliders, + faHardDrive, + faMoon, + faSun } from "@fortawesome/free-solid-svg-icons"; import {ConfigContext} from "@/common/contexts/Config"; import {StatusContext} from "@/common/contexts/Status"; import {InputDialogContext} from "@/common/contexts/InputDialog"; +import {ThemeContext} from "@/common/contexts/Theme"; import {baseRequest, jsonRequest, patchRequest, postRequest} from "@/common/utils/RequestUtil"; import {creditsInfo, recommendationsInfo} from "@/common/components/Dropdown/utils/infos"; import {levelOptions, selectOptions} from "@/common/components/Dropdown/utils/options"; @@ -34,6 +39,7 @@ import StorageDialog from "@/common/components/StorageDialog"; const DropdownComponent = ({isOpen, switchDropdown}) => { const [config, reloadConfig] = useContext(ConfigContext); const [status, updateStatus] = useContext(StatusContext); + const [isDarkMode, toggleTheme] = useContext(ThemeContext); const findNode = useContext(NodeContext)[4]; const updateNodes = useContext(NodeContext)[1]; const currentNode = useContext(NodeContext)[2]; @@ -175,6 +181,11 @@ const DropdownComponent = ({isOpen, switchDropdown}) => { const showProviderDetails = () => setDialog({title: t("dropdown.provider"), description: config.previewMessage, buttonText: t("dialog.close")}); + const handleThemeToggle = () => { + toggleTheme(); + updateToast(t(isDarkMode ? "dropdown.theme_switched_light" : "dropdown.theme_switched_dark"), "green", isDarkMode ? faSun : faMoon); + }; + const options = [ {run: updatePing, icon: faPingPongPaddleBall, text: t("dropdown.ping")}, {run: updateUpload, icon: faArrowUp, text: t("dropdown.upload")}, @@ -188,6 +199,7 @@ const DropdownComponent = ({isOpen, switchDropdown}) => { {run: togglePause, icon: status.paused ? faPlay : faPause, text: t("dropdown." + (status.paused ? "resume_tests" : "pause_tests"))}, {run: () => setShowIntegrationDialog(true), icon: faCircleNodes, text: t("dropdown.integrations")}, {hr: true, key: 2}, + {run: handleThemeToggle, icon: isDarkMode ? faSun : faMoon, text: t(isDarkMode ? "dropdown.light_mode" : "dropdown.dark_mode"), allowView: true}, {run: () => setShowLanguageDialog(true), icon: faGlobeEurope, text: t("dropdown.language"), allowView: true}, {run: showCredits, icon: faInfo, text: t("dropdown.info"), allowView: true, previewHidden: true}, {run: showProviderDetails, icon: faInfo, text: t("dropdown.provider"), previewShown: true}