diff --git a/src/components/SmartActionBar.tsx b/src/components/SmartActionBar.tsx index 1a933836..aca6c596 100644 --- a/src/components/SmartActionBar.tsx +++ b/src/components/SmartActionBar.tsx @@ -1,9 +1,10 @@ import {useClientStore} from "@/hooks/matrix/useConnection" +import useTheme from "@/hooks/util/useTheme" import useTranslation from "@/hooks/util/useTranslation" import {LangKey} from "@/lang/allKeys" import {cn} from "@/utils/utils" import {SyncState} from "matrix-js-sdk" -import React, {useState} from "react" +import React from "react" import {type FC} from "react" import {type IconType} from "react-icons" import {IoContrast, IoGlobe} from "react-icons/io5" @@ -21,13 +22,7 @@ const SmartActionBar: FC<{className?: string}> = ({className}) => { const {syncState} = useClientStore() const {t} = useTranslation() - const [isDarkTheme, setIsDarkTheme] = useState(false) - - document.querySelectorAll("html")[0].className = isDarkTheme ? "dark" : "" - - const handleSwitchTheme = (): void => { - setIsDarkTheme(prevIsDarkTheme => !prevIsDarkTheme) - } + const {toggleTheme} = useTheme() return (
= ({className}) => { + onClick={toggleTheme}> {t(LangKey.SwitchTheme)} diff --git a/src/components/TypingIndicator.tsx b/src/components/TypingIndicator.tsx index 09ed958b..ab44cbf2 100644 --- a/src/components/TypingIndicator.tsx +++ b/src/components/TypingIndicator.tsx @@ -4,6 +4,7 @@ import {stringToColor} from "@/utils/util" import Avatar from "boring-avatars" import useTranslation from "@/hooks/util/useTranslation" import {LangKey} from "@/lang/allKeys" +import {Text} from "./ui/typography" export type TypingIndicatorUser = { displayName: string @@ -29,19 +30,20 @@ const TypingIndicator: FC = ({users}) => { } return users.map((user, index) => ( - - + {user.displayName} - + {index < usersLength - 2 ? ", " : index === usersLength - 2 ? t(LangKey.And) : ""} - + )) }, [t, users, usersLength]) @@ -55,7 +57,7 @@ const TypingIndicator: FC = ({users}) => {
@@ -63,7 +65,7 @@ const TypingIndicator: FC = ({users}) => { ) : ( = ({users}) => { ) }, [users, usersLength]) - const dotClass = "h-2 w-2 animate-dot-jump rounded-full bg-neutral-300" + const dotClass = "size-2 animate-dot-jump rounded-full bg-neutral-300" return (
@@ -88,9 +90,9 @@ const TypingIndicator: FC = ({users}) => {
{typingUserElements}
-
+ {who} {verbForm} {t(LangKey.Typing)} -
+
) } diff --git a/src/components/ui/select.tsx b/src/components/ui/select.tsx index ebe34879..87755f1f 100644 --- a/src/components/ui/select.tsx +++ b/src/components/ui/select.tsx @@ -28,7 +28,7 @@ const SelectTrigger = React.forwardRef< {...props}> {children} - + )) @@ -120,9 +120,9 @@ const SelectItem = React.forwardRef< className )} {...props}> - + - + {children} diff --git a/src/components/ui/toast.tsx b/src/components/ui/toast.tsx index a3546b6d..eaf8317e 100644 --- a/src/components/ui/toast.tsx +++ b/src/components/ui/toast.tsx @@ -27,7 +27,7 @@ const toastVariants = cva( { variants: { variant: { - default: "border bg-background dark:bg-neutral-900 text-foreground", + default: "border bg-background text-foreground dark:bg-neutral-900", destructive: "group border-destructive bg-destructive text-destructive-foreground", }, diff --git a/src/containers/RoomContainer/ChatHeader.tsx b/src/containers/RoomContainer/ChatHeader.tsx index 1ac628d0..87fbcf0f 100644 --- a/src/containers/RoomContainer/ChatHeader.tsx +++ b/src/containers/RoomContainer/ChatHeader.tsx @@ -37,11 +37,11 @@ const ChatHeader: FC = ({
- + + className="w-max max-w-56 truncate text-blue-800 dark:text-blue-400 sm:max-w-md"> {roomName} diff --git a/src/hooks/util/useTheme.ts b/src/hooks/util/useTheme.ts new file mode 100644 index 00000000..7f88056c --- /dev/null +++ b/src/hooks/util/useTheme.ts @@ -0,0 +1,33 @@ +import {useCallback, useEffect, useState} from "react" + +type UseThemeReturnType = { + toggleTheme: () => void + isDarkMode: boolean +} + +const useTheme = (): UseThemeReturnType => { + const savedTheme = localStorage.getItem("darkMode") + const isDarkMode = savedTheme ? JSON.parse(savedTheme) : false + + const [isDarkTheme, setIsDarkTheme] = useState(isDarkMode) + + useEffect(() => { + const html = document.documentElement + + if (isDarkTheme) { + html.classList.add("dark") + } else { + html.classList.remove("dark") + } + + localStorage.setItem("darkMode", JSON.stringify(isDarkTheme)) + }, [isDarkTheme]) + + const toggleTheme = useCallback(() => { + setIsDarkTheme(!isDarkTheme) + }, [isDarkTheme]) + + return {toggleTheme, isDarkMode} +} + +export default useTheme