From fb267011b16edbf7bd33c14e9436e2872be9e207 Mon Sep 17 00:00:00 2001 From: sumn2u Date: Mon, 22 Jul 2024 19:31:06 -0500 Subject: [PATCH 1/6] support dark theme --- client/src/Annotation/index.jsx | 6 ++ client/src/Annotation/styles.js | 2 +- .../src/ClassDistributionSidebarBox/index.jsx | 2 +- client/src/ClassSelectionMenu/index.jsx | 2 +- client/src/FilesListMenu/index.jsx | 2 +- client/src/ImageUpload/index.jsx | 3 +- client/src/MainLayout/styles.js | 8 +- client/src/RegionSelectorSidebarBox/styles.js | 2 +- client/src/RegionTags/index.jsx | 2 +- client/src/Theme/index.jsx | 79 ++++++++++++++----- client/src/ThemeContext/index.jsx | 24 ++++++ client/src/index.jsx | 13 +-- client/src/workspace/Header/index.jsx | 2 +- client/src/workspace/IconSidebar/index.jsx | 2 +- client/src/workspace/RightSidebar/index.jsx | 4 +- client/src/workspace/SidebarBox/styles.js | 1 + client/src/workspace/WorkContainer/index.jsx | 2 +- 17 files changed, 117 insertions(+), 39 deletions(-) create mode 100644 client/src/ThemeContext/index.jsx diff --git a/client/src/Annotation/index.jsx b/client/src/Annotation/index.jsx index 59f4d6f..c1020c4 100644 --- a/client/src/Annotation/index.jsx +++ b/client/src/Annotation/index.jsx @@ -4,6 +4,7 @@ import SetupPage from "../SetupPage" import { useSettings } from "../SettingsProvider" import { setIn } from "seamless-immutable" import config from "../config.js" +import { CssBaseline } from "@mui/material" import { useSnackbar } from "../SnackbarContext" import { getImagesAnnotation } from "../utils/send-data-to-server" import CircularProgress from "@mui/material/CircularProgress" @@ -12,6 +13,8 @@ import AlertDialog from "../AlertDialog" import { clear_db, getSettings } from "../utils/get-data-from-server" import colors from "../colors.js" import { useTranslation } from "react-i18next" +import { themes } from "../Theme" +import { useTheme } from '../ThemeContext' const extractRelevantProps = (region) => ({ cls: region.cls, @@ -63,6 +66,7 @@ export default () => { const settingsConfig = useSettings() const [isLoading, setIsLoading] = useState(true) const { showSnackbar } = useSnackbar() + const { toggleTheme, theme } = useTheme(); const [settings, setSettings] = useState({ taskDescription: "", taskChoice: "image_classification", @@ -306,6 +310,7 @@ export default () => { return ( <> + {!showLabel ? ( { setIsSettingsOpen(!isSettingsOpen) setShowLabel(false) }} + rootTheme={themes[theme]} selectedImageIndex={selectedImageIndex} /> diff --git a/client/src/Annotation/styles.js b/client/src/Annotation/styles.js index a709a3b..7c5e1c4 100644 --- a/client/src/Annotation/styles.js +++ b/client/src/Annotation/styles.js @@ -2,7 +2,7 @@ export default { editBar: { padding: 10, borderBottom: "1px solid #ccc", - backgroundColor: "#f8f8f8", + // backgroundColor: "#f8f8f8", display: "flex", alignItems: "center", "& .button": { margin: 5 }, diff --git a/client/src/ClassDistributionSidebarBox/index.jsx b/client/src/ClassDistributionSidebarBox/index.jsx index 91a7fc2..a59f78b 100644 --- a/client/src/ClassDistributionSidebarBox/index.jsx +++ b/client/src/ClassDistributionSidebarBox/index.jsx @@ -77,7 +77,7 @@ export const ClassDistributionSidebarBox = ({ regionClsList, shouldExpand=false } return ( - + } diff --git a/client/src/ClassSelectionMenu/index.jsx b/client/src/ClassSelectionMenu/index.jsx index 3d71091..5102869 100644 --- a/client/src/ClassSelectionMenu/index.jsx +++ b/client/src/ClassSelectionMenu/index.jsx @@ -19,7 +19,7 @@ const LabelContainer = styled("div")(({ theme }) => ({ alignItems: "center", cursor: "pointer", opacity: 0.7, - backgroundColor: "#fff", + // backgroundColor: "#fff", "&:hover": { opacity: 1, }, diff --git a/client/src/FilesListMenu/index.jsx b/client/src/FilesListMenu/index.jsx index c750a04..21f1853 100644 --- a/client/src/FilesListMenu/index.jsx +++ b/client/src/FilesListMenu/index.jsx @@ -22,7 +22,7 @@ const LabelContainer = styled("div")(({ theme }) => ({ alignItems: "center", cursor: "pointer", opacity: 0.7, - backgroundColor: "#fff", + // backgroundColor: "#fff", "&:hover": { opacity: 1, }, diff --git a/client/src/ImageUpload/index.jsx b/client/src/ImageUpload/index.jsx index d16b7a6..c6069a3 100644 --- a/client/src/ImageUpload/index.jsx +++ b/client/src/ImageUpload/index.jsx @@ -1,7 +1,7 @@ import React, { useCallback, useState } from "react" import { useDropzone } from "react-dropzone" import { createTheme } from "@mui/material/styles" -import { Box, Typography, IconButton } from "@mui/material" +import { CssBaseline, Box, Typography, IconButton } from "@mui/material" import DeleteIcon from "@mui/icons-material/Delete" import axios from "axios" import { useSnackbar } from "../SnackbarContext" @@ -157,6 +157,7 @@ const ImageUpload = ({ onImageUpload, settingsImages }) => { return ( <> + { + const { theme } = useTheme(); // Get current theme from context + console.log('Theme:', themes[theme]); return ( - + -
{children}
+
{children}
-
- ) -} + + ); +}; -export default Theme +export default Theme; \ No newline at end of file diff --git a/client/src/ThemeContext/index.jsx b/client/src/ThemeContext/index.jsx new file mode 100644 index 0000000..accc446 --- /dev/null +++ b/client/src/ThemeContext/index.jsx @@ -0,0 +1,24 @@ +import React, { createContext, useState, useContext } from 'react'; + +export const ThemeContext = createContext(); + +export const ThemeProvider = ({ children }) => { + const [theme, setTheme] = useState('dark'); // Default to light theme + + const toggleTheme = () => { + setTheme((prevTheme) => (prevTheme === 'light' ? 'dark' : 'light')); + }; + + const themeConfig = { + theme, + toggleTheme, + }; + + return ( + + {children} + + ); +}; + +export const useTheme = () => useContext(ThemeContext); \ No newline at end of file diff --git a/client/src/index.jsx b/client/src/index.jsx index aeabbc2..3ef9686 100644 --- a/client/src/index.jsx +++ b/client/src/index.jsx @@ -2,6 +2,7 @@ import React from "react" import { createRoot } from "react-dom/client" import Theme from "./Theme" +import { ThemeProvider } from "./ThemeContext" import Annotation from "./Annotation" import "./site.css" import { SettingsProvider } from "./SettingsProvider" @@ -12,11 +13,13 @@ const Site = () => { .split("/") .slice(-1)[0] return ( - - - - - + + + + + + + ) } diff --git a/client/src/workspace/Header/index.jsx b/client/src/workspace/Header/index.jsx index 2985d87..6800ce1 100644 --- a/client/src/workspace/Header/index.jsx +++ b/client/src/workspace/Header/index.jsx @@ -11,7 +11,7 @@ const theme = createTheme() const Container = styled("div")(({ theme }) => ({ width: "100%", display: "flex", - backgroundColor: "#fff", + // backgroundColor: "#fff", borderBottom: "1px solid #ccc", alignItems: "center", flexShrink: 1, diff --git a/client/src/workspace/IconSidebar/index.jsx b/client/src/workspace/IconSidebar/index.jsx index db2259c..fb5c387 100644 --- a/client/src/workspace/IconSidebar/index.jsx +++ b/client/src/workspace/IconSidebar/index.jsx @@ -11,7 +11,7 @@ const Container = styled("div")(({ theme }) => ({ height: "100%", display: "flex", flexDirection: "column", - backgroundColor: "#fff", + // backgroundColor: "#fff", flexShrink: 0, })) diff --git a/client/src/workspace/RightSidebar/index.jsx b/client/src/workspace/RightSidebar/index.jsx index aeaf4c7..e7cfe5f 100644 --- a/client/src/workspace/RightSidebar/index.jsx +++ b/client/src/workspace/RightSidebar/index.jsx @@ -12,7 +12,7 @@ const Container = styled("div")(({ theme }) => ({ flexDirection: "column", height: "100%", flexShrink: 0, - backgroundColor: "#fff", + // backgroundColor: "#fff", position: "relative", transition: "width 500ms", "&.expanded": { @@ -34,7 +34,7 @@ const Expander = styled(ButtonBase)(({ theme }) => ({ borderBottom: `1px solid ${grey[400]}`, borderLeft: `1px solid ${grey[400]}`, boxShadow: "-1px 2px 5px rgba(0,0,0,0.2)", - backgroundColor: "#fff", + // backgroundColor: "#fff", position: "absolute", top: "calc(50% - 20px)", left: -23, diff --git a/client/src/workspace/SidebarBox/styles.js b/client/src/workspace/SidebarBox/styles.js index 4636532..e289760 100644 --- a/client/src/workspace/SidebarBox/styles.js +++ b/client/src/workspace/SidebarBox/styles.js @@ -38,6 +38,7 @@ export default { padding: 0, width: 30, height: 30, + color: grey[800], "& .icon": { width: 20, height: 20, diff --git a/client/src/workspace/WorkContainer/index.jsx b/client/src/workspace/WorkContainer/index.jsx index bd4be83..a062ff1 100644 --- a/client/src/workspace/WorkContainer/index.jsx +++ b/client/src/workspace/WorkContainer/index.jsx @@ -8,7 +8,7 @@ const Container = styled("div")(({ theme }) => ({ flexGrow: 1, flexShrink: 1, height: "100%", - backgroundColor: grey[50], + // backgroundColor: grey[50], overflowY: "auto", })) const ShadowOverlay = styled("div")(({ theme }) => ({ From 049d2987a71455bd17dd19979a375d5d11b8df03 Mon Sep 17 00:00:00 2001 From: sumn2u Date: Mon, 22 Jul 2024 22:34:17 -0500 Subject: [PATCH 2/6] fix the icon designs for dark mode in annotation screen --- client/src/HistorySidebarBox/index.jsx | 2 +- client/src/RegionSelectorSidebarBox/index.jsx | 2 +- client/src/RegionTags/index.jsx | 2 +- client/src/Theme/index.jsx | 6 +++- client/src/workspace/HeaderButton/index.jsx | 30 ++++++++++++------- client/src/workspace/IconSidebar/index.jsx | 2 +- client/src/workspace/SidebarBox/index.jsx | 13 ++++++-- client/src/workspace/SidebarBox/styles.js | 7 ++--- 8 files changed, 41 insertions(+), 23 deletions(-) diff --git a/client/src/HistorySidebarBox/index.jsx b/client/src/HistorySidebarBox/index.jsx index af44afa..b25aae1 100644 --- a/client/src/HistorySidebarBox/index.jsx +++ b/client/src/HistorySidebarBox/index.jsx @@ -20,7 +20,7 @@ const theme = createTheme() const EmptyTextDiv = styled("div")(() => ({ fontSize: 14, fontWeight: "bold", - color: grey[500], + // color: grey[500], textAlign: "center", padding: 20, })) diff --git a/client/src/RegionSelectorSidebarBox/index.jsx b/client/src/RegionSelectorSidebarBox/index.jsx index af1a651..909b679 100644 --- a/client/src/RegionSelectorSidebarBox/index.jsx +++ b/client/src/RegionSelectorSidebarBox/index.jsx @@ -27,7 +27,7 @@ const ChipSpan = styled("span")(() => styles.chip) const RowDiv = styled("div")(() => styles.row) const ContainerDiv = styled("div")(() => styles.container) const HeaderSep = styled("div")(({ theme }) => ({ - borderTop: `1px solid ${grey[200]}`, + // borderTop: `1px solid ${grey[200]}`, marginTop: 2, marginBottom: 2, })) diff --git a/client/src/RegionTags/index.jsx b/client/src/RegionTags/index.jsx index 4a4c5e2..7986982 100644 --- a/client/src/RegionTags/index.jsx +++ b/client/src/RegionTags/index.jsx @@ -105,7 +105,7 @@ export const RegionTags = ({ pointerEvents: "none", }} > - + ) diff --git a/client/src/Theme/index.jsx b/client/src/Theme/index.jsx index 5ae8216..8a0c3de 100644 --- a/client/src/Theme/index.jsx +++ b/client/src/Theme/index.jsx @@ -4,6 +4,7 @@ import React from "react" import { createTheme, ThemeProvider as MuiThemeProvider } from "@mui/material/styles" import { SnackbarProvider } from "../SnackbarContext" import { useTheme } from "../ThemeContext" +import { grey } from "@mui/material/colors" export const themes = { light: createTheme({ @@ -44,6 +45,10 @@ export const themes = { }, text: { primary: '#fff', + secondary: grey[400], + }, + default: { + main: "#ffffff", // Default color for dark mode buttons }, }, components: { @@ -60,7 +65,6 @@ export const themes = { export const Theme = ({ children }) => { const { theme } = useTheme(); // Get current theme from context - console.log('Theme:', themes[theme]); return ( diff --git a/client/src/workspace/HeaderButton/index.jsx b/client/src/workspace/HeaderButton/index.jsx index c40d161..d51b791 100644 --- a/client/src/workspace/HeaderButton/index.jsx +++ b/client/src/workspace/HeaderButton/index.jsx @@ -7,8 +7,8 @@ import { useIconDictionary } from "../icon-dictionary.js" import { iconMapping } from "../icon-mapping.js" import { colors } from "@mui/material" import useMediaQuery from "@mui/material/useMediaQuery" - -const theme = createTheme() +import { useTheme } from '../../ThemeContext' +const defaultTheme = createTheme() const defaultNameIconMapping = iconMapping const getIcon = (name, customIconMapping) => { @@ -32,8 +32,12 @@ const ButtonInnerContent = styled("div")(({ theme }) => ({ display: "flex", flexDirection: "column", })) -const IconContainer = styled("div")(({ textHidden, disabled }) => ({ - color: disabled ? colors.grey[400] : colors.grey[700], +const IconContainer = styled("div")(({defaultTheme, theme, textHidden, disabled }) => ({ + color: disabled + ? defaultTheme.palette.action.disabled + : theme === "dark" + ? colors.grey[200] + : colors.grey[700], height: textHidden ? 32 : 20, paddingTop: textHidden ? 8 : 0, "& .MuiSvgIcon-root": { @@ -41,10 +45,14 @@ const IconContainer = styled("div")(({ textHidden, disabled }) => ({ height: 18, }, })) -const Text = styled("div")(({ theme, disabled }) => ({ +const Text = styled("div")(({ defaultTheme, theme, disabled }) => ({ fontWeight: "bold", fontSize: 11, - color: disabled ? colors.grey[500] : colors.grey[800], + color: disabled + ? defaultTheme.palette.action.disabled + : theme === "dark" + ? colors.grey[200] + : colors.grey[700], display: "flex", alignItems: "center", lineHeight: 1, @@ -60,17 +68,17 @@ export const HeaderButton = ({ hideText = false, }) => { const customIconMapping = useIconDictionary() - const isSmallDevice = useMediaQuery(theme.breakpoints.down("sm")) - + const isSmallDevice = useMediaQuery(defaultTheme.breakpoints.down("sm")) + const { theme } = useTheme(); return ( - + - + {icon || getIcon(name, customIconMapping)} {!hideText && !isSmallDevice && ( - +
{label}
)} diff --git a/client/src/workspace/IconSidebar/index.jsx b/client/src/workspace/IconSidebar/index.jsx index fb5c387..6abe2eb 100644 --- a/client/src/workspace/IconSidebar/index.jsx +++ b/client/src/workspace/IconSidebar/index.jsx @@ -38,7 +38,7 @@ export const IconSidebar = ({ color={ item.selected || selectedTools.includes(item.name.toLowerCase()) ? "primary" - : "default" + : "inherit" } disabled={Boolean(item.disabled)} onClick={item.onClick ? item.onClick : () => onClickItem(item)} diff --git a/client/src/workspace/SidebarBox/index.jsx b/client/src/workspace/SidebarBox/index.jsx index eda83da..807f99c 100644 --- a/client/src/workspace/SidebarBox/index.jsx +++ b/client/src/workspace/SidebarBox/index.jsx @@ -2,6 +2,7 @@ import React, { useState, memo, useCallback } from "react" import { createTheme, styled, ThemeProvider } from "@mui/material/styles" +import { useTheme } from "../../ThemeContext" import ExpandIcon from "@mui/icons-material/ExpandMore" import IconButton from "@mui/material/IconButton" import Collapse from "@mui/material/Collapse" @@ -11,7 +12,7 @@ import Typography from "@mui/material/Typography" import { useIconDictionary } from "../icon-dictionary.js" import styles from "./styles.js" -const theme = createTheme() +// const theme = createTheme() const ContainerDiv = styled("div")(() => styles.container) const HeaderDiv = styled("div")(() => styles.header) const ContentDiv = styled("div")(() => styles.expandedContent) @@ -31,6 +32,8 @@ const setExpandedInLocalStorage = (title, expanded) => { JSON.stringify(expanded) } +// const useStyles = makeStyles(styles) + export const SidebarBox = ({ icon, title, @@ -39,6 +42,8 @@ export const SidebarBox = ({ noScroll, expandedByDefault, }) => { + + const content = ( {children} @@ -61,8 +66,10 @@ export const SidebarBox = ({ const toggleExpanded = useEventCallback(() => changeExpanded(!expanded)) const customIconMapping = useIconDictionary() const TitleIcon = customIconMapping[title.toLowerCase()] + + const { theme } = useTheme(); return ( - + <>
{icon || }
@@ -90,7 +97,7 @@ export const SidebarBox = ({ )}
-
+ ) } diff --git a/client/src/workspace/SidebarBox/styles.js b/client/src/workspace/SidebarBox/styles.js index e289760..f5503f2 100644 --- a/client/src/workspace/SidebarBox/styles.js +++ b/client/src/workspace/SidebarBox/styles.js @@ -3,7 +3,8 @@ import { grey } from "@mui/material/colors" export default { container: { borderBottom: `2px solid ${grey[400]}`, - "&:firstChild": { borderTop: `1px solid ${grey[400]}` }, + "&:firstChild": { + borderTop: `1px solid ${grey[400]}` }, }, header: { display: "flex", @@ -13,7 +14,6 @@ export default { paddingLeft: 16, paddingRight: 12, "& .iconContainer": { - color: grey[600], display: "flex", alignItems: "center", justifyContent: "center", @@ -28,7 +28,6 @@ export default { flexGrow: 1, fontWeight: 800, paddingLeft: 8, - color: grey[800], "& span": { color: grey[600], fontSize: 11, @@ -38,7 +37,7 @@ export default { padding: 0, width: 30, height: 30, - color: grey[800], + // color: grey[800], "& .icon": { width: 20, height: 20, From a15facda8d2319096d196003836a2fa5d2c1f326 Mon Sep 17 00:00:00 2001 From: sumn2u Date: Tue, 23 Jul 2024 09:18:22 -0500 Subject: [PATCH 3/6] fix dark theme design for annotation screen --- .../src/ClassDistributionSidebarBox/index.jsx | 57 +++++++++++-------- client/src/FilesListMenu/index.jsx | 2 +- client/src/HistorySidebarBox/index.jsx | 1 + client/src/SidebarBoxContainer/index.jsx | 6 +- client/src/workspace/IconSidebar/index.jsx | 9 +-- client/src/workspace/SidebarBox/index.jsx | 2 +- 6 files changed, 43 insertions(+), 34 deletions(-) diff --git a/client/src/ClassDistributionSidebarBox/index.jsx b/client/src/ClassDistributionSidebarBox/index.jsx index a59f78b..b4f1380 100644 --- a/client/src/ClassDistributionSidebarBox/index.jsx +++ b/client/src/ClassDistributionSidebarBox/index.jsx @@ -4,7 +4,7 @@ import React, { useEffect, useState } from "react" import { createTheme, ThemeProvider } from "@mui/material/styles" import SidebarBoxContainer from "../SidebarBoxContainer" import BarChartIcon from "@mui/icons-material/BarChart" -import { grey } from "@mui/material/colors" +import { grey, deepOrange } from "@mui/material/colors" import { useTranslation } from "react-i18next" import { BarChart } from "@mui/x-charts/BarChart" import RefreshIcon from "@mui/icons-material/Refresh" @@ -12,10 +12,13 @@ import IconButton from "@mui/material/IconButton" import Paper from "@mui/material/Paper" import { getLabels } from "../utils/get-data-from-server" import colors from "../colors" - -const theme = createTheme() +import { useTheme } from "../ThemeContext" +import { themes } from "../Theme" export const ClassDistributionSidebarBox = ({ regionClsList, shouldExpand=false }) => { const { t } = useTranslation() + const { theme } = useTheme() + const newTheme = createTheme({ palette: { mode: theme } }); + const [labelsInfo, setLabelsInfo] = useState([]) const assignRandomColors = (responseList, classList) => { let coloredResponse = [] @@ -55,13 +58,6 @@ export const ClassDistributionSidebarBox = ({ regionClsList, shouldExpand=false fetchData() } - const barChartsParams = { - slotProps: { - legend: { - hidden: true, - }, - }, - } const CustomItemTooltipContent = (props) => { const { itemData, series } = props @@ -75,10 +71,23 @@ export const ClassDistributionSidebarBox = ({ regionClsList, shouldExpand=false ) } + const darkMode = theme === themes.dark; + const barChartsParams = { + slotProps: { + legend: { + hidden: true, + label: { + style: { + color: darkMode ? "#ffffff" : "#000000", + }, + }, + }, + }, + }; return ( - - + } noScroll={true} @@ -93,24 +102,24 @@ export const ClassDistributionSidebarBox = ({ regionClsList, shouldExpand=false }} > - + diff --git a/client/src/FilesListMenu/index.jsx b/client/src/FilesListMenu/index.jsx index 21f1853..d9d6a1e 100644 --- a/client/src/FilesListMenu/index.jsx +++ b/client/src/FilesListMenu/index.jsx @@ -100,7 +100,7 @@ export const FilesListMenu = ({ padding: 0, "& .MuiSvgIcon-root": { fontSize: 14, // Set size - color: image.processed ? "green" : "", // Set color conditionally + color: image.processed ? "green" : "#1976d2", // Set color conditionally }, cursor: selectedImage !== null && selectedImage !== index diff --git a/client/src/HistorySidebarBox/index.jsx b/client/src/HistorySidebarBox/index.jsx index b25aae1..f294615 100644 --- a/client/src/HistorySidebarBox/index.jsx +++ b/client/src/HistorySidebarBox/index.jsx @@ -30,6 +30,7 @@ const listItemTextStyle = { fontSize: 11, paddingTop: 0, paddingBottom: 0, + color: "inherit", } export const HistorySidebarBox = ({ history, onRestoreHistory }) => { diff --git a/client/src/SidebarBoxContainer/index.jsx b/client/src/SidebarBoxContainer/index.jsx index 925863b..353874d 100644 --- a/client/src/SidebarBoxContainer/index.jsx +++ b/client/src/SidebarBoxContainer/index.jsx @@ -1,10 +1,8 @@ // @flow import React, { memo } from "react" -import { createTheme, ThemeProvider } from "@mui/material/styles" import SidebarBox from "../workspace/SidebarBox" -const theme = createTheme() export const SidebarBoxContainer = ({ icon, title, @@ -14,7 +12,7 @@ export const SidebarBoxContainer = ({ expandedByDefault = false, }) => { return ( - + <> {children} - + ) } diff --git a/client/src/workspace/IconSidebar/index.jsx b/client/src/workspace/IconSidebar/index.jsx index 6abe2eb..437836d 100644 --- a/client/src/workspace/IconSidebar/index.jsx +++ b/client/src/workspace/IconSidebar/index.jsx @@ -4,8 +4,8 @@ import IconButton from "@mui/material/IconButton" import { iconMapping } from "../icon-mapping.js" import { useIconDictionary } from "../icon-dictionary.js" import Tooltip from "@mui/material/Tooltip" - -const theme = createTheme() +import { useTheme } from "../../ThemeContext" +const defaultTheme = createTheme() const Container = styled("div")(({ theme }) => ({ width: 50, height: "100%", @@ -23,8 +23,9 @@ export const IconSidebar = ({ selectedTools = emptyAr, }) => { const customIconMapping = useIconDictionary() + const { theme } = useTheme() return ( - + {items.map((item) => { let NameIcon = @@ -38,7 +39,7 @@ export const IconSidebar = ({ color={ item.selected || selectedTools.includes(item.name.toLowerCase()) ? "primary" - : "inherit" + : theme === "dark"? "inherit" :"default" } disabled={Boolean(item.disabled)} onClick={item.onClick ? item.onClick : () => onClickItem(item)} diff --git a/client/src/workspace/SidebarBox/index.jsx b/client/src/workspace/SidebarBox/index.jsx index 807f99c..1ef735a 100644 --- a/client/src/workspace/SidebarBox/index.jsx +++ b/client/src/workspace/SidebarBox/index.jsx @@ -76,7 +76,7 @@ export const SidebarBox = ({ {title} {subTitle} - + From 0df840ccd2e9bf6888e414562e384d1892962c0b Mon Sep 17 00:00:00 2001 From: sumn2u Date: Tue, 23 Jul 2024 09:23:59 -0500 Subject: [PATCH 4/6] use browser default theme --- client/src/ThemeContext/index.jsx | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/client/src/ThemeContext/index.jsx b/client/src/ThemeContext/index.jsx index accc446..5b935cd 100644 --- a/client/src/ThemeContext/index.jsx +++ b/client/src/ThemeContext/index.jsx @@ -3,7 +3,18 @@ import React, { createContext, useState, useContext } from 'react'; export const ThemeContext = createContext(); export const ThemeProvider = ({ children }) => { - const [theme, setTheme] = useState('dark'); // Default to light theme + const getPreferredColorScheme = () => { + if (window.matchMedia && window.matchMedia('(prefers-color-scheme: dark)').matches) { + return 'dark'; + } else { + return 'light'; + } + } + + const preferredColorScheme = getPreferredColorScheme(); + console.log(`Preferred color scheme: ${preferredColorScheme}`); + + const [theme, setTheme] = useState(preferredColorScheme); // Default to browser theme const toggleTheme = () => { setTheme((prevTheme) => (prevTheme === 'light' ? 'dark' : 'light')); From ab3a54e4dac8d4966e05454d1b659ec41fcfe7ae Mon Sep 17 00:00:00 2001 From: sumn2u Date: Tue, 23 Jul 2024 10:36:43 -0500 Subject: [PATCH 5/6] add them switch button on setup page --- client/src/SetupPage/index.jsx | 33 +++++++++++++++++++++++++++------ 1 file changed, 27 insertions(+), 6 deletions(-) diff --git a/client/src/SetupPage/index.jsx b/client/src/SetupPage/index.jsx index e8a6f55..096e151 100644 --- a/client/src/SetupPage/index.jsx +++ b/client/src/SetupPage/index.jsx @@ -25,8 +25,10 @@ import CloseIcon from "@mui/icons-material/Close" import useMediaQuery from "@mui/material/useMediaQuery" import config from "../config.js" import { saveSettings } from "../utils/send-data-to-server.js" - -const theme = createTheme() +import Brightness4Icon from '@mui/icons-material/Brightness4'; +import Brightness7Icon from '@mui/icons-material/Brightness7'; +import { useTheme } from "../ThemeContext" +const defaultTheme = createTheme() const Container = styled("div")({ marginTop: "2rem", @@ -68,9 +70,9 @@ export const SetupPage = ({ const [currentTab, setTab] = useState(false) const [hasConfig, setHasConfig] = useState(false) const settingsConfig = useSettings() - const isSmallDevice = useMediaQuery(theme.breakpoints.down("sm")) - const isLargeDevice = useMediaQuery(theme.breakpoints.up("md")) - + const isSmallDevice = useMediaQuery(defaultTheme.breakpoints.down("sm")) + const isLargeDevice = useMediaQuery(defaultTheme.breakpoints.up("md")) + const { theme, toggleTheme } = useTheme() const updateConfiguration = (newConfig) => { const { labels, @@ -216,6 +218,25 @@ export const SetupPage = ({ <> + ({ paddingTop: isSmallDevice ? "0" : "0.5rem", padding: isSmallDevice ? "1.5rem" : "1rem", - [theme.breakpoints.down("sm")]: { + [defaultTheme.breakpoints.down("sm")]: { padding: "1rem", }, })} From cd245d984b7757cedaca3d03483c22ac78b5976b Mon Sep 17 00:00:00 2001 From: sumn2u Date: Tue, 23 Jul 2024 10:54:30 -0500 Subject: [PATCH 6/6] fix missing test case caused by use theme support --- .../ClassDistributionSidebarBox.test.js | 7 +++++++ client/src/ClassSelectionMenu/ClassSelectionMenu.test.js | 8 ++++++++ client/src/DebugSidebarBox/DebugSidebarBox.test.js | 9 +++++++++ client/src/FilesListMenu/FilesListMenu.test.js | 9 +++++++++ client/src/HistorySidebarBox/HistorySidebarBox.test.js | 8 ++++++++ .../KeyframesSelectorSidebarBox.test.js | 8 ++++++++ .../RegionSelectorSidebarBox.test.js | 8 ++++++++ client/src/SetupPage/SetupPage.test.js | 8 ++++++++ .../src/SidebarBoxContainer/SidebarBoxContainer.test.js | 8 ++++++++ client/src/TagsSidebarBox/TagsSidebarBox.test.js | 8 ++++++++ .../src/workspace/DownloadButton/DownloadButton.test.js | 8 ++++++++ client/src/workspace/Header/Header.test.js | 8 ++++++++ client/src/workspace/HeaderButton/HeaderButton.test.js | 8 ++++++++ client/src/workspace/IconSidebar/IconSidebar.test.js | 8 ++++++++ client/src/workspace/SidebarBox/SidebarBox.test.js | 8 ++++++++ client/src/workspace/Workspace/Workspace.test.js | 7 +++++++ 16 files changed, 128 insertions(+) diff --git a/client/src/ClassDistributionSidebarBox/ClassDistributionSidebarBox.test.js b/client/src/ClassDistributionSidebarBox/ClassDistributionSidebarBox.test.js index d251503..0c84fc1 100644 --- a/client/src/ClassDistributionSidebarBox/ClassDistributionSidebarBox.test.js +++ b/client/src/ClassDistributionSidebarBox/ClassDistributionSidebarBox.test.js @@ -10,6 +10,13 @@ jest.mock("../utils/get-data-from-server", () => ({ getLabels: jest.fn(), })) +// Mock the useTheme hook +jest.mock('../ThemeContext', () => ({ + useTheme: () => ({ + theme: 'light', // Provide mock theme + toggleTheme: jest.fn(), // Mock function + }), +})); // Mocking the useTranslation hook jest.mock("react-i18next", () => ({ useTranslation: () => ({ diff --git a/client/src/ClassSelectionMenu/ClassSelectionMenu.test.js b/client/src/ClassSelectionMenu/ClassSelectionMenu.test.js index 802ef58..8dec9b3 100644 --- a/client/src/ClassSelectionMenu/ClassSelectionMenu.test.js +++ b/client/src/ClassSelectionMenu/ClassSelectionMenu.test.js @@ -19,6 +19,14 @@ jest.mock("react-i18next", () => ({ }), })) +// Mock the useTheme hook +jest.mock('../ThemeContext', () => ({ + useTheme: () => ({ + theme: 'light', // Provide mock theme + toggleTheme: jest.fn(), // Mock function + }), +})); + describe("ClassSelectionMenu", () => { it("renders correctly", () => { const { getByText } = render( diff --git a/client/src/DebugSidebarBox/DebugSidebarBox.test.js b/client/src/DebugSidebarBox/DebugSidebarBox.test.js index d20a669..cf4172d 100644 --- a/client/src/DebugSidebarBox/DebugSidebarBox.test.js +++ b/client/src/DebugSidebarBox/DebugSidebarBox.test.js @@ -3,6 +3,15 @@ import { render } from "@testing-library/react" import "@testing-library/jest-dom" import DebugSidebarBox from "./index" +// Mock the useTheme hook +jest.mock('../ThemeContext', () => ({ + useTheme: () => ({ + theme: 'light', // Provide mock theme + toggleTheme: jest.fn(), // Mock function + }), +})); + + describe("DebugSidebarBox", () => { const mockState = { images: [ diff --git a/client/src/FilesListMenu/FilesListMenu.test.js b/client/src/FilesListMenu/FilesListMenu.test.js index 925f068..b611984 100644 --- a/client/src/FilesListMenu/FilesListMenu.test.js +++ b/client/src/FilesListMenu/FilesListMenu.test.js @@ -20,6 +20,15 @@ jest.mock("react-i18next", () => ({ }), })) +// Mock the useTheme hook +jest.mock('../ThemeContext', () => ({ + useTheme: () => ({ + theme: 'light', // Provide mock theme + toggleTheme: jest.fn(), // Mock function + }), +})); + + describe("FilesListMenu", () => { const state = { annotationType: "image", diff --git a/client/src/HistorySidebarBox/HistorySidebarBox.test.js b/client/src/HistorySidebarBox/HistorySidebarBox.test.js index 8dc5be0..2fddafc 100644 --- a/client/src/HistorySidebarBox/HistorySidebarBox.test.js +++ b/client/src/HistorySidebarBox/HistorySidebarBox.test.js @@ -14,6 +14,14 @@ jest.mock("react-i18next", () => ({ }), })) +// Mock the useTheme hook +jest.mock('../ThemeContext', () => ({ + useTheme: () => ({ + theme: 'light', // Provide mock theme + toggleTheme: jest.fn(), // Mock function + }), +})); + describe("HistorySidebarBox", () => { const history = [ { name: "History 1", time: new Date("2022-06-15T12:00:00Z") }, diff --git a/client/src/KeyframesSelectorSidebarBox/KeyframesSelectorSidebarBox.test.js b/client/src/KeyframesSelectorSidebarBox/KeyframesSelectorSidebarBox.test.js index 1617d6e..dc6f3eb 100644 --- a/client/src/KeyframesSelectorSidebarBox/KeyframesSelectorSidebarBox.test.js +++ b/client/src/KeyframesSelectorSidebarBox/KeyframesSelectorSidebarBox.test.js @@ -11,6 +11,14 @@ jest.mock("react-i18next", () => ({ }), })) +// Mock the useTheme hook +jest.mock('../ThemeContext', () => ({ + useTheme: () => ({ + theme: 'light', // Provide mock theme + toggleTheme: jest.fn(), // Mock function + }), +})); + describe("KeyframesSelectorSidebarBox", () => { const mockOnChangeVideoTime = jest.fn() const mockOnDeleteKeyframe = jest.fn() diff --git a/client/src/RegionSelectorSidebarBox/RegionSelectorSidebarBox.test.js b/client/src/RegionSelectorSidebarBox/RegionSelectorSidebarBox.test.js index b669126..535231d 100644 --- a/client/src/RegionSelectorSidebarBox/RegionSelectorSidebarBox.test.js +++ b/client/src/RegionSelectorSidebarBox/RegionSelectorSidebarBox.test.js @@ -8,6 +8,14 @@ jest.mock("react-i18next", () => ({ useTranslation: () => ({ t: (key) => key }), })) +// Mock the useTheme hook +jest.mock('../ThemeContext', () => ({ + useTheme: () => ({ + theme: 'light', // Provide mock theme + toggleTheme: jest.fn(), // Mock function + }), +})); + describe("RegionSelectorSidebarBox", () => { const mockRegions = [ { diff --git a/client/src/SetupPage/SetupPage.test.js b/client/src/SetupPage/SetupPage.test.js index 04a6e9f..1ec6d22 100644 --- a/client/src/SetupPage/SetupPage.test.js +++ b/client/src/SetupPage/SetupPage.test.js @@ -4,6 +4,14 @@ import "@testing-library/jest-dom" import { SetupPage } from "./index" import { useSettings } from "../SettingsProvider" +// Mock the useTheme hook +jest.mock('../ThemeContext', () => ({ + useTheme: () => ({ + theme: 'light', // Provide mock theme + toggleTheme: jest.fn(), // Mock function + }), +})); + // Mock useTranslation hook jest.mock("react-i18next", () => ({ useTranslation: () => ({ diff --git a/client/src/SidebarBoxContainer/SidebarBoxContainer.test.js b/client/src/SidebarBoxContainer/SidebarBoxContainer.test.js index ef13d14..92f66f7 100644 --- a/client/src/SidebarBoxContainer/SidebarBoxContainer.test.js +++ b/client/src/SidebarBoxContainer/SidebarBoxContainer.test.js @@ -3,6 +3,14 @@ import { render, screen } from "@testing-library/react" import "@testing-library/jest-dom" import SidebarBoxContainer from "./index" +// Mock the useTheme hook +jest.mock('../ThemeContext', () => ({ + useTheme: () => ({ + theme: 'light', // Provide mock theme + toggleTheme: jest.fn(), // Mock function + }), +})); + describe("SidebarBoxContainer", () => { const icon = const title = "Test Title" diff --git a/client/src/TagsSidebarBox/TagsSidebarBox.test.js b/client/src/TagsSidebarBox/TagsSidebarBox.test.js index 6df9b91..c3639da 100644 --- a/client/src/TagsSidebarBox/TagsSidebarBox.test.js +++ b/client/src/TagsSidebarBox/TagsSidebarBox.test.js @@ -14,6 +14,14 @@ jest.mock("react-i18next", () => ({ }), })) +// Mock the useTheme hook +jest.mock('../ThemeContext', () => ({ + useTheme: () => ({ + theme: 'light', // Provide mock theme + toggleTheme: jest.fn(), // Mock function + }), +})); + describe("TagsSidebarBox", () => { const mockImageClsList = ["Class A", "Class B"] const mockImageTagList = ["Tag 1", "Tag 2"] diff --git a/client/src/workspace/DownloadButton/DownloadButton.test.js b/client/src/workspace/DownloadButton/DownloadButton.test.js index 0b5dbc8..b2a0c6d 100644 --- a/client/src/workspace/DownloadButton/DownloadButton.test.js +++ b/client/src/workspace/DownloadButton/DownloadButton.test.js @@ -10,6 +10,14 @@ jest.mock("../../SnackbarContext/index.jsx", () => ({ }), })) +// Mock the useTheme hook +jest.mock('../../ThemeContext', () => ({ + useTheme: () => ({ + theme: 'light', // Provide mock theme + toggleTheme: jest.fn(), // Mock function + }), +})); + jest.mock("../../config.js", () => ({ DOCS_URL: "https://annotate-docs.dwaste.live/", SERVER_URL: "http://localhost:5000", diff --git a/client/src/workspace/Header/Header.test.js b/client/src/workspace/Header/Header.test.js index a802b74..67fbb19 100644 --- a/client/src/workspace/Header/Header.test.js +++ b/client/src/workspace/Header/Header.test.js @@ -8,6 +8,14 @@ jest.mock("../../config.js", () => ({ SERVER_URL: "http://localhost:5000", })) +// Mock the useTheme hook +jest.mock('../../ThemeContext', () => ({ + useTheme: () => ({ + theme: 'light', // Provide mock theme + toggleTheme: jest.fn(), // Mock function + }), +})); + // Mock the useTranslation hook with actual translations jest.mock("react-i18next", () => ({ useTranslation: () => ({ diff --git a/client/src/workspace/HeaderButton/HeaderButton.test.js b/client/src/workspace/HeaderButton/HeaderButton.test.js index 708b30c..662e01f 100644 --- a/client/src/workspace/HeaderButton/HeaderButton.test.js +++ b/client/src/workspace/HeaderButton/HeaderButton.test.js @@ -9,6 +9,14 @@ jest.mock("../icon-dictionary.js", () => ({ useIconDictionary: () => ({}), // Mocking an empty object since iconMapping is directly used })) +// Mock the useTheme hook +jest.mock('../../ThemeContext', () => ({ + useTheme: () => ({ + theme: 'light', // Provide mock theme + toggleTheme: jest.fn(), // Mock function + }), +})); + describe("HeaderButton", () => { it("renders button with icon and label", () => { const handleClick = jest.fn() diff --git a/client/src/workspace/IconSidebar/IconSidebar.test.js b/client/src/workspace/IconSidebar/IconSidebar.test.js index 216ed9d..308c469 100644 --- a/client/src/workspace/IconSidebar/IconSidebar.test.js +++ b/client/src/workspace/IconSidebar/IconSidebar.test.js @@ -8,6 +8,14 @@ jest.mock("../icon-dictionary.js", () => ({ useIconDictionary: jest.fn(), })) +// Mock the useTheme hook +jest.mock('../../ThemeContext', () => ({ + useTheme: () => ({ + theme: 'light', // Provide mock theme + toggleTheme: jest.fn(), // Mock function + }), +})); + const mockIconMapping = { sampleicon: () =>
Sample Icon
, } diff --git a/client/src/workspace/SidebarBox/SidebarBox.test.js b/client/src/workspace/SidebarBox/SidebarBox.test.js index aad0403..592d1fc 100644 --- a/client/src/workspace/SidebarBox/SidebarBox.test.js +++ b/client/src/workspace/SidebarBox/SidebarBox.test.js @@ -15,6 +15,14 @@ jest.mock("../icon-dictionary.js", () => ({ useIconDictionary: () => mockIconDictionary, })) +// Mock the useTheme hook +jest.mock('../../ThemeContext', () => ({ + useTheme: () => ({ + theme: 'light', // Provide mock theme + toggleTheme: jest.fn(), // Mock function + }), +})); + describe("SidebarBox", () => { beforeEach(() => { // Reset localStorage diff --git a/client/src/workspace/Workspace/Workspace.test.js b/client/src/workspace/Workspace/Workspace.test.js index 19933fe..a85f74b 100644 --- a/client/src/workspace/Workspace/Workspace.test.js +++ b/client/src/workspace/Workspace/Workspace.test.js @@ -16,6 +16,13 @@ jest.mock("../../config.js", () => ({ SERVER_URL: "http://localhost:5000", })) +// Mock the useTheme hook +jest.mock('../../ThemeContext', () => ({ + useTheme: () => ({ + theme: 'light', // Provide mock theme + toggleTheme: jest.fn(), // Mock function + }), +})); // Mock the useTranslation hook with actual translations jest.mock("react-i18next", () => ({ useTranslation: () => ({