1. 新增工作台三栏布局模式,适配宽屏设备 2. 添加跨平台系统托盘支持,新增托盘图标资源 3. 修复工作台模式下导航返回异常问题 4. 统一JSON类型安全解析,替换硬类型转换 5. 增加macOS深度链接支持,统一渠道分发信息 6. 优化部分页面生命周期和状态加载逻辑 7. 移除废弃的nearby_connections依赖
258 lines
8.2 KiB
Dart
258 lines
8.2 KiB
Dart
/// ============================================================
|
|
/// 闲言APP — 会员页面
|
|
/// 创建时间: 2026-04-20
|
|
/// 更新时间: 2026-06-19
|
|
/// 作用: 会员权益展示
|
|
/// 上次更新: 关闭按钮改用 context.appPop(),修复工作台模式下 Navigator.pop 弹空根栈导致白屏
|
|
/// ============================================================
|
|
|
|
import 'package:flutter/cupertino.dart';
|
|
import 'package:flutter_animate/flutter_animate.dart';
|
|
import 'package:heroine/heroine.dart';
|
|
|
|
import '../../../core/router/app_nav_extension.dart';
|
|
import '../../../core/theme/app_theme.dart';
|
|
import '../../../core/theme/app_spacing.dart';
|
|
import '../../../core/theme/app_typography.dart';
|
|
import '../../../core/theme/app_radius.dart';
|
|
import '../../../shared/widgets/containers/glass_container.dart';
|
|
|
|
/// 会员权益项
|
|
class _PrivilegeItem {
|
|
const _PrivilegeItem({
|
|
required this.emoji,
|
|
required this.title,
|
|
required this.description,
|
|
});
|
|
|
|
final String emoji;
|
|
final String title;
|
|
final String description;
|
|
}
|
|
|
|
const _privileges = [
|
|
_PrivilegeItem(emoji: '💎', title: '无限收藏', description: '收藏句子无数量限制'),
|
|
_PrivilegeItem(emoji: '🔓', title: '来源解锁', description: '解锁全部书籍/影视/人物来源'),
|
|
_PrivilegeItem(emoji: '🎨', title: '高级模板', description: '使用全部卡片模板和特效'),
|
|
_PrivilegeItem(emoji: '☁️', title: '云端同步', description: '多设备数据实时同步'),
|
|
_PrivilegeItem(emoji: '🚫', title: '无广告', description: '纯净阅读体验'),
|
|
_PrivilegeItem(emoji: '🎯', title: '优先推荐', description: '个性化推荐更精准'),
|
|
];
|
|
|
|
/// 会员页面
|
|
class MemberPage extends StatelessWidget {
|
|
const MemberPage({super.key});
|
|
|
|
@override
|
|
Widget build(BuildContext context) {
|
|
final ext = AppTheme.ext(context);
|
|
|
|
return CupertinoPageScaffold(
|
|
backgroundColor: ext.bgPrimary,
|
|
child: DragDismissable(
|
|
child: SafeArea(
|
|
bottom: false,
|
|
child: CustomScrollView(
|
|
physics: const BouncingScrollPhysics(),
|
|
slivers: [
|
|
// 标题栏
|
|
SliverToBoxAdapter(
|
|
child: Padding(
|
|
padding: const EdgeInsets.symmetric(
|
|
horizontal: AppSpacing.md,
|
|
vertical: AppSpacing.sm,
|
|
),
|
|
child: Row(
|
|
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
|
children: [
|
|
Text(
|
|
'👑 会员',
|
|
style: AppTypography.title1.copyWith(
|
|
color: ext.textPrimary,
|
|
),
|
|
),
|
|
CupertinoButton(
|
|
padding: EdgeInsets.zero,
|
|
onPressed: () => context.appPop(),
|
|
child: Icon(
|
|
CupertinoIcons.xmark_circle_fill,
|
|
size: 28,
|
|
color: ext.iconSecondary,
|
|
),
|
|
),
|
|
],
|
|
),
|
|
).animate().fadeIn(duration: 300.ms),
|
|
),
|
|
|
|
// 会员头部
|
|
SliverToBoxAdapter(
|
|
child: Padding(
|
|
padding: const EdgeInsets.symmetric(
|
|
horizontal: AppSpacing.md,
|
|
),
|
|
child: _MemberHeader(ext: ext),
|
|
)
|
|
.animate()
|
|
.fadeIn(duration: 300.ms, delay: 100.ms)
|
|
.slideY(begin: 0.05, end: 0),
|
|
),
|
|
|
|
// 会员权益标题
|
|
SliverToBoxAdapter(
|
|
child: Padding(
|
|
padding: const EdgeInsets.symmetric(
|
|
horizontal: AppSpacing.md,
|
|
vertical: AppSpacing.md,
|
|
),
|
|
child: Text(
|
|
'会员权益',
|
|
style: AppTypography.title3.copyWith(
|
|
color: ext.textPrimary,
|
|
),
|
|
),
|
|
),
|
|
),
|
|
|
|
// 会员权益网格
|
|
SliverToBoxAdapter(
|
|
child: Padding(
|
|
padding: const EdgeInsets.symmetric(
|
|
horizontal: AppSpacing.md,
|
|
),
|
|
child: _PrivilegeGrid(ext: ext),
|
|
).animate().fadeIn(duration: 300.ms, delay: 150.ms),
|
|
),
|
|
|
|
// 底部说明文字
|
|
SliverToBoxAdapter(
|
|
child: Padding(
|
|
padding: const EdgeInsets.symmetric(
|
|
horizontal: AppSpacing.md,
|
|
vertical: AppSpacing.xl,
|
|
),
|
|
child: Center(
|
|
child: Text(
|
|
'更多权益持续解锁中,敬请期待',
|
|
style: AppTypography.subhead.copyWith(
|
|
color: ext.textSecondary,
|
|
),
|
|
),
|
|
),
|
|
),
|
|
),
|
|
|
|
const SliverToBoxAdapter(child: SizedBox(height: 120)),
|
|
],
|
|
),
|
|
),
|
|
),
|
|
);
|
|
}
|
|
}
|
|
|
|
/// 会员头部
|
|
class _MemberHeader extends StatelessWidget {
|
|
const _MemberHeader({required this.ext});
|
|
|
|
final AppThemeExtension ext;
|
|
|
|
@override
|
|
Widget build(BuildContext context) {
|
|
return GlassContainer(
|
|
depth: GlassDepth.elevated,
|
|
margin: EdgeInsets.zero,
|
|
child: Row(
|
|
children: [
|
|
Container(
|
|
width: 56,
|
|
height: 56,
|
|
decoration: BoxDecoration(
|
|
gradient: LinearGradient(
|
|
colors: [ext.accent, ext.accentLight],
|
|
begin: Alignment.topLeft,
|
|
end: Alignment.bottomRight,
|
|
),
|
|
borderRadius: AppRadius.fullBorder,
|
|
),
|
|
child: const Center(
|
|
child: Text('👑', style: TextStyle(fontSize: 28)),
|
|
),
|
|
),
|
|
const SizedBox(width: AppSpacing.md),
|
|
Expanded(
|
|
child: Column(
|
|
crossAxisAlignment: CrossAxisAlignment.start,
|
|
children: [
|
|
Text(
|
|
'闲言会员',
|
|
style: AppTypography.title3.copyWith(
|
|
color: ext.textPrimary,
|
|
fontWeight: FontWeight.w700,
|
|
),
|
|
),
|
|
const SizedBox(height: 2),
|
|
Text(
|
|
'解锁全部权益,畅享阅读体验',
|
|
style: AppTypography.subhead.copyWith(
|
|
color: ext.textSecondary,
|
|
),
|
|
),
|
|
],
|
|
),
|
|
),
|
|
],
|
|
),
|
|
);
|
|
}
|
|
}
|
|
|
|
/// 权益网格
|
|
class _PrivilegeGrid extends StatelessWidget {
|
|
const _PrivilegeGrid({required this.ext});
|
|
|
|
final AppThemeExtension ext;
|
|
|
|
@override
|
|
Widget build(BuildContext context) {
|
|
return Wrap(
|
|
spacing: AppSpacing.sm,
|
|
runSpacing: AppSpacing.sm,
|
|
children: _privileges.map((p) {
|
|
return GlassContainer(
|
|
padding: const EdgeInsets.symmetric(
|
|
horizontal: AppSpacing.md,
|
|
vertical: AppSpacing.sm,
|
|
),
|
|
child: Row(
|
|
mainAxisSize: MainAxisSize.min,
|
|
children: [
|
|
Text(p.emoji, style: const TextStyle(fontSize: 18)),
|
|
const SizedBox(width: AppSpacing.xs),
|
|
Column(
|
|
crossAxisAlignment: CrossAxisAlignment.start,
|
|
mainAxisSize: MainAxisSize.min,
|
|
children: [
|
|
Text(
|
|
p.title,
|
|
style: AppTypography.caption1.copyWith(
|
|
color: ext.textPrimary,
|
|
fontWeight: FontWeight.w600,
|
|
),
|
|
),
|
|
Text(
|
|
p.description,
|
|
style: AppTypography.caption2.copyWith(
|
|
color: ext.textSecondary,
|
|
),
|
|
),
|
|
],
|
|
),
|
|
],
|
|
),
|
|
);
|
|
}).toList(),
|
|
);
|
|
}
|
|
}
|