feat: Refactor comment section to correctly handle API response structure
All checks were successful
Push to Helm Chart Repository / build (push) Successful in 9s

fix: Update Gravatar URL size and improve avatar rendering logic

style: Adjust footer margin for better layout consistency

refactor: Remove old navbar component and integrate new layout structure

feat: Enhance user profile page with user header component

chore: Remove unused user profile component

fix: Update posts per page configuration for better pagination

feat: Extend device context to support system theme mode

refactor: Remove unused device hook

fix: Improve storage state hook for better error handling

i18n: Add new translations for blog home page

feat: Implement pagination component for better navigation

feat: Create theme toggle component for improved user experience

feat: Introduce responsive navbar or side layout with theme toggle

feat: Develop custom select component for better UI consistency

feat: Create user header component to display user information

chore: Add query key constants for better code maintainability
This commit is contained in:
2025-09-12 00:26:08 +08:00
parent b3e8a5ef77
commit d1d8aa529f
36 changed files with 1443 additions and 731 deletions

View File

@ -1,18 +0,0 @@
import { useEffect, useState } from "react";
export function useDevice() {
const [isMobile, setIsMobile] = useState(false);
useEffect(() => {
// 简单判断移动端
const check = () => {
const ua = navigator.userAgent;
setIsMobile(/Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(ua));
};
check();
window.addEventListener("resize", check);
return () => window.removeEventListener("resize", check);
}, []);
return { isMobile };
}

View File

@ -1,35 +1,35 @@
import { useState, useEffect, useCallback } from 'react';
export function useStoredState<T>(key: string, defaultValue: T) {
const [value, setValue] = useState<T>(defaultValue);
const [isLoaded, setIsLoaded] = useState(false);
const [value, setValue] = useState<T>(defaultValue);
const [isLoaded, setIsLoaded] = useState(false);
useEffect(() => {
useEffect(() => {
try {
const stored = localStorage.getItem(key);
if (stored) {
try {
const stored = localStorage.getItem(key);
if (stored) {
try {
setValue(JSON.parse(stored));
} catch {
setValue(stored as T);
}
}
} catch (error) {
console.error('Error reading from localStorage:', error);
} finally {
setIsLoaded(true);
setValue(JSON.parse(stored));
} catch {
setValue(stored as T);
}
}, [key]);
}
} catch (error) {
console.error('Error reading from localStorage:', error);
} finally {
setIsLoaded(true);
}
}, [key]);
// 使用 useCallback 确保 setter 函数引用稳定
const setStoredValue = useCallback((newValue: T) => {
setValue(newValue);
try {
localStorage.setItem(key, typeof newValue === 'string' ? newValue : JSON.stringify(newValue));
} catch (error) {
console.error('Error writing to localStorage:', error);
}
}, [key]);
// 使用 useCallback 确保 setter 函数引用稳定
const setStoredValue = useCallback((newValue: T) => {
setValue(newValue);
try {
localStorage.setItem(key, typeof newValue === 'string' ? newValue : JSON.stringify(newValue));
} catch (error) {
console.error('Error writing to localStorage:', error);
}
}, [key]);
return [value, setStoredValue, isLoaded] as const;
return [value, setStoredValue, isLoaded] as const;
}