fix: reduce candidate coin limit to 10, fix Select scroll and flash

- Lower MaxCandidateCoins from 50 to 10 (backend)
- Update CoinSourceEditor: options 1-10, default 3, max static coins 10
- Fix NofxSelect dropdown closing on internal scroll
- Fix NofxSelect position flash on open (useLayoutEffect)
This commit is contained in:
Dean
2026-03-27 22:34:51 +08:00
committed by shinchan-zhai
parent f83f2b1c18
commit fbca4166a1
3 changed files with 32 additions and 29 deletions
+1 -1
View File
@@ -12,7 +12,7 @@ import (
// Hard limits to prevent token explosion in AI requests
const (
MaxCandidateCoins = 50
MaxCandidateCoins = 10
MaxPositions = 3
MaxTimeframes = 4
MinKlineCount = 10
@@ -33,16 +33,16 @@ export function CoinSourceEditor({
let totalLimit = 0
if (config.use_ai500) {
sources.push(`AI500(${config.ai500_limit || 10})`)
totalLimit += config.ai500_limit || 10
sources.push(`AI500(${config.ai500_limit || 3})`)
totalLimit += config.ai500_limit || 3
}
if (config.use_oi_top) {
sources.push(`${ts(coinSource.oiIncreaseShort, language)}(${config.oi_top_limit || 10})`)
totalLimit += config.oi_top_limit || 10
sources.push(`${ts(coinSource.oiIncreaseShort, language)}(${config.oi_top_limit || 3})`)
totalLimit += config.oi_top_limit || 3
}
if (config.use_oi_low) {
sources.push(`${ts(coinSource.oiDecreaseShort, language)}(${config.oi_low_limit || 10})`)
totalLimit += config.oi_low_limit || 10
sources.push(`${ts(coinSource.oiDecreaseShort, language)}(${config.oi_low_limit || 3})`)
totalLimit += config.oi_low_limit || 3
}
if ((config.static_coins || []).length > 0) {
sources.push(`${ts(coinSource.custom, language)}(${config.static_coins?.length || 0})`)
@@ -71,7 +71,7 @@ export function CoinSourceEditor({
return xyzDexAssets.has(base)
}
const MAX_STATIC_COINS = 50
const MAX_STATIC_COINS = 10
const showToast = (msg: string) => {
const toast = document.createElement('div')
@@ -327,13 +327,13 @@ export function CoinSourceEditor({
{ts(coinSource.ai500Limit, language)}:
</span>
<NofxSelect
value={config.ai500_limit || 10}
value={config.ai500_limit || 3}
onChange={(val) =>
!disabled &&
onChange({ ...config, ai500_limit: parseInt(val) || 10 })
onChange({ ...config, ai500_limit: parseInt(val) || 3 })
}
disabled={disabled}
options={[3, 5, 10, 20, 30, 40, 50].map(n => ({ value: n, label: String(n) }))}
options={[1, 2, 3, 4, 5, 6, 7, 8, 9, 10].map(n => ({ value: n, label: String(n) }))}
className="px-3 py-1.5 rounded bg-nofx-bg border border-nofx-gold/20 text-nofx-text"
/>
</div>
@@ -381,13 +381,13 @@ export function CoinSourceEditor({
{ts(coinSource.oiTopLimit, language)}:
</span>
<NofxSelect
value={config.oi_top_limit || 10}
value={config.oi_top_limit || 3}
onChange={(val) =>
!disabled &&
onChange({ ...config, oi_top_limit: parseInt(val) || 10 })
onChange({ ...config, oi_top_limit: parseInt(val) || 3 })
}
disabled={disabled}
options={[3, 5, 10, 20, 30, 40, 50].map(n => ({ value: n, label: String(n) }))}
options={[1, 2, 3, 4, 5, 6, 7, 8, 9, 10].map(n => ({ value: n, label: String(n) }))}
className="px-3 py-1.5 rounded bg-nofx-bg border border-nofx-gold/20 text-nofx-text"
/>
</div>
@@ -435,13 +435,13 @@ export function CoinSourceEditor({
{ts(coinSource.oiLowLimit, language)}:
</span>
<NofxSelect
value={config.oi_low_limit || 10}
value={config.oi_low_limit || 3}
onChange={(val) =>
!disabled &&
onChange({ ...config, oi_low_limit: parseInt(val) || 10 })
onChange({ ...config, oi_low_limit: parseInt(val) || 3 })
}
disabled={disabled}
options={[3, 5, 10, 20, 30, 40, 50].map(n => ({ value: n, label: String(n) }))}
options={[1, 2, 3, 4, 5, 6, 7, 8, 9, 10].map(n => ({ value: n, label: String(n) }))}
className="px-3 py-1.5 rounded bg-nofx-bg border border-nofx-gold/20 text-nofx-text"
/>
</div>
@@ -492,10 +492,10 @@ export function CoinSourceEditor({
<div className="flex items-center gap-2 mt-2 pl-6">
<span className="text-xs text-nofx-text-muted">Limit:</span>
<NofxSelect
value={config.ai500_limit || 10}
onChange={(val) => !disabled && onChange({ ...config, ai500_limit: parseInt(val) || 10 })}
value={config.ai500_limit || 3}
onChange={(val) => !disabled && onChange({ ...config, ai500_limit: parseInt(val) || 3 })}
disabled={disabled}
options={[3, 5, 10, 20, 30, 40, 50].map(n => ({ value: n, label: String(n) }))}
options={[1, 2, 3, 4, 5, 6, 7, 8, 9, 10].map(n => ({ value: n, label: String(n) }))}
className="px-2 py-1 rounded text-xs bg-nofx-bg border border-nofx-gold/20 text-nofx-text"
/>
</div>
@@ -532,10 +532,10 @@ export function CoinSourceEditor({
<div className="flex items-center gap-2 mt-2 pl-6">
<span className="text-xs text-nofx-text-muted">Limit:</span>
<NofxSelect
value={config.oi_top_limit || 10}
onChange={(val) => !disabled && onChange({ ...config, oi_top_limit: parseInt(val) || 10 })}
value={config.oi_top_limit || 3}
onChange={(val) => !disabled && onChange({ ...config, oi_top_limit: parseInt(val) || 3 })}
disabled={disabled}
options={[3, 5, 10, 20, 30, 40, 50].map(n => ({ value: n, label: String(n) }))}
options={[1, 2, 3, 4, 5, 6, 7, 8, 9, 10].map(n => ({ value: n, label: String(n) }))}
className="px-2 py-1 rounded text-xs bg-nofx-bg border border-nofx-gold/20 text-nofx-text"
/>
</div>
@@ -572,10 +572,10 @@ export function CoinSourceEditor({
<div className="flex items-center gap-2 mt-2 pl-6">
<span className="text-xs text-nofx-text-muted">Limit:</span>
<NofxSelect
value={config.oi_low_limit || 10}
onChange={(val) => !disabled && onChange({ ...config, oi_low_limit: parseInt(val) || 10 })}
value={config.oi_low_limit || 3}
onChange={(val) => !disabled && onChange({ ...config, oi_low_limit: parseInt(val) || 3 })}
disabled={disabled}
options={[3, 5, 10, 20, 30, 40, 50].map(n => ({ value: n, label: String(n) }))}
options={[1, 2, 3, 4, 5, 6, 7, 8, 9, 10].map(n => ({ value: n, label: String(n) }))}
className="px-2 py-1 rounded text-xs bg-nofx-bg border border-nofx-gold/20 text-nofx-text"
/>
</div>
+6 -3
View File
@@ -1,4 +1,4 @@
import { useRef, useState, useEffect, useCallback } from 'react'
import { useRef, useState, useLayoutEffect, useCallback } from 'react'
import { createPortal } from 'react-dom'
import { ChevronDown } from 'lucide-react'
import { cn } from '../../lib/cn'
@@ -30,7 +30,7 @@ export function NofxSelect({ value, onChange, options, disabled, className, styl
setPos({ top: rect.bottom + 4, left: rect.left, width: rect.width })
}, [])
useEffect(() => {
useLayoutEffect(() => {
if (!open) return
updatePos()
const handleClose = (e: MouseEvent) => {
@@ -39,7 +39,10 @@ export function NofxSelect({ value, onChange, options, disabled, className, styl
if (dropdownRef.current?.contains(target)) return
setOpen(false)
}
const handleScroll = () => setOpen(false)
const handleScroll = (e: Event) => {
if (dropdownRef.current?.contains(e.target as Node)) return
setOpen(false)
}
document.addEventListener('mousedown', handleClose)
window.addEventListener('scroll', handleScroll, true)
return () => {