mirror of
https://github.com/NoFxAiOS/nofx.git
synced 2026-07-06 20:41:14 +08:00
feat: Add trader enabled switch and fix critical bugs
New Features: - Add 'enabled' field to trader config for selective startup - Only enabled traders will be initialized and run - Display skip messages for disabled traders in logs Bug Fixes: - Fix Hyperliquid account value calculation * AccountValue is total equity, no need to add TotalMarginUsed * Correctly calculate wallet balance without unrealized PnL * Fix available balance calculation (AccountValue - TotalMarginUsed) - Fix frontend page refresh navigation issue * Use URL hash to persist page state across refreshes * Support browser back/forward buttons * Prevent Details page from reverting to Competition on refresh Technical Changes: - config/config.go: Add Enabled bool field to TraderConfig - main.go: Skip disabled traders during initialization - trader/hyperliquid_trader.go: Correct account value logic - web/src/App.tsx: Implement hash-based routing 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
@@ -19,10 +19,38 @@ type Page = 'competition' | 'trader';
|
||||
|
||||
function App() {
|
||||
const { language, setLanguage } = useLanguage();
|
||||
const [currentPage, setCurrentPage] = useState<Page>('competition');
|
||||
|
||||
// 从URL hash读取初始页面状态(支持刷新保持页面)
|
||||
const getInitialPage = (): Page => {
|
||||
const hash = window.location.hash.slice(1); // 去掉 #
|
||||
return hash === 'trader' || hash === 'details' ? 'trader' : 'competition';
|
||||
};
|
||||
|
||||
const [currentPage, setCurrentPage] = useState<Page>(getInitialPage());
|
||||
const [selectedTraderId, setSelectedTraderId] = useState<string | undefined>();
|
||||
const [lastUpdate, setLastUpdate] = useState<string>('--:--:--');
|
||||
|
||||
// 监听URL hash变化,同步页面状态
|
||||
useEffect(() => {
|
||||
const handleHashChange = () => {
|
||||
const hash = window.location.hash.slice(1);
|
||||
if (hash === 'trader' || hash === 'details') {
|
||||
setCurrentPage('trader');
|
||||
} else if (hash === 'competition' || hash === '') {
|
||||
setCurrentPage('competition');
|
||||
}
|
||||
};
|
||||
|
||||
window.addEventListener('hashchange', handleHashChange);
|
||||
return () => window.removeEventListener('hashchange', handleHashChange);
|
||||
}, []);
|
||||
|
||||
// 切换页面时更新URL hash
|
||||
const navigateToPage = (page: Page) => {
|
||||
setCurrentPage(page);
|
||||
window.location.hash = page === 'competition' ? '' : 'trader';
|
||||
};
|
||||
|
||||
// 获取trader列表
|
||||
const { data: traders } = useSWR<TraderInfo[]>('traders', api.getTraders, {
|
||||
refreshInterval: 10000,
|
||||
@@ -180,7 +208,7 @@ function App() {
|
||||
{/* Page Toggle */}
|
||||
<div className="flex gap-0.5 sm:gap-1 rounded p-0.5 sm:p-1" style={{ background: '#1E2329' }}>
|
||||
<button
|
||||
onClick={() => setCurrentPage('competition')}
|
||||
onClick={() => navigateToPage('competition')}
|
||||
className="px-2 sm:px-4 py-1.5 sm:py-2 rounded text-xs sm:text-sm font-semibold transition-all"
|
||||
style={currentPage === 'competition'
|
||||
? { background: '#F0B90B', color: '#000' }
|
||||
@@ -190,7 +218,7 @@ function App() {
|
||||
{t('competition', language)}
|
||||
</button>
|
||||
<button
|
||||
onClick={() => setCurrentPage('trader')}
|
||||
onClick={() => navigateToPage('trader')}
|
||||
className="px-2 sm:px-4 py-1.5 sm:py-2 rounded text-xs sm:text-sm font-semibold transition-all"
|
||||
style={currentPage === 'trader'
|
||||
? { background: '#F0B90B', color: '#000' }
|
||||
|
||||
Reference in New Issue
Block a user