700 lines
26 KiB
Dart
700 lines
26 KiB
Dart
// ============================================================
|
||
// SharePage — 邀请好友 / 推广分享页
|
||
//
|
||
// 路由:/share(从 ProfilePage「邀请好友」横幅入口跳转)
|
||
//
|
||
// 功能概述:
|
||
// 1. Hero Card — 渐变卡片,包含:
|
||
// · 专属二维码(qr_flutter 生成,编码 APK 直接下载链接)
|
||
// · 推荐码胶囊(可点击一键复制)
|
||
// 2. 邀请进度 — 显示直接推荐人数 + 团队总人数
|
||
// 3. 推荐奖励计划 — 营销区块:直接奖励 / 团队收益 / 新人福利
|
||
// 4. 我的推荐人信息 — 若当前用户是被推荐的,显示推荐人代码
|
||
// 5. 分享操作列表 — 三种快捷方式:复制推荐码 / 复制链接 / 原生分享
|
||
// 6. 主操作按钮 — 「分享给好友」触发系统原生分享弹层
|
||
//
|
||
// 二维码内容:
|
||
// 后端 admin-service 上传的 APK 直接下载链接
|
||
// 格式:https://api.gogenex.com/api/v1/app/version/download/{id}
|
||
// 扫码即可直接下载安装,推荐码通过注册时手动填写进行归因。
|
||
//
|
||
// 分享文案(含推荐码 + APK 链接)用于营销推广。
|
||
//
|
||
// 依赖包:
|
||
// qr_flutter ^4.1.0 — 本地生成二维码,无网络依赖
|
||
// share_plus ^10.0.2 — 调用系统原生分享弹层
|
||
// ============================================================
|
||
|
||
import 'package:flutter/material.dart';
|
||
import 'package:flutter/services.dart';
|
||
import 'package:qr_flutter/qr_flutter.dart';
|
||
import 'package:share_plus/share_plus.dart';
|
||
import '../../../../app/theme/app_colors.dart';
|
||
import '../../../../app/theme/app_typography.dart';
|
||
import '../../../../app/theme/app_spacing.dart';
|
||
import '../../../../core/services/referral_service.dart';
|
||
import '../../../../core/updater/update_service.dart';
|
||
import '../../../../shared/widgets/genex_button.dart';
|
||
import '../../../../app/i18n/app_localizations.dart';
|
||
|
||
/// A9. 邀请好友 / 推广分享页
|
||
class SharePage extends StatefulWidget {
|
||
const SharePage({super.key});
|
||
|
||
@override
|
||
State<SharePage> createState() => _SharePageState();
|
||
}
|
||
|
||
class _SharePageState extends State<SharePage> {
|
||
// ── 状态 ────────────────────────────────────────────────────────────────
|
||
|
||
ReferralInfo? _info;
|
||
bool _loading = true;
|
||
String? _error;
|
||
|
||
/// 后端 admin-service 上传的 APK 直接下载链接
|
||
/// 用于二维码内容,扫码即可直接下载安装包
|
||
String? _apkUrl;
|
||
|
||
// ── 计算属性 ─────────────────────────────────────────────────────────────
|
||
|
||
/// 二维码内容:优先用 APK 直链,fallback 用 API 域名根路径
|
||
String get _qrContent => _apkUrl ?? 'https://api.gogenex.com';
|
||
|
||
/// 分享用链接(APK 直链 或 fallback)
|
||
String get _shareLink => _apkUrl ?? 'https://api.gogenex.com';
|
||
|
||
// ── 生命周期 ─────────────────────────────────────────────────────────────
|
||
|
||
@override
|
||
void initState() {
|
||
super.initState();
|
||
_loadData();
|
||
}
|
||
|
||
// ── 数据加载 ─────────────────────────────────────────────────────────────
|
||
|
||
/// 并发加载:推荐信息 + APK 下载链接
|
||
Future<void> _loadData() async {
|
||
setState(() {
|
||
_loading = true;
|
||
_error = null;
|
||
});
|
||
|
||
// 并发请求:referral 信息 + APK 下载链接
|
||
final results = await Future.wait([
|
||
ReferralService.instance.getMyInfo().then<Object?>((v) => v).catchError((e) => e),
|
||
UpdateService().getLatestApkUrl().then<Object?>((v) => v).catchError((_) => null),
|
||
]);
|
||
|
||
if (!mounted) return;
|
||
|
||
final referralResult = results[0];
|
||
final apkUrlResult = results[1];
|
||
|
||
if (referralResult is ReferralInfo) {
|
||
setState(() {
|
||
_info = referralResult;
|
||
_apkUrl = apkUrlResult as String?;
|
||
_loading = false;
|
||
});
|
||
} else {
|
||
setState(() {
|
||
_error = referralResult.toString();
|
||
_apkUrl = apkUrlResult as String?;
|
||
_loading = false;
|
||
});
|
||
}
|
||
}
|
||
|
||
// ── 用户操作 ─────────────────────────────────────────────────────────────
|
||
|
||
void _showCopied(String message) {
|
||
ScaffoldMessenger.of(context).showSnackBar(
|
||
SnackBar(
|
||
content: Row(
|
||
mainAxisSize: MainAxisSize.min,
|
||
children: [
|
||
const Icon(Icons.check_circle_rounded, color: Colors.white, size: 18),
|
||
const SizedBox(width: 8),
|
||
Text(message),
|
||
],
|
||
),
|
||
backgroundColor: AppColors.primary,
|
||
behavior: SnackBarBehavior.floating,
|
||
duration: const Duration(seconds: 2),
|
||
shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(12)),
|
||
margin: const EdgeInsets.fromLTRB(16, 0, 16, 16),
|
||
),
|
||
);
|
||
}
|
||
|
||
Future<void> _copyCode() async {
|
||
if (_info == null) return;
|
||
await Clipboard.setData(ClipboardData(text: _info!.referralCode));
|
||
if (mounted) _showCopied(context.t('share.codeCopied'));
|
||
}
|
||
|
||
Future<void> _copyLink() async {
|
||
await Clipboard.setData(ClipboardData(text: _shareLink));
|
||
if (mounted) _showCopied(context.t('share.linkCopied'));
|
||
}
|
||
|
||
/// 系统原生分享:营销文案 = APK 链接 + 推荐码 + 奖励说明
|
||
Future<void> _shareNative() async {
|
||
final code = _info?.referralCode ?? '';
|
||
// 优先用新的营销文案模板(含 {name} 占位符),name 暂用 'Genex 用户'
|
||
final template = context.t('share.shareTextApk');
|
||
final text = template
|
||
.replaceAll('{name}', 'Genex 用户')
|
||
.replaceAll('{code}', code)
|
||
.replaceAll('{link}', _shareLink);
|
||
await Share.share(text, subject: context.t('share.nativeShareTitle'));
|
||
}
|
||
|
||
// ── Build ────────────────────────────────────────────────────────────────
|
||
|
||
@override
|
||
Widget build(BuildContext context) {
|
||
return Scaffold(
|
||
backgroundColor: AppColors.background,
|
||
appBar: AppBar(
|
||
leading: IconButton(
|
||
icon: const Icon(Icons.arrow_back_ios_new_rounded, size: 20),
|
||
onPressed: () => Navigator.of(context).pop(),
|
||
),
|
||
title: Text(context.t('share.title')),
|
||
backgroundColor: Colors.transparent,
|
||
elevation: 0,
|
||
surfaceTintColor: Colors.transparent,
|
||
),
|
||
body: _loading
|
||
? _buildLoading()
|
||
: _error != null && _info == null
|
||
? _buildError()
|
||
: _buildContent(),
|
||
);
|
||
}
|
||
|
||
// ── 加载态 ───────────────────────────────────────────────────────────────
|
||
|
||
Widget _buildLoading() {
|
||
return Center(
|
||
child: Column(
|
||
mainAxisSize: MainAxisSize.min,
|
||
children: [
|
||
const CircularProgressIndicator(),
|
||
const SizedBox(height: 16),
|
||
Text(
|
||
context.t('share.loading'),
|
||
style: AppTypography.bodyMedium.copyWith(color: AppColors.textSecondary),
|
||
),
|
||
],
|
||
),
|
||
);
|
||
}
|
||
|
||
// ── 错误态 ───────────────────────────────────────────────────────────────
|
||
|
||
Widget _buildError() {
|
||
return Center(
|
||
child: Padding(
|
||
padding: AppSpacing.pagePadding,
|
||
child: Column(
|
||
mainAxisSize: MainAxisSize.min,
|
||
children: [
|
||
const Icon(Icons.error_outline_rounded, size: 56, color: AppColors.textTertiary),
|
||
const SizedBox(height: 16),
|
||
Text(
|
||
context.t('share.loadFailed'),
|
||
style: AppTypography.bodyMedium.copyWith(color: AppColors.textSecondary),
|
||
textAlign: TextAlign.center,
|
||
),
|
||
const SizedBox(height: 20),
|
||
TextButton.icon(
|
||
onPressed: _loadData,
|
||
icon: const Icon(Icons.refresh_rounded),
|
||
label: Text(context.t('share.retry')),
|
||
style: TextButton.styleFrom(foregroundColor: AppColors.primary),
|
||
),
|
||
],
|
||
),
|
||
),
|
||
);
|
||
}
|
||
|
||
// ── 主内容 ───────────────────────────────────────────────────────────────
|
||
|
||
Widget _buildContent() {
|
||
return SingleChildScrollView(
|
||
padding: AppSpacing.pagePadding,
|
||
child: Column(
|
||
crossAxisAlignment: CrossAxisAlignment.stretch,
|
||
children: [
|
||
_buildHeroCard(), // QR 码(APK 链接)+ 推荐码
|
||
const SizedBox(height: 16),
|
||
_buildRewardPlanCard(), // 推荐奖励计划(营销区块)
|
||
const SizedBox(height: 16),
|
||
if (_info?.usedCode != null) ...[
|
||
_buildReferrerCard(), // 我的推荐人
|
||
const SizedBox(height: 16),
|
||
],
|
||
_buildShareActions(), // 快捷操作
|
||
const SizedBox(height: 24),
|
||
GenexButton(
|
||
label: context.t('share.shareToFriend'),
|
||
onPressed: _shareNative,
|
||
),
|
||
const SizedBox(height: 40),
|
||
],
|
||
),
|
||
);
|
||
}
|
||
|
||
// ── Hero Card:APK 二维码 + 推荐码 ────────────────────────────────────────
|
||
//
|
||
// 二维码内容 = APK 直接下载链接(admin-service 流式返回)
|
||
// 扫码即触发 Android 下载安装,iOS 浏览器打开提示
|
||
|
||
Widget _buildHeroCard() {
|
||
return Container(
|
||
decoration: BoxDecoration(
|
||
gradient: AppColors.cardGradient,
|
||
borderRadius: BorderRadius.circular(20),
|
||
boxShadow: [
|
||
BoxShadow(
|
||
color: AppColors.primary.withOpacity(0.35),
|
||
blurRadius: 24,
|
||
offset: const Offset(0, 8),
|
||
),
|
||
],
|
||
),
|
||
child: Padding(
|
||
padding: const EdgeInsets.symmetric(horizontal: 24, vertical: 28),
|
||
child: Column(
|
||
children: [
|
||
// ── 顶部标题 ─────────────────────────────────────────────────
|
||
Row(
|
||
mainAxisAlignment: MainAxisAlignment.center,
|
||
children: [
|
||
const Icon(Icons.auto_awesome_rounded, color: Colors.white60, size: 16),
|
||
const SizedBox(width: 6),
|
||
Text(
|
||
context.t('share.scanToDownload'),
|
||
style: AppTypography.bodyMedium.copyWith(color: Colors.white70),
|
||
),
|
||
],
|
||
),
|
||
const SizedBox(height: 6),
|
||
Text(
|
||
'Genex',
|
||
style: AppTypography.displayMedium.copyWith(
|
||
color: Colors.white,
|
||
letterSpacing: 3,
|
||
fontWeight: FontWeight.w800,
|
||
),
|
||
),
|
||
const SizedBox(height: 8),
|
||
|
||
// APK 正在加载时显示提示
|
||
if (_apkUrl == null)
|
||
Padding(
|
||
padding: const EdgeInsets.only(bottom: 8),
|
||
child: Row(
|
||
mainAxisAlignment: MainAxisAlignment.center,
|
||
children: [
|
||
const SizedBox(
|
||
width: 10,
|
||
height: 10,
|
||
child: CircularProgressIndicator(
|
||
color: Colors.white54,
|
||
strokeWidth: 1.5,
|
||
),
|
||
),
|
||
const SizedBox(width: 6),
|
||
Text(
|
||
context.t('share.apkUrlLoading'),
|
||
style: AppTypography.caption.copyWith(color: Colors.white54),
|
||
),
|
||
],
|
||
),
|
||
),
|
||
|
||
const SizedBox(height: 8),
|
||
|
||
// ── 二维码(编码 APK 下载链接)────────────────────────────────
|
||
Container(
|
||
padding: const EdgeInsets.all(14),
|
||
decoration: BoxDecoration(
|
||
color: Colors.white,
|
||
borderRadius: BorderRadius.circular(16),
|
||
boxShadow: [
|
||
BoxShadow(
|
||
color: Colors.black.withOpacity(0.12),
|
||
blurRadius: 16,
|
||
offset: const Offset(0, 4),
|
||
),
|
||
],
|
||
),
|
||
child: QrImageView(
|
||
data: _qrContent,
|
||
version: QrVersions.auto,
|
||
size: 180,
|
||
backgroundColor: Colors.white,
|
||
eyeStyle: const QrEyeStyle(
|
||
eyeShape: QrEyeShape.square,
|
||
color: Color(0xFF4834D4),
|
||
),
|
||
dataModuleStyle: const QrDataModuleStyle(
|
||
dataModuleShape: QrDataModuleShape.square,
|
||
color: Color(0xFF6C5CE7),
|
||
),
|
||
),
|
||
),
|
||
const SizedBox(height: 20),
|
||
|
||
// ── 推荐码胶囊(单独展示,注册时手动填写用于归因)──────────────
|
||
Text(
|
||
context.t('share.myReferralCode'),
|
||
style: AppTypography.caption.copyWith(color: Colors.white60),
|
||
),
|
||
const SizedBox(height: 8),
|
||
GestureDetector(
|
||
onTap: _copyCode,
|
||
child: Container(
|
||
padding: const EdgeInsets.symmetric(horizontal: 16, vertical: 10),
|
||
decoration: BoxDecoration(
|
||
color: Colors.white.withOpacity(0.15),
|
||
borderRadius: BorderRadius.circular(40),
|
||
border: Border.all(color: Colors.white30),
|
||
),
|
||
child: Row(
|
||
mainAxisSize: MainAxisSize.min,
|
||
children: [
|
||
Flexible(
|
||
child: Text(
|
||
_info?.referralCode ?? '------',
|
||
style: AppTypography.h2.copyWith(
|
||
color: Colors.white,
|
||
letterSpacing: 2,
|
||
fontWeight: FontWeight.w700,
|
||
fontFamily: 'monospace',
|
||
),
|
||
overflow: TextOverflow.ellipsis,
|
||
),
|
||
),
|
||
const SizedBox(width: 10),
|
||
Container(
|
||
padding: const EdgeInsets.symmetric(horizontal: 8, vertical: 4),
|
||
decoration: BoxDecoration(
|
||
color: Colors.white.withOpacity(0.2),
|
||
borderRadius: BorderRadius.circular(20),
|
||
),
|
||
child: Row(
|
||
mainAxisSize: MainAxisSize.min,
|
||
children: [
|
||
const Icon(Icons.copy_rounded, size: 12, color: Colors.white),
|
||
const SizedBox(width: 4),
|
||
Text(
|
||
context.t('share.copyCode'),
|
||
style: AppTypography.caption.copyWith(
|
||
color: Colors.white,
|
||
fontWeight: FontWeight.w600,
|
||
),
|
||
),
|
||
],
|
||
),
|
||
),
|
||
],
|
||
),
|
||
),
|
||
),
|
||
|
||
// ── 说明文字 ─────────────────────────────────────────────────
|
||
const SizedBox(height: 12),
|
||
Text(
|
||
context.t('share.joinWith')
|
||
.replaceAll('{code}', _info?.referralCode ?? ''),
|
||
style: AppTypography.caption.copyWith(color: Colors.white54),
|
||
textAlign: TextAlign.center,
|
||
),
|
||
],
|
||
),
|
||
),
|
||
);
|
||
}
|
||
|
||
// ── 邀请进度统计卡片 ─────────────────────────────────────────────────────
|
||
|
||
Widget _buildStatsCard() {
|
||
return Container(
|
||
padding: const EdgeInsets.symmetric(horizontal: 20, vertical: 16),
|
||
decoration: BoxDecoration(
|
||
color: AppColors.surface,
|
||
borderRadius: AppSpacing.borderRadiusMd,
|
||
border: Border.all(color: AppColors.borderLight),
|
||
boxShadow: AppSpacing.shadowSm,
|
||
),
|
||
child: Row(
|
||
children: [
|
||
Expanded(
|
||
child: _buildStatItem(
|
||
icon: Icons.people_rounded,
|
||
value: '${_info?.directReferralCount ?? 0}',
|
||
label: context.t('share.directReferrals'),
|
||
),
|
||
),
|
||
Container(width: 1, height: 44, color: AppColors.borderLight),
|
||
Expanded(
|
||
child: _buildStatItem(
|
||
icon: Icons.groups_rounded,
|
||
value: '${_info?.totalTeamCount ?? 0}',
|
||
label: context.t('share.teamSize'),
|
||
),
|
||
),
|
||
],
|
||
),
|
||
);
|
||
}
|
||
|
||
Widget _buildStatItem({
|
||
required IconData icon,
|
||
required String value,
|
||
required String label,
|
||
}) {
|
||
return Column(
|
||
children: [
|
||
Row(
|
||
mainAxisAlignment: MainAxisAlignment.center,
|
||
children: [
|
||
Icon(icon, size: 16, color: AppColors.primary),
|
||
const SizedBox(width: 4),
|
||
Text(value, style: AppTypography.h2.copyWith(color: AppColors.primary)),
|
||
],
|
||
),
|
||
const SizedBox(height: 2),
|
||
Text(label, style: AppTypography.caption.copyWith(color: AppColors.textSecondary)),
|
||
],
|
||
);
|
||
}
|
||
|
||
// ── 推荐奖励计划(营销区块)──────────────────────────────────────────────
|
||
//
|
||
// 展示推荐系统的三大核心收益,用于说服用户积极分享:
|
||
// 1. 直接推荐奖励 — 每推荐一人注册即得奖励
|
||
// 2. 团队层级收益 — 最高 50 层关系链收益
|
||
// 3. 新人专属福利 — 被推荐用户的注册礼包
|
||
|
||
Widget _buildRewardPlanCard() {
|
||
return Column(
|
||
crossAxisAlignment: CrossAxisAlignment.start,
|
||
children: [
|
||
Padding(
|
||
padding: const EdgeInsets.only(left: 4, bottom: 10),
|
||
child: Text(
|
||
context.t('share.rewardPlanTitle'),
|
||
style: AppTypography.labelSmall.copyWith(color: AppColors.textTertiary),
|
||
),
|
||
),
|
||
Container(
|
||
decoration: BoxDecoration(
|
||
color: AppColors.surface,
|
||
borderRadius: AppSpacing.borderRadiusMd,
|
||
border: Border.all(color: AppColors.borderLight),
|
||
boxShadow: AppSpacing.shadowSm,
|
||
),
|
||
child: Column(
|
||
children: [
|
||
_buildRewardItem(
|
||
icon: Icons.monetization_on_rounded,
|
||
iconBg: const Color(0xFFFFF3E0),
|
||
iconColor: const Color(0xFFFF9800),
|
||
title: context.t('share.rewardDirect'),
|
||
desc: context.t('share.rewardDirectDesc'),
|
||
),
|
||
const Divider(indent: 60, height: 1),
|
||
_buildRewardItem(
|
||
icon: Icons.card_giftcard_rounded,
|
||
iconBg: AppColors.successLight,
|
||
iconColor: AppColors.success,
|
||
title: context.t('share.rewardNewbie'),
|
||
desc: context.t('share.rewardNewbieDesc'),
|
||
),
|
||
],
|
||
),
|
||
),
|
||
],
|
||
);
|
||
}
|
||
|
||
Widget _buildRewardItem({
|
||
required IconData icon,
|
||
required Color iconBg,
|
||
required Color iconColor,
|
||
required String title,
|
||
required String desc,
|
||
}) {
|
||
return Padding(
|
||
padding: const EdgeInsets.symmetric(horizontal: 16, vertical: 14),
|
||
child: Row(
|
||
crossAxisAlignment: CrossAxisAlignment.start,
|
||
children: [
|
||
Container(
|
||
width: 38,
|
||
height: 38,
|
||
decoration: BoxDecoration(color: iconBg, borderRadius: BorderRadius.circular(10)),
|
||
child: Icon(icon, size: 20, color: iconColor),
|
||
),
|
||
const SizedBox(width: 12),
|
||
Expanded(
|
||
child: Column(
|
||
crossAxisAlignment: CrossAxisAlignment.start,
|
||
children: [
|
||
Text(title, style: AppTypography.bodyMedium.copyWith(fontWeight: FontWeight.w600)),
|
||
const SizedBox(height: 2),
|
||
Text(
|
||
desc,
|
||
style: AppTypography.caption.copyWith(color: AppColors.textSecondary),
|
||
),
|
||
],
|
||
),
|
||
),
|
||
],
|
||
),
|
||
);
|
||
}
|
||
|
||
// ── 我的推荐人 ───────────────────────────────────────────────────────────
|
||
//
|
||
// 仅在 _info.usedCode != null 时显示(即当前用户是通过推荐码注册的)
|
||
|
||
Widget _buildReferrerCard() {
|
||
return Container(
|
||
padding: const EdgeInsets.symmetric(horizontal: 16, vertical: 14),
|
||
decoration: BoxDecoration(
|
||
color: AppColors.surface,
|
||
borderRadius: AppSpacing.borderRadiusMd,
|
||
border: Border.all(color: AppColors.borderLight),
|
||
boxShadow: AppSpacing.shadowSm,
|
||
),
|
||
child: Row(
|
||
children: [
|
||
Container(
|
||
width: 38,
|
||
height: 38,
|
||
decoration: BoxDecoration(
|
||
color: AppColors.primaryContainer,
|
||
borderRadius: BorderRadius.circular(10),
|
||
),
|
||
child: const Icon(Icons.person_add_rounded, size: 20, color: AppColors.primary),
|
||
),
|
||
const SizedBox(width: 12),
|
||
Expanded(
|
||
child: Column(
|
||
crossAxisAlignment: CrossAxisAlignment.start,
|
||
children: [
|
||
Text(
|
||
context.t('share.myReferrer'),
|
||
style: AppTypography.caption.copyWith(color: AppColors.textTertiary),
|
||
),
|
||
const SizedBox(height: 2),
|
||
Text(
|
||
_info?.usedCode ?? context.t('share.noReferrer'),
|
||
style: AppTypography.bodyMedium.copyWith(
|
||
fontWeight: FontWeight.w600,
|
||
letterSpacing: 1.5,
|
||
fontFamily: 'monospace',
|
||
),
|
||
),
|
||
],
|
||
),
|
||
),
|
||
],
|
||
),
|
||
);
|
||
}
|
||
|
||
// ── 分享操作列表 ─────────────────────────────────────────────────────────
|
||
|
||
Widget _buildShareActions() {
|
||
return Column(
|
||
crossAxisAlignment: CrossAxisAlignment.start,
|
||
children: [
|
||
Padding(
|
||
padding: const EdgeInsets.only(left: 4, bottom: 10),
|
||
child: Text(
|
||
context.t('share.quickShare'),
|
||
style: AppTypography.labelSmall.copyWith(color: AppColors.textTertiary),
|
||
),
|
||
),
|
||
Container(
|
||
decoration: BoxDecoration(
|
||
color: AppColors.surface,
|
||
borderRadius: AppSpacing.borderRadiusMd,
|
||
border: Border.all(color: AppColors.borderLight),
|
||
boxShadow: AppSpacing.shadowSm,
|
||
),
|
||
child: Column(
|
||
children: [
|
||
_buildActionTile(
|
||
icon: Icons.qr_code_rounded,
|
||
iconBg: AppColors.primaryContainer,
|
||
iconColor: AppColors.primary,
|
||
title: context.t('share.copyCode'),
|
||
subtitle: _info?.referralCode ?? '',
|
||
onTap: _copyCode,
|
||
),
|
||
const Divider(indent: 60, height: 1),
|
||
_buildActionTile(
|
||
icon: Icons.link_rounded,
|
||
iconBg: AppColors.infoLight,
|
||
iconColor: AppColors.info,
|
||
title: context.t('share.copyLink'),
|
||
subtitle: _shareLink,
|
||
onTap: _copyLink,
|
||
),
|
||
const Divider(indent: 60, height: 1),
|
||
_buildActionTile(
|
||
icon: Icons.share_rounded,
|
||
iconBg: AppColors.successLight,
|
||
iconColor: AppColors.success,
|
||
title: context.t('share.shareToFriend'),
|
||
subtitle: context.t('share.shareSubtitle'),
|
||
onTap: _shareNative,
|
||
),
|
||
],
|
||
),
|
||
),
|
||
],
|
||
);
|
||
}
|
||
|
||
Widget _buildActionTile({
|
||
required IconData icon,
|
||
required Color iconBg,
|
||
required Color iconColor,
|
||
required String title,
|
||
required String subtitle,
|
||
required VoidCallback onTap,
|
||
}) {
|
||
return ListTile(
|
||
contentPadding: const EdgeInsets.symmetric(horizontal: 16, vertical: 2),
|
||
leading: Container(
|
||
width: 38,
|
||
height: 38,
|
||
decoration: BoxDecoration(color: iconBg, borderRadius: BorderRadius.circular(10)),
|
||
child: Icon(icon, size: 20, color: iconColor),
|
||
),
|
||
title: Text(title, style: AppTypography.bodyMedium),
|
||
subtitle: Text(
|
||
subtitle,
|
||
style: AppTypography.caption.copyWith(color: AppColors.textTertiary),
|
||
maxLines: 1,
|
||
overflow: TextOverflow.ellipsis,
|
||
),
|
||
trailing: const Icon(Icons.chevron_right_rounded, color: AppColors.textTertiary, size: 20),
|
||
onTap: onTap,
|
||
);
|
||
}
|
||
}
|