import 'package:flutter/material.dart'; import 'package:flutter/cupertino.dart'; import 'package:get/get.dart'; import 'package:flutter_screenutil/flutter_screenutil.dart'; import 'package:kaer_with_panels/app/widgets/kr_app_text_style.dart'; import '../../../services/singbox_imp/kr_sing_box_imp.dart'; import '../controllers/kr_setting_controller.dart'; import '../../../themes/kr_theme_service.dart'; import '../../../localization/app_translations.dart'; import '../../../routes/app_pages.dart'; class KRSettingView extends GetView { const KRSettingView({Key? key}) : super(key: key); @override Widget build(BuildContext context) { return Scaffold( extendBodyBehindAppBar: true, backgroundColor: Theme.of(context).primaryColor, appBar: AppBar( backgroundColor: Colors.transparent, elevation: 0, leading: IconButton( icon: Icon( Icons.arrow_back_ios, size: 20.r, color: Theme.of(context).textTheme.bodyMedium?.color, ), onPressed: () => Get.back(), ), centerTitle: true, title: Text( AppTranslations.kr_setting.title, style: KrAppTextStyle( color: Theme.of(context).textTheme.bodyMedium?.color, fontSize: 16, fontWeight: FontWeight.w500, ), ), ), body: Obx(() { return Container( height: MediaQuery.of(context).size.height, decoration: BoxDecoration( gradient: LinearGradient( begin: Alignment.topCenter, end: Alignment.bottomCenter, colors: [ Color.fromRGBO(23, 151, 255, 0.15), Color.fromRGBO(23, 151, 255, 0.05), ], stops: [0.0, 0.3], ), ), child: SingleChildScrollView( physics: const BouncingScrollPhysics(), child: Padding( padding: EdgeInsets.only( bottom: MediaQuery.of(context).padding.bottom), child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ SizedBox(height: kToolbarHeight + 20.w), _kr_buildSectionTitle( context, AppTranslations.kr_setting.vpnConnection), _kr_buildVPNSection(context), _kr_buildSectionTitle( context, AppTranslations.kr_setting.general), _kr_buildGeneralSection(context), SizedBox(height: 100.h), ], ), ), ), ); }), ); } Widget _kr_buildSectionTitle(BuildContext context, String title) { return Padding( padding: EdgeInsets.fromLTRB(16.w, 24.h, 16.w, 8.h), child: Text( title, style: KrAppTextStyle( fontSize: 14, fontWeight: FontWeight.w500, color: Theme.of(context).textTheme.bodyMedium?.color, ), ), ); } Widget _kr_buildVPNSection(BuildContext context) { return Container( margin: EdgeInsets.symmetric(horizontal: 16.w), decoration: BoxDecoration( color: Theme.of(context).cardColor, borderRadius: BorderRadius.circular(12.r), ), child: Column( children: [ _kr_buildSelectionTile( context, title: AppTranslations.kr_setting.mode, value: controller.kr_vpnMode.value, // subtitle: controller.kr_vpnModeRemark.value, onTap: () => _kr_showRouteRuleSelectionSheet(context), ), _kr_buildDivider(), // _kr_buildSwitchTile( // context, // title: AppTranslations.kr_setting.autoConnect, // value: controller.kr_autoConnect, // onChanged: (value) => controller.kr_autoConnect.value = value, // ), // _kr_buildDivider(), // _kr_buildSelectionTile( // context, // title: AppTranslations.kr_setting.routeRule, // value: controller.kr_routeRule.value, // onTap: () => _kr_showRouteRuleSelectionSheet(context), // ), // _kr_buildDivider(), _kr_buildSelectionTile( context, title: AppTranslations.kr_setting.countrySelector, subtitle: AppTranslations.kr_setting.connectionTypeRuleRemark, value: controller.kr_currentCountry.value, onTap: () => Get.toNamed(Routes.KR_COUNTRY_SELECTOR), ), ], ), ); } void _kr_showVPNModeSelectionSheet(BuildContext context) { Get.bottomSheet( Container( decoration: BoxDecoration( color: Theme.of(context).cardColor, borderRadius: BorderRadius.vertical(top: Radius.circular(16.r)), ), child: Padding( padding: EdgeInsets.only( bottom: MediaQuery.of(context).padding.bottom + 16.r), child: Wrap( children: [ ListTile( title: Center( child: Text(AppTranslations.kr_setting.vpnModeSmart), ), onTap: () { controller.kr_changeVPNMode(AppTranslations.kr_setting.vpnModeSmart); Get.back(); }, ), ListTile( title: Center( child: Text(AppTranslations.kr_setting.vpnModeSecure), ), onTap: () { controller.kr_changeVPNMode(AppTranslations.kr_setting.vpnModeSecure); Get.back(); }, ), ], ), ), ), ); } void _kr_showRouteRuleSelectionSheet(BuildContext context) { Get.bottomSheet( Container( decoration: BoxDecoration( color: Theme.of(context).cardColor, borderRadius: BorderRadius.vertical(top: Radius.circular(16.r)), ), child: Padding( padding: EdgeInsets.only( bottom: MediaQuery.of(context).padding.bottom + 16.r), child: Wrap( children: KRConnectionType.values.map((type) { return ListTile( title: Center( child: Text( controller.kr_getConnectionTypeString(type), style: KrAppTextStyle( fontSize: 16, color: Theme.of(context).textTheme.bodyMedium?.color, ), ), ), onTap: () { controller.kr_updateConnectionType(type); Get.back(); }, ); }).toList(), ), ), ), ); } Widget _kr_buildGeneralSection(BuildContext context) { return Container( margin: EdgeInsets.symmetric(horizontal: 16.w), decoration: BoxDecoration( color: Theme.of(context).cardColor, borderRadius: BorderRadius.circular(12.r), ), child: Column( children: [ Obx(() => _kr_buildSelectionTile( context, title: AppTranslations.kr_setting.appearance, value: controller.kr_themeOption.value, onTap: () => _showThemeSelectionSheet(context), )), _kr_buildDivider(), _kr_buildSwitchTile( context, title: AppTranslations.kr_setting.notifications, value: controller.kr_notification, onChanged: (value) => controller.kr_notification.value = value, ), _kr_buildDivider(), _kr_buildSwitchTile( context, title: AppTranslations.kr_setting.helpImprove, value: controller.kr_helpImprove, onChanged: (value) => controller.kr_helpImprove.value = value, ), _kr_buildDivider(), _kr_buildActionTile( context, title: AppTranslations.kr_userInfo.myAccount, trailing: AppTranslations.kr_setting.goToDelete, onTap: controller.kr_deleteAccount, ), _kr_buildDivider(), // _kr_buildTitleTile( // context, // title: AppTranslations.kr_setting.rateUs, // ), // _kr_buildDivider(), Obx(() => _kr_buildValueTile( context, title: AppTranslations.kr_setting.version, value: controller.kr_version.value, )), _kr_buildDivider(), _kr_buildSelectionTile( context, title: AppTranslations.kr_setting.switchLanguage, value: controller.kr_language.value, onTap: controller.kr_changeLanguage, ), ], ), ); } void _showThemeSelectionSheet(BuildContext context) { Get.bottomSheet( Container( decoration: BoxDecoration( color: Theme.of(context).cardColor, borderRadius: BorderRadius.vertical(top: Radius.circular(16.r)), ), child: Padding( padding: EdgeInsets.only( bottom: MediaQuery.of(context).padding.bottom + 16.r), child: Wrap( children: ThemeMode.values.map((option) { String optionText; switch (option) { case ThemeMode.system: optionText = AppTranslations.kr_setting.system; break; case ThemeMode.light: optionText = AppTranslations.kr_setting.light; break; case ThemeMode.dark: optionText = AppTranslations.kr_setting.dark; break; } return ListTile( title: Center( child: Text( optionText, style: KrAppTextStyle( fontSize: 16, color: Theme.of(context).textTheme.bodyMedium?.color, ), ), ), onTap: () async { final KRThemeService themeService = KRThemeService(); await themeService.kr_switchTheme(option); controller.kr_themeOption.value = optionText; Get.back(); }, ); }).toList(), ), ), ), ); } Widget _kr_buildSelectionTile( BuildContext context, { required String title, required String value, String? subtitle, required VoidCallback onTap, }) { return ListTile( title: Text( title, style: KrAppTextStyle( fontSize: 14, fontWeight: FontWeight.w500, color: Theme.of(context).textTheme.bodyMedium?.color, ), ), subtitle: subtitle != null ? Text( subtitle, style: KrAppTextStyle( fontSize: 12, color: Theme.of(context).textTheme.bodySmall?.color, ), ) : null, trailing: Row( mainAxisSize: MainAxisSize.min, children: [ Text( value, style: KrAppTextStyle( fontSize: 14, color: Theme.of(context).textTheme.bodyMedium?.color, ), ), SizedBox(width: 4.w), Icon( Icons.arrow_forward_ios, size: 16.r, color: Theme.of(context).textTheme.bodySmall?.color, ), ], ), onTap: onTap, ); } Widget _kr_buildSwitchTile( BuildContext context, { required String title, String? subtitle, required RxBool value, required Function(bool) onChanged, }) { return ListTile( title: Text( title, style: KrAppTextStyle( fontSize: 14, fontWeight: FontWeight.w500, color: Theme.of(context).textTheme.bodyMedium?.color, ), ), subtitle: subtitle != null ? Text( subtitle, style: KrAppTextStyle( fontSize: 12, color: Theme.of(context).textTheme.bodySmall?.color, ), ) : null, trailing: Obx( () => CupertinoSwitch( value: value.value, onChanged: onChanged, activeTrackColor: Colors.blue, ), ), ); } Widget _kr_buildActionTile( BuildContext context, { required String title, required String trailing, required VoidCallback onTap, }) { return ListTile( title: Text( title, style: KrAppTextStyle( fontSize: 14, fontWeight: FontWeight.w500, color: Theme.of(context).textTheme.bodyMedium?.color, ), ), trailing: Text( trailing, style: KrAppTextStyle( fontSize: 14, color: Theme.of(context).textTheme.bodySmall?.color, ), ), onTap: onTap, ); } Widget _kr_buildTitleTile( BuildContext context, { required String title, }) { return ListTile( title: Text( title, style: KrAppTextStyle( fontSize: 14, fontWeight: FontWeight.w500, color: Theme.of(context).textTheme.bodyMedium?.color, ), ), ); } Widget _kr_buildValueTile( BuildContext context, { required String title, required String value, }) { return ListTile( title: Text( title, style: KrAppTextStyle( fontSize: 14, fontWeight: FontWeight.w500, color: Theme.of(context).textTheme.bodyMedium?.color, ), ), trailing: Text( value, style: KrAppTextStyle( fontSize: 14, color: Theme.of(context).textTheme.bodySmall?.color, ), ), ); } Widget _kr_buildDivider() { return Divider( height: 1.h, thickness: 0.2, color: const Color(0xFFEEEEEE), ); } }