import 'package:flutter/material.dart'; import 'package:umbrix/core/localization/translations.dart'; import 'package:umbrix/core/model/optional_range.dart'; import 'package:umbrix/features/config_option/data/config_option_repository.dart'; import 'package:umbrix/features/config_option/overview/warp_options_widgets.dart'; import 'package:umbrix/features/config_option/widget/preference_tile.dart'; import 'package:umbrix/features/settings/widgets/sections_widgets.dart'; import 'package:hooks_riverpod/hooks_riverpod.dart'; class ExperimentalFeaturesPage extends HookConsumerWidget { const ExperimentalFeaturesPage({super.key}); @override Widget build(BuildContext context, WidgetRef ref) { final t = ref.watch(translationsProvider); return Scaffold( body: CustomScrollView( slivers: [ SliverAppBar.large( title: Text( t.settings.experimental, style: const TextStyle(fontSize: 20), ), leading: IconButton( icon: const Icon(Icons.arrow_back), onPressed: () => Navigator.of(context).pop(), ), ), SliverToBoxAdapter( child: Container( margin: const EdgeInsets.all(16), padding: const EdgeInsets.all(16), decoration: BoxDecoration( color: Theme.of(context).colorScheme.errorContainer.withOpacity(0.3), borderRadius: BorderRadius.circular(12), border: Border.all( color: Theme.of(context).colorScheme.error.withOpacity(0.3), ), ), child: Row( crossAxisAlignment: CrossAxisAlignment.start, children: [ Icon( Icons.warning_amber_rounded, color: Theme.of(context).colorScheme.error, size: 24, ), const SizedBox(width: 12), Expanded( child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Text( t.config.bypassLanWarning.title, style: Theme.of(context).textTheme.titleMedium?.copyWith( fontWeight: FontWeight.bold, color: Theme.of(context).colorScheme.error, ), ), const SizedBox(height: 4), Text( t.settings.experimentalMsg, style: Theme.of(context).textTheme.bodySmall, ), ], ), ), ], ), ), ), SliverList.list( children: [ // Разрешить подключения из LAN const SettingsDivider(), SettingsSection(t.config.section.route), SwitchListTile( title: Text(t.config.allowConnectionFromLan), value: ref.watch(ConfigOptions.allowConnectionFromLan), onChanged: ref.watch(ConfigOptions.allowConnectionFromLan.notifier).update, ), // TLS Tricks const SettingsDivider(), SettingsSection(t.config.section.tlsTricks), SwitchListTile( title: Text(t.config.enableTlsFragment), value: ref.watch(ConfigOptions.enableTlsFragment), onChanged: ref.watch(ConfigOptions.enableTlsFragment.notifier).update, ), ValuePreferenceWidget( value: ref.watch(ConfigOptions.tlsFragmentSize), preferences: ref.watch(ConfigOptions.tlsFragmentSize.notifier), title: t.config.tlsFragmentSize, inputToValue: OptionalRange.tryParse, presentValue: (value) => value.present(t), formatInputValue: (value) => value.format(), ), ValuePreferenceWidget( value: ref.watch(ConfigOptions.tlsFragmentSleep), preferences: ref.watch(ConfigOptions.tlsFragmentSleep.notifier), title: t.config.tlsFragmentSleep, inputToValue: OptionalRange.tryParse, presentValue: (value) => value.present(t), formatInputValue: (value) => value.format(), ), SwitchListTile( title: Text(t.config.enableTlsMixedSniCase), value: ref.watch(ConfigOptions.enableTlsMixedSniCase), onChanged: ref.watch(ConfigOptions.enableTlsMixedSniCase.notifier).update, ), SwitchListTile( title: Text(t.config.enableTlsPadding), value: ref.watch(ConfigOptions.enableTlsPadding), onChanged: ref.watch(ConfigOptions.enableTlsPadding.notifier).update, ), ValuePreferenceWidget( value: ref.watch(ConfigOptions.tlsPaddingSize), preferences: ref.watch(ConfigOptions.tlsPaddingSize.notifier), title: t.config.tlsPaddingSize, inputToValue: OptionalRange.tryParse, presentValue: (value) => value.format(), formatInputValue: (value) => value.format(), ), // WARP const SettingsDivider(), SettingsSection(t.config.section.warp), const WarpOptionsTiles(), // Использовать Xray Core const SettingsDivider(), SettingsSection(t.config.section.misc), SwitchListTile( title: Text(t.config.useXrayCoreWhenPossible.Label), subtitle: Text(t.config.useXrayCoreWhenPossible.Description), value: ref.watch(ConfigOptions.useXrayCoreWhenPossible), onChanged: ref.watch(ConfigOptions.useXrayCoreWhenPossible.notifier).update, ), const SizedBox(height: 24), ], ), ], ), ); } }