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 'package:pinput/pinput.dart'; import '../../../../config/theme/dark_theme_colors.dart'; import '../../../../config/translations/strings_enum.dart'; import '../../../constants/iconfont/iconfont.dart'; import '../../../widgets/info_card.dart'; import '../controllers/deviceauth_controller.dart'; import '../widgets/device_card.dart'; class DeviceauthView extends BaseView { const DeviceauthView({super.key}); @override PreferredSizeWidget? get appBar => IXAppBar(title: Strings.deviceAuthorization.tr); @override Widget buildContent(BuildContext context) { return Obx(() { final isPremium = controller.isPremium.value; return SingleChildScrollView( padding: EdgeInsets.symmetric(horizontal: 14.w, vertical: 20.w), child: Column( children: [ if (isPremium) ...[ // VIP用户界面 _buildVIPUserInterface(), ] else ...[ // 免费用户界面 _buildFreeUserInterface(), ], ], ), ); }); } /// 免费用户界面 - 显示授权码和等待授权 Widget _buildFreeUserInterface() { return Column( children: [ // 授权码显示区域 _buildAuthCodeDisplay(), // 说明卡片 _buildInstructionCards(), ], ); } /// VIP用户界面 - 输入授权码和管理设备 Widget _buildVIPUserInterface() { return Column( children: [ // 6个输入框在顶部 _buildTopCodeInput(), 20.verticalSpaceFromWidth, Padding( padding: EdgeInsets.symmetric(horizontal: 8.w), child: Divider(height: 1.w, color: Get.reactiveTheme.dividerColor), ), // 设备管理区域 _buildDeviceManagementSection(), // 授权步骤说明 _buildAuthorizationSteps(), ], ); } /// 授权码显示区域 Widget _buildAuthCodeDisplay() { return Container( padding: EdgeInsets.symmetric(horizontal: 14.w, vertical: 10.w), child: Column( children: [ // 6位授权码 Obx( () => Text( controller.authCode.value, style: TextStyle( fontSize: 34.sp, fontWeight: FontWeight.w500, height: 1.2, color: Get.reactiveTheme.textTheme.bodyLarge!.color, letterSpacing: 10.w, ), ), ), 14.verticalSpaceFromWidth, // 倒计时和复制按钮 Row( mainAxisAlignment: MainAxisAlignment.center, children: [ Icon( IconFont.icon48, size: 20.w, color: Get.reactiveTheme.hintColor, ), 4.horizontalSpace, Obx( () => Text( controller.countdownText, style: TextStyle( fontSize: 12.sp, height: 1.7, color: Get.reactiveTheme.hintColor, ), ), ), 20.horizontalSpace, Container( width: 1.w, height: 20.w, color: Get.reactiveTheme.dividerColor, ), 20.horizontalSpace, ClickOpacity( onTap: () { Clipboard.setData( ClipboardData(text: controller.authCode.value), ); controller.copyAuthCode(); }, child: Row( mainAxisSize: MainAxisSize.min, children: [ Text( Strings.copy.tr, style: TextStyle( fontSize: 12.sp, height: 1.7, color: Get.reactiveTheme.hintColor, ), ), 4.horizontalSpace, Icon( IconFont.icon57, size: 20.w, color: Get.reactiveTheme.hintColor, ), ], ), ), ], ), 20.verticalSpaceFromWidth, // 提示文字 Text( Strings.pleaseKeepPageOpen.tr, style: TextStyle( fontSize: 13.sp, color: DarkThemeColors.validTermColor, height: 1.4, ), ), ], ), ); } /// 说明卡片 Widget _buildInstructionCards() { return InfoCard( title: '', items: [ InfoItem( icon: IconFont.icon11, title: Strings.authorizationCode.tr, description: Strings.authorizationCodeDesc.tr, iconColor: DarkThemeColors.shadowColor, ), InfoItem( icon: IconFont.icon23, title: Strings.shareWithPreUser.tr, description: Strings.shareWithPreUserDesc.tr, iconColor: DarkThemeColors.shadowColor, ), InfoItem( icon: IconFont.icon49, title: Strings.waitingForAuthorization.tr, description: Strings.waitingForAuthorizationDesc.tr, iconColor: DarkThemeColors.shadowColor, ), ], ); } /// 顶部6个输入框 Widget _buildTopCodeInput() { return Obx( () => Pinput( length: 6, defaultPinTheme: PinTheme( width: 50.w, height: 50.w, textStyle: TextStyle( fontSize: 27.sp, fontWeight: FontWeight.w600, color: Get.reactiveTheme.primaryColor, ), decoration: BoxDecoration( color: Get.reactiveTheme.highlightColor, borderRadius: BorderRadius.circular(5.r), border: Border.all( color: Get.reactiveTheme.dividerColor, width: 1.5.w, ), ), ), focusedPinTheme: PinTheme( width: 50.w, height: 50.w, textStyle: TextStyle( fontSize: 27.sp, fontWeight: FontWeight.w600, color: Get.reactiveTheme.primaryColor, ), decoration: BoxDecoration( color: Get.reactiveTheme.cardColor, borderRadius: BorderRadius.circular(5.r), border: Border.all( color: Get.reactiveTheme.primaryColor, width: 1.5.w, ), ), ), submittedPinTheme: PinTheme( width: 50.w, height: 50.w, textStyle: TextStyle( fontSize: 27.sp, fontWeight: FontWeight.w600, color: Get.reactiveTheme.primaryColor, ), decoration: BoxDecoration( color: Get.reactiveTheme.cardColor, borderRadius: BorderRadius.circular(5.r), border: Border.all( color: Get.reactiveTheme.dividerColor, width: 1.5.w, ), ), ), onChanged: (value) { controller.setInputCode(value); }, onCompleted: (pin) { controller.submitAuthCode(); }, inputFormatters: [FilteringTextInputFormatter.digitsOnly], keyboardType: TextInputType.number, showCursor: true, cursor: Container( width: 1.w, height: 30.w, color: Get.reactiveTheme.textTheme.bodyLarge!.color, ), ), ); } /// 设备管理区域 Widget _buildDeviceManagementSection() { return Obx(() { final inputCodeLength = controller.inputCode.value.length; final shouldShowLoadingIcon = inputCodeLength == 6; return Container( margin: EdgeInsets.only(top: 20.w), decoration: BoxDecoration( color: Get.reactiveTheme.highlightColor, borderRadius: BorderRadius.circular(12.r), ), child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ // 设备列表 ...controller.currentDevices.map((device) { return DeviceCard( device: device, onRelieve: () => controller.removeDevice(device.id), showRelieveButton: true, ); }), // 默认显示等待激活的设备,只有当输入代码长度为6时显示加载图标 AwaitingActivationCard(showLoadingIcon: shouldShowLoadingIcon), ], ), ); }); } /// 授权步骤说明 Widget _buildAuthorizationSteps() { return InfoCard( title: '', items: [ InfoItem( icon: IconFont.icon46, title: Strings.enterCode.tr, description: Strings.enterCodeDesc.tr, iconColor: DarkThemeColors.shadowColor, ), InfoItem( icon: IconFont.icon16, title: Strings.verifyDevice.tr, description: Strings.verifyDeviceDesc.tr, iconColor: DarkThemeColors.shadowColor, ), InfoItem( icon: IconFont.icon43, title: Strings.authorizationSuccessful.tr, description: Strings.authorizationSuccessfulDesc.tr, iconColor: DarkThemeColors.shadowColor, ), ], ); } }