improve tor ui
This commit is contained in:
@@ -19,7 +19,6 @@
|
||||
*/
|
||||
import 'package:country_codes/country_codes.dart';
|
||||
import 'package:country_flags/country_flags.dart';
|
||||
import 'package:fading_scroll/fading_scroll.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_hooks/flutter_hooks.dart';
|
||||
import 'package:flutter_material_design_icons/flutter_material_design_icons.dart';
|
||||
@@ -31,7 +30,6 @@ import 'package:weblibre/features/tor/domain/services/tor_proxy.dart';
|
||||
import 'package:weblibre/features/user/data/models/tor_settings.dart';
|
||||
import 'package:weblibre/features/user/domain/repositories/tor_settings.dart';
|
||||
import 'package:weblibre/presentation/hooks/on_initialization.dart';
|
||||
import 'package:weblibre/presentation/icons/tor_icons.dart';
|
||||
import 'package:weblibre/utils/ui_helper.dart';
|
||||
|
||||
class TorProxyScreen extends HookConsumerWidget {
|
||||
@@ -95,11 +93,7 @@ class TorProxyScreen extends HookConsumerWidget {
|
||||
|
||||
final countryDropdownEntries = useMemoized(
|
||||
() => [
|
||||
const DropdownMenuEntry(
|
||||
value: null,
|
||||
label: 'Automatic',
|
||||
leadingIcon: Icon(MdiIcons.lightbulbAuto),
|
||||
),
|
||||
const DropdownMenuEntry(value: null, label: 'Automatic'),
|
||||
...CountryCodes.countryCodes().map((country) {
|
||||
final label =
|
||||
country.localizedName ??
|
||||
@@ -111,12 +105,6 @@ class TorProxyScreen extends HookConsumerWidget {
|
||||
return DropdownMenuEntry(
|
||||
value: country.alpha2Code,
|
||||
label: label,
|
||||
leadingIcon: country.alpha2Code.mapNotNull(
|
||||
(code) => CountryFlag.fromCountryCode(
|
||||
code,
|
||||
theme: const ImageTheme(width: 24, height: 16),
|
||||
),
|
||||
),
|
||||
labelWidget: Text(
|
||||
label,
|
||||
style: const TextStyle(color: Colors.white),
|
||||
@@ -127,7 +115,6 @@ class TorProxyScreen extends HookConsumerWidget {
|
||||
);
|
||||
|
||||
return Scaffold(
|
||||
appBar: AppBar(title: const Text('Tor™ Proxy')),
|
||||
body: Theme(
|
||||
data: Theme.of(context).copyWith(
|
||||
listTileTheme: ListTileTheme.of(
|
||||
@@ -160,25 +147,18 @@ class TorProxyScreen extends HookConsumerWidget {
|
||||
fillColor: WidgetStateColor.resolveWith((states) {
|
||||
return Colors.white;
|
||||
}),
|
||||
checkColor: WidgetStateProperty.all(AppColors.torPurple),
|
||||
),
|
||||
iconTheme: const IconThemeData(color: Colors.white),
|
||||
),
|
||||
child: SafeArea(
|
||||
child: ColoredBox(
|
||||
color: AppColors.torPurple,
|
||||
child: Column(
|
||||
children: [
|
||||
const SizedBox(height: 16),
|
||||
const Icon(TorIcons.onionAlt, size: 84),
|
||||
const SizedBox(height: 16),
|
||||
Container(
|
||||
margin: const EdgeInsets.symmetric(horizontal: 24),
|
||||
decoration: BoxDecoration(
|
||||
border: Border.all(color: Colors.white),
|
||||
borderRadius: BorderRadius.circular(16),
|
||||
),
|
||||
child: Column(
|
||||
children: [
|
||||
SwitchListTile.adaptive(
|
||||
child: CustomScrollView(
|
||||
slivers: [
|
||||
SliverAppBar(
|
||||
pinned: true,
|
||||
title: SwitchListTile.adaptive(
|
||||
inactiveThumbColor: Colors.white,
|
||||
activeThumbColor: AppColors.torActiveGreen,
|
||||
thumbIcon: WidgetStateProperty.resolveWith<Icon?>((
|
||||
@@ -190,7 +170,7 @@ class TorProxyScreen extends HookConsumerWidget {
|
||||
return null; // Use the default color.
|
||||
}),
|
||||
value: torPendingRequest.value ?? torIsRunning,
|
||||
title: const Text('Tor™ Proxy'),
|
||||
title: const Text('Tor™ Service'),
|
||||
secondary: const Icon(MdiIcons.power),
|
||||
onChanged: torIsBusy
|
||||
? null
|
||||
@@ -212,20 +192,36 @@ class TorProxyScreen extends HookConsumerWidget {
|
||||
}
|
||||
},
|
||||
),
|
||||
bottom: PreferredSize(
|
||||
preferredSize: const Size.fromHeight(4 + 40 + 8),
|
||||
child: Column(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: [
|
||||
if (torPendingRequest.value != false && torIsBusy)
|
||||
LinearProgressIndicator(
|
||||
backgroundColor: AppColors.torBackgroundGrey,
|
||||
color: AppColors.torActiveGreen,
|
||||
value: bootstrapProgress / 100,
|
||||
),
|
||||
Padding(
|
||||
padding: const EdgeInsets.only(
|
||||
right: 16.0,
|
||||
top: 4.0,
|
||||
right: 16,
|
||||
left: 16,
|
||||
bottom: 16,
|
||||
bottom: 4,
|
||||
),
|
||||
child: SizedBox(
|
||||
width: double.infinity,
|
||||
child: FilledButton.icon(
|
||||
onPressed:
|
||||
torIsRunning && torIsBootstrapped && !torIsBusy
|
||||
torIsRunning &&
|
||||
torIsBootstrapped &&
|
||||
!torIsBusy
|
||||
? () async {
|
||||
await ref
|
||||
.read(torProxyServiceProvider.notifier)
|
||||
.read(
|
||||
torProxyServiceProvider.notifier,
|
||||
)
|
||||
.requestNewIdentity();
|
||||
|
||||
if (context.mounted) {
|
||||
@@ -244,17 +240,8 @@ class TorProxyScreen extends HookConsumerWidget {
|
||||
],
|
||||
),
|
||||
),
|
||||
const SizedBox(height: 16),
|
||||
Expanded(
|
||||
child: FadingScroll(
|
||||
fadingSize: 25,
|
||||
builder: (context, controller) {
|
||||
return FadingScroll(
|
||||
controller: controller,
|
||||
fadingSize: 25,
|
||||
builder: (context, controller) {
|
||||
return ListView(
|
||||
controller: controller,
|
||||
),
|
||||
SliverList.list(
|
||||
children: [
|
||||
const SizedBox(height: 16),
|
||||
const Padding(
|
||||
@@ -273,13 +260,9 @@ class TorProxyScreen extends HookConsumerWidget {
|
||||
onChanged: (value) async {
|
||||
if (value != null) {
|
||||
await ref
|
||||
.read(
|
||||
saveTorSettingsControllerProvider
|
||||
.notifier,
|
||||
)
|
||||
.read(saveTorSettingsControllerProvider.notifier)
|
||||
.save(
|
||||
(currentSettings) => currentSettings
|
||||
.copyWith
|
||||
(currentSettings) => currentSettings.copyWith
|
||||
.proxyRegularTabsMode(value),
|
||||
);
|
||||
}
|
||||
@@ -307,13 +290,10 @@ class TorProxyScreen extends HookConsumerWidget {
|
||||
SwitchListTile.adaptive(
|
||||
inactiveThumbColor: Colors.white,
|
||||
activeThumbColor: AppColors.torActiveGreen,
|
||||
thumbIcon:
|
||||
WidgetStateProperty.resolveWith<Icon?>((
|
||||
thumbIcon: WidgetStateProperty.resolveWith<Icon?>((
|
||||
Set<WidgetState> states,
|
||||
) {
|
||||
if (states.contains(
|
||||
WidgetState.selected,
|
||||
)) {
|
||||
if (states.contains(WidgetState.selected)) {
|
||||
return const Icon(MdiIcons.incognito);
|
||||
}
|
||||
return null; // Use the default color.
|
||||
@@ -326,13 +306,9 @@ class TorProxyScreen extends HookConsumerWidget {
|
||||
secondary: const Icon(MdiIcons.incognito),
|
||||
onChanged: (value) async {
|
||||
await ref
|
||||
.read(
|
||||
saveTorSettingsControllerProvider
|
||||
.notifier,
|
||||
)
|
||||
.read(saveTorSettingsControllerProvider.notifier)
|
||||
.save(
|
||||
(currentSettings) => currentSettings
|
||||
.copyWith
|
||||
(currentSettings) => currentSettings.copyWith
|
||||
.proxyPrivateTabsTor(value),
|
||||
);
|
||||
},
|
||||
@@ -352,53 +328,38 @@ class TorProxyScreen extends HookConsumerWidget {
|
||||
SwitchListTile.adaptive(
|
||||
inactiveThumbColor: Colors.white,
|
||||
activeThumbColor: AppColors.torActiveGreen,
|
||||
thumbIcon:
|
||||
WidgetStateProperty.resolveWith<Icon?>((
|
||||
thumbIcon: WidgetStateProperty.resolveWith<Icon?>((
|
||||
Set<WidgetState> states,
|
||||
) {
|
||||
if (states.contains(
|
||||
WidgetState.selected,
|
||||
)) {
|
||||
return const Icon(
|
||||
MdiIcons.arrowDecisionAuto,
|
||||
);
|
||||
if (states.contains(WidgetState.selected)) {
|
||||
return const Icon(MdiIcons.arrowDecisionAuto);
|
||||
}
|
||||
return null; // Use the default color.
|
||||
}),
|
||||
value:
|
||||
torSettings.config ==
|
||||
TorConnectionConfig.auto,
|
||||
value: torSettings.config == TorConnectionConfig.auto,
|
||||
title: const Text('Auto Configure Transport'),
|
||||
subtitle: const Text(
|
||||
'From some locations, it is necessary to use a pluggable transport to connect to Tor',
|
||||
),
|
||||
secondary: const Icon(
|
||||
MdiIcons.arrowDecisionAuto,
|
||||
),
|
||||
secondary: const Icon(MdiIcons.arrowDecisionAuto),
|
||||
onChanged: torIsBusy
|
||||
? null
|
||||
: (value) async {
|
||||
await ref
|
||||
.read(
|
||||
saveTorSettingsControllerProvider
|
||||
.notifier,
|
||||
saveTorSettingsControllerProvider.notifier,
|
||||
)
|
||||
.save(
|
||||
(
|
||||
currentSettings,
|
||||
) => currentSettings.copyWith
|
||||
.config(
|
||||
(currentSettings) =>
|
||||
currentSettings.copyWith.config(
|
||||
value
|
||||
? TorConnectionConfig
|
||||
.auto
|
||||
: TorConnectionConfig
|
||||
.direct,
|
||||
? TorConnectionConfig.auto
|
||||
: TorConnectionConfig.direct,
|
||||
),
|
||||
);
|
||||
},
|
||||
),
|
||||
if (torSettings.config ==
|
||||
TorConnectionConfig.auto) ...[
|
||||
if (torSettings.config == TorConnectionConfig.auto) ...[
|
||||
SwitchListTile.adaptive(
|
||||
inactiveThumbColor: Colors.white,
|
||||
activeThumbColor: AppColors.torActiveGreen,
|
||||
@@ -416,8 +377,8 @@ class TorProxyScreen extends HookConsumerWidget {
|
||||
.notifier,
|
||||
)
|
||||
.save(
|
||||
(currentSettings) =>
|
||||
currentSettings.copyWith
|
||||
(currentSettings) => currentSettings
|
||||
.copyWith
|
||||
.requireBridge(value),
|
||||
);
|
||||
},
|
||||
@@ -432,13 +393,11 @@ class TorProxyScreen extends HookConsumerWidget {
|
||||
if (value != null) {
|
||||
await ref
|
||||
.read(
|
||||
saveTorSettingsControllerProvider
|
||||
.notifier,
|
||||
saveTorSettingsControllerProvider.notifier,
|
||||
)
|
||||
.save(
|
||||
(currentSettings) => currentSettings
|
||||
.copyWith
|
||||
.config(value),
|
||||
(currentSettings) =>
|
||||
currentSettings.copyWith.config(value),
|
||||
);
|
||||
}
|
||||
},
|
||||
@@ -485,11 +444,9 @@ class TorProxyScreen extends HookConsumerWidget {
|
||||
),
|
||||
CheckboxListTile.adaptive(
|
||||
value: torSettings.fetchRemoteBridges,
|
||||
controlAffinity:
|
||||
ListTileControlAffinity.leading,
|
||||
controlAffinity: ListTileControlAffinity.leading,
|
||||
enabled:
|
||||
torSettings.config !=
|
||||
TorConnectionConfig.direct,
|
||||
torSettings.config != TorConnectionConfig.direct,
|
||||
contentPadding: const EdgeInsets.only(
|
||||
left: 56,
|
||||
right: 24,
|
||||
@@ -504,11 +461,9 @@ class TorProxyScreen extends HookConsumerWidget {
|
||||
.notifier,
|
||||
)
|
||||
.save(
|
||||
(currentSettings) =>
|
||||
currentSettings.copyWith
|
||||
.fetchRemoteBridges(
|
||||
value,
|
||||
),
|
||||
(currentSettings) => currentSettings
|
||||
.copyWith
|
||||
.fetchRemoteBridges(value),
|
||||
);
|
||||
}
|
||||
},
|
||||
@@ -536,29 +491,33 @@ class TorProxyScreen extends HookConsumerWidget {
|
||||
top: 8.0,
|
||||
),
|
||||
child: DropdownMenu(
|
||||
initialSelection:
|
||||
torSettings.entryNodeCountry,
|
||||
enabled: !torIsBusy,
|
||||
initialSelection: torSettings.entryNodeCountry,
|
||||
menuHeight: 400,
|
||||
requestFocusOnTap: true,
|
||||
label: const Text('Entry Country'),
|
||||
textStyle: const TextStyle(
|
||||
color: Colors.white,
|
||||
),
|
||||
inputDecorationTheme:
|
||||
const InputDecorationTheme(
|
||||
labelStyle: TextStyle(
|
||||
textStyle: const TextStyle(color: Colors.white),
|
||||
leadingIcon: torSettings.entryNodeCountry.mapNotNull(
|
||||
(code) => Padding(
|
||||
padding: const EdgeInsets.all(8.0),
|
||||
child: CountryFlag.fromCountryCode(
|
||||
code,
|
||||
theme: const EmojiTheme(size: 28),
|
||||
),
|
||||
),
|
||||
),
|
||||
trailingIcon: const Icon(
|
||||
MdiIcons.chevronDown,
|
||||
color: Colors.white,
|
||||
),
|
||||
inputDecorationTheme: const InputDecorationTheme(
|
||||
labelStyle: TextStyle(color: Colors.white),
|
||||
iconColor: Colors.white,
|
||||
enabledBorder: UnderlineInputBorder(
|
||||
borderSide: BorderSide(
|
||||
color: Colors.white,
|
||||
),
|
||||
borderSide: BorderSide(color: Colors.white),
|
||||
),
|
||||
focusedBorder: UnderlineInputBorder(
|
||||
borderSide: BorderSide(
|
||||
color: Colors.white,
|
||||
),
|
||||
borderSide: BorderSide(color: Colors.white),
|
||||
),
|
||||
),
|
||||
// menuStyle: MenuStyle(
|
||||
@@ -570,13 +529,9 @@ class TorProxyScreen extends HookConsumerWidget {
|
||||
dropdownMenuEntries: countryDropdownEntries,
|
||||
onSelected: (value) async {
|
||||
await ref
|
||||
.read(
|
||||
saveTorSettingsControllerProvider
|
||||
.notifier,
|
||||
)
|
||||
.read(saveTorSettingsControllerProvider.notifier)
|
||||
.save(
|
||||
(currentSettings) => currentSettings
|
||||
.copyWith
|
||||
(currentSettings) => currentSettings.copyWith
|
||||
.entryNodeCountry(value),
|
||||
);
|
||||
},
|
||||
@@ -589,28 +544,33 @@ class TorProxyScreen extends HookConsumerWidget {
|
||||
top: 8.0,
|
||||
),
|
||||
child: DropdownMenu(
|
||||
enabled: !torIsBusy,
|
||||
initialSelection: torSettings.exitNodeCountry,
|
||||
menuHeight: 400,
|
||||
requestFocusOnTap: true,
|
||||
label: const Text('Exit Country'),
|
||||
textStyle: const TextStyle(
|
||||
color: Colors.white,
|
||||
),
|
||||
inputDecorationTheme:
|
||||
const InputDecorationTheme(
|
||||
labelStyle: TextStyle(
|
||||
textStyle: const TextStyle(color: Colors.white),
|
||||
leadingIcon: torSettings.exitNodeCountry.mapNotNull(
|
||||
(code) => Padding(
|
||||
padding: const EdgeInsets.all(8.0),
|
||||
child: CountryFlag.fromCountryCode(
|
||||
code,
|
||||
theme: const EmojiTheme(size: 28),
|
||||
),
|
||||
),
|
||||
),
|
||||
trailingIcon: const Icon(
|
||||
MdiIcons.chevronDown,
|
||||
color: Colors.white,
|
||||
),
|
||||
inputDecorationTheme: const InputDecorationTheme(
|
||||
labelStyle: TextStyle(color: Colors.white),
|
||||
iconColor: Colors.white,
|
||||
enabledBorder: UnderlineInputBorder(
|
||||
borderSide: BorderSide(
|
||||
color: Colors.white,
|
||||
),
|
||||
borderSide: BorderSide(color: Colors.white),
|
||||
),
|
||||
focusedBorder: UnderlineInputBorder(
|
||||
borderSide: BorderSide(
|
||||
color: Colors.white,
|
||||
),
|
||||
borderSide: BorderSide(color: Colors.white),
|
||||
),
|
||||
),
|
||||
// menuStyle: MenuStyle(
|
||||
@@ -622,74 +582,20 @@ class TorProxyScreen extends HookConsumerWidget {
|
||||
dropdownMenuEntries: countryDropdownEntries,
|
||||
onSelected: (value) async {
|
||||
await ref
|
||||
.read(
|
||||
saveTorSettingsControllerProvider
|
||||
.notifier,
|
||||
)
|
||||
.read(saveTorSettingsControllerProvider.notifier)
|
||||
.save(
|
||||
(currentSettings) => currentSettings
|
||||
.copyWith
|
||||
(currentSettings) => currentSettings.copyWith
|
||||
.exitNodeCountry(value),
|
||||
);
|
||||
},
|
||||
),
|
||||
),
|
||||
],
|
||||
);
|
||||
},
|
||||
);
|
||||
},
|
||||
),
|
||||
),
|
||||
Padding(
|
||||
padding: const EdgeInsets.symmetric(vertical: 24.0),
|
||||
child: Column(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: [
|
||||
if (torPendingRequest.value != false && torIsBusy)
|
||||
Column(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: [
|
||||
const SizedBox(height: 8),
|
||||
LinearProgressIndicator(
|
||||
backgroundColor: AppColors.torBackgroundGrey,
|
||||
color: AppColors.torActiveGreen,
|
||||
value: bootstrapProgress / 100,
|
||||
),
|
||||
const SizedBox(height: 8),
|
||||
const Text(
|
||||
'Establishing connection...',
|
||||
style: TextStyle(color: Colors.white),
|
||||
),
|
||||
],
|
||||
)
|
||||
else if (torPendingRequest.value != false &&
|
||||
torIsRunning &&
|
||||
torIsBootstrapped)
|
||||
Padding(
|
||||
padding: const EdgeInsets.only(top: 24.0),
|
||||
child: Row(
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
children: [
|
||||
const Icon(
|
||||
MdiIcons.shieldLockOutline,
|
||||
color: AppColors.torActiveGreen,
|
||||
size: 32,
|
||||
),
|
||||
const SizedBox(width: 12),
|
||||
Text(
|
||||
'Connected to the Tor Network',
|
||||
style: Theme.of(context).textTheme.titleMedium
|
||||
?.copyWith(color: AppColors.torActiveGreen),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
Padding(
|
||||
SliverToBoxAdapter(
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.only(
|
||||
top: 32.0,
|
||||
right: 12.0,
|
||||
left: 12.0,
|
||||
bottom: 8.0,
|
||||
@@ -699,6 +605,8 @@ class TorProxyScreen extends HookConsumerWidget {
|
||||
textAlign: TextAlign.center,
|
||||
style: Theme.of(context).textTheme.bodySmall?.copyWith(
|
||||
fontStyle: FontStyle.italic,
|
||||
color: Colors.white,
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
|
||||
Reference in New Issue
Block a user