routingmode_view.dart 4.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143
  1. import 'package:flutter/material.dart';
  2. import 'package:flutter_screenutil/flutter_screenutil.dart';
  3. import 'package:get/get.dart';
  4. import 'package:nomo/app/base/base_view.dart';
  5. import 'package:nomo/app/widgets/click_opacity.dart';
  6. import 'package:nomo/app/widgets/ix_app_bar.dart';
  7. import 'package:nomo/config/theme/theme_extensions/theme_extension.dart';
  8. import '../../../constants/iconfont/iconfont.dart';
  9. import '../controllers/routingmode_controller.dart';
  10. class RoutingmodeView extends BaseView<RoutingmodeController> {
  11. const RoutingmodeView({super.key});
  12. @override
  13. PreferredSizeWidget? get appBar => IXAppBar(title: 'Routing Mode');
  14. @override
  15. Widget buildContent(BuildContext context) {
  16. return Padding(
  17. padding: EdgeInsets.symmetric(horizontal: 14.w, vertical: 10.w),
  18. child: Container(
  19. decoration: BoxDecoration(
  20. color: Get.reactiveTheme.highlightColor,
  21. borderRadius: BorderRadius.circular(12.r),
  22. ),
  23. child: Obx(
  24. () => Column(
  25. mainAxisSize: MainAxisSize.min,
  26. children: [
  27. _buildRoutingOption(
  28. mode: RoutingMode.smart,
  29. icon: IconFont.icon50,
  30. title: 'Smart',
  31. description:
  32. 'The local and VPN networks coexist, and the optimal route is selected intelligently.',
  33. isSelected: controller.selectedMode.value == RoutingMode.smart,
  34. onTap: () => controller.selectMode(RoutingMode.smart),
  35. ),
  36. _buildDivider(),
  37. _buildRoutingOption(
  38. mode: RoutingMode.global,
  39. icon: IconFont.icon51,
  40. title: 'Global',
  41. description:
  42. 'All traffic is routed through the VPN server to ensure maximum privacy and security.',
  43. isSelected: controller.selectedMode.value == RoutingMode.global,
  44. onTap: () => controller.selectMode(RoutingMode.global),
  45. ),
  46. ],
  47. ),
  48. ),
  49. ),
  50. );
  51. }
  52. /// 构建路由选项
  53. Widget _buildRoutingOption({
  54. required RoutingMode mode,
  55. required IconData icon,
  56. required String title,
  57. required String description,
  58. required bool isSelected,
  59. required VoidCallback onTap,
  60. }) {
  61. return ClickOpacity(
  62. onTap: onTap,
  63. child: Padding(
  64. padding: EdgeInsets.symmetric(horizontal: 20.w, vertical: 16.h),
  65. child: Row(
  66. crossAxisAlignment: CrossAxisAlignment.start,
  67. children: [
  68. // 图标
  69. Container(
  70. width: 30.w,
  71. height: 30.w,
  72. decoration: BoxDecoration(
  73. color: Get.reactiveTheme.shadowColor,
  74. borderRadius: BorderRadius.circular(8.r),
  75. ),
  76. child: Icon(icon, color: Colors.white, size: 20.w),
  77. ),
  78. 10.horizontalSpace,
  79. // 标题和描述
  80. Expanded(
  81. child: Column(
  82. crossAxisAlignment: CrossAxisAlignment.start,
  83. children: [
  84. Text(
  85. title,
  86. style: TextStyle(
  87. fontSize: 14.sp,
  88. height: 1.4,
  89. color: Get.reactiveTheme.textTheme.bodyLarge!.color,
  90. ),
  91. ),
  92. Text(
  93. description,
  94. style: TextStyle(
  95. fontSize: 12.sp,
  96. color: Get.reactiveTheme.hintColor,
  97. height: 1.6,
  98. ),
  99. ),
  100. ],
  101. ),
  102. ),
  103. 10.horizontalSpace,
  104. // 选中指示器
  105. Container(
  106. width: 20.w,
  107. height: 20.w,
  108. decoration: BoxDecoration(
  109. shape: BoxShape.circle,
  110. color: isSelected
  111. ? Get.reactiveTheme.shadowColor
  112. : Colors.transparent,
  113. border: Border.all(
  114. color: isSelected
  115. ? Get.reactiveTheme.shadowColor
  116. : Colors.grey[400]!,
  117. width: 1.5.w,
  118. ),
  119. ),
  120. child: isSelected
  121. ? Icon(Icons.check, color: Colors.white, size: 16.w)
  122. : null,
  123. ),
  124. ],
  125. ),
  126. ),
  127. );
  128. }
  129. /// 构建分割线
  130. Widget _buildDivider() {
  131. return Divider(color: Get.reactiveTheme.dividerColor, height: 1.w);
  132. }
  133. }