Files
monisuo/flutter_monisuo/lib/ui/pages/home/hot_coins_section.dart
2026-04-21 08:09:45 +08:00

152 lines
4.8 KiB
Dart

import 'package:flutter/material.dart';
import 'package:provider/provider.dart';
import '../../../core/theme/app_theme.dart';
import '../../../core/theme/app_spacing.dart';
import '../../../core/theme/app_theme_extension.dart';
import '../../../data/models/coin.dart';
import '../../../providers/market_provider.dart';
import '../../components/coin_icon.dart';
import '../main/main_page.dart';
/// 首頁熱門幣種區塊
class HotCoinsSection extends StatelessWidget {
const HotCoinsSection({super.key});
@override
Widget build(BuildContext context) {
return Consumer<MarketProvider>(
builder: (context, market, _) {
// 所有币种,平台代币排首
final platformCoins = market.platformCoins;
final otherCoins = market.nonPlatformCoins;
final coins = [...platformCoins, ...otherCoins];
if (coins.isEmpty) return const SizedBox.shrink();
return Column(
children: [
// Title row
Padding(
padding: const EdgeInsets.symmetric(horizontal: AppSpacing.md),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Text(
'熱門幣種',
style: AppTextStyles.headlineLarge(context),
),
Text(
'更多',
style: AppTextStyles.bodyMedium(context).copyWith(
color: context.appColors.onSurfaceMuted,
),
),
],
),
),
const SizedBox(height: AppSpacing.sm + AppSpacing.xs),
// Card
Container(
decoration: BoxDecoration(
color: Theme.of(context).colorScheme.surfaceContainer,
border: Border.all(
color: Theme.of(context).colorScheme.outlineVariant,
width: 1,
),
borderRadius: BorderRadius.circular(AppRadius.xl),
),
child: Column(
children: List.generate(coins.length, (index) {
return Column(
children: [
_CoinRow(coin: coins[index]),
if (index < coins.length - 1)
Divider(
height: 1,
thickness: 1,
color: context.appColors.ghostBorder,
),
],
);
}),
),
),
],
);
},
);
}
}
class _CoinRow extends StatelessWidget {
const _CoinRow({required this.coin});
final Coin coin;
@override
Widget build(BuildContext context) {
final changeColor = coin.isUp
? context.appColors.up
: context.appColors.down;
return GestureDetector(
onTap: () {
if (coin.isPlatform == 1) {
final mainState = context.findAncestorStateOfType<MainPageState>();
mainState?.switchToTrade(coin.code);
}
},
behavior: HitTestBehavior.opaque,
child: Padding(
padding: const EdgeInsets.symmetric(vertical: 14, horizontal: AppSpacing.md),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
// Left: avatar + name
Row(
children: [
CoinIcon(
symbol: coin.code,
size: 36,
isCircle: false,
),
const SizedBox(width: AppSpacing.sm + AppSpacing.xs),
Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
'${coin.code}/USDT',
style: AppTextStyles.headlineMedium(context).copyWith(
fontWeight: FontWeight.bold,
),
),
Text(
coin.name,
style: AppTextStyles.bodySmall(context),
),
],
),
],
),
// Right: price + change
Column(
crossAxisAlignment: CrossAxisAlignment.end,
children: [
Text(
'\$${coin.formattedPrice}',
style: AppTextStyles.numberMedium(context),
),
Text(
coin.formattedChange,
style: AppTextStyles.labelMedium(context).copyWith(
color: changeColor,
),
),
],
),
],
),
),
);
}
}