refactor(theme): 迁移主题感知颜色至 ThemeExtension

- 创建 AppThemeColors ThemeExtension 类,统一管理主题感知颜色(涨跌色、卡片背景、渐变等)
- 从 AppColorScheme 移除主题感知辅助函数,仅保留静态颜色常量
- 在 AppTheme 中注册 ThemeExtension,支持深色/浅色主题工厂
- 重构所有 UI 组件使用 context.appColors 访问主题颜色,替代硬编码的 AppColorScheme 方法调用
- 移除组件中重复的 isDark 判断逻辑,简化颜色获取方式
- 保持向后兼容性,所有现有功能不变
This commit is contained in:
2026-04-06 01:58:08 +08:00
parent 396668aa43
commit 7ed2435a4c
36 changed files with 658 additions and 810 deletions

View File

@@ -178,57 +178,14 @@ class AppColorScheme {
static const Color info = Color(0xFF2196F3); static const Color info = Color(0xFF2196F3);
// ============================================ // ============================================
// 主题感知辅助函数 - 根据明暗模式选择正确的颜色 // 主题感知辅助函数 - 已迁移至 AppThemeColors ThemeExtension
// 以下方法保留仅供 AppThemeColors 工厂内部使用
// ============================================ // ============================================
/// 获取涨跌颜色(主题感知)
///
/// 在深色模式下使用亮绿色 (#afffd1),在亮色模式下使用深绿色 (#00a878) 以确保对比度
static Color getUpColor(bool isDark) => isDark ? darkTertiary : lightTertiary;
/// 获取涨跌背景色(主题感知)
///
/// 带透明度的背景色,用于标签、徽章等
static Color getUpBackgroundColor(bool isDark, {double opacity = 0.15}) {
return isDark
? darkTertiary.withValues(alpha: opacity)
: lightTertiary.withValues(alpha: opacity);
}
/// 获取跌/卖出颜色(主题感知)
static Color getDownColor(bool isDark) => isDark ? darkError : lightError;
/// 获取跌/卖出背景色(主题感知)
static Color getDownBackgroundColor(bool isDark, {double opacity = 0.15}) {
return isDark
? darkError.withValues(alpha: opacity)
: lightError.withValues(alpha: opacity);
}
/// 交易按钮买入色 - 深绿色填充,确保白色文字可读
static const Color buyButtonFill = Color(0xFF059669); static const Color buyButtonFill = Color(0xFF059669);
/// 交易按钮卖出色 - 深红色填充,确保白色文字可读 /// 交易按钮卖出色 - 深红色填充,确保白色文字可读
static const Color sellButtonFill = Color(0xFFDC2626); static const Color sellButtonFill = Color(0xFFDC2626);
/// 获取买入按钮渐变(主题感知)
static LinearGradient getBuyGradient(bool isDark) => LinearGradient(
colors: isDark
? [darkTertiary, darkTertiaryContainer]
: [lightTertiary, lightTertiaryContainer],
begin: const Alignment(-0.7, -0.7),
end: const Alignment(0.7, 0.7),
);
/// 获取翡翠渐变(主题感知)- 用于盈利展示
static LinearGradient getEmeraldGradient(bool isDark) => LinearGradient(
colors: isDark
? [darkTertiary, const Color(0xFF7de8b8)]
: [lightTertiary, const Color(0xFF00c987)],
begin: Alignment.topLeft,
end: Alignment.bottomRight,
);
// ============================================ // ============================================
// 渐变预设 // 渐变预设
// ============================================ // ============================================
@@ -426,14 +383,6 @@ class AppColorScheme {
/// 获取买入按钮渐变(主题感知)- 用于盈利展示 /// 获取买入按钮渐变(主题感知)- 用于盈利展示
/// 获取涨跌颜色(明暗通用)
static Color getChangeColor(bool isUp) => isUp ? AppColorScheme.up : AppColorScheme.down;
/// 获取涨跌背景色(带透明度)
static Color getChangeBackgroundColor(bool isUp, {double opacity = 0.15}) {
return isUp
? AppColorScheme.up.withValues(alpha: opacity)
: AppColorScheme.down.withValues(alpha: opacity);
}
} }

View File

@@ -2,6 +2,7 @@ import 'package:flutter/material.dart';
import 'package:google_fonts/google_fonts.dart'; import 'package:google_fonts/google_fonts.dart';
import 'app_color_scheme.dart'; import 'app_color_scheme.dart';
import 'app_spacing.dart'; import 'app_spacing.dart';
import 'app_theme_extension.dart';
/// "The Kinetic Vault" & "The Ethereal Terminal" 主题配置 /// "The Kinetic Vault" & "The Ethereal Terminal" 主题配置
class AppTheme { class AppTheme {
@@ -18,6 +19,9 @@ class AppTheme {
scaffoldBackgroundColor: AppColorScheme.darkBackground, scaffoldBackgroundColor: AppColorScheme.darkBackground,
primaryColor: AppColorScheme.darkPrimary, primaryColor: AppColorScheme.darkPrimary,
colorScheme: AppColorScheme.darkMaterial, colorScheme: AppColorScheme.darkMaterial,
extensions: <ThemeExtension<dynamic>>[
AppThemeColors.dark(),
],
// AppBar - 无边框规则 // AppBar - 无边框规则
appBarTheme: AppBarTheme( appBarTheme: AppBarTheme(
@@ -121,6 +125,9 @@ class AppTheme {
scaffoldBackgroundColor: AppColorScheme.lightBackground, scaffoldBackgroundColor: AppColorScheme.lightBackground,
primaryColor: AppColorScheme.lightPrimary, primaryColor: AppColorScheme.lightPrimary,
colorScheme: AppColorScheme.lightMaterial, colorScheme: AppColorScheme.lightMaterial,
extensions: <ThemeExtension<dynamic>>[
AppThemeColors.light(),
],
// AppBar - 珍珠白 // AppBar - 珍珠白
appBarTheme: AppBarTheme( appBarTheme: AppBarTheme(

View File

@@ -0,0 +1,220 @@
import 'package:flutter/material.dart';
import 'app_color_scheme.dart';
/// 自定义主题扩展 — 注册到 ThemeData.extensions 中
///
/// 存放 ColorScheme 标准槽位无法覆盖的语义色:
/// - 卡片背景语义色dark/light 使用不同 surface 层级)
/// - 涨跌金融色(含带透明度的背景色)
/// - 渐变预设
/// - 光效透明度等
@immutable
class AppThemeColors extends ThemeExtension<AppThemeColors> {
// ---- 卡片背景语义色 ----
/// 标准卡片背景dark: surfaceContainer, light: surfaceContainerHigh
final Color surfaceCard;
/// 高亮卡片背景dark: surfaceContainerHighest, light: surfaceContainerHigh
final Color surfaceCardHigh;
// ---- 文字语义 ----
/// 弱化/辅助文字
final Color onSurfaceMuted;
// ---- 涨跌金融色 ----
/// 涨/盈利/买入
final Color up;
final Color upBackground;
/// 跌/亏损/卖出
final Color down;
final Color downBackground;
// ---- 强调色 ----
/// 主强调色dark: secondary 金色, light: primary 蓝色)
final Color accentPrimary;
// ---- 光效 ----
/// 光晕透明度dark: 0.15, light: 0.08
final double glowOpacity;
// ---- 边框 ----
/// Ghost BorderoutlineVariant 带透明度)
final Color ghostBorder;
// ---- 渐变预设 ----
final LinearGradient ctaGradient;
final LinearGradient buyGradient;
final LinearGradient sellGradient;
final LinearGradient assetGradient;
final LinearGradient emeraldGradient;
const AppThemeColors({
required this.surfaceCard,
required this.surfaceCardHigh,
required this.onSurfaceMuted,
required this.up,
required this.upBackground,
required this.down,
required this.downBackground,
required this.accentPrimary,
required this.glowOpacity,
required this.ghostBorder,
required this.ctaGradient,
required this.buyGradient,
required this.sellGradient,
required this.assetGradient,
required this.emeraldGradient,
});
/// 深色主题工厂
factory AppThemeColors.dark() => AppThemeColors(
surfaceCard: AppColorScheme.darkSurfaceContainer,
surfaceCardHigh: AppColorScheme.darkSurfaceContainerHighest,
onSurfaceMuted: AppColorScheme.darkOnSurfaceMuted,
up: AppColorScheme.darkTertiary,
upBackground: AppColorScheme.darkTertiary.withValues(alpha: 0.15),
down: AppColorScheme.darkError,
downBackground: AppColorScheme.darkError.withValues(alpha: 0.15),
accentPrimary: AppColorScheme.darkSecondary,
glowOpacity: 0.15,
ghostBorder: AppColorScheme.darkOutlineVariant.withValues(alpha: 0.15),
ctaGradient: AppColorScheme.darkCtaGradient,
buyGradient: AppColorScheme.buyGradient,
sellGradient: AppColorScheme.sellGradient,
assetGradient: AppColorScheme.assetCardGradient,
emeraldGradient: const LinearGradient(
colors: [AppColorScheme.darkTertiary, Color(0xFF7de8b8)],
begin: Alignment.topLeft,
end: Alignment.bottomRight,
),
);
/// 浅色主题工厂
factory AppThemeColors.light() => AppThemeColors(
surfaceCard: AppColorScheme.lightSurfaceContainerHigh,
surfaceCardHigh: AppColorScheme.lightSurfaceContainerHigh,
onSurfaceMuted: AppColorScheme.lightOnSurfaceMuted,
up: AppColorScheme.lightTertiary,
upBackground: AppColorScheme.lightTertiary.withValues(alpha: 0.15),
down: AppColorScheme.lightError,
downBackground: AppColorScheme.lightError.withValues(alpha: 0.15),
accentPrimary: AppColorScheme.lightPrimary,
glowOpacity: 0.08,
ghostBorder: AppColorScheme.lightOutlineVariant.withValues(alpha: 0.5),
ctaGradient: AppColorScheme.lightCtaGradient,
buyGradient: const LinearGradient(
colors: [AppColorScheme.lightTertiary, AppColorScheme.lightTertiaryContainer],
begin: Alignment(-0.7, -0.7),
end: Alignment(0.7, 0.7),
),
sellGradient: AppColorScheme.sellGradient,
assetGradient: const LinearGradient(
colors: [AppColorScheme.lightPrimary, AppColorScheme.lightSecondary],
begin: Alignment.topLeft,
end: Alignment.bottomRight,
),
emeraldGradient: const LinearGradient(
colors: [AppColorScheme.lightTertiary, Color(0xFF00c987)],
begin: Alignment.topLeft,
end: Alignment.bottomRight,
),
);
@override
AppThemeColors copyWith({
Color? surfaceCard,
Color? surfaceCardHigh,
Color? onSurfaceMuted,
Color? up,
Color? upBackground,
Color? down,
Color? downBackground,
Color? accentPrimary,
double? glowOpacity,
Color? ghostBorder,
LinearGradient? ctaGradient,
LinearGradient? buyGradient,
LinearGradient? sellGradient,
LinearGradient? assetGradient,
LinearGradient? emeraldGradient,
}) {
return AppThemeColors(
surfaceCard: surfaceCard ?? this.surfaceCard,
surfaceCardHigh: surfaceCardHigh ?? this.surfaceCardHigh,
onSurfaceMuted: onSurfaceMuted ?? this.onSurfaceMuted,
up: up ?? this.up,
upBackground: upBackground ?? this.upBackground,
down: down ?? this.down,
downBackground: downBackground ?? this.downBackground,
accentPrimary: accentPrimary ?? this.accentPrimary,
glowOpacity: glowOpacity ?? this.glowOpacity,
ghostBorder: ghostBorder ?? this.ghostBorder,
ctaGradient: ctaGradient ?? this.ctaGradient,
buyGradient: buyGradient ?? this.buyGradient,
sellGradient: sellGradient ?? this.sellGradient,
assetGradient: assetGradient ?? this.assetGradient,
emeraldGradient: emeraldGradient ?? this.emeraldGradient,
);
}
@override
AppThemeColors lerp(AppThemeColors other, double t) {
if (t < 0.5) {
return copyWith(
surfaceCard: Color.lerp(surfaceCard, other.surfaceCard, t * 2),
surfaceCardHigh:
Color.lerp(surfaceCardHigh, other.surfaceCardHigh, t * 2),
onSurfaceMuted:
Color.lerp(onSurfaceMuted, other.onSurfaceMuted, t * 2),
up: Color.lerp(up, other.up, t * 2),
upBackground: Color.lerp(upBackground, other.upBackground, t * 2),
down: Color.lerp(down, other.down, t * 2),
downBackground: Color.lerp(downBackground, other.downBackground, t * 2),
accentPrimary:
Color.lerp(accentPrimary, other.accentPrimary, t * 2),
ghostBorder: Color.lerp(ghostBorder, other.ghostBorder, t * 2),
glowOpacity: lerpDouble(glowOpacity, other.glowOpacity, t * 2),
);
}
return other.copyWith(
surfaceCard: Color.lerp(other.surfaceCard, surfaceCard, (1 - t) * 2),
surfaceCardHigh: Color.lerp(
other.surfaceCardHigh, surfaceCardHigh, (1 - t) * 2),
onSurfaceMuted:
Color.lerp(other.onSurfaceMuted, onSurfaceMuted, (1 - t) * 2),
up: Color.lerp(other.up, up, (1 - t) * 2),
upBackground: Color.lerp(other.upBackground, upBackground, (1 - t) * 2),
down: Color.lerp(other.down, down, (1 - t) * 2),
downBackground:
Color.lerp(other.downBackground, downBackground, (1 - t) * 2),
accentPrimary:
Color.lerp(other.accentPrimary, accentPrimary, (1 - t) * 2),
ghostBorder: Color.lerp(other.ghostBorder, ghostBorder, (1 - t) * 2),
glowOpacity: lerpDouble(other.glowOpacity, glowOpacity, (1 - t) * 2),
);
}
static double lerpDouble(double a, double b, double t) => a + (b - a) * t;
}
/// BuildContext 主题快捷扩展
///
/// 用法:
/// context.colors.primary → Theme.of(context).colorScheme.primary
/// context.appColors.up → AppThemeColors 中的涨色
/// context.isDark → 是否深色模式
extension AppThemeContext on BuildContext {
/// Material ColorScheme 快捷访问
ColorScheme get colors => Theme.of(this).colorScheme;
/// 自定义语义色快捷访问
AppThemeColors get appColors =>
Theme.of(this).extension<AppThemeColors>()!;
/// 是否深色模式
bool get isDark => Theme.of(this).brightness == Brightness.dark;
/// TextTheme 快捷访问
TextTheme get textStyles => Theme.of(this).textTheme;
}

View File

@@ -77,7 +77,7 @@ class MyApp extends StatelessWidget {
colorScheme: AppColorScheme.darkShad, colorScheme: AppColorScheme.darkShad,
brightness: Brightness.dark, brightness: Brightness.dark,
), ),
appBuilder: _buildMaterialApp, appBuilder: (context) => _buildMaterialApp(context, themeProvider.themeMode),
); );
}, },
), ),
@@ -123,10 +123,12 @@ class MyApp extends StatelessWidget {
]; ];
} }
Widget _buildMaterialApp(BuildContext context) { Widget _buildMaterialApp(BuildContext context, ThemeMode themeMode) {
return MaterialApp( return MaterialApp(
debugShowCheckedModeBanner: false, debugShowCheckedModeBanner: false,
theme: Theme.of(context), theme: AppTheme.lightTheme,
darkTheme: AppTheme.darkTheme,
themeMode: themeMode,
localizationsDelegates: const [ localizationsDelegates: const [
GlobalShadLocalizations.delegate, GlobalShadLocalizations.delegate,
GlobalMaterialLocalizations.delegate, GlobalMaterialLocalizations.delegate,

View File

@@ -1,8 +1,8 @@
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:shadcn_ui/shadcn_ui.dart'; import 'package:shadcn_ui/shadcn_ui.dart';
import 'package:flutter_animate/flutter_animate.dart'; import 'package:flutter_animate/flutter_animate.dart';
import '../../core/theme/app_color_scheme.dart';
import '../../core/theme/app_spacing.dart'; import '../../core/theme/app_spacing.dart';
import '../../core/theme/app_theme_extension.dart';
/// 资产卡片组件 - 用于显示资产总览 /// 资产卡片组件 - 用于显示资产总览
/// ///
@@ -21,24 +21,6 @@ class AssetCard extends StatelessWidget {
final Gradient? gradient; final Gradient? gradient;
final VoidCallback? onTap; final VoidCallback? onTap;
/// 默认渐变色 - Neon Blue → Electric Purple
static LinearGradient defaultGradientBuilder(bool isDark) => LinearGradient(
colors: isDark
? [AppColorScheme.darkPrimary, AppColorScheme.darkSecondary]
: [AppColorScheme.lightPrimary, AppColorScheme.lightSecondary],
begin: Alignment.topLeft,
end: Alignment.bottomRight,
);
/// 翡翠渐变 - 用于盈利展示(主题感知)
static LinearGradient getEmeraldGradient(bool isDark) => LinearGradient(
colors: isDark
? [AppColorScheme.darkTertiary, const Color(0xFF7de8b8)]
: [AppColorScheme.lightTertiary, const Color(0xFF00c987)],
begin: Alignment.topLeft,
end: Alignment.bottomRight,
);
const AssetCard({ const AssetCard({
super.key, super.key,
this.title = '总资产', this.title = '总资产',
@@ -54,9 +36,9 @@ class AssetCard extends StatelessWidget {
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
final theme = ShadTheme.of(context); final theme = ShadTheme.of(context);
final colorScheme = Theme.of(context).colorScheme; final colorScheme = context.colors;
final isDark = Theme.of(context).brightness == Brightness.dark; final appColors = context.appColors;
final cardGradient = gradient ?? defaultGradientBuilder(isDark); final cardGradient = gradient ?? appColors.assetGradient;
// 主题感知颜色 - 在渐变背景上使用 onPrimary // 主题感知颜色 - 在渐变背景上使用 onPrimary
final primaryTextColor = colorScheme.onPrimary; final primaryTextColor = colorScheme.onPrimary;
@@ -197,6 +179,7 @@ class AssetCardCompact extends StatelessWidget {
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
final theme = ShadTheme.of(context); final theme = ShadTheme.of(context);
final appColors = context.appColors;
final isValueUp = isUp ?? true; final isValueUp = isUp ?? true;
return ShadCard( return ShadCard(
@@ -227,13 +210,13 @@ class AssetCardCompact extends StatelessWidget {
Container( Container(
padding: const EdgeInsets.symmetric(horizontal: 10, vertical: 6), padding: const EdgeInsets.symmetric(horizontal: 10, vertical: 6),
decoration: BoxDecoration( decoration: BoxDecoration(
color: AppColorScheme.getChangeBackgroundColor(isValueUp), color: isValueUp ? appColors.upBackground : appColors.downBackground,
borderRadius: BorderRadius.circular(AppRadius.sm), borderRadius: BorderRadius.circular(AppRadius.sm),
), ),
child: Text( child: Text(
change!, change!,
style: TextStyle( style: TextStyle(
color: AppColorScheme.getChangeColor(isValueUp), color: isValueUp ? appColors.up : appColors.down,
fontWeight: FontWeight.w600, fontWeight: FontWeight.w600,
), ),
), ),

View File

@@ -1,7 +1,7 @@
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:shadcn_ui/shadcn_ui.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_spacing.dart';
import '../../core/theme/app_theme_extension.dart';
/// 币种卡片组件 - 用于显示币种信息 /// 币种卡片组件 - 用于显示币种信息
/// ///
@@ -81,13 +81,13 @@ class CoinCard extends StatelessWidget {
Container( Container(
padding: const EdgeInsets.symmetric(horizontal: 10, vertical: 6), padding: const EdgeInsets.symmetric(horizontal: 10, vertical: 6),
decoration: BoxDecoration( decoration: BoxDecoration(
color: AppColorScheme.getChangeBackgroundColor(isUp), color: isUp ? context.appColors.upBackground : context.appColors.downBackground,
borderRadius: BorderRadius.circular(AppRadius.sm), borderRadius: BorderRadius.circular(AppRadius.sm),
), ),
child: Text( child: Text(
change, change,
style: TextStyle( style: TextStyle(
color: AppColorScheme.getChangeColor(isUp), color: isUp ? context.appColors.up : context.appColors.down,
fontWeight: FontWeight.w600, fontWeight: FontWeight.w600,
), ),
), ),

View File

@@ -1,5 +1,6 @@
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import '../../core/theme/app_spacing.dart'; import '../../core/theme/app_spacing.dart';
import '../../core/theme/app_theme_extension.dart';
/// GlassPanel - 实心背景面板 /// GlassPanel - 实心背景面板
/// ///
@@ -55,11 +56,8 @@ class GlassPanel extends StatelessWidget {
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
final colorScheme = Theme.of(context).colorScheme; final bgColor = backgroundColor ?? context.appColors.surfaceCard;
final isDark = Theme.of(context).brightness == Brightness.dark; final brColor = borderColor ?? context.appColors.ghostBorder;
final bgColor = backgroundColor ??
(isDark ? colorScheme.surfaceContainer : colorScheme.surfaceContainerHigh);
final brColor = borderColor ?? colorScheme.outlineVariant.withOpacity(0.15);
final br = borderRadius ?? BorderRadius.circular(AppRadius.xl); final br = borderRadius ?? BorderRadius.circular(AppRadius.xl);
Widget content = Container( Widget content = Container(
@@ -133,11 +131,9 @@ class GlassCard extends StatelessWidget {
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
final colorScheme = Theme.of(context).colorScheme;
final isDark = Theme.of(context).brightness == Brightness.dark;
final br = borderRadius ?? BorderRadius.circular(AppRadius.xl); final br = borderRadius ?? BorderRadius.circular(AppRadius.xl);
final glowColor = neonGlowColor ?? final glowColor = neonGlowColor ??
colorScheme.primary.withOpacity(isDark ? 0.15 : 0.08); context.colors.primary.withValues(alpha: context.appColors.glowOpacity);
Widget card = GlassPanel( Widget card = GlassPanel(
padding: padding ?? EdgeInsets.all(AppSpacing.md), padding: padding ?? EdgeInsets.all(AppSpacing.md),
@@ -200,17 +196,14 @@ class GlassBottomSheet extends StatelessWidget {
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
final colorScheme = Theme.of(context).colorScheme;
final isDark = Theme.of(context).brightness == Brightness.dark;
return Container( return Container(
decoration: BoxDecoration( decoration: BoxDecoration(
color: isDark ? colorScheme.surfaceContainer : colorScheme.surfaceContainerHigh, color: context.appColors.surfaceCard,
borderRadius: const BorderRadius.vertical( borderRadius: const BorderRadius.vertical(
top: Radius.circular(AppRadius.xxl), top: Radius.circular(AppRadius.xxl),
), ),
border: Border.all( border: Border.all(
color: colorScheme.outlineVariant.withOpacity(0.15), color: context.appColors.ghostBorder,
), ),
), ),
child: Column( child: Column(
@@ -222,7 +215,7 @@ class GlassBottomSheet extends StatelessWidget {
width: 40, width: 40,
height: 4, height: 4,
decoration: BoxDecoration( decoration: BoxDecoration(
color: colorScheme.outlineVariant.withOpacity(0.5), color: context.colors.outlineVariant.withValues(alpha: 0.5),
borderRadius: BorderRadius.circular(2), borderRadius: BorderRadius.circular(2),
), ),
), ),
@@ -244,7 +237,7 @@ class GlassBottomSheet extends StatelessWidget {
style: TextStyle( style: TextStyle(
fontSize: 18, fontSize: 18,
fontWeight: FontWeight.bold, fontWeight: FontWeight.bold,
color: colorScheme.onSurface, color: context.colors.onSurface,
), ),
), ),
), ),
@@ -254,14 +247,14 @@ class GlassBottomSheet extends StatelessWidget {
child: Container( child: Container(
padding: EdgeInsets.all(AppSpacing.sm), padding: EdgeInsets.all(AppSpacing.sm),
decoration: BoxDecoration( decoration: BoxDecoration(
color: colorScheme.outlineVariant color: context.colors.outlineVariant
.withOpacity(0.2), .withOpacity(0.2),
shape: BoxShape.circle, shape: BoxShape.circle,
), ),
child: Icon( child: Icon(
Icons.close, Icons.close,
size: 18, size: 18,
color: colorScheme.onSurfaceVariant, color: context.colors.onSurfaceVariant,
), ),
), ),
), ),

View File

@@ -1,6 +1,6 @@
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import '../../core/theme/app_color_scheme.dart';
import '../../core/theme/app_spacing.dart'; import '../../core/theme/app_spacing.dart';
import '../../core/theme/app_theme_extension.dart';
/// 渐变按钮组件 - 支持 CTA 渐变效果 /// 渐变按钮组件 - 支持 CTA 渐变效果
/// ///
@@ -36,7 +36,6 @@ class GradientButton extends StatelessWidget {
bool isLoading = false, bool isLoading = false,
bool isFullWidth = true, bool isFullWidth = true,
IconData? icon, IconData? icon,
bool isDark = true,
}) { }) {
return GradientButton( return GradientButton(
key: key, key: key,
@@ -45,7 +44,6 @@ class GradientButton extends StatelessWidget {
isLoading: isLoading, isLoading: isLoading,
isFullWidth: isFullWidth, isFullWidth: isFullWidth,
icon: icon, icon: icon,
gradient: isDark ? AppColorScheme.darkCtaGradient : AppColorScheme.lightCtaGradient,
); );
} }
@@ -57,6 +55,7 @@ class GradientButton extends StatelessWidget {
bool isLoading = false, bool isLoading = false,
bool isFullWidth = true, bool isFullWidth = true,
IconData? icon, IconData? icon,
LinearGradient? gradient,
}) { }) {
return GradientButton( return GradientButton(
key: key, key: key,
@@ -65,7 +64,6 @@ class GradientButton extends StatelessWidget {
isLoading: isLoading, isLoading: isLoading,
isFullWidth: isFullWidth, isFullWidth: isFullWidth,
icon: icon ?? Icons.arrow_downward_rounded, icon: icon ?? Icons.arrow_downward_rounded,
gradient: AppColorScheme.buyGradient,
); );
} }
@@ -77,6 +75,7 @@ class GradientButton extends StatelessWidget {
bool isLoading = false, bool isLoading = false,
bool isFullWidth = true, bool isFullWidth = true,
IconData? icon, IconData? icon,
LinearGradient? gradient,
}) { }) {
return GradientButton( return GradientButton(
key: key, key: key,
@@ -85,16 +84,14 @@ class GradientButton extends StatelessWidget {
isLoading: isLoading, isLoading: isLoading,
isFullWidth: isFullWidth, isFullWidth: isFullWidth,
icon: icon ?? Icons.arrow_upward_rounded, icon: icon ?? Icons.arrow_upward_rounded,
gradient: AppColorScheme.sellGradient,
); );
} }
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
final isDark = Theme.of(context).brightness == Brightness.dark; final appColors = context.appColors;
final colorScheme = Theme.of(context).colorScheme; final colorScheme = context.colors;
final buttonGradient = gradient ?? final buttonGradient = gradient ?? appColors.ctaGradient;
(isDark ? AppColorScheme.darkCtaGradient : AppColorScheme.lightCtaGradient);
// 主题感知颜色 - 在渐变背景上使用 onPrimary // 主题感知颜色 - 在渐变背景上使用 onPrimary
final textColor = colorScheme.onPrimary; final textColor = colorScheme.onPrimary;
@@ -172,11 +169,8 @@ class GhostButton extends StatelessWidget {
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
final isDark = Theme.of(context).brightness == Brightness.dark; final textColor = context.colors.primary;
final textColor = isDark ? AppColorScheme.darkPrimary : AppColorScheme.lightPrimary; final borderColor = context.appColors.ghostBorder;
final borderColor = isDark
? AppColorScheme.darkOutlineVariant.withValues(alpha: 0.15)
: AppColorScheme.lightOutlineVariant.withValues(alpha: 0.3);
return Container( return Container(
width: isFullWidth ? double.infinity : null, width: isFullWidth ? double.infinity : null,

View File

@@ -1,6 +1,7 @@
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import '../../core/theme/app_color_scheme.dart'; import '../../core/theme/app_color_scheme.dart';
import '../../core/theme/app_spacing.dart'; import '../../core/theme/app_spacing.dart';
import '../../core/theme/app_theme_extension.dart';
/// NeonGlow - 霓虹光效组件 /// NeonGlow - 霓虹光效组件
/// ///
@@ -94,7 +95,7 @@ class NeonGlow extends StatelessWidget {
}) { }) {
return NeonGlow( return NeonGlow(
key: key, key: key,
glowColor: AppColorScheme.down.withOpacity(0.3), glowColor: AppColorScheme.down.withValues(alpha: 0.3),
blurRadius: blurRadius, blurRadius: blurRadius,
borderRadius: borderRadius, borderRadius: borderRadius,
child: child, child: child,
@@ -205,16 +206,15 @@ class _NeonButtonState extends State<NeonButton>
} }
Color get _backgroundColor { Color get _backgroundColor {
final isDark = Theme.of(context).brightness == Brightness.dark; final colors = context.colors;
final colorScheme = Theme.of(context).colorScheme;
switch (widget.type) { switch (widget.type) {
case NeonButtonType.primary: case NeonButtonType.primary:
return colorScheme.primary; return colors.primary;
case NeonButtonType.secondary: case NeonButtonType.secondary:
return colorScheme.secondary; return colors.secondary;
case NeonButtonType.tertiary: case NeonButtonType.tertiary:
return AppColorScheme.getUpColor(isDark); return context.appColors.up;
case NeonButtonType.error: case NeonButtonType.error:
return AppColorScheme.down; return AppColorScheme.down;
case NeonButtonType.outline: case NeonButtonType.outline:
@@ -223,38 +223,37 @@ class _NeonButtonState extends State<NeonButton>
} }
Color get _foregroundColor { Color get _foregroundColor {
final isDark = Theme.of(context).brightness == Brightness.dark; final colors = context.colors;
final colorScheme = Theme.of(context).colorScheme;
switch (widget.type) { switch (widget.type) {
case NeonButtonType.primary: case NeonButtonType.primary:
return isDark ? AppColorScheme.darkOnPrimary : const Color(0xFFFFFFFF); return colors.onPrimary;
case NeonButtonType.secondary: case NeonButtonType.secondary:
return isDark ? AppColorScheme.darkOnSecondary : const Color(0xFFFFFFFF); return colors.onSecondary;
case NeonButtonType.tertiary: case NeonButtonType.tertiary:
return isDark ? AppColorScheme.darkOnTertiary : const Color(0xFFFFFFFF); return colors.onTertiary;
case NeonButtonType.error: case NeonButtonType.error:
return const Color(0xFFFFFFFF); return const Color(0xFFFFFFFF);
case NeonButtonType.outline: case NeonButtonType.outline:
return colorScheme.primary; return colors.primary;
} }
} }
Color get _glowColor { Color get _glowColor {
final isDark = Theme.of(context).brightness == Brightness.dark; final colors = context.colors;
final colorScheme = Theme.of(context).colorScheme; final appColors = context.appColors;
switch (widget.type) { switch (widget.type) {
case NeonButtonType.primary: case NeonButtonType.primary:
return colorScheme.primary.withOpacity(isDark ? 0.15 : 0.08); return colors.primary.withValues(alpha: appColors.glowOpacity);
case NeonButtonType.secondary: case NeonButtonType.secondary:
return colorScheme.secondary.withOpacity(isDark ? 0.15 : 0.08); return colors.secondary.withValues(alpha: appColors.glowOpacity);
case NeonButtonType.tertiary: case NeonButtonType.tertiary:
return AppColorScheme.getUpBackgroundColor(isDark, opacity: isDark ? 0.2 : 0.1); return context.appColors.upBackground;
case NeonButtonType.error: case NeonButtonType.error:
return AppColorScheme.down.withOpacity(0.3); return AppColorScheme.down.withValues(alpha: 0.3);
case NeonButtonType.outline: case NeonButtonType.outline:
return colorScheme.primary.withOpacity(isDark ? 0.15 : 0.08); return colors.primary.withValues(alpha: appColors.glowOpacity);
} }
} }
@@ -265,8 +264,7 @@ class _NeonButtonState extends State<NeonButton>
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
final colorScheme = Theme.of(context).colorScheme; final colors = context.colors;
final isDark = Theme.of(context).brightness == Brightness.dark;
final button = GestureDetector( final button = GestureDetector(
onTapDown: widget.onPressed != null ? _onTapDown : null, onTapDown: widget.onPressed != null ? _onTapDown : null,
@@ -286,7 +284,7 @@ class _NeonButtonState extends State<NeonButton>
), ),
border: widget.type == NeonButtonType.outline border: widget.type == NeonButtonType.outline
? Border.all( ? Border.all(
color: colorScheme.outlineVariant.withOpacity(0.3), color: colors.outlineVariant.withValues(alpha: 0.3),
) )
: null, : null,
), ),

View File

@@ -1,5 +1,6 @@
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import '../../../../core/theme/app_theme.dart'; import '../../../../core/theme/app_theme.dart';
import '../../../../core/theme/app_theme_extension.dart';
import '../../../../core/theme/app_spacing.dart'; import '../../../../core/theme/app_spacing.dart';
/// 账户标签切换器 — .pen node UE6xC /// 账户标签切换器 — .pen node UE6xC
@@ -19,14 +20,11 @@ class AccountTabSwitcher extends StatelessWidget {
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
final colorScheme = Theme.of(context).colorScheme;
final isDark = Theme.of(context).brightness == Brightness.dark;
return Container( return Container(
height: 40, height: 40,
padding: const EdgeInsets.all(3), padding: const EdgeInsets.all(3),
decoration: BoxDecoration( decoration: BoxDecoration(
color: isDark ? colorScheme.surfaceContainerHighest : colorScheme.surfaceContainerHigh, color: context.appColors.surfaceCardHigh,
borderRadius: BorderRadius.circular(AppRadius.md), borderRadius: BorderRadius.circular(AppRadius.md),
), ),
child: Row( child: Row(
@@ -36,14 +34,12 @@ class AccountTabSwitcher extends StatelessWidget {
label: '资金账户', label: '资金账户',
isSelected: selectedIndex == 0, isSelected: selectedIndex == 0,
onTap: () => onChanged(0), onTap: () => onChanged(0),
isDark: isDark,
), ),
_buildTab( _buildTab(
context: context, context: context,
label: '交易账户', label: '交易账户',
isSelected: selectedIndex == 1, isSelected: selectedIndex == 1,
onTap: () => onChanged(1), onTap: () => onChanged(1),
isDark: isDark,
), ),
], ],
), ),
@@ -55,10 +51,7 @@ class AccountTabSwitcher extends StatelessWidget {
required String label, required String label,
required bool isSelected, required bool isSelected,
required VoidCallback onTap, required VoidCallback onTap,
required bool isDark,
}) { }) {
final colorScheme = Theme.of(context).colorScheme;
return Expanded( return Expanded(
child: GestureDetector( child: GestureDetector(
onTap: onTap, onTap: onTap,
@@ -66,13 +59,13 @@ class AccountTabSwitcher extends StatelessWidget {
duration: const Duration(milliseconds: 200), duration: const Duration(milliseconds: 200),
decoration: BoxDecoration( decoration: BoxDecoration(
color: isSelected color: isSelected
? colorScheme.surface ? context.colors.surface
: const Color(0x00000000), : const Color(0x00000000),
borderRadius: BorderRadius.circular(AppRadius.sm), borderRadius: BorderRadius.circular(AppRadius.sm),
boxShadow: isSelected boxShadow: isSelected
? [ ? [
BoxShadow( BoxShadow(
color: colorScheme.shadow.withValues(alpha: 0.05), color: context.colors.shadow.withValues(alpha: 0.05),
blurRadius: 3, blurRadius: 3,
offset: const Offset(0, 1), offset: const Offset(0, 1),
), ),
@@ -86,7 +79,7 @@ class AccountTabSwitcher extends StatelessWidget {
? AppTextStyles.headlineMedium(context) ? AppTextStyles.headlineMedium(context)
: AppTextStyles.headlineMedium(context).copyWith( : AppTextStyles.headlineMedium(context).copyWith(
fontWeight: FontWeight.w500, fontWeight: FontWeight.w500,
color: colorScheme.onSurfaceVariant, color: context.colors.onSurfaceVariant,
), ),
), ),
), ),

View File

@@ -2,6 +2,7 @@ import 'package:flutter/material.dart';
import 'package:lucide_icons_flutter/lucide_icons.dart'; import 'package:lucide_icons_flutter/lucide_icons.dart';
import '../../../../core/theme/app_spacing.dart'; import '../../../../core/theme/app_spacing.dart';
import '../../../../core/theme/app_theme.dart'; import '../../../../core/theme/app_theme.dart';
import '../../../../core/theme/app_theme_extension.dart';
/// 操作按钮行 — .pen node pIpHe /// 操作按钮行 — .pen node pIpHe
/// gap: 12, three buttons evenly distributed /// gap: 12, three buttons evenly distributed
@@ -22,10 +23,8 @@ class ActionButtonsRow extends StatelessWidget {
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
final colorScheme = Theme.of(context).colorScheme; final accentColor = context.appColors.accentPrimary;
final isDark = Theme.of(context).brightness == Brightness.dark; final bgColor = context.appColors.surfaceCardHigh;
final accentColor = isDark ? colorScheme.secondary : colorScheme.primary;
final bgColor = isDark ? colorScheme.surfaceContainerHighest : colorScheme.surfaceContainerHigh;
return Row( return Row(
children: [ children: [

View File

@@ -4,6 +4,7 @@ import 'package:shadcn_ui/shadcn_ui.dart';
import 'package:lucide_icons_flutter/lucide_icons.dart'; import 'package:lucide_icons_flutter/lucide_icons.dart';
import 'package:provider/provider.dart'; import 'package:provider/provider.dart';
import '../../../../core/theme/app_theme.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_color_scheme.dart';
import '../../../../core/theme/app_spacing.dart'; import '../../../../core/theme/app_spacing.dart';
import '../../../../core/utils/toast_utils.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 walletAddress = data['walletAddress'] as String? ?? '';
final walletNetwork = data['walletNetwork'] as String? ?? 'TRC20'; final walletNetwork = data['walletNetwork'] as String? ?? 'TRC20';
final colorScheme = Theme.of(context).colorScheme; final colorScheme = Theme.of(context).colorScheme;
final isDark = Theme.of(context).brightness == Brightness.dark;
showShadDialog( showShadDialog(
context: context, context: context,
@@ -263,7 +263,7 @@ void showDepositResultDialog(BuildContext context, Map<String, dynamic> data) {
children: [ children: [
NeonIcon( NeonIcon(
icon: Icons.check_circle, icon: Icons.check_circle,
color: AppColorScheme.getUpColor(isDark), color: context.appColors.up,
size: 24, size: 24,
), ),
const SizedBox(width: AppSpacing.sm), const SizedBox(width: AppSpacing.sm),
@@ -361,7 +361,6 @@ void showWithdrawDialog(BuildContext context, String? balance) {
final contactController = TextEditingController(); final contactController = TextEditingController();
final formKey = GlobalKey<ShadFormState>(); final formKey = GlobalKey<ShadFormState>();
final colorScheme = Theme.of(context).colorScheme; final colorScheme = Theme.of(context).colorScheme;
final isDark = Theme.of(context).brightness == Brightness.dark;
showShadDialog( showShadDialog(
context: context, context: context,
@@ -412,10 +411,10 @@ void showWithdrawDialog(BuildContext context, String? balance) {
vertical: AppSpacing.sm, vertical: AppSpacing.sm,
), ),
decoration: BoxDecoration( decoration: BoxDecoration(
color: AppColorScheme.getUpBackgroundColor(isDark), color: context.appColors.upBackground,
borderRadius: BorderRadius.circular(AppRadius.full), borderRadius: BorderRadius.circular(AppRadius.full),
border: Border.all( border: Border.all(
color: AppColorScheme.getUpColor(isDark).withValues(alpha: 0.2), color: context.appColors.up.withValues(alpha: 0.2),
), ),
), ),
child: Row( child: Row(
@@ -431,7 +430,7 @@ void showWithdrawDialog(BuildContext context, String? balance) {
'$balance USDT', '$balance USDT',
style: AppTextStyles.labelLarge(context).copyWith( style: AppTextStyles.labelLarge(context).copyWith(
fontWeight: FontWeight.bold, fontWeight: FontWeight.bold,
color: AppColorScheme.getUpColor(isDark), color: context.appColors.up,
), ),
), ),
], ],

View File

@@ -1,6 +1,6 @@
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import '../../../../core/theme/app_theme.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 '../../../../core/theme/app_spacing.dart';
import '../../../../providers/asset_provider.dart'; import '../../../../providers/asset_provider.dart';
import '../../../components/glass_panel.dart'; import '../../../components/glass_panel.dart';
@@ -22,9 +22,6 @@ class BalanceCard extends StatelessWidget {
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
final colorScheme = Theme.of(context).colorScheme;
final isDark = Theme.of(context).brightness == Brightness.dark;
final displayBalance = activeTab == 0 final displayBalance = activeTab == 0
? (provider.fundAccount?.balance ?? provider.overview?.fundBalance ?? '0.00') ? (provider.fundAccount?.balance ?? provider.overview?.fundBalance ?? '0.00')
: _calculateTradeTotal(); : _calculateTradeTotal();
@@ -38,7 +35,7 @@ class BalanceCard extends StatelessWidget {
Text( Text(
'USDT 余额', 'USDT 余额',
style: AppTextStyles.bodyMedium(context).copyWith( style: AppTextStyles.bodyMedium(context).copyWith(
color: colorScheme.onSurfaceVariant, color: context.colors.onSurfaceVariant,
fontWeight: FontWeight.w400, fontWeight: FontWeight.w400,
), ),
), ),
@@ -51,7 +48,7 @@ class BalanceCard extends StatelessWidget {
Text( Text(
'\u2248 \$${_formatBalance(displayBalance)} USD', '\u2248 \$${_formatBalance(displayBalance)} USD',
style: AppTextStyles.bodyMedium(context).copyWith( style: AppTextStyles.bodyMedium(context).copyWith(
color: isDark ? AppColorScheme.darkOnSurfaceMuted : colorScheme.onSurfaceVariant, color: context.appColors.onSurfaceMuted,
fontWeight: FontWeight.w400, fontWeight: FontWeight.w400,
), ),
), ),

View File

@@ -1,6 +1,6 @@
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import '../../../../core/theme/app_theme.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 '../../../../core/theme/app_spacing.dart';
import '../../../../data/models/account_models.dart'; import '../../../../data/models/account_models.dart';
import '../../../components/glass_panel.dart'; import '../../../components/glass_panel.dart';
@@ -116,11 +116,9 @@ class HoldingRow extends StatelessWidget {
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
final colorScheme = Theme.of(context).colorScheme; final accentColor = context.appColors.accentPrimary;
final isDark = Theme.of(context).brightness == Brightness.dark;
final accentColor = isDark ? colorScheme.secondary : colorScheme.primary;
final accentBgColor = accentColor.withValues(alpha: 0.1); 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( return Padding(
padding: const EdgeInsets.symmetric(horizontal: AppSpacing.md, vertical: 14), padding: const EdgeInsets.symmetric(horizontal: AppSpacing.md, vertical: 14),
@@ -159,7 +157,7 @@ class HoldingRow extends StatelessWidget {
quantity, quantity,
style: AppTextStyles.bodyMedium(context).copyWith( style: AppTextStyles.bodyMedium(context).copyWith(
fontWeight: FontWeight.w400, fontWeight: FontWeight.w400,
color: colorScheme.onSurfaceVariant, color: context.colors.onSurfaceVariant,
), ),
), ),
], ],

View File

@@ -1,7 +1,7 @@
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:lucide_icons_flutter/lucide_icons.dart'; import 'package:lucide_icons_flutter/lucide_icons.dart';
import '../../../../core/theme/app_theme.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 '../../../../core/theme/app_spacing.dart';
import '../../../components/glass_panel.dart'; import '../../../components/glass_panel.dart';
@@ -16,9 +16,7 @@ class RecordsLinkRow extends StatelessWidget {
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
final colorScheme = Theme.of(context).colorScheme; final mutedColor = context.appColors.onSurfaceMuted;
final isDark = Theme.of(context).brightness == Brightness.dark;
final mutedColor = isDark ? AppColorScheme.darkOnSurfaceMuted : colorScheme.onSurfaceVariant;
return GestureDetector( return GestureDetector(
onTap: onTap, onTap: onTap,

View File

@@ -3,7 +3,7 @@ import 'package:flutter/services.dart';
import 'package:provider/provider.dart'; import 'package:provider/provider.dart';
import 'package:lucide_icons_flutter/lucide_icons.dart'; import 'package:lucide_icons_flutter/lucide_icons.dart';
import '../../../core/theme/app_theme.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 '../../../core/theme/app_spacing.dart';
import '../../../providers/asset_provider.dart'; import '../../../providers/asset_provider.dart';
import '../../../data/models/account_models.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 _fromBalance => _direction == 1 ? _fundBalance : _tradeUsdtBalance;
String get _toBalance => _direction == 1 ? _tradeUsdtBalance : _fundBalance; 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( decoration: InputDecoration(
hintText: '0.00', hintText: '0.00',
hintStyle: AppTextStyles.numberLarge(context).copyWith( hintStyle: AppTextStyles.numberLarge(context).copyWith(
color: AppColorScheme.darkOnSurfaceMuted, color: context.appColors.onSurfaceMuted,
), ),
border: InputBorder.none, border: InputBorder.none,
contentPadding: EdgeInsets.zero, contentPadding: EdgeInsets.zero,
@@ -375,7 +369,7 @@ class _TransferPageState extends State<TransferPage> {
padding: const EdgeInsets.only(left: AppSpacing.sm), padding: const EdgeInsets.only(left: AppSpacing.sm),
child: Text('USDT', style: AppTextStyles.headlineMedium(context).copyWith( child: Text('USDT', style: AppTextStyles.headlineMedium(context).copyWith(
fontWeight: FontWeight.w400, fontWeight: FontWeight.w400,
color: AppColorScheme.darkOnSurfaceMuted, color: context.appColors.onSurfaceMuted,
)), )),
), ),
], ],
@@ -425,13 +419,13 @@ class _TransferPageState extends State<TransferPage> {
// ============================================ // ============================================
Widget _buildTipsCard() { Widget _buildTipsCard() {
final upColor = AppColorScheme.getUpColor(_isDark); final upColor = context.appColors.up;
return Container( return Container(
width: double.infinity, width: double.infinity,
padding: const EdgeInsets.symmetric(horizontal: AppSpacing.md, vertical: 12), padding: const EdgeInsets.symmetric(horizontal: AppSpacing.md, vertical: 12),
decoration: BoxDecoration( decoration: BoxDecoration(
color: AppColorScheme.getUpBackgroundColor(_isDark), color: context.appColors.upBackground,
borderRadius: BorderRadius.circular(AppRadius.lg), borderRadius: BorderRadius.circular(AppRadius.lg),
), ),
child: Row( child: Row(

View File

@@ -5,6 +5,7 @@ import 'package:provider/provider.dart';
import '../../../core/theme/app_color_scheme.dart'; import '../../../core/theme/app_color_scheme.dart';
import '../../../core/theme/app_spacing.dart'; import '../../../core/theme/app_spacing.dart';
import '../../../core/theme/app_theme.dart'; import '../../../core/theme/app_theme.dart';
import '../../../core/theme/app_theme_extension.dart';
import '../../../providers/auth_provider.dart'; import '../../../providers/auth_provider.dart';
import '../main/main_page.dart'; import '../main/main_page.dart';
import 'register_page.dart'; import 'register_page.dart';
@@ -36,12 +37,8 @@ class _LoginPageState extends State<LoginPage> {
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
final isDark = Theme.of(context).brightness == Brightness.dark;
return Scaffold( return Scaffold(
backgroundColor: isDark backgroundColor: context.colors.surface,
? AppColorScheme.darkBackground
: AppColorScheme.lightSurface,
body: SafeArea( body: SafeArea(
child: SingleChildScrollView( child: SingleChildScrollView(
padding: const EdgeInsets.symmetric( padding: const EdgeInsets.symmetric(
@@ -53,13 +50,13 @@ class _LoginPageState extends State<LoginPage> {
child: Column( child: Column(
children: [ children: [
// 顶部品牌区域 // 顶部品牌区域
_buildBrandSection(isDark), _buildBrandSection(),
const SizedBox(height: AppSpacing.xxl), const SizedBox(height: AppSpacing.xxl),
// 表单区域 // 表单区域
_buildFormSection(isDark), _buildFormSection(),
const SizedBox(height: AppSpacing.xl), const SizedBox(height: AppSpacing.xl),
// 底部注册链接 // 底部注册链接
_buildRegisterRow(isDark), _buildRegisterRow(),
], ],
), ),
), ),
@@ -72,16 +69,16 @@ class _LoginPageState extends State<LoginPage> {
// 品牌区域 - Logo + 品牌名 + 标语 // 品牌区域 - Logo + 品牌名 + 标语
// ============================================ // ============================================
Widget _buildBrandSection(bool isDark) { Widget _buildBrandSection() {
return Column( return Column(
children: [ children: [
// Logo 圆形:渐变 #1F2937 → #374151内含 "M" // Logo 圆形:渐变 #1F2937 → #374151内含 "M"
Container( Container(
width: _logoCircleSize, width: _logoCircleSize,
height: _logoCircleSize, height: _logoCircleSize,
decoration: BoxDecoration( decoration: const BoxDecoration(
shape: BoxShape.circle, shape: BoxShape.circle,
gradient: const LinearGradient( gradient: LinearGradient(
begin: Alignment.topCenter, begin: Alignment.topCenter,
end: Alignment.bottomCenter, end: Alignment.bottomCenter,
colors: [AppColorScheme.darkSurfaceContainerHigh, AppColorScheme.darkOutline], colors: [AppColorScheme.darkSurfaceContainerHigh, AppColorScheme.darkOutline],
@@ -93,9 +90,7 @@ class _LoginPageState extends State<LoginPage> {
style: AppTextStyles.displayLarge(context).copyWith( style: AppTextStyles.displayLarge(context).copyWith(
fontSize: 32, fontSize: 32,
fontWeight: FontWeight.w800, fontWeight: FontWeight.w800,
color: isDark color: context.colors.onPrimary,
? AppColorScheme.darkOnSurface
: AppColorScheme.darkOnPrimary,
), ),
), ),
), ),
@@ -105,9 +100,7 @@ class _LoginPageState extends State<LoginPage> {
'MONISUO', 'MONISUO',
style: AppTextStyles.displayLarge(context).copyWith( style: AppTextStyles.displayLarge(context).copyWith(
letterSpacing: 3, letterSpacing: 3,
color: isDark color: context.colors.onSurface,
? AppColorScheme.darkOnSurface
: AppColorScheme.lightOnSurface,
), ),
textAlign: TextAlign.center, textAlign: TextAlign.center,
), ),
@@ -116,9 +109,7 @@ class _LoginPageState extends State<LoginPage> {
Text( Text(
'虚拟货币模拟交易平台', '虚拟货币模拟交易平台',
style: AppTextStyles.bodyLarge(context).copyWith( style: AppTextStyles.bodyLarge(context).copyWith(
color: isDark color: context.colors.onSurfaceVariant,
? AppColorScheme.darkOnSurfaceVariant
: AppColorScheme.lightOnSurfaceVariant,
), ),
textAlign: TextAlign.center, textAlign: TextAlign.center,
), ),
@@ -130,30 +121,20 @@ class _LoginPageState extends State<LoginPage> {
// 表单区域 - 用户名 + 密码 + 登录按钮 // 表单区域 - 用户名 + 密码 + 登录按钮
// ============================================ // ============================================
Widget _buildFormSection(bool isDark) { Widget _buildFormSection() {
return Column( return Column(
crossAxisAlignment: CrossAxisAlignment.stretch, crossAxisAlignment: CrossAxisAlignment.stretch,
children: [ children: [
_buildUsernameField(isDark), _buildUsernameField(),
const SizedBox(height: AppSpacing.md), const SizedBox(height: AppSpacing.md),
_buildPasswordField(isDark), _buildPasswordField(),
const SizedBox(height: AppSpacing.sm), const SizedBox(height: AppSpacing.sm),
_buildLoginButton(isDark), _buildLoginButton(),
], ],
); );
} }
Widget _buildUsernameField(bool isDark) { Widget _buildUsernameField() {
final borderColor = isDark
? AppColorScheme.darkOutlineVariant
: AppColorScheme.lightOutlineVariant;
final cardColor = isDark
? AppColorScheme.darkSurfaceContainer
: AppColorScheme.lightSurfaceLowest;
final iconColor = isDark
? AppColorScheme.darkOnSurfaceMuted
: AppColorScheme.lightOnSurfaceMuted;
return SizedBox( return SizedBox(
height: _inputHeight, height: _inputHeight,
child: ShadInputFormField( child: ShadInputFormField(
@@ -161,32 +142,25 @@ class _LoginPageState extends State<LoginPage> {
placeholder: const Text('请输入用户名'), placeholder: const Text('请输入用户名'),
leading: Padding( leading: Padding(
padding: const EdgeInsets.only(right: AppSpacing.sm), 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, validator: _validateUsername,
controller: _usernameController, controller: _usernameController,
decoration: ShadDecoration( decoration: ShadDecoration(
border: ShadBorder.all( border: ShadBorder.all(
color: borderColor, color: context.colors.outlineVariant,
radius: AppRadius.radiusLg, radius: AppRadius.radiusLg,
), ),
), ),
style: AppTextStyles.headlineMedium(context).copyWith( style: AppTextStyles.headlineMedium(context).copyWith(
color: isDark color: context.colors.onSurface,
? AppColorScheme.darkOnSurface
: AppColorScheme.lightOnSurface,
), ),
), ),
); );
} }
Widget _buildPasswordField(bool isDark) { Widget _buildPasswordField() {
final borderColor = isDark final iconColor = context.appColors.onSurfaceMuted;
? AppColorScheme.darkOutlineVariant
: AppColorScheme.lightOutlineVariant;
final iconColor = isDark
? AppColorScheme.darkOnSurfaceMuted
: AppColorScheme.lightOnSurfaceMuted;
return SizedBox( return SizedBox(
height: _inputHeight, height: _inputHeight,
@@ -210,27 +184,21 @@ class _LoginPageState extends State<LoginPage> {
controller: _passwordController, controller: _passwordController,
decoration: ShadDecoration( decoration: ShadDecoration(
border: ShadBorder.all( border: ShadBorder.all(
color: borderColor, color: context.colors.outlineVariant,
radius: AppRadius.radiusLg, radius: AppRadius.radiusLg,
), ),
), ),
style: AppTextStyles.headlineMedium(context).copyWith( style: AppTextStyles.headlineMedium(context).copyWith(
color: isDark color: context.colors.onSurface,
? AppColorScheme.darkOnSurface
: AppColorScheme.lightOnSurface,
), ),
), ),
); );
} }
Widget _buildLoginButton(bool isDark) { Widget _buildLoginButton() {
// 设计稿: accent-primary = light:#1F2937 / dark:#D4AF37 // 设计稿: accent-primary = light:#1F2937 / dark:#D4AF37
final buttonColor = isDark final buttonColor = context.appColors.accentPrimary;
? AppColorScheme.darkSecondary final textColor = context.colors.onPrimary;
: AppColorScheme.darkSurfaceContainerHigh;
final textColor = isDark
? AppColorScheme.darkBackground
: AppColorScheme.darkOnPrimary;
return Consumer<AuthProvider>( return Consumer<AuthProvider>(
builder: (context, auth, _) { builder: (context, auth, _) {
@@ -270,14 +238,10 @@ class _LoginPageState extends State<LoginPage> {
// 底部注册链接 // 底部注册链接
// ============================================ // ============================================
Widget _buildRegisterRow(bool isDark) { Widget _buildRegisterRow() {
// gold-accent: light=#F59E0B / dark=#D4AF37 // gold-accent: light=#F59E0B / dark=#D4AF37
final goldColor = isDark final goldColor = context.appColors.accentPrimary;
? AppColorScheme.darkSecondary final secondaryTextColor = context.colors.onSurfaceVariant;
: AppColorScheme.darkSecondaryFixed;
final secondaryTextColor = isDark
? AppColorScheme.darkOnSurfaceVariant
: AppColorScheme.lightOnSurfaceVariant;
return Padding( return Padding(
padding: const EdgeInsets.only(bottom: AppSpacing.xl), padding: const EdgeInsets.only(bottom: AppSpacing.xl),

View File

@@ -7,13 +7,13 @@ import 'package:provider/provider.dart';
import '../../../core/theme/app_theme.dart'; import '../../../core/theme/app_theme.dart';
import '../../../core/theme/app_color_scheme.dart'; import '../../../core/theme/app_color_scheme.dart';
import '../../../core/theme/app_spacing.dart'; import '../../../core/theme/app_spacing.dart';
import '../../../core/theme/app_theme_extension.dart';
import '../../../core/utils/toast_utils.dart'; import '../../../core/utils/toast_utils.dart';
import '../../../core/event/app_event_bus.dart'; import '../../../core/event/app_event_bus.dart';
import '../../../data/models/account_models.dart'; import '../../../data/models/account_models.dart';
import '../../../data/services/asset_service.dart'; import '../../../data/services/asset_service.dart';
import '../../../data/services/bonus_service.dart'; import '../../../data/services/bonus_service.dart';
import '../../../providers/asset_provider.dart'; import '../../../providers/asset_provider.dart';
import '../../../providers/auth_provider.dart';
import '../../components/glass_panel.dart'; import '../../components/glass_panel.dart';
import '../../components/neon_glow.dart'; import '../../components/neon_glow.dart';
import '../main/main_page.dart'; import '../main/main_page.dart';
@@ -85,15 +85,14 @@ class _HomePageState extends State<HomePage>
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
super.build(context); super.build(context);
final colorScheme = Theme.of(context).colorScheme;
return Scaffold( return Scaffold(
backgroundColor: colorScheme.background, backgroundColor: context.colors.background,
body: Consumer<AssetProvider>( body: Consumer<AssetProvider>(
builder: (context, provider, _) { builder: (context, provider, _) {
return RefreshIndicator( return RefreshIndicator(
onRefresh: () => provider.refreshAll(force: true), onRefresh: () => provider.refreshAll(force: true),
color: colorScheme.primary, color: context.colors.primary,
child: SingleChildScrollView( child: SingleChildScrollView(
physics: const AlwaysScrollableScrollPhysics(), physics: const AlwaysScrollableScrollPhysics(),
padding: EdgeInsets.only( padding: EdgeInsets.only(
@@ -149,7 +148,6 @@ class _HomePageState extends State<HomePage>
void _showDeposit() { void _showDeposit() {
final amountController = TextEditingController(); final amountController = TextEditingController();
final formKey = GlobalKey<ShadFormState>(); final formKey = GlobalKey<ShadFormState>();
final colorScheme = Theme.of(context).colorScheme;
showShadDialog( showShadDialog(
context: context, context: context,
@@ -184,10 +182,10 @@ class _HomePageState extends State<HomePage>
Container( Container(
padding: EdgeInsets.all(AppSpacing.sm), padding: EdgeInsets.all(AppSpacing.sm),
decoration: BoxDecoration( decoration: BoxDecoration(
color: colorScheme.surfaceContainerHigh, color: context.colors.surfaceContainerHigh,
borderRadius: BorderRadius.circular(AppRadius.md), 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 amount = data['amount']?.toString() ?? '0.00';
final walletAddress = data['walletAddress'] as String? ?? ''; final walletAddress = data['walletAddress'] as String? ?? '';
final walletNetwork = data['walletNetwork'] as String? ?? 'TRC20'; final walletNetwork = data['walletNetwork'] as String? ?? 'TRC20';
final colorScheme = Theme.of(context).colorScheme;
showShadDialog( showShadDialog(
context: context, context: context,
@@ -305,9 +302,9 @@ class _HomePageState extends State<HomePage>
Container( Container(
padding: EdgeInsets.all(AppSpacing.sm), padding: EdgeInsets.all(AppSpacing.sm),
decoration: BoxDecoration( decoration: BoxDecoration(
color: AppColorScheme.warning.withOpacity(0.1), color: AppColorScheme.warning.withValues(alpha: 0.1),
borderRadius: BorderRadius.circular(AppRadius.md), 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( child: Row(
children: [ children: [
@@ -371,7 +368,6 @@ class _HomePageState extends State<HomePage>
} }
void _showResultDialog(String title, String? message) { void _showResultDialog(String title, String? message) {
final colorScheme = Theme.of(context).colorScheme;
showShadDialog( showShadDialog(
context: context, context: context,
builder: (ctx) => Dialog( builder: (ctx) => Dialog(
@@ -525,10 +521,8 @@ class _AssetCardState extends State<_AssetCard> {
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
final colorScheme = Theme.of(context).colorScheme; final upColor = context.appColors.up;
final isDark = Theme.of(context).brightness == Brightness.dark; final downColor = context.appColors.down;
final upColor = AppColorScheme.getUpColor(isDark);
final downColor = AppColorScheme.getDownColor(isDark);
final isProfit = _totalProfit >= 0; final isProfit = _totalProfit >= 0;
final todayProfit = _todayProfit; final todayProfit = _todayProfit;
final isTodayProfit = (todayProfit ?? 0) >= 0; final isTodayProfit = (todayProfit ?? 0) >= 0;
@@ -558,19 +552,19 @@ class _AssetCardState extends State<_AssetCard> {
vertical: AppSpacing.xs + 2, vertical: AppSpacing.xs + 2,
), ),
decoration: BoxDecoration( decoration: BoxDecoration(
color: colorScheme.primary.withOpacity(0.1), color: context.colors.primary.withValues(alpha: 0.1),
borderRadius: BorderRadius.circular(AppRadius.full), 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( child: Row(
mainAxisSize: MainAxisSize.min, mainAxisSize: MainAxisSize.min,
children: [ children: [
Icon(Icons.add, size: 14, color: colorScheme.primary), Icon(Icons.add, size: 14, color: context.colors.primary),
SizedBox(width: AppSpacing.xs), SizedBox(width: AppSpacing.xs),
Text( Text(
'充值', '充值',
style: AppTextStyles.labelLarge(context).copyWith( 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), padding: EdgeInsets.symmetric(horizontal: 10, vertical: 4),
decoration: BoxDecoration( decoration: BoxDecoration(
color: _calendarExpanded color: _calendarExpanded
? colorScheme.primary.withOpacity(0.1) ? context.colors.primary.withValues(alpha: 0.1)
: colorScheme.surfaceContainerHigh, : context.colors.surfaceContainerHigh,
borderRadius: BorderRadius.circular(AppRadius.full), borderRadius: BorderRadius.circular(AppRadius.full),
border: _calendarExpanded border: _calendarExpanded
? Border.all(color: colorScheme.primary.withOpacity(0.2)) ? Border.all(color: context.colors.primary.withValues(alpha: 0.2))
: null, : null,
), ),
child: Row( child: Row(
@@ -634,8 +628,8 @@ class _AssetCardState extends State<_AssetCard> {
LucideIcons.chartBar, LucideIcons.chartBar,
size: 13, size: 13,
color: _calendarExpanded color: _calendarExpanded
? colorScheme.primary ? context.colors.primary
: colorScheme.onSurfaceVariant, : context.colors.onSurfaceVariant,
), ),
SizedBox(width: AppSpacing.xs), SizedBox(width: AppSpacing.xs),
Text( Text(
@@ -643,8 +637,8 @@ class _AssetCardState extends State<_AssetCard> {
style: AppTextStyles.labelMedium(context).copyWith( style: AppTextStyles.labelMedium(context).copyWith(
fontWeight: _calendarExpanded ? FontWeight.w600 : FontWeight.w500, fontWeight: _calendarExpanded ? FontWeight.w600 : FontWeight.w500,
color: _calendarExpanded color: _calendarExpanded
? colorScheme.primary ? context.colors.primary
: colorScheme.onSurfaceVariant, : context.colors.onSurfaceVariant,
), ),
), ),
SizedBox(width: 2), SizedBox(width: 2),
@@ -655,8 +649,8 @@ class _AssetCardState extends State<_AssetCard> {
LucideIcons.chevronDown, LucideIcons.chevronDown,
size: 13, size: 13,
color: _calendarExpanded color: _calendarExpanded
? colorScheme.primary ? context.colors.primary
: colorScheme.onSurfaceVariant, : context.colors.onSurfaceVariant,
), ),
), ),
], ],
@@ -669,9 +663,7 @@ class _AssetCardState extends State<_AssetCard> {
// 可折叠的盈利日历 // 可折叠的盈利日历
AnimatedCrossFade( AnimatedCrossFade(
firstChild: const SizedBox.shrink(), firstChild: const SizedBox.shrink(),
secondChild: _buildCalendarSection( secondChild: _buildCalendarSection(context),
context, colorScheme, isDark, upColor, downColor,
),
crossFadeState: _calendarExpanded crossFadeState: _calendarExpanded
? CrossFadeState.showSecond ? CrossFadeState.showSecond
: CrossFadeState.showFirst, : CrossFadeState.showFirst,
@@ -683,18 +675,14 @@ class _AssetCardState extends State<_AssetCard> {
); );
} }
Widget _buildCalendarSection( Widget _buildCalendarSection(BuildContext context) {
BuildContext context,
ColorScheme colorScheme,
bool isDark,
Color upColor,
Color downColor,
) {
final now = DateTime.now(); final now = DateTime.now();
final isCurrentMonth = _currentMonth.year == now.year && _currentMonth.month == now.month; final isCurrentMonth = _currentMonth.year == now.year && _currentMonth.month == now.month;
final firstDayOfMonth = DateTime(_currentMonth.year, _currentMonth.month, 1); final firstDayOfMonth = DateTime(_currentMonth.year, _currentMonth.month, 1);
final daysInMonth = DateTime(_currentMonth.year, _currentMonth.month + 1, 0).day; final daysInMonth = DateTime(_currentMonth.year, _currentMonth.month + 1, 0).day;
final startWeekday = firstDayOfMonth.weekday; final startWeekday = firstDayOfMonth.weekday;
final upColor = context.appColors.up;
final downColor = context.appColors.down;
return Column( return Column(
mainAxisSize: MainAxisSize.min, mainAxisSize: MainAxisSize.min,
@@ -702,7 +690,7 @@ class _AssetCardState extends State<_AssetCard> {
// 分隔线 // 分隔线
Padding( Padding(
padding: EdgeInsets.symmetric(vertical: AppSpacing.md), 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( child: Container(
padding: EdgeInsets.all(AppSpacing.xs + 1), padding: EdgeInsets.all(AppSpacing.xs + 1),
decoration: BoxDecoration( decoration: BoxDecoration(
color: colorScheme.surfaceContainerHigh, color: context.colors.surfaceContainerHigh,
borderRadius: BorderRadius.circular(AppRadius.sm), 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( Column(
@@ -745,16 +733,16 @@ class _AssetCardState extends State<_AssetCard> {
padding: EdgeInsets.all(AppSpacing.xs + 1), padding: EdgeInsets.all(AppSpacing.xs + 1),
decoration: BoxDecoration( decoration: BoxDecoration(
color: isCurrentMonth color: isCurrentMonth
? colorScheme.surfaceContainerHigh.withOpacity(0.5) ? context.colors.surfaceContainerHigh.withValues(alpha: 0.5)
: colorScheme.surfaceContainerHigh, : context.colors.surfaceContainerHigh,
borderRadius: BorderRadius.circular(AppRadius.sm), borderRadius: BorderRadius.circular(AppRadius.sm),
), ),
child: Icon( child: Icon(
LucideIcons.chevronRight, LucideIcons.chevronRight,
size: 16, size: 16,
color: isCurrentMonth color: isCurrentMonth
? colorScheme.onSurfaceVariant.withOpacity(0.4) ? context.colors.onSurfaceVariant.withValues(alpha: 0.4)
: colorScheme.onSurfaceVariant, : context.colors.onSurfaceVariant,
), ),
), ),
), ),
@@ -771,7 +759,7 @@ class _AssetCardState extends State<_AssetCard> {
d, d,
style: AppTextStyles.bodySmall(context).copyWith( style: AppTextStyles.bodySmall(context).copyWith(
fontWeight: FontWeight.w500, 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, height: 18,
child: CircularProgressIndicator( child: CircularProgressIndicator(
strokeWidth: 2, strokeWidth: 2,
color: colorScheme.primary, color: context.colors.primary,
), ),
), ),
) )
else else
..._buildCalendarGrid( ..._buildCalendarGrid(
startWeekday, daysInMonth, now, isCurrentMonth, startWeekday, daysInMonth, now, isCurrentMonth,
upColor, downColor, colorScheme,
), ),
], ],
); );
@@ -807,10 +794,9 @@ class _AssetCardState extends State<_AssetCard> {
int daysInMonth, int daysInMonth,
DateTime now, DateTime now,
bool isCurrentMonth, bool isCurrentMonth,
Color upColor,
Color downColor,
ColorScheme colorScheme,
) { ) {
final upColor = context.appColors.up;
final downColor = context.appColors.down;
final List<Widget> rows = []; final List<Widget> rows = [];
List<Widget> cells = []; List<Widget> cells = [];
@@ -831,15 +817,15 @@ class _AssetCardState extends State<_AssetCard> {
margin: EdgeInsets.all(1), margin: EdgeInsets.all(1),
decoration: BoxDecoration( decoration: BoxDecoration(
color: isToday color: isToday
? colorScheme.primary.withOpacity(0.12) ? context.colors.primary.withValues(alpha: 0.12)
: hasProfit : hasProfit
? (profit! > 0 ? (profit! > 0
? upColor.withOpacity(0.08) ? upColor.withValues(alpha: 0.08)
: downColor.withOpacity(0.08)) : downColor.withValues(alpha: 0.08))
: Colors.transparent, : Colors.transparent,
borderRadius: BorderRadius.circular(AppRadius.sm), borderRadius: BorderRadius.circular(AppRadius.sm),
border: isToday 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, : null,
), ),
child: Column( child: Column(
@@ -851,8 +837,8 @@ class _AssetCardState extends State<_AssetCard> {
fontSize: 10, fontSize: 10,
fontWeight: isToday ? FontWeight.bold : FontWeight.w400, fontWeight: isToday ? FontWeight.bold : FontWeight.w400,
color: isToday color: isToday
? colorScheme.primary ? context.colors.primary
: colorScheme.onSurface, : context.colors.onSurface,
), ),
), ),
if (hasProfit) ...[ if (hasProfit) ...[
@@ -906,9 +892,6 @@ class _WelfareCard extends StatelessWidget {
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
final colorScheme = Theme.of(context).colorScheme;
final isDark = Theme.of(context).brightness == Brightness.dark;
return GestureDetector( return GestureDetector(
onTap: onTap, onTap: onTap,
child: Container( child: Container(
@@ -917,14 +900,14 @@ class _WelfareCard extends StatelessWidget {
decoration: BoxDecoration( decoration: BoxDecoration(
gradient: LinearGradient( gradient: LinearGradient(
colors: [ colors: [
colorScheme.primary.withOpacity(0.15), context.colors.primary.withValues(alpha: 0.15),
colorScheme.secondary.withOpacity(0.1), context.colors.secondary.withValues(alpha: 0.1),
], ],
begin: Alignment.topLeft, begin: Alignment.topLeft,
end: Alignment.bottomRight, end: Alignment.bottomRight,
), ),
borderRadius: BorderRadius.circular(AppRadius.xl), 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( child: Row(
children: [ children: [
@@ -933,12 +916,12 @@ class _WelfareCard extends StatelessWidget {
width: 48, width: 48,
height: 48, height: 48,
decoration: BoxDecoration( decoration: BoxDecoration(
color: colorScheme.primary.withOpacity(0.15), color: context.colors.primary.withValues(alpha: 0.15),
borderRadius: BorderRadius.circular(AppRadius.lg), borderRadius: BorderRadius.circular(AppRadius.lg),
), ),
child: Icon( child: Icon(
LucideIcons.gift, LucideIcons.gift,
color: colorScheme.primary, color: context.colors.primary,
size: 24, size: 24,
), ),
), ),
@@ -971,9 +954,7 @@ class _WelfareCard extends StatelessWidget {
vertical: AppSpacing.sm, vertical: AppSpacing.sm,
), ),
decoration: BoxDecoration( decoration: BoxDecoration(
gradient: isDark gradient: context.appColors.ctaGradient,
? AppColorScheme.darkCtaGradient
: AppColorScheme.lightCtaGradient,
borderRadius: BorderRadius.circular(AppRadius.full), borderRadius: BorderRadius.circular(AppRadius.full),
), ),
child: Row( child: Row(
@@ -1000,7 +981,7 @@ class _WelfareCard extends StatelessWidget {
'查看', '查看',
style: AppTextStyles.headlineSmall(context).copyWith( style: AppTextStyles.headlineSmall(context).copyWith(
fontWeight: FontWeight.w700, fontWeight: FontWeight.w700,
color: isDark ? colorScheme.background : AppColorScheme.darkOnPrimary, color: context.colors.onPrimary,
), ),
), ),
], ],
@@ -1021,8 +1002,6 @@ class _HoldingsSection extends StatelessWidget {
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
final colorScheme = Theme.of(context).colorScheme;
return Column( return Column(
children: [ children: [
Row( Row(
@@ -1037,7 +1016,7 @@ class _HoldingsSection extends StatelessWidget {
TextButton( TextButton(
onPressed: () {}, onPressed: () {},
style: TextButton.styleFrom( style: TextButton.styleFrom(
foregroundColor: colorScheme.primary, foregroundColor: context.colors.primary,
padding: const EdgeInsets.symmetric(horizontal: AppSpacing.sm), padding: const EdgeInsets.symmetric(horizontal: AppSpacing.sm),
), ),
child: Row( child: Row(
@@ -1048,7 +1027,7 @@ class _HoldingsSection extends StatelessWidget {
)), )),
const SizedBox(width: AppSpacing.xs), const SizedBox(width: AppSpacing.xs),
Icon(LucideIcons.chevronRight, Icon(LucideIcons.chevronRight,
size: 16, color: colorScheme.primary), size: 16, color: context.colors.primary),
], ],
), ),
), ),
@@ -1067,19 +1046,17 @@ class _EmptyHoldings extends StatelessWidget {
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
final colorScheme = Theme.of(context).colorScheme;
return Container( return Container(
width: double.infinity, width: double.infinity,
padding: EdgeInsets.symmetric(vertical: AppSpacing.xxl, horizontal: AppSpacing.lg), padding: EdgeInsets.symmetric(vertical: AppSpacing.xxl, horizontal: AppSpacing.lg),
decoration: BoxDecoration( decoration: BoxDecoration(
color: colorScheme.surfaceContainerLow.withOpacity(0.5), color: context.colors.surfaceContainerLow.withValues(alpha: 0.5),
borderRadius: BorderRadius.circular(AppRadius.xxl), 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( child: Column(
children: [ children: [
Icon(LucideIcons.wallet, size: 48, color: colorScheme.onSurfaceVariant), Icon(LucideIcons.wallet, size: 48, color: context.colors.onSurfaceVariant),
SizedBox(height: AppSpacing.md), SizedBox(height: AppSpacing.md),
Text( Text(
'暂无持仓', '暂无持仓',
@@ -1106,15 +1083,14 @@ class _HoldingsList extends StatelessWidget {
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
final colorScheme = Theme.of(context).colorScheme;
final displayHoldings = final displayHoldings =
holdings.length > 5 ? holdings.sublist(0, 5) : holdings; holdings.length > 5 ? holdings.sublist(0, 5) : holdings;
return Container( return Container(
decoration: BoxDecoration( decoration: BoxDecoration(
color: colorScheme.surface.withOpacity(0.5), color: context.colors.surface.withValues(alpha: 0.5),
borderRadius: BorderRadius.circular(AppRadius.xxl), 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( child: ListView.separated(
shrinkWrap: true, shrinkWrap: true,
@@ -1122,7 +1098,7 @@ class _HoldingsList extends StatelessWidget {
padding: EdgeInsets.all(AppSpacing.md), padding: EdgeInsets.all(AppSpacing.md),
itemCount: displayHoldings.length, itemCount: displayHoldings.length,
separatorBuilder: (_, __) => Divider( separatorBuilder: (_, __) => Divider(
color: colorScheme.outlineVariant.withOpacity(0.1), color: context.colors.outlineVariant.withValues(alpha: 0.1),
height: 1, height: 1,
), ),
itemBuilder: (context, index) => itemBuilder: (context, index) =>
@@ -1140,9 +1116,6 @@ class _HoldingItem extends StatelessWidget {
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
final colorScheme = Theme.of(context).colorScheme;
final isDark = Theme.of(context).brightness == Brightness.dark;
return Padding( return Padding(
padding: EdgeInsets.symmetric(vertical: AppSpacing.sm + AppSpacing.xs), padding: EdgeInsets.symmetric(vertical: AppSpacing.sm + AppSpacing.xs),
child: Row( child: Row(
@@ -1152,11 +1125,11 @@ class _HoldingItem extends StatelessWidget {
children: [ children: [
CircleAvatar( CircleAvatar(
radius: 18, radius: 18,
backgroundColor: colorScheme.primary.withOpacity(0.1), backgroundColor: context.colors.primary.withValues(alpha: 0.1),
child: Text( child: Text(
holding.coinCode.substring(0, 1), holding.coinCode.substring(0, 1),
style: AppTextStyles.headlineMedium(context).copyWith( style: AppTextStyles.headlineMedium(context).copyWith(
color: colorScheme.primary, color: context.colors.primary,
fontWeight: FontWeight.bold, fontWeight: FontWeight.bold,
), ),
), ),
@@ -1185,8 +1158,8 @@ class _HoldingItem extends StatelessWidget {
Text(holding.formattedProfitRate, Text(holding.formattedProfitRate,
style: AppTextStyles.numberSmall(context).copyWith( style: AppTextStyles.numberSmall(context).copyWith(
color: holding.isProfit color: holding.isProfit
? AppColorScheme.getUpColor(isDark) ? context.appColors.up
: AppColorScheme.getDownColor(isDark), : context.appColors.down,
)), )),
], ],
), ),
@@ -1206,8 +1179,6 @@ class _InfoRow extends StatelessWidget {
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
final colorScheme = Theme.of(context).colorScheme;
return Row( return Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween, mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [ children: [
@@ -1232,14 +1203,12 @@ class _WalletAddressCard extends StatelessWidget {
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
final colorScheme = Theme.of(context).colorScheme;
return Container( return Container(
padding: EdgeInsets.all(AppSpacing.md), padding: EdgeInsets.all(AppSpacing.md),
decoration: BoxDecoration( decoration: BoxDecoration(
color: colorScheme.surfaceContainerHigh, color: context.colors.surfaceContainerHigh,
borderRadius: BorderRadius.circular(AppRadius.md), 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( child: Column(
crossAxisAlignment: CrossAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.start,
@@ -1262,11 +1231,11 @@ class _WalletAddressCard extends StatelessWidget {
child: Container( child: Container(
padding: EdgeInsets.all(AppSpacing.xs), padding: EdgeInsets.all(AppSpacing.xs),
decoration: BoxDecoration( decoration: BoxDecoration(
color: colorScheme.primary.withOpacity(0.1), color: context.colors.primary.withValues(alpha: 0.1),
borderRadius: BorderRadius.circular(AppRadius.sm), borderRadius: BorderRadius.circular(AppRadius.sm),
), ),
child: Icon(LucideIcons.copy, child: Icon(LucideIcons.copy,
size: 16, color: colorScheme.primary), size: 16, color: context.colors.primary),
), ),
), ),
], ],
@@ -1298,22 +1267,21 @@ class _ProfitStatCard extends StatelessWidget {
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
final colorScheme = Theme.of(context).colorScheme;
final hasValue = value != null; final hasValue = value != null;
final isProfit = (value ?? 0) >= 0; final isProfit = (value ?? 0) >= 0;
final color = hasValue ? (isProfit ? upColor : downColor) : colorScheme.onSurfaceVariant; final color = hasValue ? (isProfit ? upColor : downColor) : context.colors.onSurfaceVariant;
return Container( return Container(
padding: EdgeInsets.symmetric(horizontal: AppSpacing.md, vertical: AppSpacing.sm + 2), padding: EdgeInsets.symmetric(horizontal: AppSpacing.md, vertical: AppSpacing.sm + 2),
decoration: BoxDecoration( decoration: BoxDecoration(
color: hasValue color: hasValue
? (isProfit ? upColor : downColor).withOpacity(0.06) ? (isProfit ? upColor : downColor).withValues(alpha: 0.06)
: colorScheme.surfaceContainerHigh.withOpacity(0.5), : context.colors.surfaceContainerHigh.withValues(alpha: 0.5),
borderRadius: BorderRadius.circular(AppRadius.lg), borderRadius: BorderRadius.circular(AppRadius.lg),
border: Border.all( border: Border.all(
color: hasValue color: hasValue
? (isProfit ? upColor : downColor).withOpacity(0.12) ? (isProfit ? upColor : downColor).withValues(alpha: 0.12)
: colorScheme.outlineVariant.withOpacity(0.1), : context.colors.outlineVariant.withValues(alpha: 0.1),
), ),
), ),
child: Column( child: Column(
@@ -1326,14 +1294,14 @@ class _ProfitStatCard extends StatelessWidget {
? (isProfit ? LucideIcons.trendingUp : LucideIcons.trendingDown) ? (isProfit ? LucideIcons.trendingUp : LucideIcons.trendingDown)
: LucideIcons.minus, : LucideIcons.minus,
size: 11, size: 11,
color: color.withOpacity(0.7), color: color.withValues(alpha: 0.7),
), ),
SizedBox(width: 3), SizedBox(width: 3),
Text( Text(
label, label,
style: AppTextStyles.bodySmall(context).copyWith( style: AppTextStyles.bodySmall(context).copyWith(
fontWeight: FontWeight.w500, fontWeight: FontWeight.w500,
color: color.withOpacity(0.8), color: color.withValues(alpha: 0.8),
), ),
), ),
], ],

View File

@@ -1,8 +1,8 @@
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:shadcn_ui/shadcn_ui.dart'; import 'package:shadcn_ui/shadcn_ui.dart';
import '../../../core/theme/app_theme.dart'; import '../../../core/theme/app_theme.dart';
import '../../../core/theme/app_color_scheme.dart';
import '../../../core/theme/app_spacing.dart'; import '../../../core/theme/app_spacing.dart';
import '../../../core/theme/app_theme_extension.dart';
/// 首页热门币种区块 /// 首页热门币种区块
class HotCoinsSection extends StatelessWidget { class HotCoinsSection extends StatelessWidget {
@@ -10,9 +10,6 @@ class HotCoinsSection extends StatelessWidget {
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
final colorScheme = Theme.of(context).colorScheme;
final isDark = Theme.of(context).brightness == Brightness.dark;
return Column( return Column(
children: [ children: [
// Title row // Title row
@@ -36,9 +33,9 @@ class HotCoinsSection extends StatelessWidget {
// Card // Card
Container( Container(
decoration: BoxDecoration( decoration: BoxDecoration(
color: colorScheme.surfaceContainer, color: context.colors.surfaceContainer,
border: Border.all( border: Border.all(
color: colorScheme.outlineVariant, color: context.colors.outlineVariant,
width: 1, width: 1,
), ),
borderRadius: BorderRadius.circular(AppRadius.xl), borderRadius: BorderRadius.circular(AppRadius.xl),
@@ -52,13 +49,11 @@ class HotCoinsSection extends StatelessWidget {
price: '68,432.50', price: '68,432.50',
change: '+2.35%', change: '+2.35%',
isUp: true, isUp: true,
colorScheme: colorScheme,
isDark: isDark,
), ),
Divider( Divider(
height: 1, height: 1,
thickness: 1, thickness: 1,
color: colorScheme.outlineVariant.withValues(alpha: 0.15), color: context.appColors.ghostBorder,
), ),
_CoinRow( _CoinRow(
symbol: 'ETH', symbol: 'ETH',
@@ -67,13 +62,11 @@ class HotCoinsSection extends StatelessWidget {
price: '3,856.20', price: '3,856.20',
change: '+1.82%', change: '+1.82%',
isUp: true, isUp: true,
colorScheme: colorScheme,
isDark: isDark,
), ),
Divider( Divider(
height: 1, height: 1,
thickness: 1, thickness: 1,
color: colorScheme.outlineVariant.withValues(alpha: 0.15), color: context.appColors.ghostBorder,
), ),
_CoinRow( _CoinRow(
symbol: 'SOL', symbol: 'SOL',
@@ -82,8 +75,6 @@ class HotCoinsSection extends StatelessWidget {
price: '178.65', price: '178.65',
change: '-0.94%', change: '-0.94%',
isUp: false, isUp: false,
colorScheme: colorScheme,
isDark: isDark,
), ),
], ],
), ),
@@ -101,8 +92,6 @@ class _CoinRow extends StatelessWidget {
required this.price, required this.price,
required this.change, required this.change,
required this.isUp, required this.isUp,
required this.colorScheme,
required this.isDark,
}); });
final String symbol; final String symbol;
@@ -111,14 +100,12 @@ class _CoinRow extends StatelessWidget {
final String price; final String price;
final String change; final String change;
final bool isUp; final bool isUp;
final ColorScheme colorScheme;
final bool isDark;
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
final changeColor = isUp final changeColor = isUp
? AppColorScheme.getUpColor(isDark) ? context.appColors.up
: AppColorScheme.getDownColor(isDark); : context.appColors.down;
return Padding( return Padding(
padding: const EdgeInsets.symmetric(vertical: 14, horizontal: AppSpacing.md), padding: const EdgeInsets.symmetric(vertical: 14, horizontal: AppSpacing.md),
@@ -130,13 +117,13 @@ class _CoinRow extends StatelessWidget {
children: [ children: [
CircleAvatar( CircleAvatar(
radius: 18, radius: 18,
backgroundColor: colorScheme.primary.withValues(alpha: 0.1), backgroundColor: context.colors.primary.withValues(alpha: 0.1),
child: Text( child: Text(
symbol, symbol,
style: AppTextStyles.bodySmall(context).copyWith( style: AppTextStyles.bodySmall(context).copyWith(
fontSize: 10, fontSize: 10,
fontWeight: FontWeight.w700, fontWeight: FontWeight.w700,
color: colorScheme.primary, color: context.colors.primary,
), ),
), ),
), ),

View File

@@ -2,8 +2,8 @@ import 'package:flutter/material.dart';
import 'package:provider/provider.dart'; import 'package:provider/provider.dart';
import 'package:lucide_icons_flutter/lucide_icons.dart'; import 'package:lucide_icons_flutter/lucide_icons.dart';
import '../../../core/theme/app_theme.dart'; import '../../../core/theme/app_theme.dart';
import '../../../core/theme/app_color_scheme.dart';
import '../../../core/theme/app_spacing.dart'; import '../../../core/theme/app_spacing.dart';
import '../../../core/theme/app_theme_extension.dart';
import '../../../data/services/asset_service.dart'; import '../../../data/services/asset_service.dart';
/// 盈亏分析页面 - 月度盈亏日历 /// 盈亏分析页面 - 月度盈亏日历
@@ -26,26 +26,6 @@ class _ProfitAnalysisPageState extends State<ProfitAnalysisPage> {
WidgetsBinding.instance.addPostFrameCallback((_) => _loadProfit()); 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 @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
final colorScheme = Theme.of(context).colorScheme;
final now = DateTime.now(); final now = DateTime.now();
final isCurrentMonth = final isCurrentMonth =
_currentMonth.year == now.year && _currentMonth.month == now.month; _currentMonth.year == now.year && _currentMonth.month == now.month;
return Scaffold( return Scaffold(
backgroundColor: _scaffoldBg, backgroundColor: context.colors.surface,
appBar: AppBar( appBar: AppBar(
title: const Text('盈亏分析'), title: const Text('盈亏分析'),
backgroundColor: _scaffoldBg, backgroundColor: context.colors.surface,
elevation: 0, elevation: 0,
scrolledUnderElevation: 0, scrolledUnderElevation: 0,
centerTitle: true, centerTitle: true,
@@ -130,31 +109,30 @@ class _ProfitAnalysisPageState extends State<ProfitAnalysisPage> {
child: Container( child: Container(
padding: EdgeInsets.all(AppSpacing.lg), padding: EdgeInsets.all(AppSpacing.lg),
decoration: BoxDecoration( decoration: BoxDecoration(
color: _cardBg, color: context.appColors.surfaceCard,
borderRadius: BorderRadius.circular(AppRadius.xl), borderRadius: BorderRadius.circular(AppRadius.xl),
border: Border.all(color: _cardBorder), border: Border.all(color: context.appColors.ghostBorder),
), ),
child: Column( child: Column(
mainAxisSize: MainAxisSize.min, mainAxisSize: MainAxisSize.min,
children: [ children: [
// 月度盈亏摘要 // 月度盈亏摘要
_buildSummarySection(colorScheme), _buildSummarySection(),
SizedBox(height: AppSpacing.md), SizedBox(height: AppSpacing.md),
// 月份导航 // 月份导航
_buildMonthNavigation(colorScheme, isCurrentMonth), _buildMonthNavigation(isCurrentMonth),
SizedBox(height: AppSpacing.sm), SizedBox(height: AppSpacing.sm),
// 星期标题 // 星期标题
_buildWeekdayHeaders(colorScheme), _buildWeekdayHeaders(),
SizedBox(height: AppSpacing.xs), SizedBox(height: AppSpacing.xs),
// 日历网格 // 日历网格
if (_isLoading) if (_isLoading)
_buildLoadingIndicator(colorScheme) _buildLoadingIndicator()
else else
..._buildCalendarGrid( ..._buildCalendarGrid(
colorScheme,
now, now,
isCurrentMonth, 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 isProfit = _monthProfit >= 0;
final color = _isLoading ? colorScheme.onSurfaceVariant : (isProfit ? _upColor : _downColor); final color = _isLoading ? context.colors.onSurfaceVariant : (isProfit ? upColor : downColor);
return Column( return Column(
children: [ children: [
Text( Text(
'月度盈亏', '月度盈亏',
style: AppTextStyles.bodyMedium(context).copyWith( style: AppTextStyles.bodyMedium(context).copyWith(
color: colorScheme.onSurfaceVariant, color: context.colors.onSurfaceVariant,
), ),
), ),
SizedBox(height: AppSpacing.xs), 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( return Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween, mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [ children: [
@@ -203,13 +183,13 @@ class _ProfitAnalysisPageState extends State<ProfitAnalysisPage> {
child: Container( child: Container(
padding: EdgeInsets.all(AppSpacing.xs + 1), padding: EdgeInsets.all(AppSpacing.xs + 1),
decoration: BoxDecoration( decoration: BoxDecoration(
color: colorScheme.surfaceContainerHigh, color: context.colors.surfaceContainerHigh,
borderRadius: BorderRadius.circular(AppRadius.sm), borderRadius: BorderRadius.circular(AppRadius.sm),
), ),
child: Icon( child: Icon(
LucideIcons.chevronLeft, LucideIcons.chevronLeft,
size: 16, size: 16,
color: colorScheme.onSurfaceVariant, color: context.colors.onSurfaceVariant,
), ),
), ),
), ),
@@ -227,16 +207,16 @@ class _ProfitAnalysisPageState extends State<ProfitAnalysisPage> {
padding: EdgeInsets.all(AppSpacing.xs + 1), padding: EdgeInsets.all(AppSpacing.xs + 1),
decoration: BoxDecoration( decoration: BoxDecoration(
color: isCurrentMonth color: isCurrentMonth
? colorScheme.surfaceContainerHigh.withValues(alpha: 0.5) ? context.colors.surfaceContainerHigh.withValues(alpha: 0.5)
: colorScheme.surfaceContainerHigh, : context.colors.surfaceContainerHigh,
borderRadius: BorderRadius.circular(AppRadius.sm), borderRadius: BorderRadius.circular(AppRadius.sm),
), ),
child: Icon( child: Icon(
LucideIcons.chevronRight, LucideIcons.chevronRight,
size: 16, size: 16,
color: isCurrentMonth color: isCurrentMonth
? colorScheme.onSurfaceVariant.withValues(alpha: 0.4) ? context.colors.onSurfaceVariant.withValues(alpha: 0.4)
: colorScheme.onSurfaceVariant, : context.colors.onSurfaceVariant,
), ),
), ),
), ),
@@ -245,7 +225,7 @@ class _ProfitAnalysisPageState extends State<ProfitAnalysisPage> {
} }
/// 星期标题行 /// 星期标题行
Widget _buildWeekdayHeaders(ColorScheme colorScheme) { Widget _buildWeekdayHeaders() {
return Row( return Row(
children: ['', '', '', '', '', '', ''].map((d) { children: ['', '', '', '', '', '', ''].map((d) {
return Expanded( return Expanded(
@@ -254,7 +234,7 @@ class _ProfitAnalysisPageState extends State<ProfitAnalysisPage> {
d, d,
style: AppTextStyles.bodySmall(context).copyWith( style: AppTextStyles.bodySmall(context).copyWith(
fontWeight: FontWeight.w500, 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( return Padding(
padding: EdgeInsets.symmetric(vertical: AppSpacing.xxl), padding: EdgeInsets.symmetric(vertical: AppSpacing.xxl),
child: Center( child: Center(
@@ -273,7 +253,7 @@ class _ProfitAnalysisPageState extends State<ProfitAnalysisPage> {
height: 20, height: 20,
child: CircularProgressIndicator( child: CircularProgressIndicator(
strokeWidth: 2, strokeWidth: 2,
color: colorScheme.primary, color: context.colors.primary,
), ),
), ),
), ),
@@ -282,10 +262,11 @@ class _ProfitAnalysisPageState extends State<ProfitAnalysisPage> {
/// 日历网格 /// 日历网格
List<Widget> _buildCalendarGrid( List<Widget> _buildCalendarGrid(
ColorScheme colorScheme,
DateTime now, DateTime now,
bool isCurrentMonth, bool isCurrentMonth,
) { ) {
final upColor = context.appColors.up;
final downColor = context.appColors.down;
final firstDayOfMonth = DateTime(_currentMonth.year, _currentMonth.month, 1); final firstDayOfMonth = DateTime(_currentMonth.year, _currentMonth.month, 1);
final daysInMonth = final daysInMonth =
DateTime(_currentMonth.year, _currentMonth.month + 1, 0).day; DateTime(_currentMonth.year, _currentMonth.month + 1, 0).day;
@@ -313,16 +294,16 @@ class _ProfitAnalysisPageState extends State<ProfitAnalysisPage> {
margin: EdgeInsets.all(1), margin: EdgeInsets.all(1),
decoration: BoxDecoration( decoration: BoxDecoration(
color: isToday color: isToday
? colorScheme.primary.withValues(alpha: 0.12) ? context.colors.primary.withValues(alpha: 0.12)
: hasProfit : hasProfit
? (profit! > 0 ? (profit! > 0
? _upColor.withValues(alpha: 0.08) ? upColor.withValues(alpha: 0.08)
: _downColor.withValues(alpha: 0.08)) : downColor.withValues(alpha: 0.08))
: Colors.transparent, : Colors.transparent,
borderRadius: BorderRadius.circular(AppRadius.sm), borderRadius: BorderRadius.circular(AppRadius.sm),
border: isToday border: isToday
? Border.all( ? Border.all(
color: colorScheme.primary.withValues(alpha: 0.4), color: context.colors.primary.withValues(alpha: 0.4),
width: 1, width: 1,
) )
: null, : null,
@@ -336,8 +317,8 @@ class _ProfitAnalysisPageState extends State<ProfitAnalysisPage> {
fontSize: 10, fontSize: 10,
fontWeight: isToday ? FontWeight.bold : FontWeight.w400, fontWeight: isToday ? FontWeight.bold : FontWeight.w400,
color: isToday color: isToday
? colorScheme.primary ? context.colors.primary
: colorScheme.onSurface, : context.colors.onSurface,
), ),
), ),
if (hasProfit) ...[ if (hasProfit) ...[
@@ -347,7 +328,7 @@ class _ProfitAnalysisPageState extends State<ProfitAnalysisPage> {
style: TextStyle( style: TextStyle(
fontSize: 7, fontSize: 7,
fontWeight: FontWeight.w600, fontWeight: FontWeight.w600,
color: profit > 0 ? _upColor : _downColor, color: profit > 0 ? upColor : downColor,
), ),
maxLines: 1, maxLines: 1,
overflow: TextOverflow.ellipsis, overflow: TextOverflow.ellipsis,

View File

@@ -2,9 +2,9 @@ import 'dart:math';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:shadcn_ui/shadcn_ui.dart'; import 'package:shadcn_ui/shadcn_ui.dart';
import 'package:provider/provider.dart'; import 'package:provider/provider.dart';
import '../../../core/theme/app_color_scheme.dart';
import '../../../core/theme/app_spacing.dart'; import '../../../core/theme/app_spacing.dart';
import '../../../core/theme/app_theme.dart'; import '../../../core/theme/app_theme.dart';
import '../../../core/theme/app_theme_extension.dart';
import '../../../data/models/coin.dart'; import '../../../data/models/coin.dart';
import '../../../providers/market_provider.dart'; import '../../../providers/market_provider.dart';
import '../../components/glass_panel.dart'; import '../../components/glass_panel.dart';
@@ -34,10 +34,9 @@ class _MarketPageState extends State<MarketPage>
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
super.build(context); super.build(context);
final colorScheme = Theme.of(context).colorScheme;
return Scaffold( return Scaffold(
backgroundColor: colorScheme.background, backgroundColor: context.colors.surface,
body: Consumer<MarketProvider>( body: Consumer<MarketProvider>(
builder: (context, provider, _) { builder: (context, provider, _) {
if (provider.isLoading) { if (provider.isLoading) {
@@ -50,8 +49,8 @@ class _MarketPageState extends State<MarketPage>
return RefreshIndicator( return RefreshIndicator(
onRefresh: () => provider.refresh(), onRefresh: () => provider.refresh(),
color: colorScheme.primary, color: context.colors.primary,
backgroundColor: colorScheme.surfaceContainerHighest, backgroundColor: context.colors.surfaceContainerHighest,
child: SingleChildScrollView( child: SingleChildScrollView(
physics: const AlwaysScrollableScrollPhysics(), physics: const AlwaysScrollableScrollPhysics(),
padding: const EdgeInsets.only( padding: const EdgeInsets.only(
@@ -114,8 +113,6 @@ class _MarketPageState extends State<MarketPage>
/// 分区标题:全部币种 + 更多 /// 分区标题:全部币种 + 更多
Widget _buildSectionHeader() { Widget _buildSectionHeader() {
final colorScheme = Theme.of(context).colorScheme;
return Row( return Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween, mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [ children: [
@@ -126,7 +123,7 @@ class _MarketPageState extends State<MarketPage>
Text( Text(
'更多 >', '更多 >',
style: AppTextStyles.bodyMedium(context).copyWith( 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) { Widget _buildCoinList(MarketProvider provider) {
final coins = provider.otherCoins; final coins = provider.otherCoins;
final colorScheme = Theme.of(context).colorScheme;
if (coins.isEmpty) { if (coins.isEmpty) {
return _EmptyState( return _EmptyState(
@@ -148,10 +144,10 @@ class _MarketPageState extends State<MarketPage>
return Container( return Container(
decoration: BoxDecoration( decoration: BoxDecoration(
color: colorScheme.surfaceContainer, color: context.colors.surfaceContainer,
borderRadius: BorderRadius.circular(AppRadius.lg), borderRadius: BorderRadius.circular(AppRadius.lg),
border: Border.all( border: Border.all(
color: colorScheme.outlineVariant.withValues(alpha: 0.15), color: context.appColors.ghostBorder,
width: 1, width: 1,
), ),
), ),
@@ -162,7 +158,7 @@ class _MarketPageState extends State<MarketPage>
separatorBuilder: (_, __) => Divider( separatorBuilder: (_, __) => Divider(
height: 1, height: 1,
thickness: 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, indent: AppSpacing.md,
endIndent: AppSpacing.md, endIndent: AppSpacing.md,
), ),
@@ -173,18 +169,17 @@ class _MarketPageState extends State<MarketPage>
/// 错误状态 /// 错误状态
Widget _buildErrorState(MarketProvider provider) { Widget _buildErrorState(MarketProvider provider) {
final colorScheme = Theme.of(context).colorScheme;
return Center( return Center(
child: Padding( child: Padding(
padding: AppSpacing.pagePadding, padding: AppSpacing.pagePadding,
child: Column( child: Column(
mainAxisAlignment: MainAxisAlignment.center, mainAxisAlignment: MainAxisAlignment.center,
children: [ children: [
Icon(LucideIcons.circleAlert, size: 48, color: colorScheme.error), Icon(LucideIcons.circleAlert, size: 48, color: context.colors.error),
const SizedBox(height: AppSpacing.md), const SizedBox(height: AppSpacing.md),
Text( Text(
provider.error ?? '加载失败', provider.error ?? '加载失败',
style: TextStyle(color: colorScheme.error), style: TextStyle(color: context.colors.error),
textAlign: TextAlign.center, textAlign: TextAlign.center,
), ),
const SizedBox(height: AppSpacing.md), const SizedBox(height: AppSpacing.md),
@@ -207,14 +202,12 @@ class _FeaturedCard extends StatelessWidget {
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
final colorScheme = Theme.of(context).colorScheme;
final isDark = Theme.of(context).brightness == Brightness.dark;
final isUp = coin.isUp; final isUp = coin.isUp;
final changeColor = final changeColor =
isUp ? AppColorScheme.getUpColor(isDark) : AppColorScheme.down; isUp ? context.appColors.up : context.appColors.down;
final changeBgColor = isUp final changeBgColor = isUp
? AppColorScheme.getUpBackgroundColor(isDark) ? context.appColors.upBackground
: AppColorScheme.getDownBackgroundColor(isDark); : context.appColors.downBackground;
return GlassPanel( return GlassPanel(
padding: const EdgeInsets.all(AppSpacing.md), padding: const EdgeInsets.all(AppSpacing.md),
@@ -255,12 +248,12 @@ class _FeaturedCard extends StatelessWidget {
Text( Text(
coin.name, coin.name,
style: AppTextStyles.bodyMedium(context).copyWith( style: AppTextStyles.bodyMedium(context).copyWith(
color: colorScheme.onSurfaceVariant, color: context.colors.onSurfaceVariant,
), ),
), ),
// 第四行:迷你柱状图 // 第四行:迷你柱状图
Expanded( 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 { class _MiniBarChart extends StatelessWidget {
final bool isUp; final bool isUp;
final bool isDark;
final int seed; final int seed;
const _MiniBarChart({required this.isUp, required this.isDark, required this.seed}); const _MiniBarChart({required this.isUp, required this.seed});
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
final barColor = isUp final barColor = isUp
? AppColorScheme.getUpColor(isDark) ? context.appColors.up
: AppColorScheme.getDownColor(isDark); : context.appColors.down;
// 生成随机但确定的高度序列 // 生成随机但确定的高度序列
final heights = _generateHeights(); final heights = _generateHeights();
@@ -345,14 +337,12 @@ class _CoinRow extends StatelessWidget {
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
final colorScheme = Theme.of(context).colorScheme;
final isDark = Theme.of(context).brightness == Brightness.dark;
final isUp = coin.isUp; final isUp = coin.isUp;
final changeColor = final changeColor =
isUp ? AppColorScheme.getUpColor(isDark) : AppColorScheme.getDownColor(isDark); isUp ? context.appColors.up : context.appColors.down;
final changeBgColor = isUp final changeBgColor = isUp
? AppColorScheme.getUpBackgroundColor(isDark) ? context.appColors.upBackground
: AppColorScheme.getDownBackgroundColor(isDark); : context.appColors.downBackground;
return GestureDetector( return GestureDetector(
onTap: () => _navigateToTrade(context), onTap: () => _navigateToTrade(context),
@@ -428,12 +418,8 @@ class _CoinAvatar extends StatelessWidget {
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
final colorScheme = Theme.of(context).colorScheme;
final isDark = Theme.of(context).brightness == Brightness.dark;
// 从 .pen 设计中的 accent-light 和 accent-primary // 从 .pen 设计中的 accent-light 和 accent-primary
final bgColor = colorScheme.primary.withValues(alpha: isDark ? 0.15 : 0.1); final bgColor = context.colors.primary.withValues(alpha: context.appColors.glowOpacity);
final textColor = colorScheme.primary;
return Container( return Container(
width: 36, width: 36,
@@ -447,7 +433,7 @@ class _CoinAvatar extends StatelessWidget {
_getLetter(), _getLetter(),
style: AppTextStyles.labelLarge(context).copyWith( style: AppTextStyles.labelLarge(context).copyWith(
fontWeight: FontWeight.w700, fontWeight: FontWeight.w700,
color: textColor, color: context.colors.primary,
), ),
), ),
), ),
@@ -477,18 +463,16 @@ class _EmptyState extends StatelessWidget {
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
final colorScheme = Theme.of(context).colorScheme;
return Center( return Center(
child: Padding( child: Padding(
padding: const EdgeInsets.all(AppSpacing.xl), padding: const EdgeInsets.all(AppSpacing.xl),
child: Column( child: Column(
children: [ children: [
Icon(icon, size: 48, color: colorScheme.onSurfaceVariant), Icon(icon, size: 48, color: context.colors.onSurfaceVariant),
const SizedBox(height: AppSpacing.sm + AppSpacing.xs), const SizedBox(height: AppSpacing.sm + AppSpacing.xs),
Text( Text(
message, message,
style: TextStyle(color: colorScheme.onSurfaceVariant), style: TextStyle(color: context.colors.onSurfaceVariant),
), ),
if (onRetry != null) ...[ if (onRetry != null) ...[
const SizedBox(height: AppSpacing.md), const SizedBox(height: AppSpacing.md),

View File

@@ -3,6 +3,7 @@ import 'package:lucide_icons_flutter/lucide_icons.dart';
import 'package:shadcn_ui/shadcn_ui.dart'; import 'package:shadcn_ui/shadcn_ui.dart';
import '../../../../core/theme/app_color_scheme.dart'; import '../../../../core/theme/app_color_scheme.dart';
import '../../../../core/theme/app_spacing.dart'; import '../../../../core/theme/app_spacing.dart';
import '../../../../core/theme/app_theme_extension.dart';
import '../kyc_page.dart'; import '../kyc_page.dart';
import '../welfare_center_page.dart'; import '../welfare_center_page.dart';
import 'menu_group_container.dart'; import 'menu_group_container.dart';
@@ -22,9 +23,6 @@ class MenuGroup1 extends StatelessWidget {
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
final colorScheme = Theme.of(context).colorScheme;
final isDark = Theme.of(context).brightness == Brightness.dark;
return MenuGroupContainer( return MenuGroupContainer(
child: Column( child: Column(
children: [ children: [
@@ -44,7 +42,7 @@ class MenuGroup1 extends StatelessWidget {
// 实名认证 // 实名认证
MenuRow( MenuRow(
icon: LucideIcons.shieldCheck, icon: LucideIcons.shieldCheck,
iconColor: AppColorScheme.getUpColor(isDark), iconColor: context.appColors.up,
title: '实名认证', title: '实名认证',
trailing: KycBadge(kycStatus: kycStatus), trailing: KycBadge(kycStatus: kycStatus),
onTap: () { onTap: () {
@@ -62,7 +60,7 @@ class MenuGroup1 extends StatelessWidget {
// 安全设置 // 安全设置
MenuRow( MenuRow(
icon: LucideIcons.lock, icon: LucideIcons.lock,
iconColor: colorScheme.onSurfaceVariant, iconColor: context.colors.onSurfaceVariant,
title: '安全设置', title: '安全设置',
onTap: () => onShowComingSoon('安全设置'), onTap: () => onShowComingSoon('安全设置'),
), ),
@@ -70,7 +68,7 @@ class MenuGroup1 extends StatelessWidget {
// 消息通知 // 消息通知
MenuRow( MenuRow(
icon: LucideIcons.bell, icon: LucideIcons.bell,
iconColor: colorScheme.onSurfaceVariant, iconColor: context.colors.onSurfaceVariant,
title: '消息通知', title: '消息通知',
trailing: const RedDotIndicator(), trailing: const RedDotIndicator(),
onTap: () => onShowComingSoon('消息通知'), onTap: () => onShowComingSoon('消息通知'),

View File

@@ -1,5 +1,6 @@
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import '../../../../core/theme/app_spacing.dart'; import '../../../../core/theme/app_spacing.dart';
import '../../../../core/theme/app_theme_extension.dart';
/// 菜单分组容器 - 统一的圆角卡片样式 /// 菜单分组容器 - 统一的圆角卡片样式
/// ///
@@ -12,19 +13,14 @@ class MenuGroupContainer extends StatelessWidget {
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
final colorScheme = Theme.of(context).colorScheme;
final isDark = Theme.of(context).brightness == Brightness.dark;
return Container( return Container(
width: double.infinity, width: double.infinity,
clipBehavior: Clip.antiAlias, clipBehavior: Clip.antiAlias,
decoration: BoxDecoration( decoration: BoxDecoration(
color: isDark color: context.appColors.surfaceCard,
? colorScheme.surfaceContainer
: colorScheme.surfaceContainerHigh,
borderRadius: BorderRadius.circular(AppRadius.lg), borderRadius: BorderRadius.circular(AppRadius.lg),
border: Border.all( border: Border.all(
color: colorScheme.outlineVariant.withOpacity(0.15), color: context.appColors.ghostBorder,
), ),
), ),
child: child, child: child,

View File

@@ -4,6 +4,7 @@ import 'package:provider/provider.dart';
import '../../../../core/theme/app_color_scheme.dart'; import '../../../../core/theme/app_color_scheme.dart';
import '../../../../core/theme/app_spacing.dart'; import '../../../../core/theme/app_spacing.dart';
import '../../../../core/theme/app_theme.dart'; import '../../../../core/theme/app_theme.dart';
import '../../../../core/theme/app_theme_extension.dart';
import '../../../../providers/theme_provider.dart'; import '../../../../providers/theme_provider.dart';
/// KYC 状态徽章 (e.g. "已认证" green badge + chevron) /// KYC 状态徽章 (e.g. "已认证" green badge + chevron)
@@ -18,9 +19,7 @@ class KycBadge extends StatelessWidget {
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
final isDark = Theme.of(context).brightness == Brightness.dark; final green = context.appColors.up;
final green = AppColorScheme.getUpColor(isDark);
final colorScheme = Theme.of(context).colorScheme;
if (kycStatus == 2) { if (kycStatus == 2) {
return Row( return Row(
@@ -43,7 +42,7 @@ class KycBadge extends StatelessWidget {
Icon( Icon(
LucideIcons.chevronRight, LucideIcons.chevronRight,
size: 16, size: 16,
color: colorScheme.onSurfaceVariant, color: context.colors.onSurfaceVariant,
), ),
], ],
); );
@@ -70,7 +69,7 @@ class KycBadge extends StatelessWidget {
Icon( Icon(
LucideIcons.chevronRight, LucideIcons.chevronRight,
size: 16, size: 16,
color: colorScheme.onSurfaceVariant, color: context.colors.onSurfaceVariant,
), ),
], ],
); );
@@ -79,7 +78,7 @@ class KycBadge extends StatelessWidget {
return Icon( return Icon(
LucideIcons.chevronRight, LucideIcons.chevronRight,
size: 16, size: 16,
color: colorScheme.onSurfaceVariant, color: context.colors.onSurfaceVariant,
); );
} }
} }
@@ -105,7 +104,7 @@ class RedDotIndicator extends StatelessWidget {
Icon( Icon(
LucideIcons.chevronRight, LucideIcons.chevronRight,
size: 16, size: 16,
color: Theme.of(context).colorScheme.onSurfaceVariant, color: context.colors.onSurfaceVariant,
), ),
], ],
); );
@@ -118,8 +117,6 @@ class DarkModeRow extends StatelessWidget {
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
final colorScheme = Theme.of(context).colorScheme;
final isDark = Theme.of(context).brightness == Brightness.dark;
final themeProvider = context.watch<ThemeProvider>(); final themeProvider = context.watch<ThemeProvider>();
return Padding( return Padding(
@@ -131,16 +128,14 @@ class DarkModeRow extends StatelessWidget {
width: 36, width: 36,
height: 36, height: 36,
decoration: BoxDecoration( decoration: BoxDecoration(
color: isDark color: context.appColors.surfaceCardHigh,
? colorScheme.surfaceContainerHigh
: colorScheme.surfaceContainerHighest,
borderRadius: BorderRadius.circular(8), borderRadius: BorderRadius.circular(8),
), ),
child: Center( child: Center(
child: Icon( child: Icon(
LucideIcons.moon, LucideIcons.moon,
size: 18, size: 18,
color: colorScheme.onSurfaceVariant, color: context.colors.onSurfaceVariant,
), ),
), ),
), ),
@@ -160,9 +155,7 @@ class DarkModeRow extends StatelessWidget {
height: 24, height: 24,
padding: const EdgeInsets.all(2), padding: const EdgeInsets.all(2),
decoration: BoxDecoration( decoration: BoxDecoration(
color: isDark color: context.appColors.surfaceCardHigh,
? colorScheme.surfaceContainerHigh
: colorScheme.surfaceContainerHighest,
borderRadius: BorderRadius.circular(12), borderRadius: BorderRadius.circular(12),
), ),
child: AnimatedAlign( child: AnimatedAlign(
@@ -174,7 +167,7 @@ class DarkModeRow extends StatelessWidget {
width: 20, width: 20,
height: 20, height: 20,
decoration: BoxDecoration( decoration: BoxDecoration(
color: colorScheme.onSurface, color: context.colors.onSurface,
shape: BoxShape.circle, shape: BoxShape.circle,
), ),
), ),

View File

@@ -2,6 +2,7 @@ import 'package:flutter/material.dart';
import 'package:lucide_icons_flutter/lucide_icons.dart'; import 'package:lucide_icons_flutter/lucide_icons.dart';
import '../../../../core/theme/app_spacing.dart'; import '../../../../core/theme/app_spacing.dart';
import '../../../../core/theme/app_theme.dart'; import '../../../../core/theme/app_theme.dart';
import '../../../../core/theme/app_theme_extension.dart';
import 'avatar_circle.dart'; import 'avatar_circle.dart';
/// 用户资料卡片 - 头像 + 用户名 + 徽章 + chevron /// 用户资料卡片 - 头像 + 用户名 + 徽章 + chevron
@@ -11,19 +12,14 @@ class ProfileCard extends StatelessWidget {
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
final colorScheme = Theme.of(context).colorScheme;
final isDark = Theme.of(context).brightness == Brightness.dark;
return Container( return Container(
width: double.infinity, width: double.infinity,
padding: const EdgeInsets.all(20), padding: const EdgeInsets.all(20),
decoration: BoxDecoration( decoration: BoxDecoration(
color: isDark color: context.appColors.surfaceCard,
? colorScheme.surfaceContainer
: colorScheme.surfaceContainerHigh,
borderRadius: BorderRadius.circular(AppRadius.lg), borderRadius: BorderRadius.circular(AppRadius.lg),
border: Border.all( border: Border.all(
color: colorScheme.outlineVariant.withValues(alpha: 0.15), color: context.appColors.ghostBorder,
), ),
), ),
child: Row( child: Row(
@@ -58,7 +54,7 @@ class ProfileCard extends StatelessWidget {
Icon( Icon(
LucideIcons.chevronRight, LucideIcons.chevronRight,
size: 16, size: 16,
color: colorScheme.onSurfaceVariant, color: context.colors.onSurfaceVariant,
), ),
], ],
), ),

View File

@@ -2,9 +2,9 @@ import 'package:flutter/material.dart';
import 'package:flutter/services.dart'; import 'package:flutter/services.dart';
import 'package:shadcn_ui/shadcn_ui.dart'; import 'package:shadcn_ui/shadcn_ui.dart';
import 'package:provider/provider.dart'; import 'package:provider/provider.dart';
import '../../../core/theme/app_color_scheme.dart';
import '../../../core/theme/app_spacing.dart'; import '../../../core/theme/app_spacing.dart';
import '../../../core/theme/app_theme.dart'; import '../../../core/theme/app_theme.dart';
import '../../../core/theme/app_theme_extension.dart';
import '../../../core/utils/toast_utils.dart'; import '../../../core/utils/toast_utils.dart';
import '../../../core/event/app_event_bus.dart'; import '../../../core/event/app_event_bus.dart';
import '../../../data/services/bonus_service.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}) { BoxDecoration _cardDecoration({Color? borderColor}) {
final scheme = Theme.of(context).colorScheme;
return BoxDecoration( return BoxDecoration(
color: _surfaceCard, color: context.appColors.surfaceCard,
borderRadius: BorderRadius.circular(AppRadius.lg), borderRadius: BorderRadius.circular(AppRadius.lg),
border: Border.all( border: Border.all(
color: borderColor ?? scheme.outlineVariant.withValues(alpha: 0.15), color: borderColor ?? context.appColors.ghostBorder,
), ),
); );
} }
/// 金色渐变卡片容器 /// 金色渐变卡片容器
BoxDecoration _goldGradientDecoration() { BoxDecoration _goldGradientDecoration() {
final goldAccent = context.appColors.accentPrimary;
return BoxDecoration( return BoxDecoration(
borderRadius: BorderRadius.circular(AppRadius.xl), borderRadius: BorderRadius.circular(AppRadius.xl),
gradient: LinearGradient( gradient: LinearGradient(
begin: Alignment.topCenter, begin: Alignment.topCenter,
end: Alignment.bottomCenter, end: Alignment.bottomCenter,
colors: [ colors: [
_goldAccent.withValues(alpha: 0.15), goldAccent.withValues(alpha: 0.15),
_surfaceCard, context.appColors.surfaceCard,
], ],
), ),
border: Border.all( border: Border.all(
color: _goldAccent.withValues(alpha: 0.3), color: goldAccent.withValues(alpha: 0.3),
width: 1, width: 1,
), ),
); );
@@ -164,16 +130,12 @@ class _WelfareCenterPageState extends State<WelfareCenterPage> {
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
final colorScheme = Theme.of(context).colorScheme; final goldAccent = context.appColors.accentPrimary;
return Scaffold( return Scaffold(
backgroundColor: _isDark backgroundColor: context.colors.surface,
? AppColorScheme.darkBackground
: AppColorScheme.lightBackground,
appBar: AppBar( appBar: AppBar(
backgroundColor: _isDark backgroundColor: context.colors.surface,
? AppColorScheme.darkBackground
: AppColorScheme.lightSurfaceLowest,
elevation: 0, elevation: 0,
scrolledUnderElevation: 0, scrolledUnderElevation: 0,
centerTitle: false, centerTitle: false,
@@ -183,20 +145,20 @@ class _WelfareCenterPageState extends State<WelfareCenterPage> {
style: AppTextStyles.headlineLarge(context), style: AppTextStyles.headlineLarge(context),
), ),
leading: IconButton( 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(), onPressed: () => Navigator.of(context).pop(),
), ),
), ),
body: _isLoading body: _isLoading
? Center( ? Center(
child: CircularProgressIndicator( child: CircularProgressIndicator(
color: _goldAccent, color: goldAccent,
strokeWidth: 2.5, strokeWidth: 2.5,
), ),
) )
: RefreshIndicator( : RefreshIndicator(
onRefresh: _loadData, onRefresh: _loadData,
color: _goldAccent, color: goldAccent,
child: SingleChildScrollView( child: SingleChildScrollView(
physics: const AlwaysScrollableScrollPhysics(), physics: const AlwaysScrollableScrollPhysics(),
padding: const EdgeInsets.fromLTRB(16, 8, 16, 32), padding: const EdgeInsets.fromLTRB(16, 8, 16, 32),
@@ -222,7 +184,7 @@ class _WelfareCenterPageState extends State<WelfareCenterPage> {
// ============================================ // ============================================
Widget _buildReferralCodeCard(BuildContext context) { Widget _buildReferralCodeCard(BuildContext context) {
final colorScheme = Theme.of(context).colorScheme; final goldAccent = context.appColors.accentPrimary;
final referralCode = _welfareData?['referralCode'] as String? ?? ''; final referralCode = _welfareData?['referralCode'] as String? ?? '';
return Container( return Container(
@@ -235,7 +197,7 @@ class _WelfareCenterPageState extends State<WelfareCenterPage> {
// Header Row: gift icon + 标题 // Header Row: gift icon + 标题
Row( Row(
children: [ children: [
Icon(LucideIcons.gift, color: _goldAccent, size: 24), Icon(LucideIcons.gift, color: goldAccent, size: 24),
const SizedBox(width: 10), const SizedBox(width: 10),
Text( Text(
'我的邀请码', '我的邀请码',
@@ -250,7 +212,7 @@ class _WelfareCenterPageState extends State<WelfareCenterPage> {
referralCode.isEmpty ? '暂无邀请码' : referralCode, referralCode.isEmpty ? '暂无邀请码' : referralCode,
style: AppTextStyles.displayMedium(context).copyWith( style: AppTextStyles.displayMedium(context).copyWith(
fontWeight: FontWeight.w800, fontWeight: FontWeight.w800,
color: _goldAccent, color: goldAccent,
letterSpacing: 2, letterSpacing: 2,
), ),
), ),
@@ -266,17 +228,17 @@ class _WelfareCenterPageState extends State<WelfareCenterPage> {
ToastUtils.show('邀请码已复制'); ToastUtils.show('邀请码已复制');
}, },
style: ElevatedButton.styleFrom( style: ElevatedButton.styleFrom(
backgroundColor: _goldAccent, backgroundColor: goldAccent,
foregroundColor: _textInverse, foregroundColor: context.colors.onSurface,
elevation: 0, elevation: 0,
shape: RoundedRectangleBorder( shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(AppRadius.lg), borderRadius: BorderRadius.circular(AppRadius.lg),
), ),
disabledBackgroundColor: _goldAccent.withValues(alpha: 0.4), disabledBackgroundColor: goldAccent.withValues(alpha: 0.4),
), ),
child: Text( 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) { 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 newUserBonus = _welfareData?['newUserBonus'] as Map<String, dynamic>?;
final eligible = newUserBonus?['eligible'] as bool? ?? false; final eligible = newUserBonus?['eligible'] as bool? ?? false;
final claimed = newUserBonus?['claimed'] as bool? ?? false; final claimed = newUserBonus?['claimed'] as bool? ?? false;
@@ -341,7 +304,7 @@ class _WelfareCenterPageState extends State<WelfareCenterPage> {
), ),
), ),
if (showAvailableBadge) if (showAvailableBadge)
_statusBadge(badgeText, _profitGreen, _profitGreenBg), _statusBadge(badgeText, profitGreen, profitGreenBg),
], ],
), ),
const SizedBox(height: 12), const SizedBox(height: 12),
@@ -349,21 +312,21 @@ class _WelfareCenterPageState extends State<WelfareCenterPage> {
'+100 USDT', '+100 USDT',
style: AppTextStyles.displayLarge(context).copyWith( style: AppTextStyles.displayLarge(context).copyWith(
fontWeight: FontWeight.w800, fontWeight: FontWeight.w800,
color: claimed ? colorScheme.onSurfaceVariant : _profitGreen, color: claimed ? context.colors.onSurfaceVariant : profitGreen,
), ),
), ),
const SizedBox(height: 8), const SizedBox(height: 8),
Text( Text(
description, description,
style: AppTextStyles.bodyLarge(context).copyWith( style: AppTextStyles.bodyLarge(context).copyWith(
color: colorScheme.onSurfaceVariant, color: context.colors.onSurfaceVariant,
), ),
), ),
const SizedBox(height: 16), const SizedBox(height: 16),
_fullWidthButton( _fullWidthButton(
text: buttonText, text: buttonText,
backgroundColor: _profitGreen, backgroundColor: profitGreen,
foregroundColor: colorScheme.onPrimary, foregroundColor: context.colors.onPrimary,
onPressed: canClaim ? () => _claimNewUserBonus() : null, onPressed: canClaim ? () => _claimNewUserBonus() : null,
), ),
], ],
@@ -376,7 +339,6 @@ class _WelfareCenterPageState extends State<WelfareCenterPage> {
// ============================================ // ============================================
Widget _buildReferralRewardsSection(BuildContext context) { Widget _buildReferralRewardsSection(BuildContext context) {
final colorScheme = Theme.of(context).colorScheme;
final referralRewards = final referralRewards =
_welfareData?['referralRewards'] as List<dynamic>? ?? []; _welfareData?['referralRewards'] as List<dynamic>? ?? [];
@@ -392,7 +354,7 @@ class _WelfareCenterPageState extends State<WelfareCenterPage> {
Text( Text(
'每邀请一位好友充值达标奖励100 USDT', '每邀请一位好友充值达标奖励100 USDT',
style: AppTextStyles.bodySmall(context).copyWith( style: AppTextStyles.bodySmall(context).copyWith(
color: _textMuted, color: context.appColors.onSurfaceMuted,
), ),
), ),
const SizedBox(height: 12), const SizedBox(height: 12),
@@ -410,7 +372,6 @@ class _WelfareCenterPageState extends State<WelfareCenterPage> {
} }
Widget _buildEmptyReferralList(BuildContext context) { Widget _buildEmptyReferralList(BuildContext context) {
final colorScheme = Theme.of(context).colorScheme;
return Padding( return Padding(
padding: const EdgeInsets.all(32), padding: const EdgeInsets.all(32),
child: Center( child: Center(
@@ -419,13 +380,13 @@ class _WelfareCenterPageState extends State<WelfareCenterPage> {
Icon( Icon(
LucideIcons.users, LucideIcons.users,
size: 36, size: 36,
color: _textMuted.withValues(alpha: 0.4), color: context.appColors.onSurfaceMuted.withValues(alpha: 0.4),
), ),
const SizedBox(height: 8), const SizedBox(height: 8),
Text( Text(
'暂无推广用户', '暂无推广用户',
style: AppTextStyles.bodyLarge(context).copyWith( 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) { Widget _buildReferralListItems(BuildContext context, List<dynamic> referralRewards) {
final colorScheme = Theme.of(context).colorScheme;
return Column( return Column(
children: List.generate(referralRewards.length, (index) { children: List.generate(referralRewards.length, (index) {
final data = referralRewards[index] as Map<String, dynamic>; final data = referralRewards[index] as Map<String, dynamic>;
@@ -492,7 +451,7 @@ class _WelfareCenterPageState extends State<WelfareCenterPage> {
height: 6, height: 6,
child: LinearProgressIndicator( child: LinearProgressIndicator(
value: progress, value: progress,
backgroundColor: _bgTertiary, backgroundColor: context.appColors.surfaceCardHigh,
valueColor: AlwaysStoppedAnimation<Color>(progressColor), valueColor: AlwaysStoppedAnimation<Color>(progressColor),
minHeight: 6, minHeight: 6,
), ),
@@ -505,7 +464,7 @@ class _WelfareCenterPageState extends State<WelfareCenterPage> {
Divider( Divider(
height: 1, height: 1,
thickness: 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) { Widget _buildAvatar(String username) {
final colorScheme = Theme.of(context).colorScheme;
return Container( return Container(
width: 32, width: 32,
height: 32, height: 32,
decoration: BoxDecoration( decoration: BoxDecoration(
color: _bgTertiary, color: context.appColors.surfaceCardHigh,
shape: BoxShape.circle, shape: BoxShape.circle,
), ),
child: Center( child: Center(
child: Text( child: Text(
username.isNotEmpty ? username[0].toUpperCase() : '?', username.isNotEmpty ? username[0].toUpperCase() : '?',
style: AppTextStyles.headlineSmall(context).copyWith( 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) { Color _referralProgressColor(int claimableCount, double progress) {
if (claimableCount > 0) return _profitGreen; if (claimableCount > 0) return context.appColors.up;
if (progress > 0) return _goldAccent; if (progress > 0) return context.appColors.accentPrimary;
return _bgTertiary; return context.appColors.surfaceCardHigh;
} }
/// 构建推荐奖励的操作按钮 /// 构建推荐奖励的操作按钮
@@ -560,6 +518,9 @@ class _WelfareCenterPageState extends State<WelfareCenterPage> {
required List<dynamic> milestones, required List<dynamic> milestones,
required double progress, required double progress,
}) { }) {
final profitGreen = context.appColors.up;
final profitGreenBg = context.appColors.upBackground;
if (claimableCount > 0) { if (claimableCount > 0) {
final int milestoneValue = milestones.isNotEmpty final int milestoneValue = milestones.isNotEmpty
? (milestones.firstWhere( ? (milestones.firstWhere(
@@ -570,7 +531,7 @@ class _WelfareCenterPageState extends State<WelfareCenterPage> {
return GestureDetector( return GestureDetector(
onTap: () => _claimReferralBonus(data['userId'] as int, milestoneValue), onTap: () => _claimReferralBonus(data['userId'] as int, milestoneValue),
child: _statusBadge('领取', _profitGreen, _profitGreenBg), child: _statusBadge('领取', profitGreen, profitGreenBg),
); );
} }
if (progress > 0) { if (progress > 0) {
@@ -578,7 +539,7 @@ class _WelfareCenterPageState extends State<WelfareCenterPage> {
} }
return Text( 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) { Widget _buildRulesCard(BuildContext context) {
final colorScheme = Theme.of(context).colorScheme;
return Container( return Container(
width: double.infinity, width: double.infinity,
padding: const EdgeInsets.fromLTRB(20, 16, 20, 16), padding: const EdgeInsets.fromLTRB(20, 16, 20, 16),
decoration: BoxDecoration( decoration: BoxDecoration(
color: _bgTertiary, color: context.appColors.surfaceCardHigh,
borderRadius: BorderRadius.circular(AppRadius.lg), borderRadius: BorderRadius.circular(AppRadius.lg),
), ),
child: Column( child: Column(
@@ -613,15 +572,12 @@ class _WelfareCenterPageState extends State<WelfareCenterPage> {
} }
Widget _buildRuleItem(String text) { Widget _buildRuleItem(String text) {
final ruleTextColor = _isDark
? AppColorScheme.darkOnSurfaceVariant
: const Color(0xFF475569);
return Padding( return Padding(
padding: const EdgeInsets.symmetric(vertical: 3), padding: const EdgeInsets.symmetric(vertical: 3),
child: Text( child: Text(
'\u2022 $text', '\u2022 $text',
style: AppTextStyles.bodyMedium(context).copyWith( style: AppTextStyles.bodyMedium(context).copyWith(
color: ruleTextColor, color: context.colors.onSurfaceVariant,
), ),
), ),
); );

View File

@@ -3,6 +3,7 @@ import 'package:shadcn_ui/shadcn_ui.dart';
import '../../../core/theme/app_color_scheme.dart'; import '../../../core/theme/app_color_scheme.dart';
import '../../../core/theme/app_spacing.dart'; import '../../../core/theme/app_spacing.dart';
import '../../../core/theme/app_theme.dart'; import '../../../core/theme/app_theme.dart';
import '../../../core/theme/app_theme_extension.dart';
import '../../../core/storage/local_storage.dart'; import '../../../core/storage/local_storage.dart';
/// 引导页数据模型 /// 引导页数据模型
@@ -91,11 +92,8 @@ class _OnboardingPageState extends State<OnboardingPage> {
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
final colorScheme = Theme.of(context).colorScheme;
final isDark = Theme.of(context).brightness == Brightness.dark;
return Scaffold( return Scaffold(
backgroundColor: colorScheme.surface, backgroundColor: context.colors.surface,
body: SafeArea( body: SafeArea(
child: Column( child: Column(
children: [ children: [
@@ -113,7 +111,7 @@ class _OnboardingPageState extends State<OnboardingPage> {
child: Text( child: Text(
'跳过', '跳过',
style: AppTextStyles.headlineMedium(context).copyWith( style: AppTextStyles.headlineMedium(context).copyWith(
color: colorScheme.onSurfaceVariant, color: context.colors.onSurfaceVariant,
), ),
), ),
), ),
@@ -131,7 +129,7 @@ class _OnboardingPageState extends State<OnboardingPage> {
}, },
itemCount: _items.length, itemCount: _items.length,
itemBuilder: (context, index) { itemBuilder: (context, index) {
return _buildPage(_items[index], isDark); return _buildPage(_items[index]);
}, },
), ),
), ),
@@ -150,7 +148,7 @@ class _OnboardingPageState extends State<OnboardingPage> {
mainAxisAlignment: MainAxisAlignment.center, mainAxisAlignment: MainAxisAlignment.center,
children: List.generate( children: List.generate(
_items.length, _items.length,
(index) => _buildIndicator(index, isDark), (index) => _buildIndicator(index),
), ),
), ),
const SizedBox(height: AppSpacing.xl), const SizedBox(height: AppSpacing.xl),
@@ -161,8 +159,8 @@ class _OnboardingPageState extends State<OnboardingPage> {
child: ElevatedButton( child: ElevatedButton(
onPressed: _nextPage, onPressed: _nextPage,
style: ElevatedButton.styleFrom( style: ElevatedButton.styleFrom(
backgroundColor: colorScheme.primary, backgroundColor: context.colors.primary,
foregroundColor: colorScheme.onPrimary, foregroundColor: context.colors.onPrimary,
shape: RoundedRectangleBorder( shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(AppRadius.lg), borderRadius: BorderRadius.circular(AppRadius.lg),
), ),
@@ -185,9 +183,7 @@ class _OnboardingPageState extends State<OnboardingPage> {
); );
} }
Widget _buildPage(_OnboardingItem item, bool isDark) { Widget _buildPage(_OnboardingItem item) {
final colorScheme = Theme.of(context).colorScheme;
return Padding( return Padding(
padding: const EdgeInsets.symmetric(horizontal: AppSpacing.xl), padding: const EdgeInsets.symmetric(horizontal: AppSpacing.xl),
child: Column( child: Column(
@@ -225,7 +221,7 @@ class _OnboardingPageState extends State<OnboardingPage> {
return Icon( return Icon(
item.icon ?? LucideIcons.image, item.icon ?? LucideIcons.image,
size: 72, size: 72,
color: AppColorScheme.darkOnPrimary, color: context.colors.onPrimary,
); );
}, },
), ),
@@ -233,7 +229,7 @@ class _OnboardingPageState extends State<OnboardingPage> {
: Icon( : Icon(
item.icon ?? LucideIcons.star, item.icon ?? LucideIcons.star,
size: 72, size: 72,
color: AppColorScheme.darkOnPrimary, color: context.colors.onPrimary,
), ),
), ),
), ),
@@ -243,7 +239,7 @@ class _OnboardingPageState extends State<OnboardingPage> {
item.title, item.title,
style: AppTextStyles.displaySmall(context).copyWith( style: AppTextStyles.displaySmall(context).copyWith(
fontWeight: FontWeight.bold, fontWeight: FontWeight.bold,
color: colorScheme.onSurface, color: context.colors.onSurface,
letterSpacing: -0.5, letterSpacing: -0.5,
), ),
), ),
@@ -253,7 +249,7 @@ class _OnboardingPageState extends State<OnboardingPage> {
item.description, item.description,
textAlign: TextAlign.center, textAlign: TextAlign.center,
style: AppTextStyles.headlineMedium(context).copyWith( style: AppTextStyles.headlineMedium(context).copyWith(
color: colorScheme.onSurfaceVariant, color: context.colors.onSurfaceVariant,
height: 1.6, height: 1.6,
), ),
), ),
@@ -262,8 +258,7 @@ class _OnboardingPageState extends State<OnboardingPage> {
); );
} }
Widget _buildIndicator(int index, bool isDark) { Widget _buildIndicator(int index) {
final colorScheme = Theme.of(context).colorScheme;
final isActive = index == _currentPage; final isActive = index == _currentPage;
return AnimatedContainer( return AnimatedContainer(
@@ -272,7 +267,7 @@ class _OnboardingPageState extends State<OnboardingPage> {
width: isActive ? 24 : 8, width: isActive ? 24 : 8,
height: 8, height: 8,
decoration: BoxDecoration( decoration: BoxDecoration(
color: isActive ? colorScheme.primary : colorScheme.outlineVariant, color: isActive ? context.colors.primary : context.colors.outlineVariant,
borderRadius: BorderRadius.circular(AppRadius.sm), borderRadius: BorderRadius.circular(AppRadius.sm),
), ),
); );

View File

@@ -4,6 +4,7 @@ import 'package:provider/provider.dart';
import '../../../core/theme/app_color_scheme.dart'; import '../../../core/theme/app_color_scheme.dart';
import '../../../core/theme/app_spacing.dart'; import '../../../core/theme/app_spacing.dart';
import '../../../core/theme/app_theme.dart'; import '../../../core/theme/app_theme.dart';
import '../../../core/theme/app_theme_extension.dart';
import '../../../providers/asset_provider.dart'; import '../../../providers/asset_provider.dart';
import '../../../data/models/order_models.dart'; import '../../../data/models/order_models.dart';
import 'fund_order_card.dart'; import 'fund_order_card.dart';
@@ -88,8 +89,6 @@ class _FundOrderCardContent extends StatelessWidget {
const _FundOrderCardContent({required this.order}); const _FundOrderCardContent({required this.order});
bool get _isDark => true; // 默认深色
Color _getStatusColor(int status, bool isDeposit) { Color _getStatusColor(int status, bool isDeposit) {
if (isDeposit) { if (isDeposit) {
switch (status) { switch (status) {
@@ -159,8 +158,6 @@ class _FundOrderCardContent extends StatelessWidget {
final theme = ShadTheme.of(context); final theme = ShadTheme.of(context);
final isDeposit = order.type == 1; final isDeposit = order.type == 1;
final statusColor = _getStatusColor(order.status, isDeposit); final statusColor = _getStatusColor(order.status, isDeposit);
final isDark = Theme.of(context).brightness == Brightness.dark;
final onPrimaryColor = isDark ? AppColorScheme.darkOnSurface : AppColorScheme.lightOnSurface;
return ShadCard( return ShadCard(
padding: AppSpacing.cardPadding, padding: AppSpacing.cardPadding,

View File

@@ -7,6 +7,7 @@ import 'package:provider/provider.dart';
import '../../../core/theme/app_color_scheme.dart'; import '../../../core/theme/app_color_scheme.dart';
import '../../../core/theme/app_spacing.dart'; import '../../../core/theme/app_spacing.dart';
import '../../../core/theme/app_theme.dart'; import '../../../core/theme/app_theme.dart';
import '../../../core/theme/app_theme_extension.dart';
import '../../../core/utils/toast_utils.dart'; import '../../../core/utils/toast_utils.dart';
import '../../../core/event/app_event_bus.dart'; import '../../../core/event/app_event_bus.dart';
import '../../../providers/asset_provider.dart'; import '../../../providers/asset_provider.dart';
@@ -51,32 +52,21 @@ class _FundOrdersPageState extends State<FundOrdersPage> {
context.read<AssetProvider>().loadFundOrders(type: type); context.read<AssetProvider>().loadFundOrders(type: type);
} }
// ============================================
// 主题辅助
// ============================================
bool get _isDark => Theme.of(context).brightness == Brightness.dark;
/// 一次性获取所有主题感知颜色
_OrderColors get _colors => _OrderColors(_isDark);
// ============================================ // ============================================
// 构建 UI // 构建 UI
// ============================================ // ============================================
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
final c = _colors;
return Scaffold( return Scaffold(
backgroundColor: c.background, backgroundColor: context.colors.surface,
appBar: AppBar( appBar: AppBar(
leading: IconButton( leading: IconButton(
icon: const Icon(LucideIcons.arrowLeft, size: 20), icon: const Icon(LucideIcons.arrowLeft, size: 20),
onPressed: () => Navigator.of(context).pop(), onPressed: () => Navigator.of(context).pop(),
), ),
title: Text('充提记录', style: AppTextStyles.headlineLarge(context).copyWith(color: c.primaryText)), title: Text('充提记录', style: AppTextStyles.headlineLarge(context).copyWith(color: context.colors.onSurface)),
backgroundColor: c.background, backgroundColor: context.colors.surface,
elevation: 0, elevation: 0,
scrolledUnderElevation: 0, scrolledUnderElevation: 0,
centerTitle: true, centerTitle: true,
@@ -94,15 +84,13 @@ class _FundOrdersPageState extends State<FundOrdersPage> {
// Filter Tabs - pill-style segmented control // Filter Tabs - pill-style segmented control
// --------------------------------------------------------------------------- // ---------------------------------------------------------------------------
Widget _buildFilterTabs() { Widget _buildFilterTabs() {
final c = _colors;
return Padding( return Padding(
padding: const EdgeInsets.symmetric(horizontal: AppSpacing.md), padding: const EdgeInsets.symmetric(horizontal: AppSpacing.md),
child: Container( child: Container(
height: 40, height: 40,
padding: const EdgeInsets.all(AppSpacing.xs), padding: const EdgeInsets.all(AppSpacing.xs),
decoration: BoxDecoration( decoration: BoxDecoration(
color: c.tabBg, color: context.appColors.surfaceCardHigh,
borderRadius: AppRadius.radiusMd, borderRadius: AppRadius.radiusMd,
), ),
child: Row( child: Row(
@@ -117,7 +105,6 @@ class _FundOrdersPageState extends State<FundOrdersPage> {
} }
Widget _buildPillTab(String label, int index) { Widget _buildPillTab(String label, int index) {
final c = _colors;
final isActive = _activeTab == index; final isActive = _activeTab == index;
return Expanded( return Expanded(
@@ -130,15 +117,15 @@ class _FundOrdersPageState extends State<FundOrdersPage> {
}, },
child: Container( child: Container(
decoration: BoxDecoration( decoration: BoxDecoration(
color: isActive ? c.activeTabBg : AppColorScheme.darkSurfaceLowest.withValues(alpha: 0), color: isActive ? context.colors.onSurface : AppColorScheme.darkSurfaceLowest.withValues(alpha: 0),
borderRadius: AppRadius.radiusSm, borderRadius: AppRadius.radiusSm,
), ),
child: Center( child: Center(
child: Text( child: Text(
label, label,
style: isActive style: isActive
? AppTextStyles.headlineMedium(context).copyWith(color: c.activeTabText) ? AppTextStyles.headlineMedium(context).copyWith(color: context.colors.surface)
: AppTextStyles.headlineSmall(context).copyWith(color: c.inactiveTabText), : AppTextStyles.headlineSmall(context).copyWith(color: context.colors.onSurfaceVariant),
), ),
), ),
), ),
@@ -150,8 +137,6 @@ class _FundOrdersPageState extends State<FundOrdersPage> {
// Order List // Order List
// --------------------------------------------------------------------------- // ---------------------------------------------------------------------------
Widget _buildOrderList() { Widget _buildOrderList() {
final c = _colors;
return Consumer<AssetProvider>( return Consumer<AssetProvider>(
builder: (context, provider, _) { builder: (context, provider, _) {
final orders = provider.fundOrders; final orders = provider.fundOrders;
@@ -166,9 +151,9 @@ class _FundOrdersPageState extends State<FundOrdersPage> {
child: Column( child: Column(
mainAxisAlignment: MainAxisAlignment.center, mainAxisAlignment: MainAxisAlignment.center,
children: [ children: [
Icon(LucideIcons.inbox, size: 64, color: c.mutedText), Icon(LucideIcons.inbox, size: 64, color: context.appColors.onSurfaceMuted),
const SizedBox(height: AppSpacing.md), 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 // Order Card
// --------------------------------------------------------------------------- // ---------------------------------------------------------------------------
Widget _buildOrderCard(OrderFund order) { Widget _buildOrderCard(OrderFund order) {
final c = _colors;
return Container( return Container(
padding: AppSpacing.cardPadding, padding: AppSpacing.cardPadding,
decoration: BoxDecoration( decoration: BoxDecoration(
color: c.cardBg, color: context.appColors.surfaceCard,
borderRadius: AppRadius.radiusLg, borderRadius: AppRadius.radiusLg,
border: Border.all(color: c.borderColor, width: 1), border: Border.all(color: context.appColors.ghostBorder, width: 1),
), ),
child: Column( child: Column(
crossAxisAlignment: CrossAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.start,
@@ -216,7 +199,7 @@ class _FundOrdersPageState extends State<FundOrdersPage> {
], ],
if (order.withdrawContact != null) ...[ if (order.withdrawContact != null) ...[
const SizedBox(height: AppSpacing.sm - AppSpacing.xs), const SizedBox(height: AppSpacing.sm - AppSpacing.xs),
_buildDetailRow('联系方式', order.withdrawContact!, c), _buildDetailRow('联系方式', order.withdrawContact!),
], ],
if (order.receivableAmount != null && !order.isDeposit) ...[ if (order.receivableAmount != null && !order.isDeposit) ...[
const SizedBox(height: AppSpacing.sm), const SizedBox(height: AppSpacing.sm),
@@ -232,13 +215,13 @@ class _FundOrdersPageState extends State<FundOrdersPage> {
children: [ children: [
Text( Text(
'创建: ${_formatTime(order.createTime)}', '创建: ${_formatTime(order.createTime)}',
style: AppTextStyles.bodySmall(context).copyWith(color: c.mutedText), style: AppTextStyles.bodySmall(context).copyWith(color: context.appColors.onSurfaceMuted),
), ),
if (order.rejectReason != null) if (order.rejectReason != null)
Expanded( Expanded(
child: Text( child: Text(
'驳回: ${order.rejectReason}', '驳回: ${order.rejectReason}',
style: AppTextStyles.bodySmall(context).copyWith(color: AppColorScheme.getDownColor(_isDark)), style: AppTextStyles.bodySmall(context).copyWith(color: context.appColors.down),
textAlign: TextAlign.right, textAlign: TextAlign.right,
overflow: TextOverflow.ellipsis, overflow: TextOverflow.ellipsis,
), ),
@@ -254,13 +237,12 @@ class _FundOrdersPageState extends State<FundOrdersPage> {
// Card Header (order type + status badge) // Card Header (order type + status badge)
// --------------------------------------------------------------------------- // ---------------------------------------------------------------------------
Widget _buildCardHeader(OrderFund order) { Widget _buildCardHeader(OrderFund order) {
final c = _colors;
return Row( return Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween, mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [ children: [
Text( Text(
order.isDeposit ? '充值' : '提现', order.isDeposit ? '充值' : '提现',
style: AppTextStyles.headlineMedium(context).copyWith(color: c.primaryText), style: AppTextStyles.headlineMedium(context).copyWith(color: context.colors.onSurface),
), ),
_buildStatusBadge(order), _buildStatusBadge(order),
], ],
@@ -268,10 +250,10 @@ class _FundOrdersPageState extends State<FundOrdersPage> {
} }
Widget _buildStatusBadge(OrderFund order) { Widget _buildStatusBadge(OrderFund order) {
final upColor = AppColorScheme.getUpColor(_isDark); final upColor = context.appColors.up;
final downColor = AppColorScheme.getDownColor(_isDark); final downColor = context.appColors.down;
final upBg = AppColorScheme.getUpBackgroundColor(_isDark, opacity: 0.12); final upBg = context.appColors.up.withValues(alpha: 0.12);
final downBg = AppColorScheme.getDownBackgroundColor(_isDark, opacity: 0.12); final downBg = context.appColors.down.withValues(alpha: 0.12);
Color bgColor; Color bgColor;
Color textColor; Color textColor;
@@ -326,10 +308,9 @@ class _FundOrdersPageState extends State<FundOrdersPage> {
// Amount Row // Amount Row
// --------------------------------------------------------------------------- // ---------------------------------------------------------------------------
Widget _buildAmountRow(OrderFund order) { Widget _buildAmountRow(OrderFund order) {
final c = _colors;
return Text( return Text(
'${order.isDeposit ? '+' : '-'}${order.amount} USDT', '${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 // Detail Rows
// --------------------------------------------------------------------------- // ---------------------------------------------------------------------------
Widget _buildDetailRows(OrderFund order) { Widget _buildDetailRows(OrderFund order) {
final c = _colors;
return Column( return Column(
children: [ children: [
_buildDetailRow('订单号', order.orderNo, c), _buildDetailRow('订单号', order.orderNo),
const SizedBox(height: AppSpacing.sm - AppSpacing.xs), const SizedBox(height: AppSpacing.sm - AppSpacing.xs),
if (order.walletAddress != null) ...[ if (order.walletAddress != null) ...[
_buildDetailRow( _buildDetailRow(
'网络', '网络',
order.remark.isNotEmpty ? order.remark : '-', order.remark.isNotEmpty ? order.remark : '-',
c,
), ),
const SizedBox(height: AppSpacing.sm - AppSpacing.xs), const SizedBox(height: AppSpacing.sm - AppSpacing.xs),
_buildDetailRow( _buildDetailRow(
'地址', '地址',
_truncateAddress(order.walletAddress!), _truncateAddress(order.walletAddress!),
c,
trailing: GestureDetector( trailing: GestureDetector(
onTap: () { onTap: () {
Clipboard.setData(ClipboardData(text: order.walletAddress!)); Clipboard.setData(ClipboardData(text: order.walletAddress!));
ToastUtils.show('地址已复制'); 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), const SizedBox(height: AppSpacing.sm - AppSpacing.xs),
] else if (order.remark.isNotEmpty) ...[ ] else if (order.remark.isNotEmpty) ...[
_buildDetailRow('网络', order.remark, c), _buildDetailRow('网络', order.remark),
const SizedBox(height: AppSpacing.sm - AppSpacing.xs), const SizedBox(height: AppSpacing.sm - AppSpacing.xs),
], ],
if (order.fee != null && !order.isDeposit) ...[ if (order.fee != null && !order.isDeposit) ...[
_buildDetailRow('手续费', '${order.fee}%', c), _buildDetailRow('手续费', '${order.fee}%'),
const SizedBox(height: AppSpacing.sm - AppSpacing.xs), const SizedBox(height: AppSpacing.sm - AppSpacing.xs),
], ],
_buildDetailRow( _buildDetailRow(
'时间', '时间',
_formatTime(order.createTime), _formatTime(order.createTime),
c,
), ),
], ],
); );
@@ -382,16 +358,15 @@ class _FundOrdersPageState extends State<FundOrdersPage> {
Widget _buildDetailRow( Widget _buildDetailRow(
String label, String label,
String value, String value, {
_OrderColors c, {
Widget? trailing, Widget? trailing,
}) { }) {
final valueStyle = AppTextStyles.bodyMedium(context).copyWith(color: c.primaryText); final valueStyle = AppTextStyles.bodyMedium(context).copyWith(color: context.colors.onSurface);
return Row( return Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween, mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [ 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) if (trailing != null)
Row( Row(
mainAxisSize: MainAxisSize.min, mainAxisSize: MainAxisSize.min,
@@ -413,7 +388,7 @@ class _FundOrdersPageState extends State<FundOrdersPage> {
Widget _buildRejectionReason(OrderFund order) { Widget _buildRejectionReason(OrderFund order) {
return Text( return Text(
'拒绝原因: ${order.rejectReason}', '拒绝原因: ${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) // Payable Amount Row (withdrawal)
// --------------------------------------------------------------------------- // ---------------------------------------------------------------------------
Widget _buildPayableRow(OrderFund order) { Widget _buildPayableRow(OrderFund order) {
final c = _colors;
return Container( return Container(
padding: const EdgeInsets.symmetric(horizontal: AppSpacing.sm + AppSpacing.xs, vertical: AppSpacing.sm), padding: const EdgeInsets.symmetric(horizontal: AppSpacing.sm + AppSpacing.xs, vertical: AppSpacing.sm),
decoration: BoxDecoration( decoration: BoxDecoration(
color: c.bgTertiary, color: context.appColors.surfaceCardHigh,
borderRadius: AppRadius.radiusSm, borderRadius: AppRadius.radiusSm,
), ),
child: Row( child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween, mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [ children: [
Text('应付金额', style: AppTextStyles.headlineSmall(context).copyWith(color: c.secondaryText)), Text('应付金额', style: AppTextStyles.headlineSmall(context).copyWith(color: context.colors.onSurfaceVariant)),
Text('${order.receivableAmount} USDT', style: AppTextStyles.headlineMedium(context).copyWith(color: c.primaryText)), Text('${order.receivableAmount} USDT', style: AppTextStyles.headlineMedium(context).copyWith(color: context.colors.onSurface)),
], ],
), ),
); );
@@ -443,9 +416,8 @@ class _FundOrdersPageState extends State<FundOrdersPage> {
// Action Buttons // Action Buttons
// --------------------------------------------------------------------------- // ---------------------------------------------------------------------------
Widget _buildActions(OrderFund order) { Widget _buildActions(OrderFund order) {
final upColor = AppColorScheme.getUpColor(_isDark); final upColor = context.appColors.up;
final downColor = AppColorScheme.getDownColor(_isDark); final downColor = context.appColors.down;
final c = _colors;
return Row( return Row(
mainAxisAlignment: MainAxisAlignment.end, mainAxisAlignment: MainAxisAlignment.end,
@@ -473,7 +445,7 @@ class _FundOrdersPageState extends State<FundOrdersPage> {
color: upColor, color: upColor,
borderRadius: AppRadius.radiusSm, 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;
}

View File

@@ -4,6 +4,7 @@ import 'package:provider/provider.dart';
import '../../../core/theme/app_color_scheme.dart'; import '../../../core/theme/app_color_scheme.dart';
import '../../../core/theme/app_spacing.dart'; import '../../../core/theme/app_spacing.dart';
import '../../../core/theme/app_theme.dart'; import '../../../core/theme/app_theme.dart';
import '../../../core/theme/app_theme_extension.dart';
import '../../../providers/asset_provider.dart'; import '../../../providers/asset_provider.dart';
import 'fund_orders_list.dart'; import 'fund_orders_list.dart';
@@ -35,7 +36,6 @@ class _OrdersPageState extends State<OrdersPage> with AutomaticKeepAliveClientMi
Widget build(BuildContext context) { Widget build(BuildContext context) {
super.build(context); super.build(context);
final theme = ShadTheme.of(context); final theme = ShadTheme.of(context);
final isDark = Theme.of(context).brightness == Brightness.dark;
return Scaffold( return Scaffold(
backgroundColor: theme.colorScheme.background, backgroundColor: theme.colorScheme.background,
@@ -84,8 +84,6 @@ class TabSelector extends StatelessWidget {
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
final theme = ShadTheme.of(context); final theme = ShadTheme.of(context);
final isDark = Theme.of(context).brightness == Brightness.dark;
final onPrimaryBg = isDark ? AppColorScheme.darkBackground : AppColorScheme.lightSurfaceLowest;
return Container( return Container(
padding: const EdgeInsets.all(AppSpacing.xs), padding: const EdgeInsets.all(AppSpacing.xs),
@@ -114,7 +112,7 @@ class TabSelector extends StatelessWidget {
label, label,
style: isSelected style: isSelected
? AppTextStyles.labelLarge(context).copyWith( ? AppTextStyles.labelLarge(context).copyWith(
color: onPrimaryBg, color: context.colors.surface,
) )
: AppTextStyles.labelLarge(context).copyWith( : AppTextStyles.labelLarge(context).copyWith(
color: theme.colorScheme.mutedForeground, color: theme.colorScheme.mutedForeground,

View File

@@ -1,8 +1,8 @@
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:lucide_icons_flutter/lucide_icons.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_spacing.dart';
import '../../../../core/theme/app_theme.dart'; import '../../../../core/theme/app_theme.dart';
import '../../../../core/theme/app_theme_extension.dart';
import '../../../../data/models/coin.dart'; import '../../../../data/models/coin.dart';
import 'coin_avatar.dart'; import 'coin_avatar.dart';
@@ -25,21 +25,16 @@ class CoinSelector extends StatelessWidget {
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
final colorScheme = Theme.of(context).colorScheme;
final isDark = Theme.of(context).brightness == Brightness.dark;
return GestureDetector( return GestureDetector(
onTap: () => _showCoinPicker(context), onTap: () => _showCoinPicker(context),
child: Container( child: Container(
width: double.infinity, width: double.infinity,
padding: const EdgeInsets.all(AppSpacing.md), padding: const EdgeInsets.all(AppSpacing.md),
decoration: BoxDecoration( decoration: BoxDecoration(
color: isDark color: context.appColors.surfaceCard,
? colorScheme.surfaceContainer
: colorScheme.surfaceContainerLowest,
borderRadius: BorderRadius.circular(AppRadius.lg), borderRadius: BorderRadius.circular(AppRadius.lg),
border: Border.all( border: Border.all(
color: colorScheme.outlineVariant.withOpacity(0.15), color: context.appColors.ghostBorder,
), ),
), ),
child: Row( child: Row(
@@ -60,14 +55,14 @@ class CoinSelector extends StatelessWidget {
Text( Text(
selectedCoin?.name ?? '点击选择交易对', selectedCoin?.name ?? '点击选择交易对',
style: AppTextStyles.bodyMedium(context).copyWith( style: AppTextStyles.bodyMedium(context).copyWith(
color: colorScheme.onSurfaceVariant, color: context.colors.onSurfaceVariant,
), ),
), ),
], ],
), ),
// 下拉箭头 // 下拉箭头
Icon(LucideIcons.chevronDown, 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) { void _showCoinPicker(BuildContext context) {
final colorScheme = Theme.of(context).colorScheme;
final isDark = Theme.of(context).brightness == Brightness.dark;
showModalBottomSheet( showModalBottomSheet(
context: context, context: context,
backgroundColor: const Color(0x00000000), backgroundColor: const Color(0x00000000),
@@ -85,9 +77,9 @@ class CoinSelector extends StatelessWidget {
builder: (ctx) => Container( builder: (ctx) => Container(
height: MediaQuery.of(ctx).size.height * 0.65, height: MediaQuery.of(ctx).size.height * 0.65,
decoration: BoxDecoration( decoration: BoxDecoration(
color: isDark color: ctx.isDark
? colorScheme.surface ? ctx.colors.surface
: colorScheme.surfaceContainerLowest, : ctx.colors.surfaceContainerLowest,
borderRadius: borderRadius:
BorderRadius.vertical(top: Radius.circular(AppRadius.xxl)), BorderRadius.vertical(top: Radius.circular(AppRadius.xxl)),
), ),
@@ -99,7 +91,7 @@ class CoinSelector extends StatelessWidget {
width: 40, width: 40,
height: 4, height: 4,
decoration: BoxDecoration( decoration: BoxDecoration(
color: colorScheme.onSurfaceVariant.withOpacity(0.3), color: ctx.colors.onSurfaceVariant.withValues(alpha: 0.3),
borderRadius: BorderRadius.circular(AppRadius.sm), borderRadius: BorderRadius.circular(AppRadius.sm),
), ),
), ),
@@ -114,12 +106,12 @@ class CoinSelector extends StatelessWidget {
GestureDetector( GestureDetector(
onTap: () => Navigator.of(ctx).pop(), onTap: () => Navigator.of(ctx).pop(),
child: Icon(LucideIcons.x, 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( Expanded(
child: ListView.builder( child: ListView.builder(
@@ -137,12 +129,10 @@ class CoinSelector extends StatelessWidget {
Widget _buildCoinItem( Widget _buildCoinItem(
Coin coin, BuildContext context, BuildContext sheetContext) { 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 isSelected = selectedCoin?.code == coin.code;
final changeColor = coin.isUp final changeColor = coin.isUp
? AppColorScheme.getUpColor(isDark) ? context.appColors.up
: AppColorScheme.getDownColor(isDark); : context.appColors.down;
return GestureDetector( return GestureDetector(
onTap: () { onTap: () {
@@ -153,7 +143,7 @@ class CoinSelector extends StatelessWidget {
padding: EdgeInsets.symmetric( padding: EdgeInsets.symmetric(
horizontal: AppSpacing.lg, vertical: AppSpacing.md), horizontal: AppSpacing.lg, vertical: AppSpacing.md),
color: color:
isSelected ? colorScheme.primary.withOpacity(0.1) : const Color(0x00000000), isSelected ? context.colors.primary.withValues(alpha: 0.1) : const Color(0x00000000),
child: Row( child: Row(
children: [ children: [
CoinAvatar(icon: coin.displayIcon), CoinAvatar(icon: coin.displayIcon),
@@ -170,7 +160,7 @@ class CoinSelector extends StatelessWidget {
SizedBox(width: AppSpacing.xs), SizedBox(width: AppSpacing.xs),
Text('/USDT', Text('/USDT',
style: AppTextStyles.bodySmall(context).copyWith( style: AppTextStyles.bodySmall(context).copyWith(
color: colorScheme.onSurfaceVariant, color: context.colors.onSurfaceVariant,
)), )),
const Spacer(), const Spacer(),
Text('\$${coin.formattedPrice}', Text('\$${coin.formattedPrice}',
@@ -180,7 +170,7 @@ class CoinSelector extends StatelessWidget {
Container( Container(
padding: EdgeInsets.symmetric(horizontal: 6, vertical: 2), padding: EdgeInsets.symmetric(horizontal: 6, vertical: 2),
decoration: BoxDecoration( decoration: BoxDecoration(
color: changeColor.withOpacity(0.1), color: changeColor.withValues(alpha: 0.1),
borderRadius: BorderRadius.circular(AppRadius.sm), borderRadius: BorderRadius.circular(AppRadius.sm),
), ),
child: Text(coin.formattedChange, child: Text(coin.formattedChange,
@@ -192,7 +182,7 @@ class CoinSelector extends StatelessWidget {
if (isSelected) ...[ if (isSelected) ...[
SizedBox(width: AppSpacing.sm), SizedBox(width: AppSpacing.sm),
Icon(LucideIcons.check, 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, Text(coin.name,
style: AppTextStyles.bodyMedium(context).copyWith( style: AppTextStyles.bodyMedium(context).copyWith(
color: colorScheme.onSurfaceVariant, color: context.colors.onSurfaceVariant,
)), )),
], ],
), ),

View File

@@ -1,7 +1,7 @@
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import '../../../../core/theme/app_color_scheme.dart';
import '../../../../core/theme/app_spacing.dart'; import '../../../../core/theme/app_spacing.dart';
import '../../../../core/theme/app_theme.dart'; import '../../../../core/theme/app_theme.dart';
import '../../../../core/theme/app_theme_extension.dart';
import '../../../components/glass_panel.dart'; import '../../../components/glass_panel.dart';
import '../../../components/neon_glow.dart'; import '../../../components/neon_glow.dart';
@@ -27,11 +27,9 @@ class ConfirmDialog extends StatelessWidget {
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
final colorScheme = Theme.of(context).colorScheme;
final isDark = Theme.of(context).brightness == Brightness.dark;
final actionColor = isBuy final actionColor = isBuy
? AppColorScheme.getUpColor(isDark) ? context.appColors.up
: AppColorScheme.getDownColor(isDark); : context.appColors.down;
return Dialog( return Dialog(
backgroundColor: const Color(0x00000000), backgroundColor: const Color(0x00000000),
@@ -49,14 +47,14 @@ class ConfirmDialog extends StatelessWidget {
), ),
), ),
SizedBox(height: AppSpacing.lg), SizedBox(height: AppSpacing.lg),
_dialogRow(context, '交易对', '$coinCode/USDT', colorScheme), _dialogRow(context, '交易对', '$coinCode/USDT'),
SizedBox(height: AppSpacing.sm), SizedBox(height: AppSpacing.sm),
_dialogRow(context, '委托价格', '$price USDT', colorScheme), _dialogRow(context, '委托价格', '$price USDT'),
SizedBox(height: AppSpacing.sm), SizedBox(height: AppSpacing.sm),
_dialogRow(context, '交易金额', '$amount USDT', colorScheme, _dialogRow(context, '交易金额', '$amount USDT',
valueColor: actionColor), valueColor: actionColor),
SizedBox(height: AppSpacing.sm), SizedBox(height: AppSpacing.sm),
_dialogRow(context, '交易数量', '$quantity $coinCode', colorScheme), _dialogRow(context, '交易数量', '$quantity $coinCode'),
SizedBox(height: AppSpacing.lg), SizedBox(height: AppSpacing.lg),
Row( Row(
children: [ 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}) { {Color? valueColor}) {
return Row( return Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween, mainAxisAlignment: MainAxisAlignment.spaceBetween,
@@ -95,11 +93,11 @@ class ConfirmDialog extends StatelessWidget {
Text(label, Text(label,
style: AppTextStyles.headlineMedium(context).copyWith( style: AppTextStyles.headlineMedium(context).copyWith(
fontWeight: FontWeight.w400, fontWeight: FontWeight.w400,
color: colorScheme.onSurfaceVariant, color: context.colors.onSurfaceVariant,
)), )),
Text(value, Text(value,
style: AppTextStyles.numberMedium(context).copyWith( style: AppTextStyles.numberMedium(context).copyWith(
color: valueColor ?? colorScheme.onSurface, color: valueColor ?? context.colors.onSurface,
)), )),
], ],
); );

View File

@@ -1,38 +1,34 @@
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import '../../../../core/theme/app_spacing.dart'; import '../../../../core/theme/app_spacing.dart';
import '../../../../core/theme/app_theme.dart'; import '../../../../core/theme/app_theme.dart';
import '../../../../core/theme/app_theme_extension.dart';
/// 占位卡片组件 /// 占位卡片组件
/// ///
/// 当未选择币种时显示的占位提示卡片。 /// 当未选择币种时显示的占位提示卡片。
class PlaceholderCard extends StatelessWidget { class PlaceholderCard extends StatelessWidget {
final String message; final String message;
final ColorScheme colorScheme;
const PlaceholderCard({ const PlaceholderCard({
super.key, super.key,
required this.message, required this.message,
required this.colorScheme,
}); });
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
final isDark = Theme.of(context).brightness == Brightness.dark;
return Container( return Container(
width: double.infinity, width: double.infinity,
padding: const EdgeInsets.all(AppSpacing.xl), padding: const EdgeInsets.all(AppSpacing.xl),
decoration: BoxDecoration( decoration: BoxDecoration(
color: isDark color: context.appColors.surfaceCard,
? colorScheme.surfaceContainer
: colorScheme.surfaceContainerLowest,
borderRadius: BorderRadius.circular(AppRadius.lg), borderRadius: BorderRadius.circular(AppRadius.lg),
border: Border.all( border: Border.all(
color: colorScheme.outlineVariant.withOpacity(0.15), color: context.appColors.ghostBorder,
), ),
), ),
child: Center( child: Center(
child: Text(message, child: Text(message,
style: AppTextStyles.headlineMedium(context).copyWith( style: AppTextStyles.headlineMedium(context).copyWith(
color: colorScheme.onSurfaceVariant, color: context.colors.onSurfaceVariant,
)), )),
), ),
); );

View File

@@ -1,7 +1,7 @@
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import '../../../../core/theme/app_color_scheme.dart';
import '../../../../core/theme/app_spacing.dart'; import '../../../../core/theme/app_spacing.dart';
import '../../../../core/theme/app_theme.dart'; import '../../../../core/theme/app_theme.dart';
import '../../../../core/theme/app_theme_extension.dart';
import '../../../../data/models/coin.dart'; import '../../../../data/models/coin.dart';
/// 价格卡片组件 /// 价格卡片组件
@@ -14,25 +14,21 @@ class PriceCard extends StatelessWidget {
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
final colorScheme = Theme.of(context).colorScheme;
final isDark = Theme.of(context).brightness == Brightness.dark;
final isUp = coin.isUp; final isUp = coin.isUp;
final changeColor = final changeColor =
isUp ? AppColorScheme.getUpColor(isDark) : AppColorScheme.getDownColor(isDark); isUp ? context.appColors.up : context.appColors.down;
final changeBgColor = isUp final changeBgColor = isUp
? AppColorScheme.getUpBackgroundColor(isDark) ? context.appColors.upBackground
: AppColorScheme.getDownBackgroundColor(isDark); : context.appColors.downBackground;
return Container( return Container(
width: double.infinity, width: double.infinity,
padding: const EdgeInsets.all(AppSpacing.md + AppSpacing.sm), padding: const EdgeInsets.all(AppSpacing.md + AppSpacing.sm),
decoration: BoxDecoration( decoration: BoxDecoration(
color: isDark color: context.appColors.surfaceCard,
? colorScheme.surfaceContainer
: colorScheme.surfaceContainerLowest,
borderRadius: BorderRadius.circular(AppRadius.lg), borderRadius: BorderRadius.circular(AppRadius.lg),
border: Border.all( border: Border.all(
color: colorScheme.outlineVariant.withOpacity(0.15), color: context.appColors.ghostBorder,
), ),
), ),
child: Column( child: Column(

View File

@@ -2,6 +2,7 @@ import 'package:flutter/material.dart';
import '../../../../core/theme/app_color_scheme.dart'; import '../../../../core/theme/app_color_scheme.dart';
import '../../../../core/theme/app_spacing.dart'; import '../../../../core/theme/app_spacing.dart';
import '../../../../core/theme/app_theme.dart'; import '../../../../core/theme/app_theme.dart';
import '../../../../core/theme/app_theme_extension.dart';
import '../../../../data/models/coin.dart'; import '../../../../data/models/coin.dart';
import 'amount_input.dart'; import 'amount_input.dart';
@@ -37,17 +38,13 @@ class TradeFormCard extends StatelessWidget {
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
final colorScheme = Theme.of(context).colorScheme;
final isDark = Theme.of(context).brightness == Brightness.dark;
final isBuy = tradeType == 0; final isBuy = tradeType == 0;
final actionColor = isBuy final actionColor = isBuy
? AppColorScheme.getUpColor(isDark) ? context.appColors.up
: AppColorScheme.getDownColor(isDark); : context.appColors.down;
// 设计稿中 card 背景色 // 设计稿中 card 背景色
final cardBgColor = isDark final cardBgColor = context.appColors.surfaceCard;
? colorScheme.surfaceContainer
: colorScheme.surfaceContainerLowest;
return Container( return Container(
width: double.infinity, width: double.infinity,
@@ -56,7 +53,7 @@ class TradeFormCard extends StatelessWidget {
color: cardBgColor, color: cardBgColor,
borderRadius: BorderRadius.circular(AppRadius.lg), borderRadius: BorderRadius.circular(AppRadius.lg),
border: Border.all( border: Border.all(
color: colorScheme.outlineVariant.withOpacity(0.15), color: context.appColors.ghostBorder,
), ),
), ),
child: Column( child: Column(
@@ -83,7 +80,7 @@ class TradeFormCard extends StatelessWidget {
border: isBuy border: isBuy
? null ? null
: Border.all( : Border.all(
color: colorScheme.outlineVariant.withOpacity(0.15)), color: context.appColors.ghostBorder),
), ),
child: Center( child: Center(
child: Text( child: Text(
@@ -91,7 +88,7 @@ class TradeFormCard extends StatelessWidget {
style: AppTextStyles.headlineMedium(context).copyWith( style: AppTextStyles.headlineMedium(context).copyWith(
color: isBuy color: isBuy
? AppColorScheme.darkOnPrimary ? AppColorScheme.darkOnPrimary
: colorScheme.onSurfaceVariant, : context.colors.onSurfaceVariant,
), ),
), ),
), ),
@@ -113,7 +110,7 @@ class TradeFormCard extends StatelessWidget {
border: !isBuy border: !isBuy
? null ? null
: Border.all( : Border.all(
color: colorScheme.outlineVariant.withOpacity(0.15)), color: context.appColors.ghostBorder),
), ),
child: Center( child: Center(
child: Text( child: Text(
@@ -121,7 +118,7 @@ class TradeFormCard extends StatelessWidget {
style: AppTextStyles.headlineMedium(context).copyWith( style: AppTextStyles.headlineMedium(context).copyWith(
color: !isBuy color: !isBuy
? AppColorScheme.darkOnPrimary ? AppColorScheme.darkOnPrimary
: colorScheme.onSurfaceVariant, : context.colors.onSurfaceVariant,
), ),
), ),
), ),
@@ -139,7 +136,7 @@ class TradeFormCard extends StatelessWidget {
children: [ children: [
Text('交易金额', Text('交易金额',
style: AppTextStyles.bodyMedium(context).copyWith( style: AppTextStyles.bodyMedium(context).copyWith(
color: colorScheme.onSurfaceVariant, color: context.colors.onSurfaceVariant,
)), )),
Text('USDT', Text('USDT',
style: AppTextStyles.labelLarge(context)), style: AppTextStyles.labelLarge(context)),
@@ -163,7 +160,7 @@ class TradeFormCard extends StatelessWidget {
? '可用: $availableUsdt USDT' ? '可用: $availableUsdt USDT'
: '可用: $availableCoinQty ${selectedCoin?.code ?? ""}', : '可用: $availableCoinQty ${selectedCoin?.code ?? ""}',
style: AppTextStyles.bodySmall(context).copyWith( style: AppTextStyles.bodySmall(context).copyWith(
color: colorScheme.onSurfaceVariant, color: context.colors.onSurfaceVariant,
), ),
), ),
const SizedBox(height: AppSpacing.md), const SizedBox(height: AppSpacing.md),
@@ -172,13 +169,13 @@ class TradeFormCard extends StatelessWidget {
// 设计稿gap:8圆角smbg-tertiary高32 // 设计稿gap:8圆角smbg-tertiary高32
Row( Row(
children: [ children: [
_buildPctButton(context, '25%', 0.25, colorScheme), _buildPctButton(context, '25%', 0.25),
const SizedBox(width: AppSpacing.sm), const SizedBox(width: AppSpacing.sm),
_buildPctButton(context, '50%', 0.5, colorScheme), _buildPctButton(context, '50%', 0.5),
const SizedBox(width: AppSpacing.sm), const SizedBox(width: AppSpacing.sm),
_buildPctButton(context, '75%', 0.75, colorScheme), _buildPctButton(context, '75%', 0.75),
const SizedBox(width: AppSpacing.sm), const SizedBox(width: AppSpacing.sm),
_buildPctButton(context, '100%', 1.0, colorScheme), _buildPctButton(context, '100%', 1.0),
], ],
), ),
const SizedBox(height: AppSpacing.md + AppSpacing.sm), const SizedBox(height: AppSpacing.md + AppSpacing.sm),
@@ -189,7 +186,7 @@ class TradeFormCard extends StatelessWidget {
children: [ children: [
Text('交易数量', Text('交易数量',
style: AppTextStyles.bodyMedium(context).copyWith( style: AppTextStyles.bodyMedium(context).copyWith(
color: colorScheme.onSurfaceVariant, color: context.colors.onSurfaceVariant,
)), )),
Text( Text(
'$calculatedQuantity ${selectedCoin?.code ?? ''}', '$calculatedQuantity ${selectedCoin?.code ?? ''}',
@@ -203,20 +200,20 @@ class TradeFormCard extends StatelessWidget {
} }
/// 百分比按钮 - 设计稿圆角smbg-tertiary高32 /// 百分比按钮 - 设计稿圆角smbg-tertiary高32
Widget _buildPctButton(BuildContext context, String label, double pct, ColorScheme colorScheme) { Widget _buildPctButton(BuildContext context, String label, double pct) {
return Expanded( return Expanded(
child: GestureDetector( child: GestureDetector(
onTap: () => onFillPercent(pct), onTap: () => onFillPercent(pct),
child: Container( child: Container(
height: 32, height: 32,
decoration: BoxDecoration( decoration: BoxDecoration(
color: colorScheme.surfaceContainerHighest.withOpacity(0.5), color: context.colors.surfaceContainerHighest.withValues(alpha: 0.5),
borderRadius: BorderRadius.circular(AppRadius.sm), borderRadius: BorderRadius.circular(AppRadius.sm),
), ),
child: Center( child: Center(
child: Text(label, child: Text(label,
style: AppTextStyles.labelLarge(context).copyWith( style: AppTextStyles.labelLarge(context).copyWith(
color: colorScheme.onSurfaceVariant, color: context.colors.onSurfaceVariant,
)), )),
), ),
), ),

View File

@@ -1,8 +1,8 @@
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:shadcn_ui/shadcn_ui.dart'; import 'package:shadcn_ui/shadcn_ui.dart';
import 'package:provider/provider.dart'; import 'package:provider/provider.dart';
import '../../../core/theme/app_color_scheme.dart';
import '../../../core/theme/app_spacing.dart'; import '../../../core/theme/app_spacing.dart';
import '../../../core/theme/app_theme_extension.dart';
import '../../../data/models/coin.dart'; import '../../../data/models/coin.dart';
import '../../../providers/market_provider.dart'; import '../../../providers/market_provider.dart';
import '../../../providers/asset_provider.dart'; import '../../../providers/asset_provider.dart';
@@ -113,10 +113,9 @@ class _TradePageState extends State<TradePage>
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
super.build(context); super.build(context);
final colorScheme = Theme.of(context).colorScheme;
return Scaffold( return Scaffold(
backgroundColor: colorScheme.background, backgroundColor: context.colors.background,
body: Consumer2<MarketProvider, AssetProvider>( body: Consumer2<MarketProvider, AssetProvider>(
builder: (context, market, asset, _) { builder: (context, market, asset, _) {
return SafeArea( return SafeArea(
@@ -150,7 +149,6 @@ class _TradePageState extends State<TradePage>
else else
PlaceholderCard( PlaceholderCard(
message: '请先选择交易币种', message: '请先选择交易币种',
colorScheme: colorScheme,
), ),
const SizedBox(height: AppSpacing.md), const SizedBox(height: AppSpacing.md),
@@ -262,8 +260,6 @@ class _TradePageState extends State<TradePage>
} }
void _showResultDialog(bool success, String title, String message) { void _showResultDialog(bool success, String title, String message) {
final colorScheme = Theme.of(context).colorScheme;
final isDark = Theme.of(context).brightness == Brightness.dark;
showShadDialog( showShadDialog(
context: context, context: context,
builder: (ctx) => ShadDialog.alert( builder: (ctx) => ShadDialog.alert(
@@ -272,8 +268,8 @@ class _TradePageState extends State<TradePage>
NeonIcon( NeonIcon(
icon: success ? Icons.check_circle : Icons.error, icon: success ? Icons.check_circle : Icons.error,
color: success color: success
? AppColorScheme.getUpColor(isDark) ? ctx.appColors.up
: colorScheme.error, : ctx.colors.error,
size: 24, size: 24,
), ),
SizedBox(width: AppSpacing.sm), SizedBox(width: AppSpacing.sm),