| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251 |
- import 'package:flutter/material.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 '../controllers/splittunneling_controller.dart';
- class SplittunnelingView extends BaseView<SplittunnelingController> {
- const SplittunnelingView({super.key});
- @override
- Widget buildContent(BuildContext context) {
- return Column(
- children: [
- IXAppBar(title: 'Split Tunneling'),
- Expanded(
- child: SingleChildScrollView(
- padding: EdgeInsets.symmetric(horizontal: 14.w, vertical: 20.h),
- child: Column(
- crossAxisAlignment: CrossAxisAlignment.start,
- children: [
- // 顶部提示框
- _buildAlertBox(),
- SizedBox(height: 20.h),
- // 模式选择区域
- _buildModeSelection(),
- SizedBox(height: 30.h),
- // 底部信息框
- _buildInfoBox(),
- ],
- ),
- ),
- ),
- ],
- );
- }
- /// 构建顶部提示框
- Widget _buildAlertBox() {
- return Container(
- padding: EdgeInsets.all(16.w),
- decoration: BoxDecoration(
- color: Get.reactiveTheme.highlightColor,
- borderRadius: BorderRadius.circular(12.r),
- ),
- child: Row(
- children: [
- Icon(Icons.notifications, size: 20.w, color: const Color(0xFFFFB800)),
- SizedBox(width: 12.w),
- Expanded(
- child: Text(
- 'Only one mode can be active at a time.',
- style: TextStyle(
- fontSize: 14.sp,
- color: Colors.white,
- fontWeight: FontWeight.w500,
- ),
- ),
- ),
- ],
- ),
- );
- }
- /// 构建模式选择区域
- Widget _buildModeSelection() {
- return Obx(
- () => Column(
- children: [
- _buildModeCard(
- mode: SplitTunnelingMode.exclude,
- icon: Icons.block,
- title: 'Exclude selected apps from VPN',
- description:
- 'Choose apps that will connect directly without using the VPN.',
- isSelected:
- controller.selectedMode.value == SplitTunnelingMode.exclude,
- onTap: () => controller.selectMode(SplitTunnelingMode.exclude),
- ),
- SizedBox(height: 16.h),
- _buildModeCard(
- mode: SplitTunnelingMode.include,
- icon: Icons.check,
- title: 'Use VPN for selected apps only',
- description:
- 'Choose apps that will use the VPN while others connect normally.',
- isSelected:
- controller.selectedMode.value == SplitTunnelingMode.include,
- onTap: () => controller.selectMode(SplitTunnelingMode.include),
- ),
- ],
- ),
- );
- }
- /// 构建模式卡片
- Widget _buildModeCard({
- required SplitTunnelingMode mode,
- required IconData icon,
- required String title,
- required String description,
- required bool isSelected,
- required VoidCallback onTap,
- }) {
- return ClickOpacity(
- onTap: onTap,
- child: Container(
- padding: EdgeInsets.all(20.w),
- decoration: BoxDecoration(
- color: Get.reactiveTheme.highlightColor,
- borderRadius: BorderRadius.circular(16.r),
- ),
- child: Row(
- children: [
- // 图标
- Container(
- width: 40.w,
- height: 40.w,
- decoration: BoxDecoration(
- color: const Color(0xFF00A8E8),
- shape: BoxShape.circle,
- ),
- child: Icon(icon, color: Colors.white, size: 20.w),
- ),
- SizedBox(width: 16.w),
- // 标题和描述
- Expanded(
- child: Column(
- crossAxisAlignment: CrossAxisAlignment.start,
- children: [
- Text(
- title,
- style: TextStyle(
- fontSize: 16.sp,
- fontWeight: FontWeight.w500,
- color: Colors.white,
- ),
- ),
- SizedBox(height: 4.h),
- Text(
- description,
- style: TextStyle(
- fontSize: 14.sp,
- color: Get.reactiveTheme.hintColor,
- height: 1.4,
- ),
- ),
- ],
- ),
- ),
- SizedBox(width: 16.w),
- // 单选按钮
- Container(
- width: 24.w,
- height: 24.w,
- decoration: BoxDecoration(
- shape: BoxShape.circle,
- color: isSelected
- ? const Color(0xFF00A8E8)
- : Colors.transparent,
- border: Border.all(
- color: isSelected
- ? const Color(0xFF00A8E8)
- : Colors.white.withOpacity(0.3),
- width: 2.w,
- ),
- ),
- child: isSelected
- ? Icon(Icons.check, color: Colors.white, size: 16.w)
- : null,
- ),
- ],
- ),
- ),
- );
- }
- /// 构建底部信息框
- Widget _buildInfoBox() {
- return Container(
- padding: EdgeInsets.all(20.w),
- decoration: BoxDecoration(
- color: Get.reactiveTheme.highlightColor,
- borderRadius: BorderRadius.circular(16.r),
- ),
- child: Row(
- crossAxisAlignment: CrossAxisAlignment.start,
- children: [
- Container(
- width: 24.w,
- height: 24.w,
- decoration: BoxDecoration(
- color: Colors.white,
- shape: BoxShape.circle,
- ),
- child: Center(
- child: Text(
- 'i',
- style: TextStyle(
- fontSize: 14.sp,
- fontWeight: FontWeight.bold,
- color: Colors.black,
- ),
- ),
- ),
- ),
- SizedBox(width: 12.w),
- Expanded(
- child: Column(
- crossAxisAlignment: CrossAxisAlignment.start,
- children: [
- Text(
- 'Customize your VPN',
- style: TextStyle(
- fontSize: 16.sp,
- fontWeight: FontWeight.w500,
- color: Colors.white,
- ),
- ),
- SizedBox(height: 8.h),
- Text(
- 'Split tunneling lets you control which apps use the VPN connection and which connect directly. It helps you manage bandwidth and access local or foreign content without turning off the VPN.',
- style: TextStyle(
- fontSize: 14.sp,
- color: Get.reactiveTheme.hintColor,
- height: 1.4,
- ),
- ),
- ],
- ),
- ),
- ],
- ),
- );
- }
- }
|