feat(game): 添加游戏桌面组件的警告提示和动画效果

- 在动物游戏中添加余额不足和选择限制的警告提示
- 为警告状态添加震动动画和视觉反馈效果
- 实现倒计时警告状态的动画和样式变化
- 添加胜利和失败状态的历史记录显示
- 为筹码和操作按钮添加禁用状态的视觉效果
- 实现用户信息和流程按钮的交互功能
- 添加自动设置弹窗的打开功能
- 优化游戏阶段切换时的选择清空逻辑
- 添加剩余时间变化的回调函数支持
- 为历史记录添加中奖状态的颜色标识
This commit is contained in:
JiaJun
2026-05-18 18:01:33 +08:00
parent 85b4d9481f
commit 6ac42cf35e
15 changed files with 1125 additions and 91 deletions

View File

@@ -4,7 +4,11 @@ import { CHIP_IMAGE_MAP, CHIP_IMAGE_OPTIONS } from '@/constants'
import { placeGameBet } from '@/features/game'
import { notify } from '@/lib/notify'
import { useAuthStore, useModalStore } from '@/store'
import { selectSelectionTotal, useGameRoundStore } from '@/store/game'
import {
selectSelectionTotal,
useGameRoundStore,
useGameSessionStore,
} from '@/store/game'
type ConfirmState = 'idle' | 'ready' | 'insufficient' | 'submitting'
@@ -71,6 +75,12 @@ export function useGameControlVm() {
)
const selectChip = useGameRoundStore((state) => state.selectChip)
const totalBetAmount = useGameRoundStore(selectSelectionTotal)
const connectionStatus = useGameSessionStore(
(state) => state.connection.status,
)
const shouldConnectRealtime = useGameSessionStore(
(state) => state.shouldConnectRealtime,
)
const authStatus = useAuthStore((state) => state.status)
const currentUser = useAuthStore((state) => state.currentUser)
const setCurrentUser = useAuthStore((state) => state.setCurrentUser)
@@ -99,6 +109,8 @@ export function useGameControlVm() {
chipItems.find((chip) => chip.id === activeChipId) ?? chipItems[0] ?? null
const balance = parseBalance(currentUser?.coin)
const hasSelections = selections.length > 0
const hasEnteredGame =
shouldConnectRealtime && connectionStatus === 'connected'
const hasInsufficientBalance = hasSelections && totalBetAmount > balance
const confirmState: ConfirmState = isSubmitting
? 'submitting'
@@ -235,7 +247,13 @@ export function useGameControlVm() {
notify.success(t('commonUi.toast.repeatSelectionsRestored'))
}, [restoreRecentSuccessfulSelections, round.phase, t])
const handleOpenAutoSetting = useCallback(() => {
setModalOpen('desktopAutoSetting', true)
}, [setModalOpen])
return {
acceptingBets: round.phase === 'betting',
actionsEnabled: hasEnteredGame,
canClear: selections.length > 0,
confirmLabel:
confirmState === 'idle'
@@ -250,6 +268,7 @@ export function useGameControlVm() {
onChipSelect: selectChip,
onConfirm: handleConfirm,
onClearSelections: clearSelections,
onOpenAutoSetting: handleOpenAutoSetting,
onRepeatSelections: handleRepeatSelections,
maxSelectionCountLabel: maxSelectionCount,
selectedChipAmountLabel: selectedChip?.valueLabel ?? '--',

View File

@@ -69,14 +69,17 @@ export function useGameHistoryVm() {
i18n.resolvedLanguage ?? 'en-US',
),
id: entry.order_no,
isWin:
entry.result_number !== null &&
entry.numbers.includes(entry.result_number),
numbersLabel: formatNumbers(entry.numbers),
numbers: entry.numbers,
orderNo: entry.order_no,
periodNo: entry.period_no,
resultNumberLabel:
entry.result_number === null
? '--'
: String(entry.result_number).padStart(2, '0'),
statusLabel: entry.status,
winAmountLabel: entry.win_amount,
})),
),