Add new hook: 'useTheme'

This commit is contained in:
0x1eef 2023-10-22 16:24:09 -03:00
parent c9347a490e
commit 47847b2545
4 changed files with 44 additions and 14 deletions

View file

@ -1,6 +1,5 @@
import React from "react";
import { Select, SelectOption } from "components/Select";
import { set as setCookie } from "es-cookie";
interface Props {
setTheme: (theme: string) => void;
@ -8,15 +7,18 @@ interface Props {
}
export function ThemeSelect({ setTheme, theme }: Props) {
const onThemeChange = (o: SelectOption) => {
setCookie("theme", o.value, { domain: location.host, expires: 365 });
setTheme(o.value);
};
return (
<Select className="theme" value={theme} onChange={onThemeChange}>
<option value="moon">🌛</option>
<option value="leaf">🌿</option>
<Select
className="theme"
value={theme}
onChange={(o: SelectOption) => setTheme(o.value)}
>
<option value="blue">
<span className="blue" />
</option>
<option value="green">
<span className="green" />
</option>
</Select>
);
}

26
src/js/hooks/useTheme.ts Normal file
View file

@ -0,0 +1,26 @@
import { useEffect, useState } from "react";
import { get as getCookie, set as setCookie } from "es-cookie";
type Theme = "blue" | "green";
const THEMES: Theme[] = ["blue", "green"];
const DEFAULT_THEME = "blue";
export function useTheme(): [Theme, (t: string) => void] {
const [theme, setTheme] = useState<Theme | null>(null);
const cookie = getCookie("theme");
useEffect(() => {
const _theme = THEMES.find((theme: Theme) => cookie === theme);
setTheme(_theme || DEFAULT_THEME);
}, []);
function _setTheme(newTheme: string) {
const matchedTheme = THEMES.find((theme: Theme) => newTheme === theme);
if (matchedTheme) {
setCookie("theme", matchedTheme, { domain: location.host, expires: 365 });
setTheme(matchedTheme);
}
}
return [theme, _setTheme];
}

View file

@ -1,8 +1,9 @@
import React, { useState } from "react";
import React from "react";
import ReactDOM from "react-dom/client";
import classNames from "classnames";
import { get as getCookie } from "es-cookie";
import * as Quran from "lib/Quran";
import { useTheme } from "hooks/useTheme";
import { SelectOption } from "components/Select";
import { ThemeSelect } from "components/ThemeSelect";
import { LanguageSelect } from "components/LanguageSelect";
@ -15,7 +16,7 @@ interface Props {
}
function SurahIndex({ locale, surahs, t }: Props) {
const [theme, setTheme] = useState(getCookie("theme") || "moon");
const [theme, setTheme] = useTheme();
const onLanguageChange = (o: SelectOption) => {
document.location.replace(`/${o.value}/`);
};

View file

@ -1,7 +1,8 @@
import React, { useState, useEffect } from "react";
import ReactDOM from "react-dom/client";
import classNames from "classnames";
import { get as getCookie } from "es-cookie";
import { useTheme } from "hooks/useTheme";
import { Timer } from "components/Timer";
import { Stream } from "components/Stream";
import { SelectOption } from "components/Select";
@ -32,7 +33,7 @@ function SurahStream({ node, recitations, locale, paused, t }: Props) {
const [soundOn, setSoundOn] = useState<boolean>(false);
const [isStalled, setIsStalled] = useState<boolean>(false);
const [endOfStream, setEndOfStream] = useState<boolean>(false);
const [theme, setTheme] = useState(getCookie("theme") || "moon");
const [theme, setTheme] = useTheme();
const [recitation] = useState<Quran.Recitation>(recitations[0]);
const [surah] = useState<Quran.Surah>(
Quran.Surah.fromDOMNode(locale, node, getTimeSlots(recitation)),