feat: refine login flows and integrate tiangong worship audio

This commit is contained in:
zhouzhibo committed 2026-10-18 23:35:28 +08:00
1 parent bc7bbc52c8
commit 38fc4187ea
49 files changed
+1786 -224

No files matched your search

+9 -2
View File
@@ -1,13 +1,13 @@
import { useRef, useState } from 'react'
import Taro from '@tarojs/taro'
import { Button, Image, Text, View } from '@tarojs/components'
import { deityCatalog, getDeity, tiangongMock } from '../services/tiangong'
import { deityCatalog, getDeity, isTiangongDemo, tiangongMock } from '../services/tiangong'
import { DeityId } from '../utils/tiangongMock'
import { useTiangongSnapshot } from '../hooks/useTiangongSnapshot'
import './DeityBinding.scss'
export function BindingGate({ onBind, lock = true }: { onBind: () => void; lock?: boolean }) {
return <View className='binding-gate'>
return <View className='binding-gate' catchMove>
<View className='binding-gate-content'>
{lock && <View className='binding-lock'><View /></View>}
<Text>须绑定神仙</Text><Text>开启你的守护之旅</Text>
@@ -27,6 +27,12 @@ export function DeityCardDialog({ deityId, mode = 'view', onClose }: { deityId:
const [confirmUnbind, setConfirmUnbind] = useState(false)
const [error, setError] = useState('')
const working = useRef(false)
if (!isTiangongDemo()) return <View className='binding-dialog-mask' catchMove><View className='binding-picker' role='dialog' aria-label='神仙信息'>
<Text className='binding-confirm-title'>{deity.name}</Text>
<Image className='binding-card-art' src={deity.icon} mode='aspectFit' />
<Text className='binding-picker-note'>{state.unlocked ? `已守护 ${state.days} 天 · 持有记录 ${state.holdingId}` : '请通过 NFC 绑定神仙。此处不模拟建立真实绑定关系。'}</Text>
<Button className='binding-outline binding-picker-cancel' onClick={onClose}>关闭</Button>
</View></View>
const perform = (action: () => void) => {
if (working.current) return
working.current = true
@@ -82,6 +88,7 @@ export function DeityCardDialog({ deityId, mode = 'view', onClose }: { deityId:
export function DeityBindingFlow({ initialDeity, onClose }: { initialDeity?: DeityId; onClose: () => void }) {
const [selected, setSelected] = useState<DeityId | null>(initialDeity || null)
const snapshot = useTiangongSnapshot()
if (!isTiangongDemo()) return <View className='binding-dialog-mask' catchMove><View className='binding-picker' role='dialog' aria-label='绑定神仙说明'><Text className='binding-confirm-title'>碰一碰,绑定神仙</Text><Text className='binding-picker-note'>请通过 NFC 绑定神仙,本次不在页面中模拟真实设备绑定。</Text><Button className='binding-outline binding-picker-cancel' onClick={onClose}>关闭</Button></View></View>
if (selected) return <DeityCardDialog deityId={selected} mode='bind' onClose={onClose} />
const available = deityCatalog.filter(item => !snapshot.deities[item.id].unlocked)
return <View className='binding-dialog-mask' catchMove><View className='binding-picker' role='dialog' aria-label='模拟 NFC 识别'>