diff --git a/package.json b/package.json index 16a6511..ceb9c03 100644 --- a/package.json +++ b/package.json @@ -43,7 +43,8 @@ "react-redux": "^9.2.0", "react-router-dom": "^6.26.0", "redux": "^5.0.1", - "redux-thunk": "^3.1.0" + "redux-thunk": "^3.1.0", + "zustand": "^5.0.8" }, "devDependencies": { "@commitlint/cli": "^19.8.1", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 121b9a9..9277746 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -35,6 +35,9 @@ importers: redux-thunk: specifier: ^3.1.0 version: 3.1.0(redux@5.0.1) + zustand: + specifier: ^5.0.8 + version: 5.0.8(@types/react@18.3.24)(immer@10.1.3)(react@18.3.1)(use-sync-external-store@1.5.0(react@18.3.1)) devDependencies: '@commitlint/cli': specifier: ^19.8.1 @@ -3579,6 +3582,24 @@ packages: resolution: {integrity: sha512-AyeEbWOu/TAXdxlV9wmGcR0+yh2j3vYPGOECcIj2S7MkrLyC7ne+oye2BKTItt0ii2PHk4cDy+95+LshzbXnGg==} engines: {node: '>=12.20'} + zustand@5.0.8: + resolution: {integrity: sha512-gyPKpIaxY9XcO2vSMrLbiER7QMAMGOQZVRdJ6Zi782jkbzZygq5GI9nG8g+sMgitRtndwaBSl7uiqC49o1SSiw==} + engines: {node: '>=12.20.0'} + peerDependencies: + '@types/react': '>=18.0.0' + immer: '>=9.0.6' + react: '>=18.0.0' + use-sync-external-store: '>=1.2.0' + peerDependenciesMeta: + '@types/react': + optional: true + immer: + optional: true + react: + optional: true + use-sync-external-store: + optional: true + snapshots: '@adobe/css-tools@4.4.4': {} @@ -7510,3 +7531,10 @@ snapshots: yocto-queue@0.1.0: {} yocto-queue@1.2.1: {} + + zustand@5.0.8(@types/react@18.3.24)(immer@10.1.3)(react@18.3.1)(use-sync-external-store@1.5.0(react@18.3.1)): + optionalDependencies: + '@types/react': 18.3.24 + immer: 10.1.3 + react: 18.3.1 + use-sync-external-store: 1.5.0(react@18.3.1) diff --git a/src/hooks/useSdk.ts b/src/hooks/useSdk.ts index 6818764..e3c79f5 100644 --- a/src/hooks/useSdk.ts +++ b/src/hooks/useSdk.ts @@ -1,10 +1,12 @@ -import { SdkServer } from "../sdk/sdk-server"; +import { SdkServer } from '../sdk/sdk-server'; export function useSdk() { - // H5版本暂时返回空对象,广告相关功能不需要 - return {}; + // H5版本暂时返回空对象,广告相关功能不需要 + return {}; } -export function useServerSdk(){ - return new SdkServer(); +export function useServerSdk() { + return new SdkServer(); } + +export const serverSdk = new SdkServer(); diff --git a/src/pages/history/index.css b/src/pages/history/index.css index 05b8865..a3a9106 100644 --- a/src/pages/history/index.css +++ b/src/pages/history/index.css @@ -156,6 +156,8 @@ align-items: center; position: relative; overflow: hidden; + text-decoration: none; + color: #1d1f22; } .item-thumbnail { diff --git a/src/pages/history/index.tsx b/src/pages/history/index.tsx index 7c1cd5c..b506377 100644 --- a/src/pages/history/index.tsx +++ b/src/pages/history/index.tsx @@ -1,23 +1,19 @@ -import { useEffect, useState } from 'react'; -import { useNavigate } from 'react-router-dom'; -import { useServerSdk } from '../../hooks/index'; +import { useCallback, useEffect, useState } from 'react'; +import { serverSdk } from '../../hooks/useSdk'; import { useI18n } from '../../hooks/useI18n'; -import { i18nManager } from '../../i18n/manager'; import { authService } from '../../services/auth'; -// import LanguageSwitcher from '../../components/LanguageSwitcher'; // 已隐藏 - 只支持英语 import './index.css'; + export default function History() { const { t } = useI18n(); - const navigate = useNavigate(); const [records, setRecords] = useState([]); const [refreshing, setRefreshing] = useState(false); const [loading, setLoading] = useState(true); - const [isLoggedIn, setIsLoggedIn] = useState(null); - const serverSdk = useServerSdk(); + const [isLoggedIn, setIsLoggedIn] = useState(false); const [loginRedirecting, setLoginRedirecting] = useState(false); - const checkLoginStatus = async () => { + const checkLoginStatus = useCallback(async () => { try { const loginStatus = await authService.checkLogin(); setIsLoggedIn(loginStatus); @@ -27,9 +23,9 @@ export default function History() { setIsLoggedIn(false); return false; } - }; + }, []); - const loadRecords = async () => { + const loadRecords = useCallback(async () => { try { const logs = await serverSdk.getMineLogs(); setRecords(logs || []); @@ -38,7 +34,7 @@ export default function History() { } finally { setLoading(false); } - }; + }, []); useEffect(() => { const initPage = async () => { @@ -51,25 +47,10 @@ export default function History() { }; initPage(); - // Set page title - i18nManager.updateNavigationBarTitle('history'); }, []); - // Regularly update progress of generating tasks - useEffect(() => { - const hasGeneratingTasks = records.some(record => record.status === 'processing'); - if (!hasGeneratingTasks) return; - - const interval = setInterval(() => { - // Trigger re-render to update progress - setRecords(prevRecords => [...prevRecords]); - }, 1000); - - return () => clearInterval(interval); - }, [records]); - // Pull to refresh - const handleRefresh = async () => { + const handleRefresh = useCallback(async () => { setRefreshing(true); try { await loadRecords(); @@ -78,41 +59,16 @@ export default function History() { } finally { setRefreshing(false); } - }; + }, [loadRecords]); - // Click history record item - const handleItemClick = (record: any) => { - console.log('record', record); - if (record.status === 'failed') { - console.error('Refresh failed:', record.errorMessage); - // Show error message - } else { - console.log('record.paymentId', record); - // Navigate to generation page to view progress - navigate(`/result?taskId=${record.paymentId}`); - } - }; - - const formatTime = (timeStr: string) => { - const date = new Date(timeStr); - const year = date.getFullYear(); - const month = String(date.getMonth() + 1).padStart(2, '0'); - const day = String(date.getDate()).padStart(2, '0'); - const hours = String(date.getHours()).padStart(2, '0'); - const minutes = String(date.getMinutes()).padStart(2, '0'); - const seconds = String(date.getSeconds()).padStart(2, '0'); - - return `${year}-${month}-${day} ${hours}:${minutes}:${seconds}`; - }; - - const handleLogin = async () => { + const handleLogin = useCallback(async () => { try { setLoginRedirecting(true); await authService.login('/history'); } catch (error) { console.error('Login failed:', error); } - }; + }, []); if (loginRedirecting) { return ( @@ -122,6 +78,14 @@ export default function History() { ); } + if (loading) { + return ( +
+ {t('common.loading')} +
+ ); + } + return (
{/* Settings area */} @@ -130,11 +94,7 @@ export default function History() { {refreshing &&
Refreshing...
}
- {loading ? ( -
- {t('common.loading')} -
- ) : isLoggedIn === false ? ( + {isLoggedIn === false ? (
login
@@ -155,7 +115,7 @@ export default function History() { // const progress = calculateProgress(record); // Temporarily unused const isGenerating = record.status === 'processing'; return ( - -
+ ); }) )} @@ -192,3 +152,15 @@ export default function History() {
); } + +const formatTime = (timeStr: string) => { + const date = new Date(timeStr); + const year = date.getFullYear(); + const month = String(date.getMonth() + 1).padStart(2, '0'); + const day = String(date.getDate()).padStart(2, '0'); + const hours = String(date.getHours()).padStart(2, '0'); + const minutes = String(date.getMinutes()).padStart(2, '0'); + const seconds = String(date.getSeconds()).padStart(2, '0'); + + return `${year}-${month}-${day} ${hours}:${minutes}:${seconds}`; +}; diff --git a/src/sdk/sdk-server.ts b/src/sdk/sdk-server.ts index a47b3c0..b442cbc 100644 --- a/src/sdk/sdk-server.ts +++ b/src/sdk/sdk-server.ts @@ -4,7 +4,7 @@ import { IToken, IUser } from "./types"; // ==================== 常量定义 ==================== -const TOKEN_STORAGE_KEY = 'access_token'; // OAuth访问令牌存储键 +export const TOKEN_STORAGE_KEY = 'access_token'; // OAuth访问令牌存储键 const TOKEN_UID_KEY = 'user_uid'; // 用户ID存储键 /**