refactor(game): 优化游戏组件并实现国际化支持
- 在AppBootResourceGate组件中集成react-i18next实现资源加载文本的国际化 - 修改DesktopAnimal组件中的loading dots key以提高渲染性能 - 在DesktopControl组件中添加useRef和useEffect钩子管理定时器清理逻辑 - 将DesktopTitle组件重构为MessageBroadcast组件并增强其响应式设计 - 更新DesktopSupportModal组件中的客户服务文本为国际化格式 - 在AuthSession模块中实现本地存储数据清理时保留关键偏好设置 - 调整多个游戏组件的样式类以改进移动端适配效果 - 移除未使用的桌面提取功能相关代码文件 - 更新GitNexus索引统计数据反映最新的代码变更
This commit is contained in:
@@ -1,4 +1,5 @@
|
||||
import { useCallback, useEffect, useRef, useState } from 'react'
|
||||
import { useTranslation } from 'react-i18next'
|
||||
import { CenterModal } from '@/components/center-modal.tsx'
|
||||
import { DataLoadingIndicator } from '@/components/ui/data-loading-indicator'
|
||||
import { useModalStore } from '@/store'
|
||||
@@ -8,6 +9,7 @@ const SUPPORT_CHAT_URL =
|
||||
const IFRAME_READY_DELAY_MS = 2_000
|
||||
|
||||
function DesktopSupportModal() {
|
||||
const { t } = useTranslation()
|
||||
const [isLoading, setIsLoading] = useState(true)
|
||||
const readyTimerRef = useRef<number | null>(null)
|
||||
const open = useModalStore((state) => state.modals.desktopSupport)
|
||||
@@ -49,14 +51,18 @@ function DesktopSupportModal() {
|
||||
isNormalBg={true}
|
||||
onClose={handleClose}
|
||||
titleAlign="left"
|
||||
title={<div className="modal-title-glow text-design-30">在线客服</div>}
|
||||
title={
|
||||
<div className="modal-title-glow text-design-30">
|
||||
{t('commonUi.support.title')}
|
||||
</div>
|
||||
}
|
||||
className="h-design-760 w-design-980"
|
||||
>
|
||||
<div className="h-full px-design-24 pb-design-40 pt-design-10">
|
||||
<div className="relative h-full overflow-hidden rounded-[calc(var(--design-unit)*14)] border border-[#2A6D73] bg-[linear-gradient(180deg,rgba(5,22,31,0.98),rgba(2,10,17,0.98))] shadow-[inset_0_0_calc(var(--design-unit)*22)_rgba(88,205,218,0.13),0_0_calc(var(--design-unit)*18)_rgba(31,156,174,0.14)]">
|
||||
{isLoading ? (
|
||||
<div className="absolute inset-0 z-10 flex items-center justify-center bg-[radial-gradient(circle_at_center,rgba(20,92,105,0.38),rgba(2,10,17,0.98)_58%)]">
|
||||
<DataLoadingIndicator label="客服连线中" />
|
||||
<DataLoadingIndicator label={t('commonUi.support.connecting')} />
|
||||
</div>
|
||||
) : null}
|
||||
<iframe
|
||||
|
||||
@@ -112,32 +112,32 @@ function MobileAutoSettingModal() {
|
||||
open={open}
|
||||
onClose={handleClose}
|
||||
title={
|
||||
<div className={'modal-title-glow text-design-26 uppercase'}>
|
||||
<div className={'modal-title-glow text-design-16'}>
|
||||
{t('game.modals.autoSetting.title')}
|
||||
</div>
|
||||
}
|
||||
isNormalBg={true}
|
||||
titleAlign="left"
|
||||
className="!h-[min(calc(var(--design-unit)*500),calc(100dvh-var(--design-unit)*28))]"
|
||||
className="h-design-370"
|
||||
>
|
||||
<div
|
||||
className={
|
||||
'flex h-full w-full flex-col justify-between px-design-18 pt-design-30 pb-design-60'
|
||||
'flex h-full w-full flex-col justify-between px-design-10 pt-design-10 pb-design-14'
|
||||
}
|
||||
>
|
||||
<div className={'flex w-full flex-col gap-design-26'}>
|
||||
<div className={'flex items-center justify-between gap-design-30'}>
|
||||
<div
|
||||
className={
|
||||
'w-design-300 shrink-0 text-design-22 leading-[1.1] text-[#9CF7FF]'
|
||||
}
|
||||
>
|
||||
<div className={'flex w-full flex-col gap-design-8'}>
|
||||
<div
|
||||
className={
|
||||
'rounded-[calc(var(--design-unit)*8)] border border-[rgba(104,214,222,0.3)] bg-[rgba(4,30,38,0.7)] px-design-8 py-design-8 shadow-[inset_0_0_calc(var(--design-unit)*8)_rgba(33,193,219,0.08)]'
|
||||
}
|
||||
>
|
||||
<div className={'text-design-12 leading-[1.35] text-[#9CF7FF]'}>
|
||||
{t('game.modals.autoSetting.rows.stopIfBalanceLowerThan')}
|
||||
</div>
|
||||
|
||||
<div
|
||||
className={
|
||||
'game-setting-input-shell flex h-design-58 w-design-410 items-center justify-between pl-design-18 pr-design-10'
|
||||
'mt-design-6 flex items-center gap-design-6 rounded-[calc(var(--design-unit)*8)] border border-[rgba(111,235,245,0.16)] bg-[rgba(10,57,66,0.7)] px-design-8 py-design-6'
|
||||
}
|
||||
>
|
||||
<Input
|
||||
@@ -145,29 +145,30 @@ function MobileAutoSettingModal() {
|
||||
inputMode="decimal"
|
||||
onChange={(event) => setBalanceLimitValue(event.target.value)}
|
||||
className={
|
||||
'game-setting-input h-full w-design-280 text-design-18'
|
||||
'game-setting-input h-design-32 flex-1 bg-transparent px-design-6 py-design-6 text-design-12'
|
||||
}
|
||||
/>
|
||||
<Switch
|
||||
size={'sm'}
|
||||
className="scale-[0.82]"
|
||||
checked={balanceLimitEnabled}
|
||||
onCheckedChange={setBalanceLimitEnabled}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className={'flex items-center justify-between gap-design-30'}>
|
||||
<div
|
||||
className={
|
||||
'w-design-300 shrink-0 text-design-22 leading-[1.1] text-[#9CF7FF]'
|
||||
}
|
||||
>
|
||||
<div
|
||||
className={
|
||||
'rounded-[calc(var(--design-unit)*8)] border border-[rgba(104,214,222,0.3)] bg-[rgba(4,30,38,0.7)] px-design-8 py-design-8 shadow-[inset_0_0_calc(var(--design-unit)*8)_rgba(33,193,219,0.08)]'
|
||||
}
|
||||
>
|
||||
<div className={'text-design-12 leading-[1.35] text-[#9CF7FF]'}>
|
||||
{t('game.modals.autoSetting.rows.stopIfSingleWinExceeds')}
|
||||
</div>
|
||||
|
||||
<div
|
||||
className={
|
||||
'game-setting-input-shell flex h-design-58 w-design-410 items-center justify-between pl-design-18 pr-design-10'
|
||||
'mt-design-6 flex items-center gap-design-6 rounded-[calc(var(--design-unit)*8)] border border-[rgba(111,235,245,0.16)] bg-[rgba(10,57,66,0.7)] px-design-8 py-design-6'
|
||||
}
|
||||
>
|
||||
<Input
|
||||
@@ -175,29 +176,30 @@ function MobileAutoSettingModal() {
|
||||
inputMode="decimal"
|
||||
onChange={(event) => setSingleWinLimitValue(event.target.value)}
|
||||
className={
|
||||
'game-setting-input h-full w-design-280 text-design-18'
|
||||
'game-setting-input h-design-32 flex-1 bg-transparent px-design-6 py-design-6 text-design-12'
|
||||
}
|
||||
/>
|
||||
<Switch
|
||||
size={'sm'}
|
||||
className="scale-[0.82]"
|
||||
checked={singleWinLimitEnabled}
|
||||
onCheckedChange={setSingleWinLimitEnabled}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className={'flex items-center justify-between gap-design-30'}>
|
||||
<div
|
||||
className={
|
||||
'w-design-300 shrink-0 text-design-22 leading-[1.1] text-[#9CF7FF]'
|
||||
}
|
||||
>
|
||||
{t('game.modals.autoSetting.rows.stopOnAnyJackpot')}
|
||||
</div>
|
||||
|
||||
<div className={'flex w-design-410 justify-end pr-design-2'}>
|
||||
<div
|
||||
className={
|
||||
'rounded-[calc(var(--design-unit)*8)] border border-[rgba(104,214,222,0.3)] bg-[rgba(4,30,38,0.7)] px-design-8 py-design-8 shadow-[inset_0_0_calc(var(--design-unit)*8)_rgba(33,193,219,0.08)]'
|
||||
}
|
||||
>
|
||||
<div className={'flex items-center justify-between gap-design-8'}>
|
||||
<div className={'text-design-12 leading-[1.35] text-[#9CF7FF]'}>
|
||||
{t('game.modals.autoSetting.rows.stopOnAnyJackpot')}
|
||||
</div>
|
||||
<Switch
|
||||
size={'sm'}
|
||||
className="scale-[0.82]"
|
||||
checked={jackpotStopEnabled}
|
||||
onCheckedChange={setJackpotStopEnabled}
|
||||
/>
|
||||
@@ -205,7 +207,7 @@ function MobileAutoSettingModal() {
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className={'flex w-full justify-center'}>
|
||||
<div className={'flex w-full justify-center pt-design-10'}>
|
||||
<SmartBackground
|
||||
as="button"
|
||||
src={lengthBlueBtn}
|
||||
@@ -215,7 +217,7 @@ function MobileAutoSettingModal() {
|
||||
type="button"
|
||||
onClick={handleSubmit}
|
||||
className={
|
||||
'w-design-300 h-design-72 pb-design-4 flex cursor-pointer items-center justify-center text-design-24 font-bold tracking-wide text-[#E7FBFF] transition-transform hover:-translate-y-[1px] active:translate-y-0'
|
||||
'flex h-design-45 w-full max-w-[calc(var(--design-unit)*160)] cursor-pointer items-center justify-center pb-design-2 !text-design-12 font-bold mt-design-5 tracking-wide text-[#E7FBFF] transition-transform hover:-translate-y-[1px] active:translate-y-0'
|
||||
}
|
||||
>
|
||||
{t('game.modals.autoSetting.startAutoSpin')}
|
||||
|
||||
@@ -33,7 +33,7 @@ function MobileLanguageModal() {
|
||||
}
|
||||
isNormalBg={true}
|
||||
titleAlign="left"
|
||||
className="!h-design-350"
|
||||
className="!h-design-330"
|
||||
>
|
||||
<div className="flex h-full min-h-0 flex-col px-design-14 pt-design-5">
|
||||
<div className="w-full flex flex-wrap gap-design-10 overflow-y-auto">
|
||||
|
||||
@@ -2,28 +2,34 @@ import { X } from 'lucide-react'
|
||||
import { AnimatePresence, motion, useReducedMotion } from 'motion/react'
|
||||
import { useState } from 'react'
|
||||
import { useTranslation } from 'react-i18next'
|
||||
import { PeriodHistoryList } from '@/features/game/components/shared/period-history-list'
|
||||
import { MobileGameHistory } from '@/features/game/components/mobile/mobile-game-history.tsx'
|
||||
import { MobilePeriodHistoryList } from '@/features/game/components/mobile/mobile-period-history-list'
|
||||
import {
|
||||
DEFAULT_PERIOD_HISTORY_LIMIT,
|
||||
type PeriodHistoryDisplayItem,
|
||||
usePeriodHistoryVm,
|
||||
} from '@/hooks/use-period-history-vm'
|
||||
import { cn } from '@/lib/utils'
|
||||
import { useModalStore } from '@/store'
|
||||
|
||||
const OVERLAY_EASE = [0.16, 1, 0.3, 1] as const
|
||||
const DRAWER_TRANSITION = {
|
||||
type: 'tween',
|
||||
duration: 0.34,
|
||||
duration: 0.3,
|
||||
ease: OVERLAY_EASE,
|
||||
} as const
|
||||
|
||||
type HistoryTab = 'period' | 'record'
|
||||
|
||||
interface PeriodHistoryDrawerLabels {
|
||||
close: string
|
||||
empty: string
|
||||
failed: string
|
||||
loading: string
|
||||
recordTab: string
|
||||
retry: string
|
||||
title: string
|
||||
periodTab: string
|
||||
}
|
||||
|
||||
interface MobilePeriodHistoryDrawerViewProps {
|
||||
@@ -59,6 +65,8 @@ export function MobilePeriodHistoryDrawer() {
|
||||
empty: t('gameDesktop.periodHistory.empty'),
|
||||
failed: t('gameDesktop.periodHistory.failed'),
|
||||
loading: t('gameDesktop.periodHistory.loading'),
|
||||
periodTab: t('gameDesktop.periodHistory.title'),
|
||||
recordTab: t('gameDesktop.history.title'),
|
||||
retry: t('gameDesktop.periodHistory.retry'),
|
||||
title: t('gameDesktop.periodHistory.title'),
|
||||
}}
|
||||
@@ -78,104 +86,130 @@ export function MobilePeriodHistoryDrawerView({
|
||||
open,
|
||||
}: MobilePeriodHistoryDrawerViewProps) {
|
||||
const prefersReducedMotion = useReducedMotion()
|
||||
const [isDrawerAnimating, setIsDrawerAnimating] = useState(false)
|
||||
const [activeTab, setActiveTab] = useState<HistoryTab>('period')
|
||||
|
||||
return (
|
||||
<AnimatePresence>
|
||||
{open && (
|
||||
{open ? (
|
||||
<>
|
||||
<motion.button
|
||||
type="button"
|
||||
aria-label={labels.close}
|
||||
className="fixed left-0 right-0 top-0 bottom-[calc(var(--design-unit)*150)] z-30 cursor-default bg-black/48"
|
||||
className="fixed inset-0 z-30 cursor-default bg-black/58"
|
||||
initial={{ opacity: 0 }}
|
||||
animate={{ opacity: 1 }}
|
||||
exit={{ opacity: 0 }}
|
||||
transition={{
|
||||
duration: prefersReducedMotion ? 0.12 : 0.26,
|
||||
duration: prefersReducedMotion ? 0.12 : 0.22,
|
||||
ease: OVERLAY_EASE,
|
||||
}}
|
||||
onClick={onClose}
|
||||
/>
|
||||
|
||||
<motion.aside
|
||||
role="dialog"
|
||||
aria-modal="true"
|
||||
aria-label={labels.title}
|
||||
className="fixed left-0 top-design-16 bottom-[calc(var(--design-unit)*150)] z-40 flex w-design-1120 max-w-[calc(100vw-var(--design-unit)*24)] origin-left flex-col overflow-hidden rounded-r-[calc(var(--design-unit)*10)] border border-[rgba(81,230,255,0.62)] bg-[linear-gradient(180deg,rgba(6,19,32,0.98),rgba(3,12,22,0.96))] text-[#D5FBFF] shadow-[0_0_calc(var(--design-unit)*18)_rgba(39,216,255,0.28),0_0_calc(var(--design-unit)*54)_rgba(39,216,255,0.16),inset_0_0_calc(var(--design-unit)*18)_rgba(74,224,255,0.16)]"
|
||||
className="fixed inset-x-0 bottom-0 z-40 flex h-[min(calc(var(--design-unit)*620),calc(100dvh-var(--design-unit)*12))] flex-col overflow-hidden rounded-t-[calc(var(--design-unit)*10)] border border-[rgba(81,230,255,0.62)] bg-[linear-gradient(180deg,rgba(6,19,32,0.98),rgba(3,12,22,0.96))] text-[#D5FBFF] shadow-[0_0_calc(var(--design-unit)*16)_rgba(39,216,255,0.22),0_0_calc(var(--design-unit)*40)_rgba(39,216,255,0.1),inset_0_0_calc(var(--design-unit)*14)_rgba(74,224,255,0.12)]"
|
||||
initial={
|
||||
prefersReducedMotion
|
||||
? { opacity: 0 }
|
||||
: { x: '-100%', opacity: 0.98 }
|
||||
: { y: '100%', opacity: 0.98 }
|
||||
}
|
||||
animate={
|
||||
prefersReducedMotion ? { opacity: 1 } : { x: 0, opacity: 1 }
|
||||
prefersReducedMotion ? { opacity: 1 } : { y: 0, opacity: 1 }
|
||||
}
|
||||
exit={
|
||||
prefersReducedMotion
|
||||
? { opacity: 0 }
|
||||
: { x: '-100%', opacity: 0.98 }
|
||||
: { y: '100%', opacity: 0.98 }
|
||||
}
|
||||
transition={
|
||||
prefersReducedMotion ? { duration: 0.12 } : DRAWER_TRANSITION
|
||||
}
|
||||
onAnimationStart={() => setIsDrawerAnimating(true)}
|
||||
onAnimationComplete={() => setIsDrawerAnimating(false)}
|
||||
style={
|
||||
isDrawerAnimating
|
||||
? { willChange: 'transform, opacity' }
|
||||
: undefined
|
||||
}
|
||||
>
|
||||
<span
|
||||
aria-hidden="true"
|
||||
className="pointer-events-none absolute inset-x-design-8 top-0 h-px bg-[linear-gradient(90deg,transparent,rgba(80,241,255,0.96),transparent)]"
|
||||
/>
|
||||
<span
|
||||
aria-hidden="true"
|
||||
className="pointer-events-none absolute bottom-0 left-0 h-design-28 w-design-28 border-b-2 border-l-2 border-[#28E6FF]"
|
||||
/>
|
||||
<span
|
||||
aria-hidden="true"
|
||||
className="pointer-events-none absolute bottom-0 right-0 h-design-28 w-design-28 border-b-2 border-r-2 border-[#28E6FF]"
|
||||
/>
|
||||
<div className="relative flex h-design-78 shrink-0 items-center justify-between border-b border-[rgba(80,224,255,0.38)] px-design-42">
|
||||
<h2 className="text-design-28 font-bold leading-none text-white [text-shadow:0_0_calc(var(--design-unit)*10)_rgba(156,244,255,0.42)]">
|
||||
{labels.title}
|
||||
</h2>
|
||||
|
||||
<div className="relative flex h-design-40 shrink-0 items-center justify-between gap-design-4 border-b border-[rgba(80,224,255,0.3)] px-design-8">
|
||||
<div className="relative grid h-design-26 w-[calc(var(--design-unit)*170)] max-w-[calc(100%-var(--design-unit)*30)] shrink-0 grid-cols-2 overflow-hidden rounded-[calc(var(--design-unit)*7)] border border-[#2B8CA3]/24 bg-[#031B24]/68 p-[calc(var(--design-unit)*1.5)]">
|
||||
{(
|
||||
[
|
||||
['period', labels.periodTab],
|
||||
['record', labels.recordTab],
|
||||
] as const
|
||||
).map(([tab, label]) => {
|
||||
const isActive = activeTab === tab
|
||||
|
||||
return (
|
||||
<button
|
||||
key={tab}
|
||||
type="button"
|
||||
onClick={() => setActiveTab(tab)}
|
||||
className={cn(
|
||||
'relative flex min-w-0 cursor-pointer items-center justify-center overflow-hidden rounded-[calc(var(--design-unit)*5)] px-design-3 text-[calc(var(--design-unit)*8.5)] font-semibold transition-colors duration-200',
|
||||
isActive
|
||||
? 'text-[#FEEEB0]'
|
||||
: 'text-[#58ADAF] hover:text-[#BFEAEC]',
|
||||
)}
|
||||
>
|
||||
{isActive ? (
|
||||
<motion.span
|
||||
layoutId="mobile-period-history-tab-active-bg"
|
||||
aria-hidden="true"
|
||||
className="absolute inset-0 rounded-[calc(var(--design-unit)*5)] bg-[linear-gradient(180deg,rgba(254,238,176,0.28)_0%,rgba(254,238,176,0.1)_100%)]"
|
||||
transition={{
|
||||
type: 'spring',
|
||||
stiffness: 430,
|
||||
damping: 36,
|
||||
}}
|
||||
/>
|
||||
) : null}
|
||||
{isActive ? (
|
||||
<motion.span
|
||||
layoutId="mobile-period-history-tab-active-indicator"
|
||||
aria-hidden="true"
|
||||
className="absolute inset-x-design-5 bottom-0 h-[calc(var(--design-unit)*1.5)] rounded-full bg-[linear-gradient(90deg,rgba(255,248,214,0.14),rgba(254,238,176,0.9),rgba(255,248,214,0.14))] shadow-[0_0_calc(var(--design-unit)*5)_rgba(254,238,176,0.24)]"
|
||||
transition={{
|
||||
type: 'spring',
|
||||
stiffness: 430,
|
||||
damping: 36,
|
||||
}}
|
||||
/>
|
||||
) : null}
|
||||
<span className="min-w-0 truncate">{label}</span>
|
||||
</button>
|
||||
)
|
||||
})}
|
||||
</div>
|
||||
<button
|
||||
type="button"
|
||||
aria-label={labels.close}
|
||||
className="flex h-design-42 w-design-42 cursor-pointer items-center justify-center text-[#C8F7FF] transition-colors duration-200 hover:text-white focus-visible:ring-2 focus-visible:ring-[#4FEAFF]"
|
||||
className="flex h-design-22 w-design-22 cursor-pointer items-center justify-center text-[#C8F7FF] transition-colors duration-200 hover:text-white"
|
||||
onClick={onClose}
|
||||
>
|
||||
<X size={32} strokeWidth={2.1} />
|
||||
<X size={14} strokeWidth={2.1} />
|
||||
</button>
|
||||
</div>
|
||||
<motion.div
|
||||
className="history-scroll-hidden min-h-0 flex-1 overflow-y-auto px-design-34 py-design-26"
|
||||
initial={
|
||||
prefersReducedMotion ? { opacity: 0 } : { opacity: 0, y: 8 }
|
||||
}
|
||||
animate={
|
||||
prefersReducedMotion ? { opacity: 1 } : { opacity: 1, y: 0 }
|
||||
}
|
||||
transition={
|
||||
prefersReducedMotion
|
||||
? { duration: 0.12 }
|
||||
: { duration: 0.22, delay: 0.08, ease: OVERLAY_EASE }
|
||||
}
|
||||
>
|
||||
<PeriodHistoryList
|
||||
items={items}
|
||||
isLoading={isLoading}
|
||||
isError={isError}
|
||||
labels={labels}
|
||||
onRetry={onRetry}
|
||||
/>
|
||||
</motion.div>
|
||||
|
||||
<div className="min-h-0 flex-1 px-design-8 py-design-8">
|
||||
{activeTab === 'period' ? (
|
||||
<MobilePeriodHistoryList
|
||||
items={items}
|
||||
isLoading={isLoading}
|
||||
isError={isError}
|
||||
labels={labels}
|
||||
onRetry={onRetry}
|
||||
/>
|
||||
) : (
|
||||
<MobileGameHistory />
|
||||
)}
|
||||
</div>
|
||||
</motion.aside>
|
||||
</>
|
||||
)}
|
||||
) : null}
|
||||
</AnimatePresence>
|
||||
)
|
||||
}
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import { useCallback, useEffect, useRef, useState } from 'react'
|
||||
import { useTranslation } from 'react-i18next'
|
||||
import { MobileCenterModal } from '@/components/mobile-center-modal.tsx'
|
||||
import { DataLoadingIndicator } from '@/components/ui/data-loading-indicator'
|
||||
import { useModalStore } from '@/store'
|
||||
@@ -8,6 +9,7 @@ const SUPPORT_CHAT_URL =
|
||||
const IFRAME_READY_DELAY_MS = 2_000
|
||||
|
||||
function MobileSupportModal() {
|
||||
const { t } = useTranslation()
|
||||
const [isLoading, setIsLoading] = useState(true)
|
||||
const readyTimerRef = useRef<number | null>(null)
|
||||
const open = useModalStore((state) => state.modals.desktopSupport)
|
||||
@@ -49,7 +51,11 @@ function MobileSupportModal() {
|
||||
isNormalBg={true}
|
||||
onClose={handleClose}
|
||||
titleAlign="left"
|
||||
title={<div className="modal-title-glow text-design-16">在线客服</div>}
|
||||
title={
|
||||
<div className="modal-title-glow text-design-16">
|
||||
{t('commonUi.support.title')}
|
||||
</div>
|
||||
}
|
||||
className="h-design-500"
|
||||
>
|
||||
<div className="h-full min-h-0 px-design-8 pb-design-10 pt-design-4">
|
||||
@@ -57,7 +63,7 @@ function MobileSupportModal() {
|
||||
{isLoading ? (
|
||||
<div className="absolute inset-0 z-10 flex items-center justify-center bg-[radial-gradient(circle_at_center,rgba(20,92,105,0.38),rgba(2,10,17,0.98)_58%)]">
|
||||
<DataLoadingIndicator
|
||||
label="客服连线中"
|
||||
label={t('commonUi.support.connecting')}
|
||||
className="text-design-12"
|
||||
/>
|
||||
</div>
|
||||
|
||||
Reference in New Issue
Block a user