interface: better theme & state

This commit is contained in:
Alikia2x 2024-03-31 01:35:55 +08:00
parent 9a623164e4
commit 8c005b3769
4 changed files with 59 additions and 22 deletions

View File

@ -1,5 +1,6 @@
'use client'; 'use client';
import { useState, useEffect } from "react";
import { useRecoilState } from "recoil"; import { useRecoilState } from "recoil";
import Background from "./background"; import Background from "./background";
import Search from "./search/search"; import Search from "./search/search";
@ -8,16 +9,33 @@ import Time from "./time";
export default function Homepage() { export default function Homepage() {
const [isFocus, setFocus] = useRecoilState(bgFocusState); const [isFocus, setFocus] = useRecoilState(bgFocusState);
const [colorScheme, setColorScheme] = useState('');
useEffect(() => {
const colorSchemeQueryList = window.matchMedia('(prefers-color-scheme: dark)');
setColorScheme(colorSchemeQueryList.matches ? 'dark' : 'light');
const handleChange = () => {
setColorScheme(colorSchemeQueryList.matches ? 'dark' : 'light');
};
colorSchemeQueryList.addListener(handleChange);
return () => {
colorSchemeQueryList.removeListener(handleChange);
};
}, []);
return ( return (
<div className="h-full fixed overflow-hidden w-full bg-black"> <div className="h-full fixed overflow-hidden w-full bg-black">
<Time showSecond={true} /> <Time />
{colorScheme === 'dark' && (
<Background src="rgb(23,25,29)" isFocus={isFocus} onClick={() => setFocus(false)} /> <Background src="rgb(23,25,29)" isFocus={isFocus} onClick={() => setFocus(false)} />
<Search )}
onFocus={() => { {colorScheme === 'light' && (
setFocus(true); <Background src="white" isFocus={isFocus} onClick={() => setFocus(false)} />
console.log("focus"); )}
}} <Search onFocus={() => setFocus(true)} />
/>
</div> </div>
); );
} }

View File

@ -16,7 +16,7 @@ export default function Search(props: {
<div className="absolute w-full top-[8.5rem] lg:top-56 short:top-24 z-1 left-1/2 translate-x-[-50%] "> <div className="absolute w-full top-[8.5rem] lg:top-56 short:top-24 z-1 left-1/2 translate-x-[-50%] ">
<input <input
className="absolute z-1 w-11/12 sm:w-[700px] h-10 rounded-lg left-1/2 translate-x-[-50%] className="absolute z-1 w-11/12 sm:w-[700px] h-10 rounded-lg left-1/2 translate-x-[-50%]
text-center outline-none border-[1px] focus:border-2 duration-200 pr-2 shadow-lg bg-white dark:bg-[rgb(23,25,29)] text-center outline-none border-[1px] focus:border-2 duration-200 pr-2 shadow-md focus:shadow-none dark:shadow-zinc-800 dark:shadow-md bg-white dark:bg-[rgb(23,25,29)]
dark:border-neutral-500 dark:focus:border-neutral-300 placeholder:text-slate-500 dark:border-neutral-500 dark:focus:border-neutral-300 placeholder:text-slate-500
dark:placeholder:text-slate-400 text-slate-900 dark:text-white" dark:placeholder:text-slate-400 text-slate-900 dark:text-white"
id="searchBox" id="searchBox"
@ -34,7 +34,7 @@ export default function Search(props: {
className={ className={
`absolute z-1 w-2/3 sm:w-80 md:w-[400px] focus:w-11/12 focus:sm:w-[700px] hover:w-11/12 `absolute z-1 w-2/3 sm:w-80 md:w-[400px] focus:w-11/12 focus:sm:w-[700px] hover:w-11/12
hover:sm:w-[700px] h-10 rounded-3xl left-1/2 translate-x-[-50%] text-center outline-none hover:sm:w-[700px] h-10 rounded-3xl left-1/2 translate-x-[-50%] text-center outline-none
border-solid border-0 duration-200 pr-2 shadow-lg` + border-solid border-0 duration-200 pr-2 shadow-md focus:shadow-none` +
(settings.bgBlur (settings.bgBlur
? `bg-[rgba(255,255,255,0.5)] dark:bg-[rgba(24,24,24,0.75)] backdrop-blur-xl ? `bg-[rgba(255,255,255,0.5)] dark:bg-[rgba(24,24,24,0.75)] backdrop-blur-xl
placeholder:text-slate-500 dark:placeholder:text-slate-400 text-slate-900 dark:text-white` placeholder:text-slate-500 dark:placeholder:text-slate-400 text-slate-900 dark:text-white`

View File

@ -5,7 +5,16 @@ const settingsState = atom({
default: { default: {
version: 1, version: 1,
elementBackdrop: true, elementBackdrop: true,
bgBlur: true bgBlur: true,
timeShowSecond: false,
currentSearchEngine: "google",
searchEngines: {
"google": "https://www.google.com/search?q=%s",
"bing": "https://www.bing.com/search?q=%s",
"baidu": "https://www.baidu.com/s?wd=%s",
"duckduckgo": "https://duckduckgo.com/?q=%s",
"yandex": "https://yandex.com/search/?text=%s",
}
} }
}); });

View File

@ -1,11 +1,14 @@
'use client'; "use client";
import React, { useState, useEffect } from "react"; import React, { useState, useEffect } from "react";
import { useRecoilValue } from "recoil";
import { settingsState } from "./state/settings";
import { useFormatter } from "next-intl";
export default function Time(props: { export default function Time() {
showSecond: boolean;
}){
const [currentTime, setCurrentTime] = useState(new Date()); const [currentTime, setCurrentTime] = useState(new Date());
const settings = useRecoilValue(settingsState);
const format = useFormatter();
useEffect(() => { useEffect(() => {
const timer = setInterval(() => { const timer = setInterval(() => {
@ -22,7 +25,7 @@ export default function Time(props: {
const minutes = currentTime.getMinutes().toString().padStart(2, "0"); const minutes = currentTime.getMinutes().toString().padStart(2, "0");
const seconds = currentTime.getSeconds().toString().padStart(2, "0"); const seconds = currentTime.getSeconds().toString().padStart(2, "0");
if (props.showSecond) { if (settings.timeShowSecond) {
return `${hours}:${minutes}:${seconds}`; return `${hours}:${minutes}:${seconds}`;
} else { } else {
return `${hours}:${minutes}`; return `${hours}:${minutes}`;
@ -31,11 +34,18 @@ export default function Time(props: {
return ( return (
<div <div
className="absolute top-20 lg:top-[9.5rem] short:top-0 translate-x-[-50%] left-1/2 duration-200 className="absolute top-20 lg:top-44 short:top-0 translate-x-[-50%]
text-white text-[40px] text-center text-shadow-lg z-10" left-1/2 w-11/12 sm:w-[700px] text:black
style={{textShadow: "0px 0px 5px rgba(30,30,30,0.5)"}} dark:text-white text-3xl text-left text-shadow-lg z-10"
> >
{formatTime()} {formatTime()}{" "}
<span className="text-lg leading-9 relative">
{format.dateTime(currentTime, {
year: "numeric",
month: "short",
day: "numeric"
})}
</span>
</div> </div>
); );
}; }