refactor(theme): 迁移主题感知颜色至 ThemeExtension
- 创建 AppThemeColors ThemeExtension 类,统一管理主题感知颜色(涨跌色、卡片背景、渐变等) - 从 AppColorScheme 移除主题感知辅助函数,仅保留静态颜色常量 - 在 AppTheme 中注册 ThemeExtension,支持深色/浅色主题工厂 - 重构所有 UI 组件使用 context.appColors 访问主题颜色,替代硬编码的 AppColorScheme 方法调用 - 移除组件中重复的 isDark 判断逻辑,简化颜色获取方式 - 保持向后兼容性,所有现有功能不变
This commit is contained in:
@@ -1,5 +1,6 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import '../../../../core/theme/app_theme.dart';
|
||||
import '../../../../core/theme/app_theme_extension.dart';
|
||||
import '../../../../core/theme/app_spacing.dart';
|
||||
|
||||
/// 账户标签切换器 — .pen node UE6xC
|
||||
@@ -19,14 +20,11 @@ class AccountTabSwitcher extends StatelessWidget {
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final colorScheme = Theme.of(context).colorScheme;
|
||||
final isDark = Theme.of(context).brightness == Brightness.dark;
|
||||
|
||||
return Container(
|
||||
height: 40,
|
||||
padding: const EdgeInsets.all(3),
|
||||
decoration: BoxDecoration(
|
||||
color: isDark ? colorScheme.surfaceContainerHighest : colorScheme.surfaceContainerHigh,
|
||||
color: context.appColors.surfaceCardHigh,
|
||||
borderRadius: BorderRadius.circular(AppRadius.md),
|
||||
),
|
||||
child: Row(
|
||||
@@ -36,14 +34,12 @@ class AccountTabSwitcher extends StatelessWidget {
|
||||
label: '资金账户',
|
||||
isSelected: selectedIndex == 0,
|
||||
onTap: () => onChanged(0),
|
||||
isDark: isDark,
|
||||
),
|
||||
_buildTab(
|
||||
context: context,
|
||||
label: '交易账户',
|
||||
isSelected: selectedIndex == 1,
|
||||
onTap: () => onChanged(1),
|
||||
isDark: isDark,
|
||||
),
|
||||
],
|
||||
),
|
||||
@@ -55,10 +51,7 @@ class AccountTabSwitcher extends StatelessWidget {
|
||||
required String label,
|
||||
required bool isSelected,
|
||||
required VoidCallback onTap,
|
||||
required bool isDark,
|
||||
}) {
|
||||
final colorScheme = Theme.of(context).colorScheme;
|
||||
|
||||
return Expanded(
|
||||
child: GestureDetector(
|
||||
onTap: onTap,
|
||||
@@ -66,13 +59,13 @@ class AccountTabSwitcher extends StatelessWidget {
|
||||
duration: const Duration(milliseconds: 200),
|
||||
decoration: BoxDecoration(
|
||||
color: isSelected
|
||||
? colorScheme.surface
|
||||
? context.colors.surface
|
||||
: const Color(0x00000000),
|
||||
borderRadius: BorderRadius.circular(AppRadius.sm),
|
||||
boxShadow: isSelected
|
||||
? [
|
||||
BoxShadow(
|
||||
color: colorScheme.shadow.withValues(alpha: 0.05),
|
||||
color: context.colors.shadow.withValues(alpha: 0.05),
|
||||
blurRadius: 3,
|
||||
offset: const Offset(0, 1),
|
||||
),
|
||||
@@ -86,7 +79,7 @@ class AccountTabSwitcher extends StatelessWidget {
|
||||
? AppTextStyles.headlineMedium(context)
|
||||
: AppTextStyles.headlineMedium(context).copyWith(
|
||||
fontWeight: FontWeight.w500,
|
||||
color: colorScheme.onSurfaceVariant,
|
||||
color: context.colors.onSurfaceVariant,
|
||||
),
|
||||
),
|
||||
),
|
||||
|
||||
@@ -2,6 +2,7 @@ import 'package:flutter/material.dart';
|
||||
import 'package:lucide_icons_flutter/lucide_icons.dart';
|
||||
import '../../../../core/theme/app_spacing.dart';
|
||||
import '../../../../core/theme/app_theme.dart';
|
||||
import '../../../../core/theme/app_theme_extension.dart';
|
||||
|
||||
/// 操作按钮行 — .pen node pIpHe
|
||||
/// gap: 12, three buttons evenly distributed
|
||||
@@ -22,10 +23,8 @@ class ActionButtonsRow extends StatelessWidget {
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final colorScheme = Theme.of(context).colorScheme;
|
||||
final isDark = Theme.of(context).brightness == Brightness.dark;
|
||||
final accentColor = isDark ? colorScheme.secondary : colorScheme.primary;
|
||||
final bgColor = isDark ? colorScheme.surfaceContainerHighest : colorScheme.surfaceContainerHigh;
|
||||
final accentColor = context.appColors.accentPrimary;
|
||||
final bgColor = context.appColors.surfaceCardHigh;
|
||||
|
||||
return Row(
|
||||
children: [
|
||||
|
||||
@@ -4,6 +4,7 @@ import 'package:shadcn_ui/shadcn_ui.dart';
|
||||
import 'package:lucide_icons_flutter/lucide_icons.dart';
|
||||
import 'package:provider/provider.dart';
|
||||
import '../../../../core/theme/app_theme.dart';
|
||||
import '../../../../core/theme/app_theme_extension.dart';
|
||||
import '../../../../core/theme/app_color_scheme.dart';
|
||||
import '../../../../core/theme/app_spacing.dart';
|
||||
import '../../../../core/utils/toast_utils.dart';
|
||||
@@ -246,7 +247,6 @@ void showDepositResultDialog(BuildContext context, Map<String, dynamic> data) {
|
||||
final walletAddress = data['walletAddress'] as String? ?? '';
|
||||
final walletNetwork = data['walletNetwork'] as String? ?? 'TRC20';
|
||||
final colorScheme = Theme.of(context).colorScheme;
|
||||
final isDark = Theme.of(context).brightness == Brightness.dark;
|
||||
|
||||
showShadDialog(
|
||||
context: context,
|
||||
@@ -263,7 +263,7 @@ void showDepositResultDialog(BuildContext context, Map<String, dynamic> data) {
|
||||
children: [
|
||||
NeonIcon(
|
||||
icon: Icons.check_circle,
|
||||
color: AppColorScheme.getUpColor(isDark),
|
||||
color: context.appColors.up,
|
||||
size: 24,
|
||||
),
|
||||
const SizedBox(width: AppSpacing.sm),
|
||||
@@ -361,7 +361,6 @@ void showWithdrawDialog(BuildContext context, String? balance) {
|
||||
final contactController = TextEditingController();
|
||||
final formKey = GlobalKey<ShadFormState>();
|
||||
final colorScheme = Theme.of(context).colorScheme;
|
||||
final isDark = Theme.of(context).brightness == Brightness.dark;
|
||||
|
||||
showShadDialog(
|
||||
context: context,
|
||||
@@ -412,10 +411,10 @@ void showWithdrawDialog(BuildContext context, String? balance) {
|
||||
vertical: AppSpacing.sm,
|
||||
),
|
||||
decoration: BoxDecoration(
|
||||
color: AppColorScheme.getUpBackgroundColor(isDark),
|
||||
color: context.appColors.upBackground,
|
||||
borderRadius: BorderRadius.circular(AppRadius.full),
|
||||
border: Border.all(
|
||||
color: AppColorScheme.getUpColor(isDark).withValues(alpha: 0.2),
|
||||
color: context.appColors.up.withValues(alpha: 0.2),
|
||||
),
|
||||
),
|
||||
child: Row(
|
||||
@@ -431,7 +430,7 @@ void showWithdrawDialog(BuildContext context, String? balance) {
|
||||
'$balance USDT',
|
||||
style: AppTextStyles.labelLarge(context).copyWith(
|
||||
fontWeight: FontWeight.bold,
|
||||
color: AppColorScheme.getUpColor(isDark),
|
||||
color: context.appColors.up,
|
||||
),
|
||||
),
|
||||
],
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import '../../../../core/theme/app_theme.dart';
|
||||
import '../../../../core/theme/app_color_scheme.dart';
|
||||
import '../../../../core/theme/app_theme_extension.dart';
|
||||
import '../../../../core/theme/app_spacing.dart';
|
||||
import '../../../../providers/asset_provider.dart';
|
||||
import '../../../components/glass_panel.dart';
|
||||
@@ -22,9 +22,6 @@ class BalanceCard extends StatelessWidget {
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final colorScheme = Theme.of(context).colorScheme;
|
||||
final isDark = Theme.of(context).brightness == Brightness.dark;
|
||||
|
||||
final displayBalance = activeTab == 0
|
||||
? (provider.fundAccount?.balance ?? provider.overview?.fundBalance ?? '0.00')
|
||||
: _calculateTradeTotal();
|
||||
@@ -38,7 +35,7 @@ class BalanceCard extends StatelessWidget {
|
||||
Text(
|
||||
'USDT 余额',
|
||||
style: AppTextStyles.bodyMedium(context).copyWith(
|
||||
color: colorScheme.onSurfaceVariant,
|
||||
color: context.colors.onSurfaceVariant,
|
||||
fontWeight: FontWeight.w400,
|
||||
),
|
||||
),
|
||||
@@ -51,7 +48,7 @@ class BalanceCard extends StatelessWidget {
|
||||
Text(
|
||||
'\u2248 \$${_formatBalance(displayBalance)} USD',
|
||||
style: AppTextStyles.bodyMedium(context).copyWith(
|
||||
color: isDark ? AppColorScheme.darkOnSurfaceMuted : colorScheme.onSurfaceVariant,
|
||||
color: context.appColors.onSurfaceMuted,
|
||||
fontWeight: FontWeight.w400,
|
||||
),
|
||||
),
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import '../../../../core/theme/app_theme.dart';
|
||||
import '../../../../core/theme/app_color_scheme.dart';
|
||||
import '../../../../core/theme/app_theme_extension.dart';
|
||||
import '../../../../core/theme/app_spacing.dart';
|
||||
import '../../../../data/models/account_models.dart';
|
||||
import '../../../components/glass_panel.dart';
|
||||
@@ -116,11 +116,9 @@ class HoldingRow extends StatelessWidget {
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final colorScheme = Theme.of(context).colorScheme;
|
||||
final isDark = Theme.of(context).brightness == Brightness.dark;
|
||||
final accentColor = isDark ? colorScheme.secondary : colorScheme.primary;
|
||||
final accentColor = context.appColors.accentPrimary;
|
||||
final accentBgColor = accentColor.withValues(alpha: 0.1);
|
||||
final profitColor = isProfit ? AppColorScheme.getUpColor(isDark) : AppColorScheme.getDownColor(isDark);
|
||||
final profitColor = isProfit ? context.appColors.up : context.appColors.down;
|
||||
|
||||
return Padding(
|
||||
padding: const EdgeInsets.symmetric(horizontal: AppSpacing.md, vertical: 14),
|
||||
@@ -159,7 +157,7 @@ class HoldingRow extends StatelessWidget {
|
||||
quantity,
|
||||
style: AppTextStyles.bodyMedium(context).copyWith(
|
||||
fontWeight: FontWeight.w400,
|
||||
color: colorScheme.onSurfaceVariant,
|
||||
color: context.colors.onSurfaceVariant,
|
||||
),
|
||||
),
|
||||
],
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:lucide_icons_flutter/lucide_icons.dart';
|
||||
import '../../../../core/theme/app_theme.dart';
|
||||
import '../../../../core/theme/app_color_scheme.dart';
|
||||
import '../../../../core/theme/app_theme_extension.dart';
|
||||
import '../../../../core/theme/app_spacing.dart';
|
||||
import '../../../components/glass_panel.dart';
|
||||
|
||||
@@ -16,9 +16,7 @@ class RecordsLinkRow extends StatelessWidget {
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final colorScheme = Theme.of(context).colorScheme;
|
||||
final isDark = Theme.of(context).brightness == Brightness.dark;
|
||||
final mutedColor = isDark ? AppColorScheme.darkOnSurfaceMuted : colorScheme.onSurfaceVariant;
|
||||
final mutedColor = context.appColors.onSurfaceMuted;
|
||||
|
||||
return GestureDetector(
|
||||
onTap: onTap,
|
||||
|
||||
@@ -3,7 +3,7 @@ import 'package:flutter/services.dart';
|
||||
import 'package:provider/provider.dart';
|
||||
import 'package:lucide_icons_flutter/lucide_icons.dart';
|
||||
import '../../../core/theme/app_theme.dart';
|
||||
import '../../../core/theme/app_color_scheme.dart';
|
||||
import '../../../core/theme/app_theme_extension.dart';
|
||||
import '../../../core/theme/app_spacing.dart';
|
||||
import '../../../providers/asset_provider.dart';
|
||||
import '../../../data/models/account_models.dart';
|
||||
@@ -76,12 +76,6 @@ class _TransferPageState extends State<TransferPage> {
|
||||
String get _fromBalance => _direction == 1 ? _fundBalance : _tradeUsdtBalance;
|
||||
String get _toBalance => _direction == 1 ? _tradeUsdtBalance : _fundBalance;
|
||||
|
||||
// ============================================
|
||||
// 主题辅助
|
||||
// ============================================
|
||||
|
||||
bool get _isDark => Theme.of(context).brightness == Brightness.dark;
|
||||
|
||||
// ============================================
|
||||
// 业务逻辑
|
||||
// ============================================
|
||||
@@ -363,7 +357,7 @@ class _TransferPageState extends State<TransferPage> {
|
||||
decoration: InputDecoration(
|
||||
hintText: '0.00',
|
||||
hintStyle: AppTextStyles.numberLarge(context).copyWith(
|
||||
color: AppColorScheme.darkOnSurfaceMuted,
|
||||
color: context.appColors.onSurfaceMuted,
|
||||
),
|
||||
border: InputBorder.none,
|
||||
contentPadding: EdgeInsets.zero,
|
||||
@@ -375,7 +369,7 @@ class _TransferPageState extends State<TransferPage> {
|
||||
padding: const EdgeInsets.only(left: AppSpacing.sm),
|
||||
child: Text('USDT', style: AppTextStyles.headlineMedium(context).copyWith(
|
||||
fontWeight: FontWeight.w400,
|
||||
color: AppColorScheme.darkOnSurfaceMuted,
|
||||
color: context.appColors.onSurfaceMuted,
|
||||
)),
|
||||
),
|
||||
],
|
||||
@@ -425,13 +419,13 @@ class _TransferPageState extends State<TransferPage> {
|
||||
// ============================================
|
||||
|
||||
Widget _buildTipsCard() {
|
||||
final upColor = AppColorScheme.getUpColor(_isDark);
|
||||
final upColor = context.appColors.up;
|
||||
|
||||
return Container(
|
||||
width: double.infinity,
|
||||
padding: const EdgeInsets.symmetric(horizontal: AppSpacing.md, vertical: 12),
|
||||
decoration: BoxDecoration(
|
||||
color: AppColorScheme.getUpBackgroundColor(_isDark),
|
||||
color: context.appColors.upBackground,
|
||||
borderRadius: BorderRadius.circular(AppRadius.lg),
|
||||
),
|
||||
child: Row(
|
||||
|
||||
@@ -5,6 +5,7 @@ import 'package:provider/provider.dart';
|
||||
import '../../../core/theme/app_color_scheme.dart';
|
||||
import '../../../core/theme/app_spacing.dart';
|
||||
import '../../../core/theme/app_theme.dart';
|
||||
import '../../../core/theme/app_theme_extension.dart';
|
||||
import '../../../providers/auth_provider.dart';
|
||||
import '../main/main_page.dart';
|
||||
import 'register_page.dart';
|
||||
@@ -36,12 +37,8 @@ class _LoginPageState extends State<LoginPage> {
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final isDark = Theme.of(context).brightness == Brightness.dark;
|
||||
|
||||
return Scaffold(
|
||||
backgroundColor: isDark
|
||||
? AppColorScheme.darkBackground
|
||||
: AppColorScheme.lightSurface,
|
||||
backgroundColor: context.colors.surface,
|
||||
body: SafeArea(
|
||||
child: SingleChildScrollView(
|
||||
padding: const EdgeInsets.symmetric(
|
||||
@@ -53,13 +50,13 @@ class _LoginPageState extends State<LoginPage> {
|
||||
child: Column(
|
||||
children: [
|
||||
// 顶部品牌区域
|
||||
_buildBrandSection(isDark),
|
||||
_buildBrandSection(),
|
||||
const SizedBox(height: AppSpacing.xxl),
|
||||
// 表单区域
|
||||
_buildFormSection(isDark),
|
||||
_buildFormSection(),
|
||||
const SizedBox(height: AppSpacing.xl),
|
||||
// 底部注册链接
|
||||
_buildRegisterRow(isDark),
|
||||
_buildRegisterRow(),
|
||||
],
|
||||
),
|
||||
),
|
||||
@@ -72,16 +69,16 @@ class _LoginPageState extends State<LoginPage> {
|
||||
// 品牌区域 - Logo + 品牌名 + 标语
|
||||
// ============================================
|
||||
|
||||
Widget _buildBrandSection(bool isDark) {
|
||||
Widget _buildBrandSection() {
|
||||
return Column(
|
||||
children: [
|
||||
// Logo 圆形:渐变 #1F2937 → #374151,内含 "M"
|
||||
Container(
|
||||
width: _logoCircleSize,
|
||||
height: _logoCircleSize,
|
||||
decoration: BoxDecoration(
|
||||
decoration: const BoxDecoration(
|
||||
shape: BoxShape.circle,
|
||||
gradient: const LinearGradient(
|
||||
gradient: LinearGradient(
|
||||
begin: Alignment.topCenter,
|
||||
end: Alignment.bottomCenter,
|
||||
colors: [AppColorScheme.darkSurfaceContainerHigh, AppColorScheme.darkOutline],
|
||||
@@ -93,9 +90,7 @@ class _LoginPageState extends State<LoginPage> {
|
||||
style: AppTextStyles.displayLarge(context).copyWith(
|
||||
fontSize: 32,
|
||||
fontWeight: FontWeight.w800,
|
||||
color: isDark
|
||||
? AppColorScheme.darkOnSurface
|
||||
: AppColorScheme.darkOnPrimary,
|
||||
color: context.colors.onPrimary,
|
||||
),
|
||||
),
|
||||
),
|
||||
@@ -105,9 +100,7 @@ class _LoginPageState extends State<LoginPage> {
|
||||
'MONISUO',
|
||||
style: AppTextStyles.displayLarge(context).copyWith(
|
||||
letterSpacing: 3,
|
||||
color: isDark
|
||||
? AppColorScheme.darkOnSurface
|
||||
: AppColorScheme.lightOnSurface,
|
||||
color: context.colors.onSurface,
|
||||
),
|
||||
textAlign: TextAlign.center,
|
||||
),
|
||||
@@ -116,9 +109,7 @@ class _LoginPageState extends State<LoginPage> {
|
||||
Text(
|
||||
'虚拟货币模拟交易平台',
|
||||
style: AppTextStyles.bodyLarge(context).copyWith(
|
||||
color: isDark
|
||||
? AppColorScheme.darkOnSurfaceVariant
|
||||
: AppColorScheme.lightOnSurfaceVariant,
|
||||
color: context.colors.onSurfaceVariant,
|
||||
),
|
||||
textAlign: TextAlign.center,
|
||||
),
|
||||
@@ -130,30 +121,20 @@ class _LoginPageState extends State<LoginPage> {
|
||||
// 表单区域 - 用户名 + 密码 + 登录按钮
|
||||
// ============================================
|
||||
|
||||
Widget _buildFormSection(bool isDark) {
|
||||
Widget _buildFormSection() {
|
||||
return Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.stretch,
|
||||
children: [
|
||||
_buildUsernameField(isDark),
|
||||
_buildUsernameField(),
|
||||
const SizedBox(height: AppSpacing.md),
|
||||
_buildPasswordField(isDark),
|
||||
_buildPasswordField(),
|
||||
const SizedBox(height: AppSpacing.sm),
|
||||
_buildLoginButton(isDark),
|
||||
_buildLoginButton(),
|
||||
],
|
||||
);
|
||||
}
|
||||
|
||||
Widget _buildUsernameField(bool isDark) {
|
||||
final borderColor = isDark
|
||||
? AppColorScheme.darkOutlineVariant
|
||||
: AppColorScheme.lightOutlineVariant;
|
||||
final cardColor = isDark
|
||||
? AppColorScheme.darkSurfaceContainer
|
||||
: AppColorScheme.lightSurfaceLowest;
|
||||
final iconColor = isDark
|
||||
? AppColorScheme.darkOnSurfaceMuted
|
||||
: AppColorScheme.lightOnSurfaceMuted;
|
||||
|
||||
Widget _buildUsernameField() {
|
||||
return SizedBox(
|
||||
height: _inputHeight,
|
||||
child: ShadInputFormField(
|
||||
@@ -161,32 +142,25 @@ class _LoginPageState extends State<LoginPage> {
|
||||
placeholder: const Text('请输入用户名'),
|
||||
leading: Padding(
|
||||
padding: const EdgeInsets.only(right: AppSpacing.sm),
|
||||
child: Icon(LucideIcons.user, size: 18, color: iconColor),
|
||||
child: Icon(LucideIcons.user, size: 18, color: context.appColors.onSurfaceMuted),
|
||||
),
|
||||
validator: _validateUsername,
|
||||
controller: _usernameController,
|
||||
decoration: ShadDecoration(
|
||||
border: ShadBorder.all(
|
||||
color: borderColor,
|
||||
color: context.colors.outlineVariant,
|
||||
radius: AppRadius.radiusLg,
|
||||
),
|
||||
),
|
||||
style: AppTextStyles.headlineMedium(context).copyWith(
|
||||
color: isDark
|
||||
? AppColorScheme.darkOnSurface
|
||||
: AppColorScheme.lightOnSurface,
|
||||
color: context.colors.onSurface,
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
Widget _buildPasswordField(bool isDark) {
|
||||
final borderColor = isDark
|
||||
? AppColorScheme.darkOutlineVariant
|
||||
: AppColorScheme.lightOutlineVariant;
|
||||
final iconColor = isDark
|
||||
? AppColorScheme.darkOnSurfaceMuted
|
||||
: AppColorScheme.lightOnSurfaceMuted;
|
||||
Widget _buildPasswordField() {
|
||||
final iconColor = context.appColors.onSurfaceMuted;
|
||||
|
||||
return SizedBox(
|
||||
height: _inputHeight,
|
||||
@@ -210,27 +184,21 @@ class _LoginPageState extends State<LoginPage> {
|
||||
controller: _passwordController,
|
||||
decoration: ShadDecoration(
|
||||
border: ShadBorder.all(
|
||||
color: borderColor,
|
||||
color: context.colors.outlineVariant,
|
||||
radius: AppRadius.radiusLg,
|
||||
),
|
||||
),
|
||||
style: AppTextStyles.headlineMedium(context).copyWith(
|
||||
color: isDark
|
||||
? AppColorScheme.darkOnSurface
|
||||
: AppColorScheme.lightOnSurface,
|
||||
color: context.colors.onSurface,
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
Widget _buildLoginButton(bool isDark) {
|
||||
Widget _buildLoginButton() {
|
||||
// 设计稿: accent-primary = light:#1F2937 / dark:#D4AF37
|
||||
final buttonColor = isDark
|
||||
? AppColorScheme.darkSecondary
|
||||
: AppColorScheme.darkSurfaceContainerHigh;
|
||||
final textColor = isDark
|
||||
? AppColorScheme.darkBackground
|
||||
: AppColorScheme.darkOnPrimary;
|
||||
final buttonColor = context.appColors.accentPrimary;
|
||||
final textColor = context.colors.onPrimary;
|
||||
|
||||
return Consumer<AuthProvider>(
|
||||
builder: (context, auth, _) {
|
||||
@@ -270,14 +238,10 @@ class _LoginPageState extends State<LoginPage> {
|
||||
// 底部注册链接
|
||||
// ============================================
|
||||
|
||||
Widget _buildRegisterRow(bool isDark) {
|
||||
Widget _buildRegisterRow() {
|
||||
// gold-accent: light=#F59E0B / dark=#D4AF37
|
||||
final goldColor = isDark
|
||||
? AppColorScheme.darkSecondary
|
||||
: AppColorScheme.darkSecondaryFixed;
|
||||
final secondaryTextColor = isDark
|
||||
? AppColorScheme.darkOnSurfaceVariant
|
||||
: AppColorScheme.lightOnSurfaceVariant;
|
||||
final goldColor = context.appColors.accentPrimary;
|
||||
final secondaryTextColor = context.colors.onSurfaceVariant;
|
||||
|
||||
return Padding(
|
||||
padding: const EdgeInsets.only(bottom: AppSpacing.xl),
|
||||
|
||||
@@ -7,13 +7,13 @@ import 'package:provider/provider.dart';
|
||||
import '../../../core/theme/app_theme.dart';
|
||||
import '../../../core/theme/app_color_scheme.dart';
|
||||
import '../../../core/theme/app_spacing.dart';
|
||||
import '../../../core/theme/app_theme_extension.dart';
|
||||
import '../../../core/utils/toast_utils.dart';
|
||||
import '../../../core/event/app_event_bus.dart';
|
||||
import '../../../data/models/account_models.dart';
|
||||
import '../../../data/services/asset_service.dart';
|
||||
import '../../../data/services/bonus_service.dart';
|
||||
import '../../../providers/asset_provider.dart';
|
||||
import '../../../providers/auth_provider.dart';
|
||||
import '../../components/glass_panel.dart';
|
||||
import '../../components/neon_glow.dart';
|
||||
import '../main/main_page.dart';
|
||||
@@ -85,15 +85,14 @@ class _HomePageState extends State<HomePage>
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
super.build(context);
|
||||
final colorScheme = Theme.of(context).colorScheme;
|
||||
|
||||
return Scaffold(
|
||||
backgroundColor: colorScheme.background,
|
||||
backgroundColor: context.colors.background,
|
||||
body: Consumer<AssetProvider>(
|
||||
builder: (context, provider, _) {
|
||||
return RefreshIndicator(
|
||||
onRefresh: () => provider.refreshAll(force: true),
|
||||
color: colorScheme.primary,
|
||||
color: context.colors.primary,
|
||||
child: SingleChildScrollView(
|
||||
physics: const AlwaysScrollableScrollPhysics(),
|
||||
padding: EdgeInsets.only(
|
||||
@@ -149,7 +148,6 @@ class _HomePageState extends State<HomePage>
|
||||
void _showDeposit() {
|
||||
final amountController = TextEditingController();
|
||||
final formKey = GlobalKey<ShadFormState>();
|
||||
final colorScheme = Theme.of(context).colorScheme;
|
||||
|
||||
showShadDialog(
|
||||
context: context,
|
||||
@@ -184,10 +182,10 @@ class _HomePageState extends State<HomePage>
|
||||
Container(
|
||||
padding: EdgeInsets.all(AppSpacing.sm),
|
||||
decoration: BoxDecoration(
|
||||
color: colorScheme.surfaceContainerHigh,
|
||||
color: context.colors.surfaceContainerHigh,
|
||||
borderRadius: BorderRadius.circular(AppRadius.md),
|
||||
),
|
||||
child: Icon(LucideIcons.wallet, color: colorScheme.secondary),
|
||||
child: Icon(LucideIcons.wallet, color: context.colors.secondary),
|
||||
),
|
||||
],
|
||||
),
|
||||
@@ -261,7 +259,6 @@ class _HomePageState extends State<HomePage>
|
||||
final amount = data['amount']?.toString() ?? '0.00';
|
||||
final walletAddress = data['walletAddress'] as String? ?? '';
|
||||
final walletNetwork = data['walletNetwork'] as String? ?? 'TRC20';
|
||||
final colorScheme = Theme.of(context).colorScheme;
|
||||
|
||||
showShadDialog(
|
||||
context: context,
|
||||
@@ -305,9 +302,9 @@ class _HomePageState extends State<HomePage>
|
||||
Container(
|
||||
padding: EdgeInsets.all(AppSpacing.sm),
|
||||
decoration: BoxDecoration(
|
||||
color: AppColorScheme.warning.withOpacity(0.1),
|
||||
color: AppColorScheme.warning.withValues(alpha: 0.1),
|
||||
borderRadius: BorderRadius.circular(AppRadius.md),
|
||||
border: Border.all(color: AppColorScheme.warning.withOpacity(0.2)),
|
||||
border: Border.all(color: AppColorScheme.warning.withValues(alpha: 0.2)),
|
||||
),
|
||||
child: Row(
|
||||
children: [
|
||||
@@ -371,7 +368,6 @@ class _HomePageState extends State<HomePage>
|
||||
}
|
||||
|
||||
void _showResultDialog(String title, String? message) {
|
||||
final colorScheme = Theme.of(context).colorScheme;
|
||||
showShadDialog(
|
||||
context: context,
|
||||
builder: (ctx) => Dialog(
|
||||
@@ -525,10 +521,8 @@ class _AssetCardState extends State<_AssetCard> {
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final colorScheme = Theme.of(context).colorScheme;
|
||||
final isDark = Theme.of(context).brightness == Brightness.dark;
|
||||
final upColor = AppColorScheme.getUpColor(isDark);
|
||||
final downColor = AppColorScheme.getDownColor(isDark);
|
||||
final upColor = context.appColors.up;
|
||||
final downColor = context.appColors.down;
|
||||
final isProfit = _totalProfit >= 0;
|
||||
final todayProfit = _todayProfit;
|
||||
final isTodayProfit = (todayProfit ?? 0) >= 0;
|
||||
@@ -558,19 +552,19 @@ class _AssetCardState extends State<_AssetCard> {
|
||||
vertical: AppSpacing.xs + 2,
|
||||
),
|
||||
decoration: BoxDecoration(
|
||||
color: colorScheme.primary.withOpacity(0.1),
|
||||
color: context.colors.primary.withValues(alpha: 0.1),
|
||||
borderRadius: BorderRadius.circular(AppRadius.full),
|
||||
border: Border.all(color: colorScheme.primary.withOpacity(0.2)),
|
||||
border: Border.all(color: context.colors.primary.withValues(alpha: 0.2)),
|
||||
),
|
||||
child: Row(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: [
|
||||
Icon(Icons.add, size: 14, color: colorScheme.primary),
|
||||
Icon(Icons.add, size: 14, color: context.colors.primary),
|
||||
SizedBox(width: AppSpacing.xs),
|
||||
Text(
|
||||
'充值',
|
||||
style: AppTextStyles.labelLarge(context).copyWith(
|
||||
color: colorScheme.primary,
|
||||
color: context.colors.primary,
|
||||
),
|
||||
),
|
||||
],
|
||||
@@ -620,11 +614,11 @@ class _AssetCardState extends State<_AssetCard> {
|
||||
padding: EdgeInsets.symmetric(horizontal: 10, vertical: 4),
|
||||
decoration: BoxDecoration(
|
||||
color: _calendarExpanded
|
||||
? colorScheme.primary.withOpacity(0.1)
|
||||
: colorScheme.surfaceContainerHigh,
|
||||
? context.colors.primary.withValues(alpha: 0.1)
|
||||
: context.colors.surfaceContainerHigh,
|
||||
borderRadius: BorderRadius.circular(AppRadius.full),
|
||||
border: _calendarExpanded
|
||||
? Border.all(color: colorScheme.primary.withOpacity(0.2))
|
||||
? Border.all(color: context.colors.primary.withValues(alpha: 0.2))
|
||||
: null,
|
||||
),
|
||||
child: Row(
|
||||
@@ -634,8 +628,8 @@ class _AssetCardState extends State<_AssetCard> {
|
||||
LucideIcons.chartBar,
|
||||
size: 13,
|
||||
color: _calendarExpanded
|
||||
? colorScheme.primary
|
||||
: colorScheme.onSurfaceVariant,
|
||||
? context.colors.primary
|
||||
: context.colors.onSurfaceVariant,
|
||||
),
|
||||
SizedBox(width: AppSpacing.xs),
|
||||
Text(
|
||||
@@ -643,8 +637,8 @@ class _AssetCardState extends State<_AssetCard> {
|
||||
style: AppTextStyles.labelMedium(context).copyWith(
|
||||
fontWeight: _calendarExpanded ? FontWeight.w600 : FontWeight.w500,
|
||||
color: _calendarExpanded
|
||||
? colorScheme.primary
|
||||
: colorScheme.onSurfaceVariant,
|
||||
? context.colors.primary
|
||||
: context.colors.onSurfaceVariant,
|
||||
),
|
||||
),
|
||||
SizedBox(width: 2),
|
||||
@@ -655,8 +649,8 @@ class _AssetCardState extends State<_AssetCard> {
|
||||
LucideIcons.chevronDown,
|
||||
size: 13,
|
||||
color: _calendarExpanded
|
||||
? colorScheme.primary
|
||||
: colorScheme.onSurfaceVariant,
|
||||
? context.colors.primary
|
||||
: context.colors.onSurfaceVariant,
|
||||
),
|
||||
),
|
||||
],
|
||||
@@ -669,9 +663,7 @@ class _AssetCardState extends State<_AssetCard> {
|
||||
// 可折叠的盈利日历
|
||||
AnimatedCrossFade(
|
||||
firstChild: const SizedBox.shrink(),
|
||||
secondChild: _buildCalendarSection(
|
||||
context, colorScheme, isDark, upColor, downColor,
|
||||
),
|
||||
secondChild: _buildCalendarSection(context),
|
||||
crossFadeState: _calendarExpanded
|
||||
? CrossFadeState.showSecond
|
||||
: CrossFadeState.showFirst,
|
||||
@@ -683,18 +675,14 @@ class _AssetCardState extends State<_AssetCard> {
|
||||
);
|
||||
}
|
||||
|
||||
Widget _buildCalendarSection(
|
||||
BuildContext context,
|
||||
ColorScheme colorScheme,
|
||||
bool isDark,
|
||||
Color upColor,
|
||||
Color downColor,
|
||||
) {
|
||||
Widget _buildCalendarSection(BuildContext context) {
|
||||
final now = DateTime.now();
|
||||
final isCurrentMonth = _currentMonth.year == now.year && _currentMonth.month == now.month;
|
||||
final firstDayOfMonth = DateTime(_currentMonth.year, _currentMonth.month, 1);
|
||||
final daysInMonth = DateTime(_currentMonth.year, _currentMonth.month + 1, 0).day;
|
||||
final startWeekday = firstDayOfMonth.weekday;
|
||||
final upColor = context.appColors.up;
|
||||
final downColor = context.appColors.down;
|
||||
|
||||
return Column(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
@@ -702,7 +690,7 @@ class _AssetCardState extends State<_AssetCard> {
|
||||
// 分隔线
|
||||
Padding(
|
||||
padding: EdgeInsets.symmetric(vertical: AppSpacing.md),
|
||||
child: Divider(color: colorScheme.outlineVariant.withOpacity(0.15), height: 1),
|
||||
child: Divider(color: context.appColors.ghostBorder, height: 1),
|
||||
),
|
||||
|
||||
// 月份导航行
|
||||
@@ -714,10 +702,10 @@ class _AssetCardState extends State<_AssetCard> {
|
||||
child: Container(
|
||||
padding: EdgeInsets.all(AppSpacing.xs + 1),
|
||||
decoration: BoxDecoration(
|
||||
color: colorScheme.surfaceContainerHigh,
|
||||
color: context.colors.surfaceContainerHigh,
|
||||
borderRadius: BorderRadius.circular(AppRadius.sm),
|
||||
),
|
||||
child: Icon(LucideIcons.chevronLeft, size: 16, color: colorScheme.onSurfaceVariant),
|
||||
child: Icon(LucideIcons.chevronLeft, size: 16, color: context.colors.onSurfaceVariant),
|
||||
),
|
||||
),
|
||||
Column(
|
||||
@@ -745,16 +733,16 @@ class _AssetCardState extends State<_AssetCard> {
|
||||
padding: EdgeInsets.all(AppSpacing.xs + 1),
|
||||
decoration: BoxDecoration(
|
||||
color: isCurrentMonth
|
||||
? colorScheme.surfaceContainerHigh.withOpacity(0.5)
|
||||
: colorScheme.surfaceContainerHigh,
|
||||
? context.colors.surfaceContainerHigh.withValues(alpha: 0.5)
|
||||
: context.colors.surfaceContainerHigh,
|
||||
borderRadius: BorderRadius.circular(AppRadius.sm),
|
||||
),
|
||||
child: Icon(
|
||||
LucideIcons.chevronRight,
|
||||
size: 16,
|
||||
color: isCurrentMonth
|
||||
? colorScheme.onSurfaceVariant.withOpacity(0.4)
|
||||
: colorScheme.onSurfaceVariant,
|
||||
? context.colors.onSurfaceVariant.withValues(alpha: 0.4)
|
||||
: context.colors.onSurfaceVariant,
|
||||
),
|
||||
),
|
||||
),
|
||||
@@ -771,7 +759,7 @@ class _AssetCardState extends State<_AssetCard> {
|
||||
d,
|
||||
style: AppTextStyles.bodySmall(context).copyWith(
|
||||
fontWeight: FontWeight.w500,
|
||||
color: colorScheme.onSurfaceVariant.withOpacity(0.6),
|
||||
color: context.colors.onSurfaceVariant.withValues(alpha: 0.6),
|
||||
),
|
||||
),
|
||||
),
|
||||
@@ -789,14 +777,13 @@ class _AssetCardState extends State<_AssetCard> {
|
||||
height: 18,
|
||||
child: CircularProgressIndicator(
|
||||
strokeWidth: 2,
|
||||
color: colorScheme.primary,
|
||||
color: context.colors.primary,
|
||||
),
|
||||
),
|
||||
)
|
||||
else
|
||||
..._buildCalendarGrid(
|
||||
startWeekday, daysInMonth, now, isCurrentMonth,
|
||||
upColor, downColor, colorScheme,
|
||||
),
|
||||
],
|
||||
);
|
||||
@@ -807,10 +794,9 @@ class _AssetCardState extends State<_AssetCard> {
|
||||
int daysInMonth,
|
||||
DateTime now,
|
||||
bool isCurrentMonth,
|
||||
Color upColor,
|
||||
Color downColor,
|
||||
ColorScheme colorScheme,
|
||||
) {
|
||||
final upColor = context.appColors.up;
|
||||
final downColor = context.appColors.down;
|
||||
final List<Widget> rows = [];
|
||||
List<Widget> cells = [];
|
||||
|
||||
@@ -831,15 +817,15 @@ class _AssetCardState extends State<_AssetCard> {
|
||||
margin: EdgeInsets.all(1),
|
||||
decoration: BoxDecoration(
|
||||
color: isToday
|
||||
? colorScheme.primary.withOpacity(0.12)
|
||||
? context.colors.primary.withValues(alpha: 0.12)
|
||||
: hasProfit
|
||||
? (profit! > 0
|
||||
? upColor.withOpacity(0.08)
|
||||
: downColor.withOpacity(0.08))
|
||||
? upColor.withValues(alpha: 0.08)
|
||||
: downColor.withValues(alpha: 0.08))
|
||||
: Colors.transparent,
|
||||
borderRadius: BorderRadius.circular(AppRadius.sm),
|
||||
border: isToday
|
||||
? Border.all(color: colorScheme.primary.withOpacity(0.4), width: 1)
|
||||
? Border.all(color: context.colors.primary.withValues(alpha: 0.4), width: 1)
|
||||
: null,
|
||||
),
|
||||
child: Column(
|
||||
@@ -851,8 +837,8 @@ class _AssetCardState extends State<_AssetCard> {
|
||||
fontSize: 10,
|
||||
fontWeight: isToday ? FontWeight.bold : FontWeight.w400,
|
||||
color: isToday
|
||||
? colorScheme.primary
|
||||
: colorScheme.onSurface,
|
||||
? context.colors.primary
|
||||
: context.colors.onSurface,
|
||||
),
|
||||
),
|
||||
if (hasProfit) ...[
|
||||
@@ -906,9 +892,6 @@ class _WelfareCard extends StatelessWidget {
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final colorScheme = Theme.of(context).colorScheme;
|
||||
final isDark = Theme.of(context).brightness == Brightness.dark;
|
||||
|
||||
return GestureDetector(
|
||||
onTap: onTap,
|
||||
child: Container(
|
||||
@@ -917,14 +900,14 @@ class _WelfareCard extends StatelessWidget {
|
||||
decoration: BoxDecoration(
|
||||
gradient: LinearGradient(
|
||||
colors: [
|
||||
colorScheme.primary.withOpacity(0.15),
|
||||
colorScheme.secondary.withOpacity(0.1),
|
||||
context.colors.primary.withValues(alpha: 0.15),
|
||||
context.colors.secondary.withValues(alpha: 0.1),
|
||||
],
|
||||
begin: Alignment.topLeft,
|
||||
end: Alignment.bottomRight,
|
||||
),
|
||||
borderRadius: BorderRadius.circular(AppRadius.xl),
|
||||
border: Border.all(color: colorScheme.primary.withOpacity(0.2)),
|
||||
border: Border.all(color: context.colors.primary.withValues(alpha: 0.2)),
|
||||
),
|
||||
child: Row(
|
||||
children: [
|
||||
@@ -933,12 +916,12 @@ class _WelfareCard extends StatelessWidget {
|
||||
width: 48,
|
||||
height: 48,
|
||||
decoration: BoxDecoration(
|
||||
color: colorScheme.primary.withOpacity(0.15),
|
||||
color: context.colors.primary.withValues(alpha: 0.15),
|
||||
borderRadius: BorderRadius.circular(AppRadius.lg),
|
||||
),
|
||||
child: Icon(
|
||||
LucideIcons.gift,
|
||||
color: colorScheme.primary,
|
||||
color: context.colors.primary,
|
||||
size: 24,
|
||||
),
|
||||
),
|
||||
@@ -971,9 +954,7 @@ class _WelfareCard extends StatelessWidget {
|
||||
vertical: AppSpacing.sm,
|
||||
),
|
||||
decoration: BoxDecoration(
|
||||
gradient: isDark
|
||||
? AppColorScheme.darkCtaGradient
|
||||
: AppColorScheme.lightCtaGradient,
|
||||
gradient: context.appColors.ctaGradient,
|
||||
borderRadius: BorderRadius.circular(AppRadius.full),
|
||||
),
|
||||
child: Row(
|
||||
@@ -1000,7 +981,7 @@ class _WelfareCard extends StatelessWidget {
|
||||
'查看',
|
||||
style: AppTextStyles.headlineSmall(context).copyWith(
|
||||
fontWeight: FontWeight.w700,
|
||||
color: isDark ? colorScheme.background : AppColorScheme.darkOnPrimary,
|
||||
color: context.colors.onPrimary,
|
||||
),
|
||||
),
|
||||
],
|
||||
@@ -1021,8 +1002,6 @@ class _HoldingsSection extends StatelessWidget {
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final colorScheme = Theme.of(context).colorScheme;
|
||||
|
||||
return Column(
|
||||
children: [
|
||||
Row(
|
||||
@@ -1037,7 +1016,7 @@ class _HoldingsSection extends StatelessWidget {
|
||||
TextButton(
|
||||
onPressed: () {},
|
||||
style: TextButton.styleFrom(
|
||||
foregroundColor: colorScheme.primary,
|
||||
foregroundColor: context.colors.primary,
|
||||
padding: const EdgeInsets.symmetric(horizontal: AppSpacing.sm),
|
||||
),
|
||||
child: Row(
|
||||
@@ -1048,7 +1027,7 @@ class _HoldingsSection extends StatelessWidget {
|
||||
)),
|
||||
const SizedBox(width: AppSpacing.xs),
|
||||
Icon(LucideIcons.chevronRight,
|
||||
size: 16, color: colorScheme.primary),
|
||||
size: 16, color: context.colors.primary),
|
||||
],
|
||||
),
|
||||
),
|
||||
@@ -1067,19 +1046,17 @@ class _EmptyHoldings extends StatelessWidget {
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final colorScheme = Theme.of(context).colorScheme;
|
||||
|
||||
return Container(
|
||||
width: double.infinity,
|
||||
padding: EdgeInsets.symmetric(vertical: AppSpacing.xxl, horizontal: AppSpacing.lg),
|
||||
decoration: BoxDecoration(
|
||||
color: colorScheme.surfaceContainerLow.withOpacity(0.5),
|
||||
color: context.colors.surfaceContainerLow.withValues(alpha: 0.5),
|
||||
borderRadius: BorderRadius.circular(AppRadius.xxl),
|
||||
border: Border.all(color: colorScheme.outlineVariant.withOpacity(0.1)),
|
||||
border: Border.all(color: context.colors.outlineVariant.withValues(alpha: 0.1)),
|
||||
),
|
||||
child: Column(
|
||||
children: [
|
||||
Icon(LucideIcons.wallet, size: 48, color: colorScheme.onSurfaceVariant),
|
||||
Icon(LucideIcons.wallet, size: 48, color: context.colors.onSurfaceVariant),
|
||||
SizedBox(height: AppSpacing.md),
|
||||
Text(
|
||||
'暂无持仓',
|
||||
@@ -1106,15 +1083,14 @@ class _HoldingsList extends StatelessWidget {
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final colorScheme = Theme.of(context).colorScheme;
|
||||
final displayHoldings =
|
||||
holdings.length > 5 ? holdings.sublist(0, 5) : holdings;
|
||||
|
||||
return Container(
|
||||
decoration: BoxDecoration(
|
||||
color: colorScheme.surface.withOpacity(0.5),
|
||||
color: context.colors.surface.withValues(alpha: 0.5),
|
||||
borderRadius: BorderRadius.circular(AppRadius.xxl),
|
||||
border: Border.all(color: colorScheme.outlineVariant.withOpacity(0.1)),
|
||||
border: Border.all(color: context.colors.outlineVariant.withValues(alpha: 0.1)),
|
||||
),
|
||||
child: ListView.separated(
|
||||
shrinkWrap: true,
|
||||
@@ -1122,7 +1098,7 @@ class _HoldingsList extends StatelessWidget {
|
||||
padding: EdgeInsets.all(AppSpacing.md),
|
||||
itemCount: displayHoldings.length,
|
||||
separatorBuilder: (_, __) => Divider(
|
||||
color: colorScheme.outlineVariant.withOpacity(0.1),
|
||||
color: context.colors.outlineVariant.withValues(alpha: 0.1),
|
||||
height: 1,
|
||||
),
|
||||
itemBuilder: (context, index) =>
|
||||
@@ -1140,9 +1116,6 @@ class _HoldingItem extends StatelessWidget {
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final colorScheme = Theme.of(context).colorScheme;
|
||||
final isDark = Theme.of(context).brightness == Brightness.dark;
|
||||
|
||||
return Padding(
|
||||
padding: EdgeInsets.symmetric(vertical: AppSpacing.sm + AppSpacing.xs),
|
||||
child: Row(
|
||||
@@ -1152,11 +1125,11 @@ class _HoldingItem extends StatelessWidget {
|
||||
children: [
|
||||
CircleAvatar(
|
||||
radius: 18,
|
||||
backgroundColor: colorScheme.primary.withOpacity(0.1),
|
||||
backgroundColor: context.colors.primary.withValues(alpha: 0.1),
|
||||
child: Text(
|
||||
holding.coinCode.substring(0, 1),
|
||||
style: AppTextStyles.headlineMedium(context).copyWith(
|
||||
color: colorScheme.primary,
|
||||
color: context.colors.primary,
|
||||
fontWeight: FontWeight.bold,
|
||||
),
|
||||
),
|
||||
@@ -1185,8 +1158,8 @@ class _HoldingItem extends StatelessWidget {
|
||||
Text(holding.formattedProfitRate,
|
||||
style: AppTextStyles.numberSmall(context).copyWith(
|
||||
color: holding.isProfit
|
||||
? AppColorScheme.getUpColor(isDark)
|
||||
: AppColorScheme.getDownColor(isDark),
|
||||
? context.appColors.up
|
||||
: context.appColors.down,
|
||||
)),
|
||||
],
|
||||
),
|
||||
@@ -1206,8 +1179,6 @@ class _InfoRow extends StatelessWidget {
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final colorScheme = Theme.of(context).colorScheme;
|
||||
|
||||
return Row(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
children: [
|
||||
@@ -1232,14 +1203,12 @@ class _WalletAddressCard extends StatelessWidget {
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final colorScheme = Theme.of(context).colorScheme;
|
||||
|
||||
return Container(
|
||||
padding: EdgeInsets.all(AppSpacing.md),
|
||||
decoration: BoxDecoration(
|
||||
color: colorScheme.surfaceContainerHigh,
|
||||
color: context.colors.surfaceContainerHigh,
|
||||
borderRadius: BorderRadius.circular(AppRadius.md),
|
||||
border: Border.all(color: colorScheme.outlineVariant.withOpacity(0.3)),
|
||||
border: Border.all(color: context.colors.outlineVariant.withValues(alpha: 0.3)),
|
||||
),
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
@@ -1262,11 +1231,11 @@ class _WalletAddressCard extends StatelessWidget {
|
||||
child: Container(
|
||||
padding: EdgeInsets.all(AppSpacing.xs),
|
||||
decoration: BoxDecoration(
|
||||
color: colorScheme.primary.withOpacity(0.1),
|
||||
color: context.colors.primary.withValues(alpha: 0.1),
|
||||
borderRadius: BorderRadius.circular(AppRadius.sm),
|
||||
),
|
||||
child: Icon(LucideIcons.copy,
|
||||
size: 16, color: colorScheme.primary),
|
||||
size: 16, color: context.colors.primary),
|
||||
),
|
||||
),
|
||||
],
|
||||
@@ -1298,22 +1267,21 @@ class _ProfitStatCard extends StatelessWidget {
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final colorScheme = Theme.of(context).colorScheme;
|
||||
final hasValue = value != null;
|
||||
final isProfit = (value ?? 0) >= 0;
|
||||
final color = hasValue ? (isProfit ? upColor : downColor) : colorScheme.onSurfaceVariant;
|
||||
final color = hasValue ? (isProfit ? upColor : downColor) : context.colors.onSurfaceVariant;
|
||||
|
||||
return Container(
|
||||
padding: EdgeInsets.symmetric(horizontal: AppSpacing.md, vertical: AppSpacing.sm + 2),
|
||||
decoration: BoxDecoration(
|
||||
color: hasValue
|
||||
? (isProfit ? upColor : downColor).withOpacity(0.06)
|
||||
: colorScheme.surfaceContainerHigh.withOpacity(0.5),
|
||||
? (isProfit ? upColor : downColor).withValues(alpha: 0.06)
|
||||
: context.colors.surfaceContainerHigh.withValues(alpha: 0.5),
|
||||
borderRadius: BorderRadius.circular(AppRadius.lg),
|
||||
border: Border.all(
|
||||
color: hasValue
|
||||
? (isProfit ? upColor : downColor).withOpacity(0.12)
|
||||
: colorScheme.outlineVariant.withOpacity(0.1),
|
||||
? (isProfit ? upColor : downColor).withValues(alpha: 0.12)
|
||||
: context.colors.outlineVariant.withValues(alpha: 0.1),
|
||||
),
|
||||
),
|
||||
child: Column(
|
||||
@@ -1326,14 +1294,14 @@ class _ProfitStatCard extends StatelessWidget {
|
||||
? (isProfit ? LucideIcons.trendingUp : LucideIcons.trendingDown)
|
||||
: LucideIcons.minus,
|
||||
size: 11,
|
||||
color: color.withOpacity(0.7),
|
||||
color: color.withValues(alpha: 0.7),
|
||||
),
|
||||
SizedBox(width: 3),
|
||||
Text(
|
||||
label,
|
||||
style: AppTextStyles.bodySmall(context).copyWith(
|
||||
fontWeight: FontWeight.w500,
|
||||
color: color.withOpacity(0.8),
|
||||
color: color.withValues(alpha: 0.8),
|
||||
),
|
||||
),
|
||||
],
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:shadcn_ui/shadcn_ui.dart';
|
||||
import '../../../core/theme/app_theme.dart';
|
||||
import '../../../core/theme/app_color_scheme.dart';
|
||||
import '../../../core/theme/app_spacing.dart';
|
||||
import '../../../core/theme/app_theme_extension.dart';
|
||||
|
||||
/// 首页热门币种区块
|
||||
class HotCoinsSection extends StatelessWidget {
|
||||
@@ -10,9 +10,6 @@ class HotCoinsSection extends StatelessWidget {
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final colorScheme = Theme.of(context).colorScheme;
|
||||
final isDark = Theme.of(context).brightness == Brightness.dark;
|
||||
|
||||
return Column(
|
||||
children: [
|
||||
// Title row
|
||||
@@ -36,9 +33,9 @@ class HotCoinsSection extends StatelessWidget {
|
||||
// Card
|
||||
Container(
|
||||
decoration: BoxDecoration(
|
||||
color: colorScheme.surfaceContainer,
|
||||
color: context.colors.surfaceContainer,
|
||||
border: Border.all(
|
||||
color: colorScheme.outlineVariant,
|
||||
color: context.colors.outlineVariant,
|
||||
width: 1,
|
||||
),
|
||||
borderRadius: BorderRadius.circular(AppRadius.xl),
|
||||
@@ -52,13 +49,11 @@ class HotCoinsSection extends StatelessWidget {
|
||||
price: '68,432.50',
|
||||
change: '+2.35%',
|
||||
isUp: true,
|
||||
colorScheme: colorScheme,
|
||||
isDark: isDark,
|
||||
),
|
||||
Divider(
|
||||
height: 1,
|
||||
thickness: 1,
|
||||
color: colorScheme.outlineVariant.withValues(alpha: 0.15),
|
||||
color: context.appColors.ghostBorder,
|
||||
),
|
||||
_CoinRow(
|
||||
symbol: 'ETH',
|
||||
@@ -67,13 +62,11 @@ class HotCoinsSection extends StatelessWidget {
|
||||
price: '3,856.20',
|
||||
change: '+1.82%',
|
||||
isUp: true,
|
||||
colorScheme: colorScheme,
|
||||
isDark: isDark,
|
||||
),
|
||||
Divider(
|
||||
height: 1,
|
||||
thickness: 1,
|
||||
color: colorScheme.outlineVariant.withValues(alpha: 0.15),
|
||||
color: context.appColors.ghostBorder,
|
||||
),
|
||||
_CoinRow(
|
||||
symbol: 'SOL',
|
||||
@@ -82,8 +75,6 @@ class HotCoinsSection extends StatelessWidget {
|
||||
price: '178.65',
|
||||
change: '-0.94%',
|
||||
isUp: false,
|
||||
colorScheme: colorScheme,
|
||||
isDark: isDark,
|
||||
),
|
||||
],
|
||||
),
|
||||
@@ -101,8 +92,6 @@ class _CoinRow extends StatelessWidget {
|
||||
required this.price,
|
||||
required this.change,
|
||||
required this.isUp,
|
||||
required this.colorScheme,
|
||||
required this.isDark,
|
||||
});
|
||||
|
||||
final String symbol;
|
||||
@@ -111,14 +100,12 @@ class _CoinRow extends StatelessWidget {
|
||||
final String price;
|
||||
final String change;
|
||||
final bool isUp;
|
||||
final ColorScheme colorScheme;
|
||||
final bool isDark;
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final changeColor = isUp
|
||||
? AppColorScheme.getUpColor(isDark)
|
||||
: AppColorScheme.getDownColor(isDark);
|
||||
? context.appColors.up
|
||||
: context.appColors.down;
|
||||
|
||||
return Padding(
|
||||
padding: const EdgeInsets.symmetric(vertical: 14, horizontal: AppSpacing.md),
|
||||
@@ -130,13 +117,13 @@ class _CoinRow extends StatelessWidget {
|
||||
children: [
|
||||
CircleAvatar(
|
||||
radius: 18,
|
||||
backgroundColor: colorScheme.primary.withValues(alpha: 0.1),
|
||||
backgroundColor: context.colors.primary.withValues(alpha: 0.1),
|
||||
child: Text(
|
||||
symbol,
|
||||
style: AppTextStyles.bodySmall(context).copyWith(
|
||||
fontSize: 10,
|
||||
fontWeight: FontWeight.w700,
|
||||
color: colorScheme.primary,
|
||||
color: context.colors.primary,
|
||||
),
|
||||
),
|
||||
),
|
||||
|
||||
@@ -2,8 +2,8 @@ import 'package:flutter/material.dart';
|
||||
import 'package:provider/provider.dart';
|
||||
import 'package:lucide_icons_flutter/lucide_icons.dart';
|
||||
import '../../../core/theme/app_theme.dart';
|
||||
import '../../../core/theme/app_color_scheme.dart';
|
||||
import '../../../core/theme/app_spacing.dart';
|
||||
import '../../../core/theme/app_theme_extension.dart';
|
||||
import '../../../data/services/asset_service.dart';
|
||||
|
||||
/// 盈亏分析页面 - 月度盈亏日历
|
||||
@@ -26,26 +26,6 @@ class _ProfitAnalysisPageState extends State<ProfitAnalysisPage> {
|
||||
WidgetsBinding.instance.addPostFrameCallback((_) => _loadProfit());
|
||||
}
|
||||
|
||||
// ============================================
|
||||
// 主题感知颜色
|
||||
// ============================================
|
||||
|
||||
bool get _isDark => Theme.of(context).brightness == Brightness.dark;
|
||||
|
||||
Color get _upColor => AppColorScheme.getUpColor(_isDark);
|
||||
Color get _downColor => AppColorScheme.getDownColor(_isDark);
|
||||
|
||||
Color get _scaffoldBg =>
|
||||
_isDark ? AppColorScheme.darkBackground : AppColorScheme.lightBackground;
|
||||
|
||||
Color get _cardBg => _isDark
|
||||
? AppColorScheme.darkSurfaceContainer
|
||||
: AppColorScheme.lightSurfaceLowest;
|
||||
|
||||
Color get _cardBorder => _isDark
|
||||
? AppColorScheme.darkOutlineVariant.withValues(alpha: 0.15)
|
||||
: AppColorScheme.lightOutlineVariant.withValues(alpha: 0.5);
|
||||
|
||||
// ============================================
|
||||
// 数据加载
|
||||
// ============================================
|
||||
@@ -111,16 +91,15 @@ class _ProfitAnalysisPageState extends State<ProfitAnalysisPage> {
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final colorScheme = Theme.of(context).colorScheme;
|
||||
final now = DateTime.now();
|
||||
final isCurrentMonth =
|
||||
_currentMonth.year == now.year && _currentMonth.month == now.month;
|
||||
|
||||
return Scaffold(
|
||||
backgroundColor: _scaffoldBg,
|
||||
backgroundColor: context.colors.surface,
|
||||
appBar: AppBar(
|
||||
title: const Text('盈亏分析'),
|
||||
backgroundColor: _scaffoldBg,
|
||||
backgroundColor: context.colors.surface,
|
||||
elevation: 0,
|
||||
scrolledUnderElevation: 0,
|
||||
centerTitle: true,
|
||||
@@ -130,31 +109,30 @@ class _ProfitAnalysisPageState extends State<ProfitAnalysisPage> {
|
||||
child: Container(
|
||||
padding: EdgeInsets.all(AppSpacing.lg),
|
||||
decoration: BoxDecoration(
|
||||
color: _cardBg,
|
||||
color: context.appColors.surfaceCard,
|
||||
borderRadius: BorderRadius.circular(AppRadius.xl),
|
||||
border: Border.all(color: _cardBorder),
|
||||
border: Border.all(color: context.appColors.ghostBorder),
|
||||
),
|
||||
child: Column(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: [
|
||||
// 月度盈亏摘要
|
||||
_buildSummarySection(colorScheme),
|
||||
_buildSummarySection(),
|
||||
SizedBox(height: AppSpacing.md),
|
||||
|
||||
// 月份导航
|
||||
_buildMonthNavigation(colorScheme, isCurrentMonth),
|
||||
_buildMonthNavigation(isCurrentMonth),
|
||||
SizedBox(height: AppSpacing.sm),
|
||||
|
||||
// 星期标题
|
||||
_buildWeekdayHeaders(colorScheme),
|
||||
_buildWeekdayHeaders(),
|
||||
SizedBox(height: AppSpacing.xs),
|
||||
|
||||
// 日历网格
|
||||
if (_isLoading)
|
||||
_buildLoadingIndicator(colorScheme)
|
||||
_buildLoadingIndicator()
|
||||
else
|
||||
..._buildCalendarGrid(
|
||||
colorScheme,
|
||||
now,
|
||||
isCurrentMonth,
|
||||
),
|
||||
@@ -166,16 +144,18 @@ class _ProfitAnalysisPageState extends State<ProfitAnalysisPage> {
|
||||
}
|
||||
|
||||
/// 月度盈亏摘要
|
||||
Widget _buildSummarySection(ColorScheme colorScheme) {
|
||||
Widget _buildSummarySection() {
|
||||
final upColor = context.appColors.up;
|
||||
final downColor = context.appColors.down;
|
||||
final isProfit = _monthProfit >= 0;
|
||||
final color = _isLoading ? colorScheme.onSurfaceVariant : (isProfit ? _upColor : _downColor);
|
||||
final color = _isLoading ? context.colors.onSurfaceVariant : (isProfit ? upColor : downColor);
|
||||
|
||||
return Column(
|
||||
children: [
|
||||
Text(
|
||||
'月度盈亏',
|
||||
style: AppTextStyles.bodyMedium(context).copyWith(
|
||||
color: colorScheme.onSurfaceVariant,
|
||||
color: context.colors.onSurfaceVariant,
|
||||
),
|
||||
),
|
||||
SizedBox(height: AppSpacing.xs),
|
||||
@@ -193,7 +173,7 @@ class _ProfitAnalysisPageState extends State<ProfitAnalysisPage> {
|
||||
}
|
||||
|
||||
/// 月份导航行
|
||||
Widget _buildMonthNavigation(ColorScheme colorScheme, bool isCurrentMonth) {
|
||||
Widget _buildMonthNavigation(bool isCurrentMonth) {
|
||||
return Row(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
children: [
|
||||
@@ -203,13 +183,13 @@ class _ProfitAnalysisPageState extends State<ProfitAnalysisPage> {
|
||||
child: Container(
|
||||
padding: EdgeInsets.all(AppSpacing.xs + 1),
|
||||
decoration: BoxDecoration(
|
||||
color: colorScheme.surfaceContainerHigh,
|
||||
color: context.colors.surfaceContainerHigh,
|
||||
borderRadius: BorderRadius.circular(AppRadius.sm),
|
||||
),
|
||||
child: Icon(
|
||||
LucideIcons.chevronLeft,
|
||||
size: 16,
|
||||
color: colorScheme.onSurfaceVariant,
|
||||
color: context.colors.onSurfaceVariant,
|
||||
),
|
||||
),
|
||||
),
|
||||
@@ -227,16 +207,16 @@ class _ProfitAnalysisPageState extends State<ProfitAnalysisPage> {
|
||||
padding: EdgeInsets.all(AppSpacing.xs + 1),
|
||||
decoration: BoxDecoration(
|
||||
color: isCurrentMonth
|
||||
? colorScheme.surfaceContainerHigh.withValues(alpha: 0.5)
|
||||
: colorScheme.surfaceContainerHigh,
|
||||
? context.colors.surfaceContainerHigh.withValues(alpha: 0.5)
|
||||
: context.colors.surfaceContainerHigh,
|
||||
borderRadius: BorderRadius.circular(AppRadius.sm),
|
||||
),
|
||||
child: Icon(
|
||||
LucideIcons.chevronRight,
|
||||
size: 16,
|
||||
color: isCurrentMonth
|
||||
? colorScheme.onSurfaceVariant.withValues(alpha: 0.4)
|
||||
: colorScheme.onSurfaceVariant,
|
||||
? context.colors.onSurfaceVariant.withValues(alpha: 0.4)
|
||||
: context.colors.onSurfaceVariant,
|
||||
),
|
||||
),
|
||||
),
|
||||
@@ -245,7 +225,7 @@ class _ProfitAnalysisPageState extends State<ProfitAnalysisPage> {
|
||||
}
|
||||
|
||||
/// 星期标题行
|
||||
Widget _buildWeekdayHeaders(ColorScheme colorScheme) {
|
||||
Widget _buildWeekdayHeaders() {
|
||||
return Row(
|
||||
children: ['一', '二', '三', '四', '五', '六', '日'].map((d) {
|
||||
return Expanded(
|
||||
@@ -254,7 +234,7 @@ class _ProfitAnalysisPageState extends State<ProfitAnalysisPage> {
|
||||
d,
|
||||
style: AppTextStyles.bodySmall(context).copyWith(
|
||||
fontWeight: FontWeight.w500,
|
||||
color: colorScheme.onSurfaceVariant.withValues(alpha: 0.6),
|
||||
color: context.colors.onSurfaceVariant.withValues(alpha: 0.6),
|
||||
),
|
||||
),
|
||||
),
|
||||
@@ -264,7 +244,7 @@ class _ProfitAnalysisPageState extends State<ProfitAnalysisPage> {
|
||||
}
|
||||
|
||||
/// 加载指示器
|
||||
Widget _buildLoadingIndicator(ColorScheme colorScheme) {
|
||||
Widget _buildLoadingIndicator() {
|
||||
return Padding(
|
||||
padding: EdgeInsets.symmetric(vertical: AppSpacing.xxl),
|
||||
child: Center(
|
||||
@@ -273,7 +253,7 @@ class _ProfitAnalysisPageState extends State<ProfitAnalysisPage> {
|
||||
height: 20,
|
||||
child: CircularProgressIndicator(
|
||||
strokeWidth: 2,
|
||||
color: colorScheme.primary,
|
||||
color: context.colors.primary,
|
||||
),
|
||||
),
|
||||
),
|
||||
@@ -282,10 +262,11 @@ class _ProfitAnalysisPageState extends State<ProfitAnalysisPage> {
|
||||
|
||||
/// 日历网格
|
||||
List<Widget> _buildCalendarGrid(
|
||||
ColorScheme colorScheme,
|
||||
DateTime now,
|
||||
bool isCurrentMonth,
|
||||
) {
|
||||
final upColor = context.appColors.up;
|
||||
final downColor = context.appColors.down;
|
||||
final firstDayOfMonth = DateTime(_currentMonth.year, _currentMonth.month, 1);
|
||||
final daysInMonth =
|
||||
DateTime(_currentMonth.year, _currentMonth.month + 1, 0).day;
|
||||
@@ -313,16 +294,16 @@ class _ProfitAnalysisPageState extends State<ProfitAnalysisPage> {
|
||||
margin: EdgeInsets.all(1),
|
||||
decoration: BoxDecoration(
|
||||
color: isToday
|
||||
? colorScheme.primary.withValues(alpha: 0.12)
|
||||
? context.colors.primary.withValues(alpha: 0.12)
|
||||
: hasProfit
|
||||
? (profit! > 0
|
||||
? _upColor.withValues(alpha: 0.08)
|
||||
: _downColor.withValues(alpha: 0.08))
|
||||
? upColor.withValues(alpha: 0.08)
|
||||
: downColor.withValues(alpha: 0.08))
|
||||
: Colors.transparent,
|
||||
borderRadius: BorderRadius.circular(AppRadius.sm),
|
||||
border: isToday
|
||||
? Border.all(
|
||||
color: colorScheme.primary.withValues(alpha: 0.4),
|
||||
color: context.colors.primary.withValues(alpha: 0.4),
|
||||
width: 1,
|
||||
)
|
||||
: null,
|
||||
@@ -336,8 +317,8 @@ class _ProfitAnalysisPageState extends State<ProfitAnalysisPage> {
|
||||
fontSize: 10,
|
||||
fontWeight: isToday ? FontWeight.bold : FontWeight.w400,
|
||||
color: isToday
|
||||
? colorScheme.primary
|
||||
: colorScheme.onSurface,
|
||||
? context.colors.primary
|
||||
: context.colors.onSurface,
|
||||
),
|
||||
),
|
||||
if (hasProfit) ...[
|
||||
@@ -347,7 +328,7 @@ class _ProfitAnalysisPageState extends State<ProfitAnalysisPage> {
|
||||
style: TextStyle(
|
||||
fontSize: 7,
|
||||
fontWeight: FontWeight.w600,
|
||||
color: profit > 0 ? _upColor : _downColor,
|
||||
color: profit > 0 ? upColor : downColor,
|
||||
),
|
||||
maxLines: 1,
|
||||
overflow: TextOverflow.ellipsis,
|
||||
|
||||
@@ -2,9 +2,9 @@ import 'dart:math';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:shadcn_ui/shadcn_ui.dart';
|
||||
import 'package:provider/provider.dart';
|
||||
import '../../../core/theme/app_color_scheme.dart';
|
||||
import '../../../core/theme/app_spacing.dart';
|
||||
import '../../../core/theme/app_theme.dart';
|
||||
import '../../../core/theme/app_theme_extension.dart';
|
||||
import '../../../data/models/coin.dart';
|
||||
import '../../../providers/market_provider.dart';
|
||||
import '../../components/glass_panel.dart';
|
||||
@@ -34,10 +34,9 @@ class _MarketPageState extends State<MarketPage>
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
super.build(context);
|
||||
final colorScheme = Theme.of(context).colorScheme;
|
||||
|
||||
return Scaffold(
|
||||
backgroundColor: colorScheme.background,
|
||||
backgroundColor: context.colors.surface,
|
||||
body: Consumer<MarketProvider>(
|
||||
builder: (context, provider, _) {
|
||||
if (provider.isLoading) {
|
||||
@@ -50,8 +49,8 @@ class _MarketPageState extends State<MarketPage>
|
||||
|
||||
return RefreshIndicator(
|
||||
onRefresh: () => provider.refresh(),
|
||||
color: colorScheme.primary,
|
||||
backgroundColor: colorScheme.surfaceContainerHighest,
|
||||
color: context.colors.primary,
|
||||
backgroundColor: context.colors.surfaceContainerHighest,
|
||||
child: SingleChildScrollView(
|
||||
physics: const AlwaysScrollableScrollPhysics(),
|
||||
padding: const EdgeInsets.only(
|
||||
@@ -114,8 +113,6 @@ class _MarketPageState extends State<MarketPage>
|
||||
|
||||
/// 分区标题:全部币种 + 更多
|
||||
Widget _buildSectionHeader() {
|
||||
final colorScheme = Theme.of(context).colorScheme;
|
||||
|
||||
return Row(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
children: [
|
||||
@@ -126,7 +123,7 @@ class _MarketPageState extends State<MarketPage>
|
||||
Text(
|
||||
'更多 >',
|
||||
style: AppTextStyles.bodyMedium(context).copyWith(
|
||||
color: colorScheme.onSurfaceVariant,
|
||||
color: context.colors.onSurfaceVariant,
|
||||
),
|
||||
),
|
||||
],
|
||||
@@ -136,7 +133,6 @@ class _MarketPageState extends State<MarketPage>
|
||||
/// 币种列表
|
||||
Widget _buildCoinList(MarketProvider provider) {
|
||||
final coins = provider.otherCoins;
|
||||
final colorScheme = Theme.of(context).colorScheme;
|
||||
|
||||
if (coins.isEmpty) {
|
||||
return _EmptyState(
|
||||
@@ -148,10 +144,10 @@ class _MarketPageState extends State<MarketPage>
|
||||
|
||||
return Container(
|
||||
decoration: BoxDecoration(
|
||||
color: colorScheme.surfaceContainer,
|
||||
color: context.colors.surfaceContainer,
|
||||
borderRadius: BorderRadius.circular(AppRadius.lg),
|
||||
border: Border.all(
|
||||
color: colorScheme.outlineVariant.withValues(alpha: 0.15),
|
||||
color: context.appColors.ghostBorder,
|
||||
width: 1,
|
||||
),
|
||||
),
|
||||
@@ -162,7 +158,7 @@ class _MarketPageState extends State<MarketPage>
|
||||
separatorBuilder: (_, __) => Divider(
|
||||
height: 1,
|
||||
thickness: 1,
|
||||
color: colorScheme.outlineVariant.withValues(alpha: 0.5 * 0.15),
|
||||
color: context.colors.outlineVariant.withValues(alpha: 0.5 * 0.15),
|
||||
indent: AppSpacing.md,
|
||||
endIndent: AppSpacing.md,
|
||||
),
|
||||
@@ -173,18 +169,17 @@ class _MarketPageState extends State<MarketPage>
|
||||
|
||||
/// 错误状态
|
||||
Widget _buildErrorState(MarketProvider provider) {
|
||||
final colorScheme = Theme.of(context).colorScheme;
|
||||
return Center(
|
||||
child: Padding(
|
||||
padding: AppSpacing.pagePadding,
|
||||
child: Column(
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
children: [
|
||||
Icon(LucideIcons.circleAlert, size: 48, color: colorScheme.error),
|
||||
Icon(LucideIcons.circleAlert, size: 48, color: context.colors.error),
|
||||
const SizedBox(height: AppSpacing.md),
|
||||
Text(
|
||||
provider.error ?? '加载失败',
|
||||
style: TextStyle(color: colorScheme.error),
|
||||
style: TextStyle(color: context.colors.error),
|
||||
textAlign: TextAlign.center,
|
||||
),
|
||||
const SizedBox(height: AppSpacing.md),
|
||||
@@ -207,14 +202,12 @@ class _FeaturedCard extends StatelessWidget {
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final colorScheme = Theme.of(context).colorScheme;
|
||||
final isDark = Theme.of(context).brightness == Brightness.dark;
|
||||
final isUp = coin.isUp;
|
||||
final changeColor =
|
||||
isUp ? AppColorScheme.getUpColor(isDark) : AppColorScheme.down;
|
||||
isUp ? context.appColors.up : context.appColors.down;
|
||||
final changeBgColor = isUp
|
||||
? AppColorScheme.getUpBackgroundColor(isDark)
|
||||
: AppColorScheme.getDownBackgroundColor(isDark);
|
||||
? context.appColors.upBackground
|
||||
: context.appColors.downBackground;
|
||||
|
||||
return GlassPanel(
|
||||
padding: const EdgeInsets.all(AppSpacing.md),
|
||||
@@ -255,12 +248,12 @@ class _FeaturedCard extends StatelessWidget {
|
||||
Text(
|
||||
coin.name,
|
||||
style: AppTextStyles.bodyMedium(context).copyWith(
|
||||
color: colorScheme.onSurfaceVariant,
|
||||
color: context.colors.onSurfaceVariant,
|
||||
),
|
||||
),
|
||||
// 第四行:迷你柱状图
|
||||
Expanded(
|
||||
child: _MiniBarChart(isUp: isUp, isDark: isDark, seed: coin.code.hashCode),
|
||||
child: _MiniBarChart(isUp: isUp, seed: coin.code.hashCode),
|
||||
),
|
||||
],
|
||||
),
|
||||
@@ -295,16 +288,15 @@ class _FeaturedCard extends StatelessWidget {
|
||||
/// 迷你柱状图(模拟价格走势)
|
||||
class _MiniBarChart extends StatelessWidget {
|
||||
final bool isUp;
|
||||
final bool isDark;
|
||||
final int seed;
|
||||
|
||||
const _MiniBarChart({required this.isUp, required this.isDark, required this.seed});
|
||||
const _MiniBarChart({required this.isUp, required this.seed});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final barColor = isUp
|
||||
? AppColorScheme.getUpColor(isDark)
|
||||
: AppColorScheme.getDownColor(isDark);
|
||||
? context.appColors.up
|
||||
: context.appColors.down;
|
||||
|
||||
// 生成随机但确定的高度序列
|
||||
final heights = _generateHeights();
|
||||
@@ -345,14 +337,12 @@ class _CoinRow extends StatelessWidget {
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final colorScheme = Theme.of(context).colorScheme;
|
||||
final isDark = Theme.of(context).brightness == Brightness.dark;
|
||||
final isUp = coin.isUp;
|
||||
final changeColor =
|
||||
isUp ? AppColorScheme.getUpColor(isDark) : AppColorScheme.getDownColor(isDark);
|
||||
isUp ? context.appColors.up : context.appColors.down;
|
||||
final changeBgColor = isUp
|
||||
? AppColorScheme.getUpBackgroundColor(isDark)
|
||||
: AppColorScheme.getDownBackgroundColor(isDark);
|
||||
? context.appColors.upBackground
|
||||
: context.appColors.downBackground;
|
||||
|
||||
return GestureDetector(
|
||||
onTap: () => _navigateToTrade(context),
|
||||
@@ -428,12 +418,8 @@ class _CoinAvatar extends StatelessWidget {
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final colorScheme = Theme.of(context).colorScheme;
|
||||
final isDark = Theme.of(context).brightness == Brightness.dark;
|
||||
|
||||
// 从 .pen 设计中的 accent-light 和 accent-primary
|
||||
final bgColor = colorScheme.primary.withValues(alpha: isDark ? 0.15 : 0.1);
|
||||
final textColor = colorScheme.primary;
|
||||
final bgColor = context.colors.primary.withValues(alpha: context.appColors.glowOpacity);
|
||||
|
||||
return Container(
|
||||
width: 36,
|
||||
@@ -447,7 +433,7 @@ class _CoinAvatar extends StatelessWidget {
|
||||
_getLetter(),
|
||||
style: AppTextStyles.labelLarge(context).copyWith(
|
||||
fontWeight: FontWeight.w700,
|
||||
color: textColor,
|
||||
color: context.colors.primary,
|
||||
),
|
||||
),
|
||||
),
|
||||
@@ -477,18 +463,16 @@ class _EmptyState extends StatelessWidget {
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final colorScheme = Theme.of(context).colorScheme;
|
||||
|
||||
return Center(
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.all(AppSpacing.xl),
|
||||
child: Column(
|
||||
children: [
|
||||
Icon(icon, size: 48, color: colorScheme.onSurfaceVariant),
|
||||
Icon(icon, size: 48, color: context.colors.onSurfaceVariant),
|
||||
const SizedBox(height: AppSpacing.sm + AppSpacing.xs),
|
||||
Text(
|
||||
message,
|
||||
style: TextStyle(color: colorScheme.onSurfaceVariant),
|
||||
style: TextStyle(color: context.colors.onSurfaceVariant),
|
||||
),
|
||||
if (onRetry != null) ...[
|
||||
const SizedBox(height: AppSpacing.md),
|
||||
|
||||
@@ -3,6 +3,7 @@ import 'package:lucide_icons_flutter/lucide_icons.dart';
|
||||
import 'package:shadcn_ui/shadcn_ui.dart';
|
||||
import '../../../../core/theme/app_color_scheme.dart';
|
||||
import '../../../../core/theme/app_spacing.dart';
|
||||
import '../../../../core/theme/app_theme_extension.dart';
|
||||
import '../kyc_page.dart';
|
||||
import '../welfare_center_page.dart';
|
||||
import 'menu_group_container.dart';
|
||||
@@ -22,9 +23,6 @@ class MenuGroup1 extends StatelessWidget {
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final colorScheme = Theme.of(context).colorScheme;
|
||||
final isDark = Theme.of(context).brightness == Brightness.dark;
|
||||
|
||||
return MenuGroupContainer(
|
||||
child: Column(
|
||||
children: [
|
||||
@@ -44,7 +42,7 @@ class MenuGroup1 extends StatelessWidget {
|
||||
// 实名认证
|
||||
MenuRow(
|
||||
icon: LucideIcons.shieldCheck,
|
||||
iconColor: AppColorScheme.getUpColor(isDark),
|
||||
iconColor: context.appColors.up,
|
||||
title: '实名认证',
|
||||
trailing: KycBadge(kycStatus: kycStatus),
|
||||
onTap: () {
|
||||
@@ -62,7 +60,7 @@ class MenuGroup1 extends StatelessWidget {
|
||||
// 安全设置
|
||||
MenuRow(
|
||||
icon: LucideIcons.lock,
|
||||
iconColor: colorScheme.onSurfaceVariant,
|
||||
iconColor: context.colors.onSurfaceVariant,
|
||||
title: '安全设置',
|
||||
onTap: () => onShowComingSoon('安全设置'),
|
||||
),
|
||||
@@ -70,7 +68,7 @@ class MenuGroup1 extends StatelessWidget {
|
||||
// 消息通知
|
||||
MenuRow(
|
||||
icon: LucideIcons.bell,
|
||||
iconColor: colorScheme.onSurfaceVariant,
|
||||
iconColor: context.colors.onSurfaceVariant,
|
||||
title: '消息通知',
|
||||
trailing: const RedDotIndicator(),
|
||||
onTap: () => onShowComingSoon('消息通知'),
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import '../../../../core/theme/app_spacing.dart';
|
||||
import '../../../../core/theme/app_theme_extension.dart';
|
||||
|
||||
/// 菜单分组容器 - 统一的圆角卡片样式
|
||||
///
|
||||
@@ -12,19 +13,14 @@ class MenuGroupContainer extends StatelessWidget {
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final colorScheme = Theme.of(context).colorScheme;
|
||||
final isDark = Theme.of(context).brightness == Brightness.dark;
|
||||
|
||||
return Container(
|
||||
width: double.infinity,
|
||||
clipBehavior: Clip.antiAlias,
|
||||
decoration: BoxDecoration(
|
||||
color: isDark
|
||||
? colorScheme.surfaceContainer
|
||||
: colorScheme.surfaceContainerHigh,
|
||||
color: context.appColors.surfaceCard,
|
||||
borderRadius: BorderRadius.circular(AppRadius.lg),
|
||||
border: Border.all(
|
||||
color: colorScheme.outlineVariant.withOpacity(0.15),
|
||||
color: context.appColors.ghostBorder,
|
||||
),
|
||||
),
|
||||
child: child,
|
||||
|
||||
@@ -4,6 +4,7 @@ import 'package:provider/provider.dart';
|
||||
import '../../../../core/theme/app_color_scheme.dart';
|
||||
import '../../../../core/theme/app_spacing.dart';
|
||||
import '../../../../core/theme/app_theme.dart';
|
||||
import '../../../../core/theme/app_theme_extension.dart';
|
||||
import '../../../../providers/theme_provider.dart';
|
||||
|
||||
/// KYC 状态徽章 (e.g. "已认证" green badge + chevron)
|
||||
@@ -18,9 +19,7 @@ class KycBadge extends StatelessWidget {
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final isDark = Theme.of(context).brightness == Brightness.dark;
|
||||
final green = AppColorScheme.getUpColor(isDark);
|
||||
final colorScheme = Theme.of(context).colorScheme;
|
||||
final green = context.appColors.up;
|
||||
|
||||
if (kycStatus == 2) {
|
||||
return Row(
|
||||
@@ -43,7 +42,7 @@ class KycBadge extends StatelessWidget {
|
||||
Icon(
|
||||
LucideIcons.chevronRight,
|
||||
size: 16,
|
||||
color: colorScheme.onSurfaceVariant,
|
||||
color: context.colors.onSurfaceVariant,
|
||||
),
|
||||
],
|
||||
);
|
||||
@@ -70,7 +69,7 @@ class KycBadge extends StatelessWidget {
|
||||
Icon(
|
||||
LucideIcons.chevronRight,
|
||||
size: 16,
|
||||
color: colorScheme.onSurfaceVariant,
|
||||
color: context.colors.onSurfaceVariant,
|
||||
),
|
||||
],
|
||||
);
|
||||
@@ -79,7 +78,7 @@ class KycBadge extends StatelessWidget {
|
||||
return Icon(
|
||||
LucideIcons.chevronRight,
|
||||
size: 16,
|
||||
color: colorScheme.onSurfaceVariant,
|
||||
color: context.colors.onSurfaceVariant,
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -105,7 +104,7 @@ class RedDotIndicator extends StatelessWidget {
|
||||
Icon(
|
||||
LucideIcons.chevronRight,
|
||||
size: 16,
|
||||
color: Theme.of(context).colorScheme.onSurfaceVariant,
|
||||
color: context.colors.onSurfaceVariant,
|
||||
),
|
||||
],
|
||||
);
|
||||
@@ -118,8 +117,6 @@ class DarkModeRow extends StatelessWidget {
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final colorScheme = Theme.of(context).colorScheme;
|
||||
final isDark = Theme.of(context).brightness == Brightness.dark;
|
||||
final themeProvider = context.watch<ThemeProvider>();
|
||||
|
||||
return Padding(
|
||||
@@ -131,16 +128,14 @@ class DarkModeRow extends StatelessWidget {
|
||||
width: 36,
|
||||
height: 36,
|
||||
decoration: BoxDecoration(
|
||||
color: isDark
|
||||
? colorScheme.surfaceContainerHigh
|
||||
: colorScheme.surfaceContainerHighest,
|
||||
color: context.appColors.surfaceCardHigh,
|
||||
borderRadius: BorderRadius.circular(8),
|
||||
),
|
||||
child: Center(
|
||||
child: Icon(
|
||||
LucideIcons.moon,
|
||||
size: 18,
|
||||
color: colorScheme.onSurfaceVariant,
|
||||
color: context.colors.onSurfaceVariant,
|
||||
),
|
||||
),
|
||||
),
|
||||
@@ -160,9 +155,7 @@ class DarkModeRow extends StatelessWidget {
|
||||
height: 24,
|
||||
padding: const EdgeInsets.all(2),
|
||||
decoration: BoxDecoration(
|
||||
color: isDark
|
||||
? colorScheme.surfaceContainerHigh
|
||||
: colorScheme.surfaceContainerHighest,
|
||||
color: context.appColors.surfaceCardHigh,
|
||||
borderRadius: BorderRadius.circular(12),
|
||||
),
|
||||
child: AnimatedAlign(
|
||||
@@ -174,7 +167,7 @@ class DarkModeRow extends StatelessWidget {
|
||||
width: 20,
|
||||
height: 20,
|
||||
decoration: BoxDecoration(
|
||||
color: colorScheme.onSurface,
|
||||
color: context.colors.onSurface,
|
||||
shape: BoxShape.circle,
|
||||
),
|
||||
),
|
||||
|
||||
@@ -2,6 +2,7 @@ import 'package:flutter/material.dart';
|
||||
import 'package:lucide_icons_flutter/lucide_icons.dart';
|
||||
import '../../../../core/theme/app_spacing.dart';
|
||||
import '../../../../core/theme/app_theme.dart';
|
||||
import '../../../../core/theme/app_theme_extension.dart';
|
||||
import 'avatar_circle.dart';
|
||||
|
||||
/// 用户资料卡片 - 头像 + 用户名 + 徽章 + chevron
|
||||
@@ -11,19 +12,14 @@ class ProfileCard extends StatelessWidget {
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final colorScheme = Theme.of(context).colorScheme;
|
||||
final isDark = Theme.of(context).brightness == Brightness.dark;
|
||||
|
||||
return Container(
|
||||
width: double.infinity,
|
||||
padding: const EdgeInsets.all(20),
|
||||
decoration: BoxDecoration(
|
||||
color: isDark
|
||||
? colorScheme.surfaceContainer
|
||||
: colorScheme.surfaceContainerHigh,
|
||||
color: context.appColors.surfaceCard,
|
||||
borderRadius: BorderRadius.circular(AppRadius.lg),
|
||||
border: Border.all(
|
||||
color: colorScheme.outlineVariant.withValues(alpha: 0.15),
|
||||
color: context.appColors.ghostBorder,
|
||||
),
|
||||
),
|
||||
child: Row(
|
||||
@@ -58,7 +54,7 @@ class ProfileCard extends StatelessWidget {
|
||||
Icon(
|
||||
LucideIcons.chevronRight,
|
||||
size: 16,
|
||||
color: colorScheme.onSurfaceVariant,
|
||||
color: context.colors.onSurfaceVariant,
|
||||
),
|
||||
],
|
||||
),
|
||||
|
||||
@@ -2,9 +2,9 @@ import 'package:flutter/material.dart';
|
||||
import 'package:flutter/services.dart';
|
||||
import 'package:shadcn_ui/shadcn_ui.dart';
|
||||
import 'package:provider/provider.dart';
|
||||
import '../../../core/theme/app_color_scheme.dart';
|
||||
import '../../../core/theme/app_spacing.dart';
|
||||
import '../../../core/theme/app_theme.dart';
|
||||
import '../../../core/theme/app_theme_extension.dart';
|
||||
import '../../../core/utils/toast_utils.dart';
|
||||
import '../../../core/event/app_event_bus.dart';
|
||||
import '../../../data/services/bonus_service.dart';
|
||||
@@ -43,70 +43,36 @@ class _WelfareCenterPageState extends State<WelfareCenterPage> {
|
||||
}
|
||||
}
|
||||
|
||||
// ============================================
|
||||
// 主题感知颜色辅助
|
||||
// ============================================
|
||||
|
||||
bool get _isDark => Theme.of(context).brightness == Brightness.dark;
|
||||
|
||||
/// 金色强调色 ($gold-accent)
|
||||
Color get _goldAccent =>
|
||||
_isDark ? AppColorScheme.darkSecondary : const Color(0xFFF59E0B);
|
||||
|
||||
/// 盈利绿色 ($profit-green)
|
||||
Color get _profitGreen =>
|
||||
_isDark ? const Color(0xFF4ADE80) : const Color(0xFF16A34A);
|
||||
|
||||
/// 盈利绿色背景 ($profit-green-bg)
|
||||
Color get _profitGreenBg =>
|
||||
_isDark ? const Color(0xFF052E16) : const Color(0xFFF0FDF4);
|
||||
|
||||
/// 文字静默色 ($text-muted)
|
||||
Color get _textMuted =>
|
||||
_isDark ? AppColorScheme.darkOnSurfaceMuted : AppColorScheme.lightOnSurfaceMuted;
|
||||
|
||||
/// 第三级背景色 ($bg-tertiary)
|
||||
Color get _bgTertiary =>
|
||||
_isDark ? AppColorScheme.darkSurfaceContainerHigh : AppColorScheme.lightSurfaceContainer;
|
||||
|
||||
/// 卡片表面色 ($surface-card)
|
||||
Color get _surfaceCard =>
|
||||
_isDark ? AppColorScheme.darkSurfaceContainer : AppColorScheme.lightSurfaceLowest;
|
||||
|
||||
/// 反色文字 ($text-inverse)
|
||||
Color get _textInverse =>
|
||||
_isDark ? AppColorScheme.darkInverseSurface : AppColorScheme.lightSurfaceLowest;
|
||||
|
||||
// ============================================
|
||||
// 容器样式辅助
|
||||
// ============================================
|
||||
|
||||
/// 标准卡片容器
|
||||
BoxDecoration _cardDecoration({Color? borderColor}) {
|
||||
final scheme = Theme.of(context).colorScheme;
|
||||
return BoxDecoration(
|
||||
color: _surfaceCard,
|
||||
color: context.appColors.surfaceCard,
|
||||
borderRadius: BorderRadius.circular(AppRadius.lg),
|
||||
border: Border.all(
|
||||
color: borderColor ?? scheme.outlineVariant.withValues(alpha: 0.15),
|
||||
color: borderColor ?? context.appColors.ghostBorder,
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
/// 金色渐变卡片容器
|
||||
BoxDecoration _goldGradientDecoration() {
|
||||
final goldAccent = context.appColors.accentPrimary;
|
||||
return BoxDecoration(
|
||||
borderRadius: BorderRadius.circular(AppRadius.xl),
|
||||
gradient: LinearGradient(
|
||||
begin: Alignment.topCenter,
|
||||
end: Alignment.bottomCenter,
|
||||
colors: [
|
||||
_goldAccent.withValues(alpha: 0.15),
|
||||
_surfaceCard,
|
||||
goldAccent.withValues(alpha: 0.15),
|
||||
context.appColors.surfaceCard,
|
||||
],
|
||||
),
|
||||
border: Border.all(
|
||||
color: _goldAccent.withValues(alpha: 0.3),
|
||||
color: goldAccent.withValues(alpha: 0.3),
|
||||
width: 1,
|
||||
),
|
||||
);
|
||||
@@ -164,16 +130,12 @@ class _WelfareCenterPageState extends State<WelfareCenterPage> {
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final colorScheme = Theme.of(context).colorScheme;
|
||||
final goldAccent = context.appColors.accentPrimary;
|
||||
|
||||
return Scaffold(
|
||||
backgroundColor: _isDark
|
||||
? AppColorScheme.darkBackground
|
||||
: AppColorScheme.lightBackground,
|
||||
backgroundColor: context.colors.surface,
|
||||
appBar: AppBar(
|
||||
backgroundColor: _isDark
|
||||
? AppColorScheme.darkBackground
|
||||
: AppColorScheme.lightSurfaceLowest,
|
||||
backgroundColor: context.colors.surface,
|
||||
elevation: 0,
|
||||
scrolledUnderElevation: 0,
|
||||
centerTitle: false,
|
||||
@@ -183,20 +145,20 @@ class _WelfareCenterPageState extends State<WelfareCenterPage> {
|
||||
style: AppTextStyles.headlineLarge(context),
|
||||
),
|
||||
leading: IconButton(
|
||||
icon: Icon(LucideIcons.arrowLeft, color: colorScheme.onSurface, size: 24),
|
||||
icon: Icon(LucideIcons.arrowLeft, color: context.colors.onSurface, size: 24),
|
||||
onPressed: () => Navigator.of(context).pop(),
|
||||
),
|
||||
),
|
||||
body: _isLoading
|
||||
? Center(
|
||||
child: CircularProgressIndicator(
|
||||
color: _goldAccent,
|
||||
color: goldAccent,
|
||||
strokeWidth: 2.5,
|
||||
),
|
||||
)
|
||||
: RefreshIndicator(
|
||||
onRefresh: _loadData,
|
||||
color: _goldAccent,
|
||||
color: goldAccent,
|
||||
child: SingleChildScrollView(
|
||||
physics: const AlwaysScrollableScrollPhysics(),
|
||||
padding: const EdgeInsets.fromLTRB(16, 8, 16, 32),
|
||||
@@ -222,7 +184,7 @@ class _WelfareCenterPageState extends State<WelfareCenterPage> {
|
||||
// ============================================
|
||||
|
||||
Widget _buildReferralCodeCard(BuildContext context) {
|
||||
final colorScheme = Theme.of(context).colorScheme;
|
||||
final goldAccent = context.appColors.accentPrimary;
|
||||
final referralCode = _welfareData?['referralCode'] as String? ?? '';
|
||||
|
||||
return Container(
|
||||
@@ -235,7 +197,7 @@ class _WelfareCenterPageState extends State<WelfareCenterPage> {
|
||||
// Header Row: gift icon + 标题
|
||||
Row(
|
||||
children: [
|
||||
Icon(LucideIcons.gift, color: _goldAccent, size: 24),
|
||||
Icon(LucideIcons.gift, color: goldAccent, size: 24),
|
||||
const SizedBox(width: 10),
|
||||
Text(
|
||||
'我的邀请码',
|
||||
@@ -250,7 +212,7 @@ class _WelfareCenterPageState extends State<WelfareCenterPage> {
|
||||
referralCode.isEmpty ? '暂无邀请码' : referralCode,
|
||||
style: AppTextStyles.displayMedium(context).copyWith(
|
||||
fontWeight: FontWeight.w800,
|
||||
color: _goldAccent,
|
||||
color: goldAccent,
|
||||
letterSpacing: 2,
|
||||
),
|
||||
),
|
||||
@@ -266,17 +228,17 @@ class _WelfareCenterPageState extends State<WelfareCenterPage> {
|
||||
ToastUtils.show('邀请码已复制');
|
||||
},
|
||||
style: ElevatedButton.styleFrom(
|
||||
backgroundColor: _goldAccent,
|
||||
foregroundColor: _textInverse,
|
||||
backgroundColor: goldAccent,
|
||||
foregroundColor: context.colors.onSurface,
|
||||
elevation: 0,
|
||||
shape: RoundedRectangleBorder(
|
||||
borderRadius: BorderRadius.circular(AppRadius.lg),
|
||||
),
|
||||
disabledBackgroundColor: _goldAccent.withValues(alpha: 0.4),
|
||||
disabledBackgroundColor: goldAccent.withValues(alpha: 0.4),
|
||||
),
|
||||
child: Text(
|
||||
'复制邀请码',
|
||||
style: AppTextStyles.headlineMedium(context).copyWith(color: _textInverse),
|
||||
style: AppTextStyles.headlineMedium(context).copyWith(color: context.colors.onSurface),
|
||||
),
|
||||
),
|
||||
),
|
||||
@@ -290,7 +252,8 @@ class _WelfareCenterPageState extends State<WelfareCenterPage> {
|
||||
// ============================================
|
||||
|
||||
Widget _buildNewUserBonusCard(BuildContext context) {
|
||||
final colorScheme = Theme.of(context).colorScheme;
|
||||
final profitGreen = context.appColors.up;
|
||||
final profitGreenBg = context.appColors.upBackground;
|
||||
final newUserBonus = _welfareData?['newUserBonus'] as Map<String, dynamic>?;
|
||||
final eligible = newUserBonus?['eligible'] as bool? ?? false;
|
||||
final claimed = newUserBonus?['claimed'] as bool? ?? false;
|
||||
@@ -341,7 +304,7 @@ class _WelfareCenterPageState extends State<WelfareCenterPage> {
|
||||
),
|
||||
),
|
||||
if (showAvailableBadge)
|
||||
_statusBadge(badgeText, _profitGreen, _profitGreenBg),
|
||||
_statusBadge(badgeText, profitGreen, profitGreenBg),
|
||||
],
|
||||
),
|
||||
const SizedBox(height: 12),
|
||||
@@ -349,21 +312,21 @@ class _WelfareCenterPageState extends State<WelfareCenterPage> {
|
||||
'+100 USDT',
|
||||
style: AppTextStyles.displayLarge(context).copyWith(
|
||||
fontWeight: FontWeight.w800,
|
||||
color: claimed ? colorScheme.onSurfaceVariant : _profitGreen,
|
||||
color: claimed ? context.colors.onSurfaceVariant : profitGreen,
|
||||
),
|
||||
),
|
||||
const SizedBox(height: 8),
|
||||
Text(
|
||||
description,
|
||||
style: AppTextStyles.bodyLarge(context).copyWith(
|
||||
color: colorScheme.onSurfaceVariant,
|
||||
color: context.colors.onSurfaceVariant,
|
||||
),
|
||||
),
|
||||
const SizedBox(height: 16),
|
||||
_fullWidthButton(
|
||||
text: buttonText,
|
||||
backgroundColor: _profitGreen,
|
||||
foregroundColor: colorScheme.onPrimary,
|
||||
backgroundColor: profitGreen,
|
||||
foregroundColor: context.colors.onPrimary,
|
||||
onPressed: canClaim ? () => _claimNewUserBonus() : null,
|
||||
),
|
||||
],
|
||||
@@ -376,7 +339,6 @@ class _WelfareCenterPageState extends State<WelfareCenterPage> {
|
||||
// ============================================
|
||||
|
||||
Widget _buildReferralRewardsSection(BuildContext context) {
|
||||
final colorScheme = Theme.of(context).colorScheme;
|
||||
final referralRewards =
|
||||
_welfareData?['referralRewards'] as List<dynamic>? ?? [];
|
||||
|
||||
@@ -392,7 +354,7 @@ class _WelfareCenterPageState extends State<WelfareCenterPage> {
|
||||
Text(
|
||||
'每邀请一位好友充值达标,奖励100 USDT',
|
||||
style: AppTextStyles.bodySmall(context).copyWith(
|
||||
color: _textMuted,
|
||||
color: context.appColors.onSurfaceMuted,
|
||||
),
|
||||
),
|
||||
const SizedBox(height: 12),
|
||||
@@ -410,7 +372,6 @@ class _WelfareCenterPageState extends State<WelfareCenterPage> {
|
||||
}
|
||||
|
||||
Widget _buildEmptyReferralList(BuildContext context) {
|
||||
final colorScheme = Theme.of(context).colorScheme;
|
||||
return Padding(
|
||||
padding: const EdgeInsets.all(32),
|
||||
child: Center(
|
||||
@@ -419,13 +380,13 @@ class _WelfareCenterPageState extends State<WelfareCenterPage> {
|
||||
Icon(
|
||||
LucideIcons.users,
|
||||
size: 36,
|
||||
color: _textMuted.withValues(alpha: 0.4),
|
||||
color: context.appColors.onSurfaceMuted.withValues(alpha: 0.4),
|
||||
),
|
||||
const SizedBox(height: 8),
|
||||
Text(
|
||||
'暂无推广用户',
|
||||
style: AppTextStyles.bodyLarge(context).copyWith(
|
||||
color: colorScheme.onSurfaceVariant,
|
||||
color: context.colors.onSurfaceVariant,
|
||||
),
|
||||
),
|
||||
],
|
||||
@@ -435,8 +396,6 @@ class _WelfareCenterPageState extends State<WelfareCenterPage> {
|
||||
}
|
||||
|
||||
Widget _buildReferralListItems(BuildContext context, List<dynamic> referralRewards) {
|
||||
final colorScheme = Theme.of(context).colorScheme;
|
||||
|
||||
return Column(
|
||||
children: List.generate(referralRewards.length, (index) {
|
||||
final data = referralRewards[index] as Map<String, dynamic>;
|
||||
@@ -492,7 +451,7 @@ class _WelfareCenterPageState extends State<WelfareCenterPage> {
|
||||
height: 6,
|
||||
child: LinearProgressIndicator(
|
||||
value: progress,
|
||||
backgroundColor: _bgTertiary,
|
||||
backgroundColor: context.appColors.surfaceCardHigh,
|
||||
valueColor: AlwaysStoppedAnimation<Color>(progressColor),
|
||||
minHeight: 6,
|
||||
),
|
||||
@@ -505,7 +464,7 @@ class _WelfareCenterPageState extends State<WelfareCenterPage> {
|
||||
Divider(
|
||||
height: 1,
|
||||
thickness: 1,
|
||||
color: colorScheme.outlineVariant.withValues(alpha: 0.15),
|
||||
color: context.appColors.ghostBorder,
|
||||
),
|
||||
],
|
||||
);
|
||||
@@ -514,19 +473,18 @@ class _WelfareCenterPageState extends State<WelfareCenterPage> {
|
||||
}
|
||||
|
||||
Widget _buildAvatar(String username) {
|
||||
final colorScheme = Theme.of(context).colorScheme;
|
||||
return Container(
|
||||
width: 32,
|
||||
height: 32,
|
||||
decoration: BoxDecoration(
|
||||
color: _bgTertiary,
|
||||
color: context.appColors.surfaceCardHigh,
|
||||
shape: BoxShape.circle,
|
||||
),
|
||||
child: Center(
|
||||
child: Text(
|
||||
username.isNotEmpty ? username[0].toUpperCase() : '?',
|
||||
style: AppTextStyles.headlineSmall(context).copyWith(
|
||||
color: colorScheme.onSurfaceVariant,
|
||||
color: context.colors.onSurfaceVariant,
|
||||
),
|
||||
),
|
||||
),
|
||||
@@ -548,9 +506,9 @@ class _WelfareCenterPageState extends State<WelfareCenterPage> {
|
||||
|
||||
/// 根据状态获取进度条颜色
|
||||
Color _referralProgressColor(int claimableCount, double progress) {
|
||||
if (claimableCount > 0) return _profitGreen;
|
||||
if (progress > 0) return _goldAccent;
|
||||
return _bgTertiary;
|
||||
if (claimableCount > 0) return context.appColors.up;
|
||||
if (progress > 0) return context.appColors.accentPrimary;
|
||||
return context.appColors.surfaceCardHigh;
|
||||
}
|
||||
|
||||
/// 构建推荐奖励的操作按钮
|
||||
@@ -560,6 +518,9 @@ class _WelfareCenterPageState extends State<WelfareCenterPage> {
|
||||
required List<dynamic> milestones,
|
||||
required double progress,
|
||||
}) {
|
||||
final profitGreen = context.appColors.up;
|
||||
final profitGreenBg = context.appColors.upBackground;
|
||||
|
||||
if (claimableCount > 0) {
|
||||
final int milestoneValue = milestones.isNotEmpty
|
||||
? (milestones.firstWhere(
|
||||
@@ -570,7 +531,7 @@ class _WelfareCenterPageState extends State<WelfareCenterPage> {
|
||||
|
||||
return GestureDetector(
|
||||
onTap: () => _claimReferralBonus(data['userId'] as int, milestoneValue),
|
||||
child: _statusBadge('领取', _profitGreen, _profitGreenBg),
|
||||
child: _statusBadge('领取', profitGreen, profitGreenBg),
|
||||
);
|
||||
}
|
||||
if (progress > 0) {
|
||||
@@ -578,7 +539,7 @@ class _WelfareCenterPageState extends State<WelfareCenterPage> {
|
||||
}
|
||||
return Text(
|
||||
'待达标',
|
||||
style: AppTextStyles.labelLarge(context).copyWith(color: _textMuted),
|
||||
style: AppTextStyles.labelLarge(context).copyWith(color: context.appColors.onSurfaceMuted),
|
||||
);
|
||||
}
|
||||
|
||||
@@ -587,13 +548,11 @@ class _WelfareCenterPageState extends State<WelfareCenterPage> {
|
||||
// ============================================
|
||||
|
||||
Widget _buildRulesCard(BuildContext context) {
|
||||
final colorScheme = Theme.of(context).colorScheme;
|
||||
|
||||
return Container(
|
||||
width: double.infinity,
|
||||
padding: const EdgeInsets.fromLTRB(20, 16, 20, 16),
|
||||
decoration: BoxDecoration(
|
||||
color: _bgTertiary,
|
||||
color: context.appColors.surfaceCardHigh,
|
||||
borderRadius: BorderRadius.circular(AppRadius.lg),
|
||||
),
|
||||
child: Column(
|
||||
@@ -613,15 +572,12 @@ class _WelfareCenterPageState extends State<WelfareCenterPage> {
|
||||
}
|
||||
|
||||
Widget _buildRuleItem(String text) {
|
||||
final ruleTextColor = _isDark
|
||||
? AppColorScheme.darkOnSurfaceVariant
|
||||
: const Color(0xFF475569);
|
||||
return Padding(
|
||||
padding: const EdgeInsets.symmetric(vertical: 3),
|
||||
child: Text(
|
||||
'\u2022 $text',
|
||||
style: AppTextStyles.bodyMedium(context).copyWith(
|
||||
color: ruleTextColor,
|
||||
color: context.colors.onSurfaceVariant,
|
||||
),
|
||||
),
|
||||
);
|
||||
|
||||
@@ -3,6 +3,7 @@ import 'package:shadcn_ui/shadcn_ui.dart';
|
||||
import '../../../core/theme/app_color_scheme.dart';
|
||||
import '../../../core/theme/app_spacing.dart';
|
||||
import '../../../core/theme/app_theme.dart';
|
||||
import '../../../core/theme/app_theme_extension.dart';
|
||||
import '../../../core/storage/local_storage.dart';
|
||||
|
||||
/// 引导页数据模型
|
||||
@@ -91,11 +92,8 @@ class _OnboardingPageState extends State<OnboardingPage> {
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final colorScheme = Theme.of(context).colorScheme;
|
||||
final isDark = Theme.of(context).brightness == Brightness.dark;
|
||||
|
||||
return Scaffold(
|
||||
backgroundColor: colorScheme.surface,
|
||||
backgroundColor: context.colors.surface,
|
||||
body: SafeArea(
|
||||
child: Column(
|
||||
children: [
|
||||
@@ -113,7 +111,7 @@ class _OnboardingPageState extends State<OnboardingPage> {
|
||||
child: Text(
|
||||
'跳过',
|
||||
style: AppTextStyles.headlineMedium(context).copyWith(
|
||||
color: colorScheme.onSurfaceVariant,
|
||||
color: context.colors.onSurfaceVariant,
|
||||
),
|
||||
),
|
||||
),
|
||||
@@ -131,7 +129,7 @@ class _OnboardingPageState extends State<OnboardingPage> {
|
||||
},
|
||||
itemCount: _items.length,
|
||||
itemBuilder: (context, index) {
|
||||
return _buildPage(_items[index], isDark);
|
||||
return _buildPage(_items[index]);
|
||||
},
|
||||
),
|
||||
),
|
||||
@@ -150,7 +148,7 @@ class _OnboardingPageState extends State<OnboardingPage> {
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
children: List.generate(
|
||||
_items.length,
|
||||
(index) => _buildIndicator(index, isDark),
|
||||
(index) => _buildIndicator(index),
|
||||
),
|
||||
),
|
||||
const SizedBox(height: AppSpacing.xl),
|
||||
@@ -161,8 +159,8 @@ class _OnboardingPageState extends State<OnboardingPage> {
|
||||
child: ElevatedButton(
|
||||
onPressed: _nextPage,
|
||||
style: ElevatedButton.styleFrom(
|
||||
backgroundColor: colorScheme.primary,
|
||||
foregroundColor: colorScheme.onPrimary,
|
||||
backgroundColor: context.colors.primary,
|
||||
foregroundColor: context.colors.onPrimary,
|
||||
shape: RoundedRectangleBorder(
|
||||
borderRadius: BorderRadius.circular(AppRadius.lg),
|
||||
),
|
||||
@@ -185,9 +183,7 @@ class _OnboardingPageState extends State<OnboardingPage> {
|
||||
);
|
||||
}
|
||||
|
||||
Widget _buildPage(_OnboardingItem item, bool isDark) {
|
||||
final colorScheme = Theme.of(context).colorScheme;
|
||||
|
||||
Widget _buildPage(_OnboardingItem item) {
|
||||
return Padding(
|
||||
padding: const EdgeInsets.symmetric(horizontal: AppSpacing.xl),
|
||||
child: Column(
|
||||
@@ -225,7 +221,7 @@ class _OnboardingPageState extends State<OnboardingPage> {
|
||||
return Icon(
|
||||
item.icon ?? LucideIcons.image,
|
||||
size: 72,
|
||||
color: AppColorScheme.darkOnPrimary,
|
||||
color: context.colors.onPrimary,
|
||||
);
|
||||
},
|
||||
),
|
||||
@@ -233,7 +229,7 @@ class _OnboardingPageState extends State<OnboardingPage> {
|
||||
: Icon(
|
||||
item.icon ?? LucideIcons.star,
|
||||
size: 72,
|
||||
color: AppColorScheme.darkOnPrimary,
|
||||
color: context.colors.onPrimary,
|
||||
),
|
||||
),
|
||||
),
|
||||
@@ -243,7 +239,7 @@ class _OnboardingPageState extends State<OnboardingPage> {
|
||||
item.title,
|
||||
style: AppTextStyles.displaySmall(context).copyWith(
|
||||
fontWeight: FontWeight.bold,
|
||||
color: colorScheme.onSurface,
|
||||
color: context.colors.onSurface,
|
||||
letterSpacing: -0.5,
|
||||
),
|
||||
),
|
||||
@@ -253,7 +249,7 @@ class _OnboardingPageState extends State<OnboardingPage> {
|
||||
item.description,
|
||||
textAlign: TextAlign.center,
|
||||
style: AppTextStyles.headlineMedium(context).copyWith(
|
||||
color: colorScheme.onSurfaceVariant,
|
||||
color: context.colors.onSurfaceVariant,
|
||||
height: 1.6,
|
||||
),
|
||||
),
|
||||
@@ -262,8 +258,7 @@ class _OnboardingPageState extends State<OnboardingPage> {
|
||||
);
|
||||
}
|
||||
|
||||
Widget _buildIndicator(int index, bool isDark) {
|
||||
final colorScheme = Theme.of(context).colorScheme;
|
||||
Widget _buildIndicator(int index) {
|
||||
final isActive = index == _currentPage;
|
||||
|
||||
return AnimatedContainer(
|
||||
@@ -272,7 +267,7 @@ class _OnboardingPageState extends State<OnboardingPage> {
|
||||
width: isActive ? 24 : 8,
|
||||
height: 8,
|
||||
decoration: BoxDecoration(
|
||||
color: isActive ? colorScheme.primary : colorScheme.outlineVariant,
|
||||
color: isActive ? context.colors.primary : context.colors.outlineVariant,
|
||||
borderRadius: BorderRadius.circular(AppRadius.sm),
|
||||
),
|
||||
);
|
||||
|
||||
@@ -4,6 +4,7 @@ import 'package:provider/provider.dart';
|
||||
import '../../../core/theme/app_color_scheme.dart';
|
||||
import '../../../core/theme/app_spacing.dart';
|
||||
import '../../../core/theme/app_theme.dart';
|
||||
import '../../../core/theme/app_theme_extension.dart';
|
||||
import '../../../providers/asset_provider.dart';
|
||||
import '../../../data/models/order_models.dart';
|
||||
import 'fund_order_card.dart';
|
||||
@@ -88,8 +89,6 @@ class _FundOrderCardContent extends StatelessWidget {
|
||||
|
||||
const _FundOrderCardContent({required this.order});
|
||||
|
||||
bool get _isDark => true; // 默认深色
|
||||
|
||||
Color _getStatusColor(int status, bool isDeposit) {
|
||||
if (isDeposit) {
|
||||
switch (status) {
|
||||
@@ -159,8 +158,6 @@ class _FundOrderCardContent extends StatelessWidget {
|
||||
final theme = ShadTheme.of(context);
|
||||
final isDeposit = order.type == 1;
|
||||
final statusColor = _getStatusColor(order.status, isDeposit);
|
||||
final isDark = Theme.of(context).brightness == Brightness.dark;
|
||||
final onPrimaryColor = isDark ? AppColorScheme.darkOnSurface : AppColorScheme.lightOnSurface;
|
||||
|
||||
return ShadCard(
|
||||
padding: AppSpacing.cardPadding,
|
||||
|
||||
@@ -7,6 +7,7 @@ import 'package:provider/provider.dart';
|
||||
import '../../../core/theme/app_color_scheme.dart';
|
||||
import '../../../core/theme/app_spacing.dart';
|
||||
import '../../../core/theme/app_theme.dart';
|
||||
import '../../../core/theme/app_theme_extension.dart';
|
||||
import '../../../core/utils/toast_utils.dart';
|
||||
import '../../../core/event/app_event_bus.dart';
|
||||
import '../../../providers/asset_provider.dart';
|
||||
@@ -51,32 +52,21 @@ class _FundOrdersPageState extends State<FundOrdersPage> {
|
||||
context.read<AssetProvider>().loadFundOrders(type: type);
|
||||
}
|
||||
|
||||
// ============================================
|
||||
// 主题辅助
|
||||
// ============================================
|
||||
|
||||
bool get _isDark => Theme.of(context).brightness == Brightness.dark;
|
||||
|
||||
/// 一次性获取所有主题感知颜色
|
||||
_OrderColors get _colors => _OrderColors(_isDark);
|
||||
|
||||
// ============================================
|
||||
// 构建 UI
|
||||
// ============================================
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final c = _colors;
|
||||
|
||||
return Scaffold(
|
||||
backgroundColor: c.background,
|
||||
backgroundColor: context.colors.surface,
|
||||
appBar: AppBar(
|
||||
leading: IconButton(
|
||||
icon: const Icon(LucideIcons.arrowLeft, size: 20),
|
||||
onPressed: () => Navigator.of(context).pop(),
|
||||
),
|
||||
title: Text('充提记录', style: AppTextStyles.headlineLarge(context).copyWith(color: c.primaryText)),
|
||||
backgroundColor: c.background,
|
||||
title: Text('充提记录', style: AppTextStyles.headlineLarge(context).copyWith(color: context.colors.onSurface)),
|
||||
backgroundColor: context.colors.surface,
|
||||
elevation: 0,
|
||||
scrolledUnderElevation: 0,
|
||||
centerTitle: true,
|
||||
@@ -94,15 +84,13 @@ class _FundOrdersPageState extends State<FundOrdersPage> {
|
||||
// Filter Tabs - pill-style segmented control
|
||||
// ---------------------------------------------------------------------------
|
||||
Widget _buildFilterTabs() {
|
||||
final c = _colors;
|
||||
|
||||
return Padding(
|
||||
padding: const EdgeInsets.symmetric(horizontal: AppSpacing.md),
|
||||
child: Container(
|
||||
height: 40,
|
||||
padding: const EdgeInsets.all(AppSpacing.xs),
|
||||
decoration: BoxDecoration(
|
||||
color: c.tabBg,
|
||||
color: context.appColors.surfaceCardHigh,
|
||||
borderRadius: AppRadius.radiusMd,
|
||||
),
|
||||
child: Row(
|
||||
@@ -117,7 +105,6 @@ class _FundOrdersPageState extends State<FundOrdersPage> {
|
||||
}
|
||||
|
||||
Widget _buildPillTab(String label, int index) {
|
||||
final c = _colors;
|
||||
final isActive = _activeTab == index;
|
||||
|
||||
return Expanded(
|
||||
@@ -130,15 +117,15 @@ class _FundOrdersPageState extends State<FundOrdersPage> {
|
||||
},
|
||||
child: Container(
|
||||
decoration: BoxDecoration(
|
||||
color: isActive ? c.activeTabBg : AppColorScheme.darkSurfaceLowest.withValues(alpha: 0),
|
||||
color: isActive ? context.colors.onSurface : AppColorScheme.darkSurfaceLowest.withValues(alpha: 0),
|
||||
borderRadius: AppRadius.radiusSm,
|
||||
),
|
||||
child: Center(
|
||||
child: Text(
|
||||
label,
|
||||
style: isActive
|
||||
? AppTextStyles.headlineMedium(context).copyWith(color: c.activeTabText)
|
||||
: AppTextStyles.headlineSmall(context).copyWith(color: c.inactiveTabText),
|
||||
? AppTextStyles.headlineMedium(context).copyWith(color: context.colors.surface)
|
||||
: AppTextStyles.headlineSmall(context).copyWith(color: context.colors.onSurfaceVariant),
|
||||
),
|
||||
),
|
||||
),
|
||||
@@ -150,8 +137,6 @@ class _FundOrdersPageState extends State<FundOrdersPage> {
|
||||
// Order List
|
||||
// ---------------------------------------------------------------------------
|
||||
Widget _buildOrderList() {
|
||||
final c = _colors;
|
||||
|
||||
return Consumer<AssetProvider>(
|
||||
builder: (context, provider, _) {
|
||||
final orders = provider.fundOrders;
|
||||
@@ -166,9 +151,9 @@ class _FundOrdersPageState extends State<FundOrdersPage> {
|
||||
child: Column(
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
children: [
|
||||
Icon(LucideIcons.inbox, size: 64, color: c.mutedText),
|
||||
Icon(LucideIcons.inbox, size: 64, color: context.appColors.onSurfaceMuted),
|
||||
const SizedBox(height: AppSpacing.md),
|
||||
Text('暂无订单记录', style: AppTextStyles.headlineMedium(context).copyWith(color: c.secondaryText)),
|
||||
Text('暂无订单记录', style: AppTextStyles.headlineMedium(context).copyWith(color: context.colors.onSurfaceVariant)),
|
||||
],
|
||||
),
|
||||
);
|
||||
@@ -193,14 +178,12 @@ class _FundOrdersPageState extends State<FundOrdersPage> {
|
||||
// Order Card
|
||||
// ---------------------------------------------------------------------------
|
||||
Widget _buildOrderCard(OrderFund order) {
|
||||
final c = _colors;
|
||||
|
||||
return Container(
|
||||
padding: AppSpacing.cardPadding,
|
||||
decoration: BoxDecoration(
|
||||
color: c.cardBg,
|
||||
color: context.appColors.surfaceCard,
|
||||
borderRadius: AppRadius.radiusLg,
|
||||
border: Border.all(color: c.borderColor, width: 1),
|
||||
border: Border.all(color: context.appColors.ghostBorder, width: 1),
|
||||
),
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
@@ -216,7 +199,7 @@ class _FundOrdersPageState extends State<FundOrdersPage> {
|
||||
],
|
||||
if (order.withdrawContact != null) ...[
|
||||
const SizedBox(height: AppSpacing.sm - AppSpacing.xs),
|
||||
_buildDetailRow('联系方式', order.withdrawContact!, c),
|
||||
_buildDetailRow('联系方式', order.withdrawContact!),
|
||||
],
|
||||
if (order.receivableAmount != null && !order.isDeposit) ...[
|
||||
const SizedBox(height: AppSpacing.sm),
|
||||
@@ -232,13 +215,13 @@ class _FundOrdersPageState extends State<FundOrdersPage> {
|
||||
children: [
|
||||
Text(
|
||||
'创建: ${_formatTime(order.createTime)}',
|
||||
style: AppTextStyles.bodySmall(context).copyWith(color: c.mutedText),
|
||||
style: AppTextStyles.bodySmall(context).copyWith(color: context.appColors.onSurfaceMuted),
|
||||
),
|
||||
if (order.rejectReason != null)
|
||||
Expanded(
|
||||
child: Text(
|
||||
'驳回: ${order.rejectReason}',
|
||||
style: AppTextStyles.bodySmall(context).copyWith(color: AppColorScheme.getDownColor(_isDark)),
|
||||
style: AppTextStyles.bodySmall(context).copyWith(color: context.appColors.down),
|
||||
textAlign: TextAlign.right,
|
||||
overflow: TextOverflow.ellipsis,
|
||||
),
|
||||
@@ -254,13 +237,12 @@ class _FundOrdersPageState extends State<FundOrdersPage> {
|
||||
// Card Header (order type + status badge)
|
||||
// ---------------------------------------------------------------------------
|
||||
Widget _buildCardHeader(OrderFund order) {
|
||||
final c = _colors;
|
||||
return Row(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
children: [
|
||||
Text(
|
||||
order.isDeposit ? '充值' : '提现',
|
||||
style: AppTextStyles.headlineMedium(context).copyWith(color: c.primaryText),
|
||||
style: AppTextStyles.headlineMedium(context).copyWith(color: context.colors.onSurface),
|
||||
),
|
||||
_buildStatusBadge(order),
|
||||
],
|
||||
@@ -268,10 +250,10 @@ class _FundOrdersPageState extends State<FundOrdersPage> {
|
||||
}
|
||||
|
||||
Widget _buildStatusBadge(OrderFund order) {
|
||||
final upColor = AppColorScheme.getUpColor(_isDark);
|
||||
final downColor = AppColorScheme.getDownColor(_isDark);
|
||||
final upBg = AppColorScheme.getUpBackgroundColor(_isDark, opacity: 0.12);
|
||||
final downBg = AppColorScheme.getDownBackgroundColor(_isDark, opacity: 0.12);
|
||||
final upColor = context.appColors.up;
|
||||
final downColor = context.appColors.down;
|
||||
final upBg = context.appColors.up.withValues(alpha: 0.12);
|
||||
final downBg = context.appColors.down.withValues(alpha: 0.12);
|
||||
|
||||
Color bgColor;
|
||||
Color textColor;
|
||||
@@ -326,10 +308,9 @@ class _FundOrdersPageState extends State<FundOrdersPage> {
|
||||
// Amount Row
|
||||
// ---------------------------------------------------------------------------
|
||||
Widget _buildAmountRow(OrderFund order) {
|
||||
final c = _colors;
|
||||
return Text(
|
||||
'${order.isDeposit ? '+' : '-'}${order.amount} USDT',
|
||||
style: AppTextStyles.displaySmall(context).copyWith(color: c.primaryText, height: 1.3),
|
||||
style: AppTextStyles.displaySmall(context).copyWith(color: context.colors.onSurface, height: 1.3),
|
||||
);
|
||||
}
|
||||
|
||||
@@ -337,44 +318,39 @@ class _FundOrdersPageState extends State<FundOrdersPage> {
|
||||
// Detail Rows
|
||||
// ---------------------------------------------------------------------------
|
||||
Widget _buildDetailRows(OrderFund order) {
|
||||
final c = _colors;
|
||||
|
||||
return Column(
|
||||
children: [
|
||||
_buildDetailRow('订单号', order.orderNo, c),
|
||||
_buildDetailRow('订单号', order.orderNo),
|
||||
const SizedBox(height: AppSpacing.sm - AppSpacing.xs),
|
||||
if (order.walletAddress != null) ...[
|
||||
_buildDetailRow(
|
||||
'网络',
|
||||
order.remark.isNotEmpty ? order.remark : '-',
|
||||
c,
|
||||
),
|
||||
const SizedBox(height: AppSpacing.sm - AppSpacing.xs),
|
||||
_buildDetailRow(
|
||||
'地址',
|
||||
_truncateAddress(order.walletAddress!),
|
||||
c,
|
||||
trailing: GestureDetector(
|
||||
onTap: () {
|
||||
Clipboard.setData(ClipboardData(text: order.walletAddress!));
|
||||
ToastUtils.show('地址已复制');
|
||||
},
|
||||
child: Icon(LucideIcons.copy, size: 14, color: c.mutedText),
|
||||
child: Icon(LucideIcons.copy, size: 14, color: context.appColors.onSurfaceMuted),
|
||||
),
|
||||
),
|
||||
const SizedBox(height: AppSpacing.sm - AppSpacing.xs),
|
||||
] else if (order.remark.isNotEmpty) ...[
|
||||
_buildDetailRow('网络', order.remark, c),
|
||||
_buildDetailRow('网络', order.remark),
|
||||
const SizedBox(height: AppSpacing.sm - AppSpacing.xs),
|
||||
],
|
||||
if (order.fee != null && !order.isDeposit) ...[
|
||||
_buildDetailRow('手续费', '${order.fee}%', c),
|
||||
_buildDetailRow('手续费', '${order.fee}%'),
|
||||
const SizedBox(height: AppSpacing.sm - AppSpacing.xs),
|
||||
],
|
||||
_buildDetailRow(
|
||||
'时间',
|
||||
_formatTime(order.createTime),
|
||||
c,
|
||||
),
|
||||
],
|
||||
);
|
||||
@@ -382,16 +358,15 @@ class _FundOrdersPageState extends State<FundOrdersPage> {
|
||||
|
||||
Widget _buildDetailRow(
|
||||
String label,
|
||||
String value,
|
||||
_OrderColors c, {
|
||||
String value, {
|
||||
Widget? trailing,
|
||||
}) {
|
||||
final valueStyle = AppTextStyles.bodyMedium(context).copyWith(color: c.primaryText);
|
||||
final valueStyle = AppTextStyles.bodyMedium(context).copyWith(color: context.colors.onSurface);
|
||||
|
||||
return Row(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
children: [
|
||||
Text(label, style: AppTextStyles.bodyMedium(context).copyWith(color: c.mutedText)),
|
||||
Text(label, style: AppTextStyles.bodyMedium(context).copyWith(color: context.appColors.onSurfaceMuted)),
|
||||
if (trailing != null)
|
||||
Row(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
@@ -413,7 +388,7 @@ class _FundOrdersPageState extends State<FundOrdersPage> {
|
||||
Widget _buildRejectionReason(OrderFund order) {
|
||||
return Text(
|
||||
'拒绝原因: ${order.rejectReason}',
|
||||
style: AppTextStyles.bodyMedium(context).copyWith(color: AppColorScheme.getDownColor(_isDark)),
|
||||
style: AppTextStyles.bodyMedium(context).copyWith(color: context.appColors.down),
|
||||
);
|
||||
}
|
||||
|
||||
@@ -421,19 +396,17 @@ class _FundOrdersPageState extends State<FundOrdersPage> {
|
||||
// Payable Amount Row (withdrawal)
|
||||
// ---------------------------------------------------------------------------
|
||||
Widget _buildPayableRow(OrderFund order) {
|
||||
final c = _colors;
|
||||
|
||||
return Container(
|
||||
padding: const EdgeInsets.symmetric(horizontal: AppSpacing.sm + AppSpacing.xs, vertical: AppSpacing.sm),
|
||||
decoration: BoxDecoration(
|
||||
color: c.bgTertiary,
|
||||
color: context.appColors.surfaceCardHigh,
|
||||
borderRadius: AppRadius.radiusSm,
|
||||
),
|
||||
child: Row(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
children: [
|
||||
Text('应付金额', style: AppTextStyles.headlineSmall(context).copyWith(color: c.secondaryText)),
|
||||
Text('${order.receivableAmount} USDT', style: AppTextStyles.headlineMedium(context).copyWith(color: c.primaryText)),
|
||||
Text('应付金额', style: AppTextStyles.headlineSmall(context).copyWith(color: context.colors.onSurfaceVariant)),
|
||||
Text('${order.receivableAmount} USDT', style: AppTextStyles.headlineMedium(context).copyWith(color: context.colors.onSurface)),
|
||||
],
|
||||
),
|
||||
);
|
||||
@@ -443,9 +416,8 @@ class _FundOrdersPageState extends State<FundOrdersPage> {
|
||||
// Action Buttons
|
||||
// ---------------------------------------------------------------------------
|
||||
Widget _buildActions(OrderFund order) {
|
||||
final upColor = AppColorScheme.getUpColor(_isDark);
|
||||
final downColor = AppColorScheme.getDownColor(_isDark);
|
||||
final c = _colors;
|
||||
final upColor = context.appColors.up;
|
||||
final downColor = context.appColors.down;
|
||||
|
||||
return Row(
|
||||
mainAxisAlignment: MainAxisAlignment.end,
|
||||
@@ -473,7 +445,7 @@ class _FundOrdersPageState extends State<FundOrdersPage> {
|
||||
color: upColor,
|
||||
borderRadius: AppRadius.radiusSm,
|
||||
),
|
||||
child: Text('已打款', style: AppTextStyles.headlineSmall(context).copyWith(color: c.activeTabText)),
|
||||
child: Text('已打款', style: AppTextStyles.headlineSmall(context).copyWith(color: context.colors.surface)),
|
||||
),
|
||||
),
|
||||
],
|
||||
@@ -552,37 +524,3 @@ class _FundOrdersPageState extends State<FundOrdersPage> {
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
/// 充提订单页面的主题感知颜色集合
|
||||
class _OrderColors {
|
||||
final Color background;
|
||||
final Color cardBg;
|
||||
final Color borderColor;
|
||||
final Color bgTertiary;
|
||||
final Color primaryText;
|
||||
final Color secondaryText;
|
||||
final Color mutedText;
|
||||
final Color tabBg;
|
||||
final Color activeTabBg;
|
||||
final Color activeTabText;
|
||||
final Color inactiveTabText;
|
||||
|
||||
_OrderColors(bool isDark)
|
||||
: background = isDark ? AppColorScheme.darkBackground : AppColorScheme.lightBackground,
|
||||
cardBg = isDark ? AppColorScheme.darkSurfaceContainer : AppColorScheme.lightSurfaceLowest,
|
||||
borderColor = isDark
|
||||
? AppColorScheme.darkOutlineVariant.withValues(alpha: 0.15)
|
||||
: AppColorScheme.lightOutlineVariant.withValues(alpha: 0.5),
|
||||
bgTertiary = isDark
|
||||
? AppColorScheme.darkSurfaceContainerHigh
|
||||
: AppColorScheme.lightSurfaceHigh,
|
||||
primaryText = isDark ? AppColorScheme.darkOnSurface : AppColorScheme.lightOnSurface,
|
||||
secondaryText = isDark
|
||||
? AppColorScheme.darkOnSurfaceVariant
|
||||
: AppColorScheme.lightOnSurfaceVariant,
|
||||
mutedText = isDark ? AppColorScheme.darkOnSurfaceMuted : AppColorScheme.lightOnSurfaceMuted,
|
||||
tabBg = isDark ? AppColorScheme.darkSurfaceContainerHigh : AppColorScheme.lightSurfaceHigh,
|
||||
activeTabBg = isDark ? AppColorScheme.darkOnSurface : AppColorScheme.lightSurfaceLowest,
|
||||
activeTabText = isDark ? AppColorScheme.darkBackground : AppColorScheme.lightOnSurface,
|
||||
inactiveTabText = isDark ? AppColorScheme.darkOnSurfaceVariant : AppColorScheme.lightOnSurfaceVariant;
|
||||
}
|
||||
|
||||
@@ -4,6 +4,7 @@ import 'package:provider/provider.dart';
|
||||
import '../../../core/theme/app_color_scheme.dart';
|
||||
import '../../../core/theme/app_spacing.dart';
|
||||
import '../../../core/theme/app_theme.dart';
|
||||
import '../../../core/theme/app_theme_extension.dart';
|
||||
import '../../../providers/asset_provider.dart';
|
||||
import 'fund_orders_list.dart';
|
||||
|
||||
@@ -35,7 +36,6 @@ class _OrdersPageState extends State<OrdersPage> with AutomaticKeepAliveClientMi
|
||||
Widget build(BuildContext context) {
|
||||
super.build(context);
|
||||
final theme = ShadTheme.of(context);
|
||||
final isDark = Theme.of(context).brightness == Brightness.dark;
|
||||
|
||||
return Scaffold(
|
||||
backgroundColor: theme.colorScheme.background,
|
||||
@@ -84,8 +84,6 @@ class TabSelector extends StatelessWidget {
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final theme = ShadTheme.of(context);
|
||||
final isDark = Theme.of(context).brightness == Brightness.dark;
|
||||
final onPrimaryBg = isDark ? AppColorScheme.darkBackground : AppColorScheme.lightSurfaceLowest;
|
||||
|
||||
return Container(
|
||||
padding: const EdgeInsets.all(AppSpacing.xs),
|
||||
@@ -114,7 +112,7 @@ class TabSelector extends StatelessWidget {
|
||||
label,
|
||||
style: isSelected
|
||||
? AppTextStyles.labelLarge(context).copyWith(
|
||||
color: onPrimaryBg,
|
||||
color: context.colors.surface,
|
||||
)
|
||||
: AppTextStyles.labelLarge(context).copyWith(
|
||||
color: theme.colorScheme.mutedForeground,
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:lucide_icons_flutter/lucide_icons.dart';
|
||||
import '../../../../core/theme/app_color_scheme.dart';
|
||||
import '../../../../core/theme/app_spacing.dart';
|
||||
import '../../../../core/theme/app_theme.dart';
|
||||
import '../../../../core/theme/app_theme_extension.dart';
|
||||
import '../../../../data/models/coin.dart';
|
||||
import 'coin_avatar.dart';
|
||||
|
||||
@@ -25,21 +25,16 @@ class CoinSelector extends StatelessWidget {
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final colorScheme = Theme.of(context).colorScheme;
|
||||
final isDark = Theme.of(context).brightness == Brightness.dark;
|
||||
|
||||
return GestureDetector(
|
||||
onTap: () => _showCoinPicker(context),
|
||||
child: Container(
|
||||
width: double.infinity,
|
||||
padding: const EdgeInsets.all(AppSpacing.md),
|
||||
decoration: BoxDecoration(
|
||||
color: isDark
|
||||
? colorScheme.surfaceContainer
|
||||
: colorScheme.surfaceContainerLowest,
|
||||
color: context.appColors.surfaceCard,
|
||||
borderRadius: BorderRadius.circular(AppRadius.lg),
|
||||
border: Border.all(
|
||||
color: colorScheme.outlineVariant.withOpacity(0.15),
|
||||
color: context.appColors.ghostBorder,
|
||||
),
|
||||
),
|
||||
child: Row(
|
||||
@@ -60,14 +55,14 @@ class CoinSelector extends StatelessWidget {
|
||||
Text(
|
||||
selectedCoin?.name ?? '点击选择交易对',
|
||||
style: AppTextStyles.bodyMedium(context).copyWith(
|
||||
color: colorScheme.onSurfaceVariant,
|
||||
color: context.colors.onSurfaceVariant,
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
// 下拉箭头
|
||||
Icon(LucideIcons.chevronDown,
|
||||
size: 16, color: colorScheme.onSurfaceVariant),
|
||||
size: 16, color: context.colors.onSurfaceVariant),
|
||||
],
|
||||
),
|
||||
),
|
||||
@@ -75,9 +70,6 @@ class CoinSelector extends StatelessWidget {
|
||||
}
|
||||
|
||||
void _showCoinPicker(BuildContext context) {
|
||||
final colorScheme = Theme.of(context).colorScheme;
|
||||
final isDark = Theme.of(context).brightness == Brightness.dark;
|
||||
|
||||
showModalBottomSheet(
|
||||
context: context,
|
||||
backgroundColor: const Color(0x00000000),
|
||||
@@ -85,9 +77,9 @@ class CoinSelector extends StatelessWidget {
|
||||
builder: (ctx) => Container(
|
||||
height: MediaQuery.of(ctx).size.height * 0.65,
|
||||
decoration: BoxDecoration(
|
||||
color: isDark
|
||||
? colorScheme.surface
|
||||
: colorScheme.surfaceContainerLowest,
|
||||
color: ctx.isDark
|
||||
? ctx.colors.surface
|
||||
: ctx.colors.surfaceContainerLowest,
|
||||
borderRadius:
|
||||
BorderRadius.vertical(top: Radius.circular(AppRadius.xxl)),
|
||||
),
|
||||
@@ -99,7 +91,7 @@ class CoinSelector extends StatelessWidget {
|
||||
width: 40,
|
||||
height: 4,
|
||||
decoration: BoxDecoration(
|
||||
color: colorScheme.onSurfaceVariant.withOpacity(0.3),
|
||||
color: ctx.colors.onSurfaceVariant.withValues(alpha: 0.3),
|
||||
borderRadius: BorderRadius.circular(AppRadius.sm),
|
||||
),
|
||||
),
|
||||
@@ -114,12 +106,12 @@ class CoinSelector extends StatelessWidget {
|
||||
GestureDetector(
|
||||
onTap: () => Navigator.of(ctx).pop(),
|
||||
child: Icon(LucideIcons.x,
|
||||
color: colorScheme.onSurfaceVariant),
|
||||
color: ctx.colors.onSurfaceVariant),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
Divider(height: 1, color: colorScheme.outlineVariant.withOpacity(0.2)),
|
||||
Divider(height: 1, color: ctx.colors.outlineVariant.withValues(alpha: 0.2)),
|
||||
// 币种列表
|
||||
Expanded(
|
||||
child: ListView.builder(
|
||||
@@ -137,12 +129,10 @@ class CoinSelector extends StatelessWidget {
|
||||
|
||||
Widget _buildCoinItem(
|
||||
Coin coin, BuildContext context, BuildContext sheetContext) {
|
||||
final colorScheme = Theme.of(context).colorScheme;
|
||||
final isDark = Theme.of(context).brightness == Brightness.dark;
|
||||
final isSelected = selectedCoin?.code == coin.code;
|
||||
final changeColor = coin.isUp
|
||||
? AppColorScheme.getUpColor(isDark)
|
||||
: AppColorScheme.getDownColor(isDark);
|
||||
? context.appColors.up
|
||||
: context.appColors.down;
|
||||
|
||||
return GestureDetector(
|
||||
onTap: () {
|
||||
@@ -153,7 +143,7 @@ class CoinSelector extends StatelessWidget {
|
||||
padding: EdgeInsets.symmetric(
|
||||
horizontal: AppSpacing.lg, vertical: AppSpacing.md),
|
||||
color:
|
||||
isSelected ? colorScheme.primary.withOpacity(0.1) : const Color(0x00000000),
|
||||
isSelected ? context.colors.primary.withValues(alpha: 0.1) : const Color(0x00000000),
|
||||
child: Row(
|
||||
children: [
|
||||
CoinAvatar(icon: coin.displayIcon),
|
||||
@@ -170,7 +160,7 @@ class CoinSelector extends StatelessWidget {
|
||||
SizedBox(width: AppSpacing.xs),
|
||||
Text('/USDT',
|
||||
style: AppTextStyles.bodySmall(context).copyWith(
|
||||
color: colorScheme.onSurfaceVariant,
|
||||
color: context.colors.onSurfaceVariant,
|
||||
)),
|
||||
const Spacer(),
|
||||
Text('\$${coin.formattedPrice}',
|
||||
@@ -180,7 +170,7 @@ class CoinSelector extends StatelessWidget {
|
||||
Container(
|
||||
padding: EdgeInsets.symmetric(horizontal: 6, vertical: 2),
|
||||
decoration: BoxDecoration(
|
||||
color: changeColor.withOpacity(0.1),
|
||||
color: changeColor.withValues(alpha: 0.1),
|
||||
borderRadius: BorderRadius.circular(AppRadius.sm),
|
||||
),
|
||||
child: Text(coin.formattedChange,
|
||||
@@ -192,7 +182,7 @@ class CoinSelector extends StatelessWidget {
|
||||
if (isSelected) ...[
|
||||
SizedBox(width: AppSpacing.sm),
|
||||
Icon(LucideIcons.check,
|
||||
size: 16, color: colorScheme.primary),
|
||||
size: 16, color: context.colors.primary),
|
||||
],
|
||||
],
|
||||
),
|
||||
@@ -200,7 +190,7 @@ class CoinSelector extends StatelessWidget {
|
||||
// 第二行:币种名称
|
||||
Text(coin.name,
|
||||
style: AppTextStyles.bodyMedium(context).copyWith(
|
||||
color: colorScheme.onSurfaceVariant,
|
||||
color: context.colors.onSurfaceVariant,
|
||||
)),
|
||||
],
|
||||
),
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import '../../../../core/theme/app_color_scheme.dart';
|
||||
import '../../../../core/theme/app_spacing.dart';
|
||||
import '../../../../core/theme/app_theme.dart';
|
||||
import '../../../../core/theme/app_theme_extension.dart';
|
||||
import '../../../components/glass_panel.dart';
|
||||
import '../../../components/neon_glow.dart';
|
||||
|
||||
@@ -27,11 +27,9 @@ class ConfirmDialog extends StatelessWidget {
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final colorScheme = Theme.of(context).colorScheme;
|
||||
final isDark = Theme.of(context).brightness == Brightness.dark;
|
||||
final actionColor = isBuy
|
||||
? AppColorScheme.getUpColor(isDark)
|
||||
: AppColorScheme.getDownColor(isDark);
|
||||
? context.appColors.up
|
||||
: context.appColors.down;
|
||||
|
||||
return Dialog(
|
||||
backgroundColor: const Color(0x00000000),
|
||||
@@ -49,14 +47,14 @@ class ConfirmDialog extends StatelessWidget {
|
||||
),
|
||||
),
|
||||
SizedBox(height: AppSpacing.lg),
|
||||
_dialogRow(context, '交易对', '$coinCode/USDT', colorScheme),
|
||||
_dialogRow(context, '交易对', '$coinCode/USDT'),
|
||||
SizedBox(height: AppSpacing.sm),
|
||||
_dialogRow(context, '委托价格', '$price USDT', colorScheme),
|
||||
_dialogRow(context, '委托价格', '$price USDT'),
|
||||
SizedBox(height: AppSpacing.sm),
|
||||
_dialogRow(context, '交易金额', '$amount USDT', colorScheme,
|
||||
_dialogRow(context, '交易金额', '$amount USDT',
|
||||
valueColor: actionColor),
|
||||
SizedBox(height: AppSpacing.sm),
|
||||
_dialogRow(context, '交易数量', '$quantity $coinCode', colorScheme),
|
||||
_dialogRow(context, '交易数量', '$quantity $coinCode'),
|
||||
SizedBox(height: AppSpacing.lg),
|
||||
Row(
|
||||
children: [
|
||||
@@ -87,7 +85,7 @@ class ConfirmDialog extends StatelessWidget {
|
||||
);
|
||||
}
|
||||
|
||||
Widget _dialogRow(BuildContext context, String label, String value, ColorScheme colorScheme,
|
||||
Widget _dialogRow(BuildContext context, String label, String value,
|
||||
{Color? valueColor}) {
|
||||
return Row(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
@@ -95,11 +93,11 @@ class ConfirmDialog extends StatelessWidget {
|
||||
Text(label,
|
||||
style: AppTextStyles.headlineMedium(context).copyWith(
|
||||
fontWeight: FontWeight.w400,
|
||||
color: colorScheme.onSurfaceVariant,
|
||||
color: context.colors.onSurfaceVariant,
|
||||
)),
|
||||
Text(value,
|
||||
style: AppTextStyles.numberMedium(context).copyWith(
|
||||
color: valueColor ?? colorScheme.onSurface,
|
||||
color: valueColor ?? context.colors.onSurface,
|
||||
)),
|
||||
],
|
||||
);
|
||||
|
||||
@@ -1,38 +1,34 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import '../../../../core/theme/app_spacing.dart';
|
||||
import '../../../../core/theme/app_theme.dart';
|
||||
import '../../../../core/theme/app_theme_extension.dart';
|
||||
|
||||
/// 占位卡片组件
|
||||
///
|
||||
/// 当未选择币种时显示的占位提示卡片。
|
||||
class PlaceholderCard extends StatelessWidget {
|
||||
final String message;
|
||||
final ColorScheme colorScheme;
|
||||
const PlaceholderCard({
|
||||
super.key,
|
||||
required this.message,
|
||||
required this.colorScheme,
|
||||
});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final isDark = Theme.of(context).brightness == Brightness.dark;
|
||||
return Container(
|
||||
width: double.infinity,
|
||||
padding: const EdgeInsets.all(AppSpacing.xl),
|
||||
decoration: BoxDecoration(
|
||||
color: isDark
|
||||
? colorScheme.surfaceContainer
|
||||
: colorScheme.surfaceContainerLowest,
|
||||
color: context.appColors.surfaceCard,
|
||||
borderRadius: BorderRadius.circular(AppRadius.lg),
|
||||
border: Border.all(
|
||||
color: colorScheme.outlineVariant.withOpacity(0.15),
|
||||
color: context.appColors.ghostBorder,
|
||||
),
|
||||
),
|
||||
child: Center(
|
||||
child: Text(message,
|
||||
style: AppTextStyles.headlineMedium(context).copyWith(
|
||||
color: colorScheme.onSurfaceVariant,
|
||||
color: context.colors.onSurfaceVariant,
|
||||
)),
|
||||
),
|
||||
);
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import '../../../../core/theme/app_color_scheme.dart';
|
||||
import '../../../../core/theme/app_spacing.dart';
|
||||
import '../../../../core/theme/app_theme.dart';
|
||||
import '../../../../core/theme/app_theme_extension.dart';
|
||||
import '../../../../data/models/coin.dart';
|
||||
|
||||
/// 价格卡片组件
|
||||
@@ -14,25 +14,21 @@ class PriceCard extends StatelessWidget {
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final colorScheme = Theme.of(context).colorScheme;
|
||||
final isDark = Theme.of(context).brightness == Brightness.dark;
|
||||
final isUp = coin.isUp;
|
||||
final changeColor =
|
||||
isUp ? AppColorScheme.getUpColor(isDark) : AppColorScheme.getDownColor(isDark);
|
||||
isUp ? context.appColors.up : context.appColors.down;
|
||||
final changeBgColor = isUp
|
||||
? AppColorScheme.getUpBackgroundColor(isDark)
|
||||
: AppColorScheme.getDownBackgroundColor(isDark);
|
||||
? context.appColors.upBackground
|
||||
: context.appColors.downBackground;
|
||||
|
||||
return Container(
|
||||
width: double.infinity,
|
||||
padding: const EdgeInsets.all(AppSpacing.md + AppSpacing.sm),
|
||||
decoration: BoxDecoration(
|
||||
color: isDark
|
||||
? colorScheme.surfaceContainer
|
||||
: colorScheme.surfaceContainerLowest,
|
||||
color: context.appColors.surfaceCard,
|
||||
borderRadius: BorderRadius.circular(AppRadius.lg),
|
||||
border: Border.all(
|
||||
color: colorScheme.outlineVariant.withOpacity(0.15),
|
||||
color: context.appColors.ghostBorder,
|
||||
),
|
||||
),
|
||||
child: Column(
|
||||
|
||||
@@ -2,6 +2,7 @@ import 'package:flutter/material.dart';
|
||||
import '../../../../core/theme/app_color_scheme.dart';
|
||||
import '../../../../core/theme/app_spacing.dart';
|
||||
import '../../../../core/theme/app_theme.dart';
|
||||
import '../../../../core/theme/app_theme_extension.dart';
|
||||
import '../../../../data/models/coin.dart';
|
||||
import 'amount_input.dart';
|
||||
|
||||
@@ -37,17 +38,13 @@ class TradeFormCard extends StatelessWidget {
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final colorScheme = Theme.of(context).colorScheme;
|
||||
final isDark = Theme.of(context).brightness == Brightness.dark;
|
||||
final isBuy = tradeType == 0;
|
||||
final actionColor = isBuy
|
||||
? AppColorScheme.getUpColor(isDark)
|
||||
: AppColorScheme.getDownColor(isDark);
|
||||
? context.appColors.up
|
||||
: context.appColors.down;
|
||||
|
||||
// 设计稿中 card 背景色
|
||||
final cardBgColor = isDark
|
||||
? colorScheme.surfaceContainer
|
||||
: colorScheme.surfaceContainerLowest;
|
||||
final cardBgColor = context.appColors.surfaceCard;
|
||||
|
||||
return Container(
|
||||
width: double.infinity,
|
||||
@@ -56,7 +53,7 @@ class TradeFormCard extends StatelessWidget {
|
||||
color: cardBgColor,
|
||||
borderRadius: BorderRadius.circular(AppRadius.lg),
|
||||
border: Border.all(
|
||||
color: colorScheme.outlineVariant.withOpacity(0.15),
|
||||
color: context.appColors.ghostBorder,
|
||||
),
|
||||
),
|
||||
child: Column(
|
||||
@@ -83,7 +80,7 @@ class TradeFormCard extends StatelessWidget {
|
||||
border: isBuy
|
||||
? null
|
||||
: Border.all(
|
||||
color: colorScheme.outlineVariant.withOpacity(0.15)),
|
||||
color: context.appColors.ghostBorder),
|
||||
),
|
||||
child: Center(
|
||||
child: Text(
|
||||
@@ -91,7 +88,7 @@ class TradeFormCard extends StatelessWidget {
|
||||
style: AppTextStyles.headlineMedium(context).copyWith(
|
||||
color: isBuy
|
||||
? AppColorScheme.darkOnPrimary
|
||||
: colorScheme.onSurfaceVariant,
|
||||
: context.colors.onSurfaceVariant,
|
||||
),
|
||||
),
|
||||
),
|
||||
@@ -113,7 +110,7 @@ class TradeFormCard extends StatelessWidget {
|
||||
border: !isBuy
|
||||
? null
|
||||
: Border.all(
|
||||
color: colorScheme.outlineVariant.withOpacity(0.15)),
|
||||
color: context.appColors.ghostBorder),
|
||||
),
|
||||
child: Center(
|
||||
child: Text(
|
||||
@@ -121,7 +118,7 @@ class TradeFormCard extends StatelessWidget {
|
||||
style: AppTextStyles.headlineMedium(context).copyWith(
|
||||
color: !isBuy
|
||||
? AppColorScheme.darkOnPrimary
|
||||
: colorScheme.onSurfaceVariant,
|
||||
: context.colors.onSurfaceVariant,
|
||||
),
|
||||
),
|
||||
),
|
||||
@@ -139,7 +136,7 @@ class TradeFormCard extends StatelessWidget {
|
||||
children: [
|
||||
Text('交易金额',
|
||||
style: AppTextStyles.bodyMedium(context).copyWith(
|
||||
color: colorScheme.onSurfaceVariant,
|
||||
color: context.colors.onSurfaceVariant,
|
||||
)),
|
||||
Text('USDT',
|
||||
style: AppTextStyles.labelLarge(context)),
|
||||
@@ -163,7 +160,7 @@ class TradeFormCard extends StatelessWidget {
|
||||
? '可用: $availableUsdt USDT'
|
||||
: '可用: $availableCoinQty ${selectedCoin?.code ?? ""}',
|
||||
style: AppTextStyles.bodySmall(context).copyWith(
|
||||
color: colorScheme.onSurfaceVariant,
|
||||
color: context.colors.onSurfaceVariant,
|
||||
),
|
||||
),
|
||||
const SizedBox(height: AppSpacing.md),
|
||||
@@ -172,13 +169,13 @@ class TradeFormCard extends StatelessWidget {
|
||||
// 设计稿:gap:8,圆角sm,bg-tertiary,高32
|
||||
Row(
|
||||
children: [
|
||||
_buildPctButton(context, '25%', 0.25, colorScheme),
|
||||
_buildPctButton(context, '25%', 0.25),
|
||||
const SizedBox(width: AppSpacing.sm),
|
||||
_buildPctButton(context, '50%', 0.5, colorScheme),
|
||||
_buildPctButton(context, '50%', 0.5),
|
||||
const SizedBox(width: AppSpacing.sm),
|
||||
_buildPctButton(context, '75%', 0.75, colorScheme),
|
||||
_buildPctButton(context, '75%', 0.75),
|
||||
const SizedBox(width: AppSpacing.sm),
|
||||
_buildPctButton(context, '100%', 1.0, colorScheme),
|
||||
_buildPctButton(context, '100%', 1.0),
|
||||
],
|
||||
),
|
||||
const SizedBox(height: AppSpacing.md + AppSpacing.sm),
|
||||
@@ -189,7 +186,7 @@ class TradeFormCard extends StatelessWidget {
|
||||
children: [
|
||||
Text('交易数量',
|
||||
style: AppTextStyles.bodyMedium(context).copyWith(
|
||||
color: colorScheme.onSurfaceVariant,
|
||||
color: context.colors.onSurfaceVariant,
|
||||
)),
|
||||
Text(
|
||||
'$calculatedQuantity ${selectedCoin?.code ?? ''}',
|
||||
@@ -203,20 +200,20 @@ class TradeFormCard extends StatelessWidget {
|
||||
}
|
||||
|
||||
/// 百分比按钮 - 设计稿:圆角sm,bg-tertiary,高32
|
||||
Widget _buildPctButton(BuildContext context, String label, double pct, ColorScheme colorScheme) {
|
||||
Widget _buildPctButton(BuildContext context, String label, double pct) {
|
||||
return Expanded(
|
||||
child: GestureDetector(
|
||||
onTap: () => onFillPercent(pct),
|
||||
child: Container(
|
||||
height: 32,
|
||||
decoration: BoxDecoration(
|
||||
color: colorScheme.surfaceContainerHighest.withOpacity(0.5),
|
||||
color: context.colors.surfaceContainerHighest.withValues(alpha: 0.5),
|
||||
borderRadius: BorderRadius.circular(AppRadius.sm),
|
||||
),
|
||||
child: Center(
|
||||
child: Text(label,
|
||||
style: AppTextStyles.labelLarge(context).copyWith(
|
||||
color: colorScheme.onSurfaceVariant,
|
||||
color: context.colors.onSurfaceVariant,
|
||||
)),
|
||||
),
|
||||
),
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:shadcn_ui/shadcn_ui.dart';
|
||||
import 'package:provider/provider.dart';
|
||||
import '../../../core/theme/app_color_scheme.dart';
|
||||
import '../../../core/theme/app_spacing.dart';
|
||||
import '../../../core/theme/app_theme_extension.dart';
|
||||
import '../../../data/models/coin.dart';
|
||||
import '../../../providers/market_provider.dart';
|
||||
import '../../../providers/asset_provider.dart';
|
||||
@@ -113,10 +113,9 @@ class _TradePageState extends State<TradePage>
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
super.build(context);
|
||||
final colorScheme = Theme.of(context).colorScheme;
|
||||
|
||||
return Scaffold(
|
||||
backgroundColor: colorScheme.background,
|
||||
backgroundColor: context.colors.background,
|
||||
body: Consumer2<MarketProvider, AssetProvider>(
|
||||
builder: (context, market, asset, _) {
|
||||
return SafeArea(
|
||||
@@ -150,7 +149,6 @@ class _TradePageState extends State<TradePage>
|
||||
else
|
||||
PlaceholderCard(
|
||||
message: '请先选择交易币种',
|
||||
colorScheme: colorScheme,
|
||||
),
|
||||
const SizedBox(height: AppSpacing.md),
|
||||
|
||||
@@ -262,8 +260,6 @@ class _TradePageState extends State<TradePage>
|
||||
}
|
||||
|
||||
void _showResultDialog(bool success, String title, String message) {
|
||||
final colorScheme = Theme.of(context).colorScheme;
|
||||
final isDark = Theme.of(context).brightness == Brightness.dark;
|
||||
showShadDialog(
|
||||
context: context,
|
||||
builder: (ctx) => ShadDialog.alert(
|
||||
@@ -272,8 +268,8 @@ class _TradePageState extends State<TradePage>
|
||||
NeonIcon(
|
||||
icon: success ? Icons.check_circle : Icons.error,
|
||||
color: success
|
||||
? AppColorScheme.getUpColor(isDark)
|
||||
: colorScheme.error,
|
||||
? ctx.appColors.up
|
||||
: ctx.colors.error,
|
||||
size: 24,
|
||||
),
|
||||
SizedBox(width: AppSpacing.sm),
|
||||
|
||||
Reference in New Issue
Block a user