Files
umbrix/lib/features/settings/experimental_features_page.dart
2026-01-15 12:28:40 +03:00

150 lines
6.2 KiB
Dart

import 'package:flutter/material.dart';
import 'package:hiddify/core/localization/translations.dart';
import 'package:hiddify/core/model/optional_range.dart';
import 'package:hiddify/features/config_option/data/config_option_repository.dart';
import 'package:hiddify/features/config_option/overview/warp_options_widgets.dart';
import 'package:hiddify/features/config_option/widget/preference_tile.dart';
import 'package:hiddify/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),
],
),
],
),
);
}
}