mirror of
https://github.com/NoFxAiOS/nofx.git
synced 2026-07-10 06:20:58 +08:00
feat: implement hybrid database architecture and frontend encryption
- Add PostgreSQL + SQLite hybrid database support with automatic switching - Implement frontend AES-GCM + RSA-OAEP encryption for sensitive data - Add comprehensive DatabaseInterface with all required methods - Fix compilation issues with interface consistency - Update all database method signatures to use DatabaseInterface - Add missing UpdateTraderInitialBalance method to PostgreSQL implementation - Integrate RSA public key distribution via /api/config endpoint - Add frontend crypto service with proper error handling - Support graceful degradation between encrypted and plaintext transmission - Add directory creation for RSA keys and PEM parsing fixes - Test both SQLite and PostgreSQL modes successfully 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: tinkle-community <tinklefund@gmail.com>
This commit is contained in:
51
web/src/hooks/useCounterAnimation.ts
Normal file
51
web/src/hooks/useCounterAnimation.ts
Normal file
@@ -0,0 +1,51 @@
|
||||
import { useEffect, useState } from 'react'
|
||||
|
||||
interface UseCounterAnimationOptions {
|
||||
start?: number
|
||||
end: number
|
||||
duration?: number
|
||||
decimals?: number
|
||||
}
|
||||
|
||||
export function useCounterAnimation({
|
||||
start = 0,
|
||||
end,
|
||||
duration = 2000,
|
||||
decimals = 0,
|
||||
}: UseCounterAnimationOptions): number {
|
||||
const [count, setCount] = useState(start)
|
||||
|
||||
useEffect(() => {
|
||||
if (end === 0) return
|
||||
|
||||
let startTime: number | null = null
|
||||
let animationFrame: number
|
||||
|
||||
const animate = (currentTime: number) => {
|
||||
if (startTime === null) startTime = currentTime
|
||||
const progress = Math.min((currentTime - startTime) / duration, 1)
|
||||
|
||||
// 使用 easeOutExpo 缓动函数,让数字快速启动后缓慢停止
|
||||
const easeOutExpo = progress === 1 ? 1 : 1 - Math.pow(2, -10 * progress)
|
||||
|
||||
const currentCount = start + (end - start) * easeOutExpo
|
||||
setCount(currentCount)
|
||||
|
||||
if (progress < 1) {
|
||||
animationFrame = requestAnimationFrame(animate)
|
||||
} else {
|
||||
setCount(end)
|
||||
}
|
||||
}
|
||||
|
||||
animationFrame = requestAnimationFrame(animate)
|
||||
|
||||
return () => {
|
||||
if (animationFrame) {
|
||||
cancelAnimationFrame(animationFrame)
|
||||
}
|
||||
}
|
||||
}, [start, end, duration])
|
||||
|
||||
return decimals > 0 ? parseFloat(count.toFixed(decimals)) : Math.floor(count)
|
||||
}
|
||||
Reference in New Issue
Block a user