improve: Time component with props

This commit is contained in:
Alikia2x 2024-04-02 01:14:39 +08:00
parent 0aef1e1641
commit 090154115a
8 changed files with 1082 additions and 51 deletions

View File

@ -1,40 +1,45 @@
'use client';
"use client";
import { useState, useEffect } from "react";
import { useRecoilState } from "recoil";
import { settingsState } from "./state/settings";
import Background from "./background";
import Search from "./search/search";
import { bgFocusState } from "./state/background";
import Time from "./time";
import loadSettings from "@/lib/loadSettings";
export default function Homepage() {
const [settings, setSettings] = useRecoilState(settingsState);
const [isFocus, setFocus] = useRecoilState(bgFocusState);
const [colorScheme, setColorScheme] = useState('');
const [colorScheme, setColorScheme] = useState("");
useEffect(() => {
const colorSchemeQueryList = window.matchMedia('(prefers-color-scheme: dark)');
setColorScheme(colorSchemeQueryList.matches ? 'dark' : 'light');
loadSettings(setSettings);
}, [setSettings]);
useEffect(() => {
const colorSchemeQueryList = window.matchMedia("(prefers-color-scheme: dark)");
setColorScheme(colorSchemeQueryList.matches ? "dark" : "light");
const handleChange = () => {
setColorScheme(colorSchemeQueryList.matches ? 'dark' : 'light');
setColorScheme(colorSchemeQueryList.matches ? "dark" : "light");
};
colorSchemeQueryList.addListener(handleChange);
colorSchemeQueryList.addEventListener("change", handleChange);
return () => {
colorSchemeQueryList.removeListener(handleChange);
colorSchemeQueryList.removeEventListener("change", handleChange);
};
}, []);
return (
<div className="h-full fixed overflow-hidden w-full bg-black">
<Time />
{colorScheme === 'dark' && (
<Time showSecond={settings.timeShowSecond} />
{colorScheme === "dark" && (
<Background src="rgb(23,25,29)" isFocus={isFocus} onClick={() => setFocus(false)} />
)}
{colorScheme === 'light' && (
<Background src="white" isFocus={isFocus} onClick={() => setFocus(false)} />
)}
{colorScheme === "light" && <Background src="white" isFocus={isFocus} onClick={() => setFocus(false)} />}
<Search onFocus={() => setFocus(true)} />
</div>
);

View File

@ -1,4 +1,4 @@
import { atom, selector } from "recoil";
import { atom } from "recoil";
const settingsState = atom({
key: "settings",

View File

@ -1,13 +1,12 @@
"use client";
import React, { useState, useEffect } from "react";
import { useRecoilValue } from "recoil";
import { settingsState } from "./state/settings";
import { useFormatter } from "next-intl";
export default function Time() {
export default function Time(props: {
showSecond: boolean
}) {
const [currentTime, setCurrentTime] = useState(new Date());
const settings = useRecoilValue(settingsState);
const format = useFormatter();
useEffect(() => {
@ -25,7 +24,7 @@ export default function Time() {
const minutes = currentTime.getMinutes().toString().padStart(2, "0");
const seconds = currentTime.getSeconds().toString().padStart(2, "0");
if (settings.timeShowSecond) {
if (props.showSecond) {
return `${hours}:${minutes}:${seconds}`;
} else {
return `${hours}:${minutes}`;

View File

@ -1,5 +0,0 @@
/** @type {import('ts-jest').JestConfigWithTsJest} */
module.exports = {
preset: 'ts-jest',
testEnvironment: 'node',
};

18
jest.config.ts Normal file
View File

@ -0,0 +1,18 @@
import type { Config } from 'jest'
import nextJest from 'next/jest.js'
const createJestConfig = nextJest({
// Provide the path to your Next.js app to load next.config.js and .env files in your test environment
dir: './',
})
// Add any custom config to be passed to Jest
const config: Config = {
coverageProvider: 'v8',
testEnvironment: 'jsdom',
// Add more setup options before each test is run
// setupFilesAfterEnv: ['<rootDir>/jest.setup.ts'],
}
// createJestConfig is exported this way to ensure that next/jest can load the Next.js config which is async
export default createJestConfig(config)

38
lib/loadSettings.ts Normal file
View File

@ -0,0 +1,38 @@
'use client';
const defaultSettings = {
version: 1,
elementBackdrop: 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",
}
}
function isLocalStorageAvailable(){
var test = 'test';
try {
localStorage.setItem(test, test);
localStorage.removeItem(test);
return true;
} catch(e) {
return false;
}
}
export default function (setSettings: any) {
if (isLocalStorageAvailable()===false){
return;
}
if (localStorage.getItem("settings") === null) {
localStorage.setItem("settings", JSON.stringify(defaultSettings));
return;
}
const localSettings = JSON.parse(localStorage.getItem("settings") as string);
setSettings(localSettings);
}

View File

@ -19,11 +19,14 @@
"react-dom": "^18.2.0",
"recoil": "^0.7.7",
"tailwind-merge": "^2.2.2",
"ts-node": "^10.9.2",
"valid-url": "^1.0.9",
"validate-color": "^2.2.4"
},
"devDependencies": {
"@jest/globals": "^29.7.0",
"@testing-library/jest-dom": "^6.4.2",
"@testing-library/react": "^14.2.2",
"@types/jest": "^29.5.12",
"@types/node": "^20",
"@types/punycode": "^2.1.4",
@ -32,6 +35,7 @@
"@types/valid-url": "^1.0.7",
"autoprefixer": "^10.0.1",
"jest": "^29.7.0",
"jest-environment-jsdom": "^29.7.0",
"postcss": "^8",
"tailwindcss": "^3.3.0",
"ts-jest": "^29.1.2",

File diff suppressed because it is too large Load Diff