| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474 |
- import 'package:flutter/material.dart';
- import 'package:flutter/services.dart';
- import 'package:flutter_screenutil/flutter_screenutil.dart';
- import 'package:get/get.dart';
- import 'package:nomo/app/base/base_view.dart';
- import 'package:nomo/app/widgets/click_opacity.dart';
- import 'package:nomo/app/widgets/ix_app_bar.dart';
- import 'package:nomo/config/theme/theme_extensions/theme_extension.dart';
- import '../../../constants/assets.dart';
- import '../../../widgets/ix_image.dart';
- import '../controllers/account_controller.dart';
- class AccountView extends BaseView<AccountController> {
- const AccountView({super.key});
- @override
- PreferredSizeWidget? get appBar => IXAppBar(title: 'Account');
- @override
- Widget buildContent(BuildContext context) {
- return Obx(() {
- final isPremium = controller.isPremium.value;
- return SingleChildScrollView(
- padding: EdgeInsets.symmetric(horizontal: 14.w, vertical: 20.h),
- child: Column(
- children: [
- // Account 信息卡片
- _buildAccountCard(isPremium),
- 20.verticalSpaceFromWidth,
- // Premium 功能列表
- _buildPremiumFeatures(isPremium),
- 30.verticalSpaceFromWidth,
- // 底部按钮
- _buildBottomButtons(isPremium),
- 20.verticalSpaceFromWidth,
- ],
- ),
- );
- });
- }
- /// 构建账户信息卡片
- Widget _buildAccountCard(bool isPremium) {
- return Container(
- decoration: BoxDecoration(
- color: Get.reactiveTheme.highlightColor,
- borderRadius: BorderRadius.circular(16.r),
- ),
- child: Column(
- children: [
- // Account 条目
- _buildAccountItem(isPremium),
- _buildDivider(),
- // UID 条目
- _buildUIDItem(),
- _buildDivider(),
- // Time/Term 条目
- if (isPremium) _buildValidTermItem() else _buildFreeTimeItem(),
- ],
- ),
- );
- }
- /// Account 条目
- Widget _buildAccountItem(bool isPremium) {
- return Container(
- height: 56.h,
- padding: EdgeInsets.symmetric(horizontal: 16.w),
- child: Row(
- children: [
- // 图标
- Container(
- width: 32.w,
- height: 32.w,
- decoration: BoxDecoration(
- color: const Color(0xFF00A8E8),
- borderRadius: BorderRadius.circular(8.r),
- ),
- child: Icon(Icons.account_circle, size: 20.w, color: Colors.white),
- ),
- SizedBox(width: 12.w),
- // 标题
- Expanded(
- child: Text(
- 'Account',
- style: TextStyle(
- fontSize: 16.sp,
- color: Get.reactiveTheme.textTheme.bodyLarge!.color,
- fontWeight: FontWeight.w400,
- ),
- ),
- ),
- // 徽章
- IXImage(
- source: isPremium ? Assets.premium : Assets.free,
- width: isPremium ? 92.w : 64.w,
- height: 28.w,
- sourceType: ImageSourceType.asset,
- ),
- ],
- ),
- );
- }
- /// UID 条目
- Widget _buildUIDItem() {
- return ClickOpacity(
- onTap: () {
- Clipboard.setData(ClipboardData(text: controller.uid));
- Get.snackbar('已复制', 'UID 已复制到剪贴板');
- },
- child: Container(
- height: 56.h,
- padding: EdgeInsets.symmetric(horizontal: 16.w),
- child: Row(
- children: [
- // 图标
- Container(
- width: 32.w,
- height: 32.w,
- decoration: BoxDecoration(
- color: const Color(0xFF00A8E8),
- borderRadius: BorderRadius.circular(8.r),
- ),
- child: Icon(
- Icons.badge_outlined,
- size: 20.w,
- color: Colors.white,
- ),
- ),
- SizedBox(width: 12.w),
- // UID
- Expanded(
- child: Text(
- controller.uid,
- style: TextStyle(
- fontSize: 16.sp,
- color: Get.reactiveTheme.textTheme.bodyLarge!.color,
- fontWeight: FontWeight.w400,
- ),
- ),
- ),
- // 复制图标
- Icon(Icons.copy, size: 20.w, color: Get.reactiveTheme.hintColor),
- ],
- ),
- ),
- );
- }
- /// Free Time 条目
- Widget _buildFreeTimeItem() {
- return Container(
- height: 56.h,
- padding: EdgeInsets.symmetric(horizontal: 16.w),
- child: Row(
- children: [
- // 图标
- Container(
- width: 32.w,
- height: 32.w,
- decoration: BoxDecoration(
- color: const Color(0xFF00A8E8),
- borderRadius: BorderRadius.circular(8.r),
- ),
- child: Icon(Icons.access_time, size: 20.w, color: Colors.white),
- ),
- SizedBox(width: 12.w),
- // 标题
- Expanded(
- child: Text(
- 'Free Time',
- style: TextStyle(
- fontSize: 16.sp,
- color: Get.reactiveTheme.textTheme.bodyLarge!.color,
- fontWeight: FontWeight.w400,
- ),
- ),
- ),
- // 时间
- Text(
- controller.freeTime,
- style: TextStyle(
- fontSize: 14.sp,
- color: const Color(0xFFFF9500),
- fontWeight: FontWeight.w500,
- ),
- ),
- ],
- ),
- );
- }
- /// Valid Term 条目
- Widget _buildValidTermItem() {
- return Container(
- height: 56.h,
- padding: EdgeInsets.symmetric(horizontal: 16.w),
- child: Row(
- children: [
- // 图标
- Container(
- width: 32.w,
- height: 32.w,
- decoration: BoxDecoration(
- color: const Color(0xFF00A8E8),
- borderRadius: BorderRadius.circular(8.r),
- ),
- child: Icon(Icons.event, size: 20.w, color: Colors.white),
- ),
- SizedBox(width: 12.w),
- // 标题
- Expanded(
- child: Text(
- 'Valid Term',
- style: TextStyle(
- fontSize: 16.sp,
- color: Get.reactiveTheme.textTheme.bodyLarge!.color,
- fontWeight: FontWeight.w400,
- ),
- ),
- ),
- // 有效期
- Text(
- controller.validTerm,
- style: TextStyle(
- fontSize: 14.sp,
- color: const Color(0xFF00A8E8),
- fontWeight: FontWeight.w500,
- ),
- ),
- ],
- ),
- );
- }
- /// Premium 功能列表
- Widget _buildPremiumFeatures(bool isPremium) {
- final features = [
- {'icon': Icons.lock_open, 'title': 'Unlock all free locations'},
- {'icon': Icons.flash_on, 'title': 'Unlock smart mode'},
- {'icon': Icons.timeline, 'title': 'Unlock Multi-hop mode'},
- {'icon': Icons.phone_iphone, 'title': 'Premium can share X devices'},
- {'icon': Icons.dns, 'title': 'Own your own private server'},
- {'icon': Icons.block, 'title': 'Close ads'},
- ];
- return Container(
- decoration: BoxDecoration(
- color: Get.reactiveTheme.highlightColor,
- borderRadius: BorderRadius.circular(16.r),
- ),
- child: Column(
- children: [
- for (int i = 0; i < features.length; i++) ...[
- _buildFeatureItem(
- icon: features[i]['icon'] as IconData,
- title: features[i]['title'] as String,
- isActive: isPremium,
- ),
- if (i < features.length - 1) _buildDivider(),
- ],
- ],
- ),
- );
- }
- /// 功能条目
- Widget _buildFeatureItem({
- required IconData icon,
- required String title,
- required bool isActive,
- }) {
- return Container(
- height: 56.h,
- padding: EdgeInsets.symmetric(horizontal: 16.w),
- child: Row(
- children: [
- // 图标
- Icon(
- icon,
- size: 24.w,
- color: isActive
- ? const Color(0xFFFF9500)
- : Get.reactiveTheme.hintColor.withOpacity(0.5),
- ),
- SizedBox(width: 12.w),
- // 标题
- Expanded(
- child: Text(
- title,
- style: TextStyle(
- fontSize: 16.sp,
- color: isActive
- ? Get.reactiveTheme.hintColor
- : Get.reactiveTheme.hintColor.withOpacity(0.5),
- fontWeight: FontWeight.w400,
- ),
- ),
- ),
- // 状态图标
- Container(
- width: 24.w,
- height: 24.w,
- decoration: BoxDecoration(
- color: isActive
- ? const Color(0xFF00D9A3)
- : Get.reactiveTheme.hintColor.withOpacity(0.3),
- shape: BoxShape.circle,
- ),
- child: Icon(
- isActive ? Icons.check : Icons.close,
- size: 16.w,
- color: isActive
- ? Colors.white
- : Get.reactiveTheme.hintColor.withOpacity(0.5),
- ),
- ),
- ],
- ),
- );
- }
- /// 底部按钮
- Widget _buildBottomButtons(bool isPremium) {
- if (isPremium) {
- return Column(
- children: [
- // Change Subscription 按钮
- _buildPrimaryButton(
- text: 'Change Subscription',
- onTap: () {
- // TODO: 修改订阅
- },
- ),
- SizedBox(height: 16.h),
- // Device Authorization 按钮
- _buildSecondaryButton(
- text:
- 'Device Authorization (${controller.deviceCount}/${controller.maxDeviceCount})',
- icon: Icons.link,
- onTap: () {
- // TODO: 设备授权
- },
- ),
- SizedBox(height: 12.h),
- // 提示文字
- Text(
- 'You can authorize other devices as Premium users\n(${controller.deviceCount}/${controller.maxDeviceCount})',
- textAlign: TextAlign.center,
- style: TextStyle(
- fontSize: 12.sp,
- color: Get.reactiveTheme.hintColor.withOpacity(0.6),
- height: 1.5,
- ),
- ),
- ],
- );
- } else {
- return Column(
- children: [
- // Upgrade to Premium 按钮
- _buildPrimaryButton(
- text: 'Upgrade to Premium',
- onTap: () {
- // TODO: 升级到会员
- },
- ),
- SizedBox(height: 16.h),
- // Activate Pre Code 按钮
- _buildSecondaryButton(
- text: 'Activate Pre Code',
- icon: Icons.workspace_premium,
- onTap: () {
- // TODO: 激活兑换码
- },
- ),
- SizedBox(height: 12.h),
- // 提示文字
- Text(
- 'Have a Premium code? Activate it here.',
- textAlign: TextAlign.center,
- style: TextStyle(
- fontSize: 12.sp,
- color: Get.reactiveTheme.hintColor.withOpacity(0.6),
- ),
- ),
- ],
- );
- }
- }
- /// 主按钮(橙色)
- Widget _buildPrimaryButton({
- required String text,
- required VoidCallback onTap,
- }) {
- return ClickOpacity(
- onTap: onTap,
- child: Container(
- height: 52.h,
- decoration: BoxDecoration(
- gradient: const LinearGradient(
- colors: [Color(0xFFFFB800), Color(0xFFFF9500)],
- begin: Alignment.centerLeft,
- end: Alignment.centerRight,
- ),
- borderRadius: BorderRadius.circular(26.r),
- ),
- alignment: Alignment.center,
- child: Text(
- text,
- style: TextStyle(
- fontSize: 16.sp,
- color: Colors.white,
- fontWeight: FontWeight.w600,
- ),
- ),
- ),
- );
- }
- /// 次要按钮(黑色边框)
- Widget _buildSecondaryButton({
- required String text,
- required IconData icon,
- required VoidCallback onTap,
- }) {
- return ClickOpacity(
- onTap: onTap,
- child: Container(
- height: 52.h,
- decoration: BoxDecoration(
- border: Border.all(color: const Color(0xFFFF9500), width: 1.5),
- borderRadius: BorderRadius.circular(26.r),
- ),
- child: Row(
- mainAxisAlignment: MainAxisAlignment.center,
- children: [
- Text(
- text,
- style: TextStyle(
- fontSize: 16.sp,
- color: const Color(0xFFFF9500),
- fontWeight: FontWeight.w600,
- ),
- ),
- SizedBox(width: 8.w),
- Icon(icon, size: 20.w, color: const Color(0xFFFF9500)),
- ],
- ),
- ),
- );
- }
- /// 构建分割线
- Widget _buildDivider() {
- return Padding(
- padding: EdgeInsets.only(left: 60.w),
- child: Divider(
- height: 1,
- color: Get.reactiveTheme.dividerColor.withOpacity(0.3),
- ),
- );
- }
- }
|