hook up existing ui elements to the tor service

and add a status getter to the tor service
This commit is contained in:
sneurlax 2023-09-07 18:28:55 -05:00
parent 5cf202efc0
commit 79c1dee7ad
3 changed files with 170 additions and 29 deletions

View file

@ -8,21 +8,26 @@
* *
*/ */
import 'dart:async';
import 'dart:io'; import 'dart:io';
import 'package:event_bus/event_bus.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter/services.dart'; import 'package:flutter/services.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart'; import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:flutter_svg/flutter_svg.dart'; import 'package:flutter_svg/flutter_svg.dart';
import 'package:stackwallet/services/event_bus/events/global/tor_connection_status_changed_event.dart';
import 'package:stackwallet/pages_desktop_specific/desktop_menu_item.dart'; import 'package:stackwallet/pages_desktop_specific/desktop_menu_item.dart';
import 'package:stackwallet/pages_desktop_specific/settings/settings_menu.dart'; import 'package:stackwallet/pages_desktop_specific/settings/settings_menu.dart';
import 'package:stackwallet/providers/desktop/current_desktop_menu_item.dart'; import 'package:stackwallet/providers/desktop/current_desktop_menu_item.dart';
import 'package:stackwallet/services/event_bus/events/global/tor_connection_status_changed_event.dart';
import 'package:stackwallet/services/tor_service.dart';
import 'package:stackwallet/themes/stack_colors.dart'; import 'package:stackwallet/themes/stack_colors.dart';
import 'package:stackwallet/utilities/assets.dart'; import 'package:stackwallet/utilities/assets.dart';
import 'package:stackwallet/utilities/text_styles.dart'; import 'package:stackwallet/utilities/text_styles.dart';
import 'package:stackwallet/widgets/desktop/living_stack_icon.dart'; import 'package:stackwallet/widgets/desktop/living_stack_icon.dart';
import '../services/event_bus/global_event_bus.dart';
enum DesktopMenuItemId { enum DesktopMenuItemId {
myStack, myStack,
exchange, exchange,
@ -59,6 +64,17 @@ class _DesktopMenuState extends ConsumerState<DesktopMenu> {
// final _buyDataLoadingService = BuyDataLoadingService(); // final _buyDataLoadingService = BuyDataLoadingService();
/// The global event bus.
late final EventBus eventBus;
/// The subscription to the TorConnectionStatusChangedEvent.
late StreamSubscription<TorConnectionStatusChangedEvent>
_torConnectionStatusSubscription;
/// The current status of the Tor connection.
TorConnectionStatus _torConnectionStatus = TorConnectionStatus.disconnected;
/// Builds the tor icon based on the current status.
Widget _buildTorIcon(TorConnectionStatus status) { Widget _buildTorIcon(TorConnectionStatus status) {
switch (status) { switch (status) {
case TorConnectionStatus.disconnected: case TorConnectionStatus.disconnected:
@ -80,26 +96,6 @@ class _DesktopMenuState extends ConsumerState<DesktopMenu> {
) )
], ],
); );
case TorConnectionStatus.connected:
return Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
SvgPicture.asset(
Assets.svg.tor,
color:
Theme.of(context).extension<StackColors>()!.accentColorGreen,
width: 20,
height: 20,
),
Text(
"\tConnected",
style: STextStyles.smallMed12(context).copyWith(
color: Theme.of(context)
.extension<StackColors>()!
.accentColorGreen),
)
],
);
case TorConnectionStatus.connecting: case TorConnectionStatus.connecting:
return Row( return Row(
mainAxisAlignment: MainAxisAlignment.center, mainAxisAlignment: MainAxisAlignment.center,
@ -120,6 +116,26 @@ class _DesktopMenuState extends ConsumerState<DesktopMenu> {
) )
], ],
); );
case TorConnectionStatus.connected:
return Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
SvgPicture.asset(
Assets.svg.tor,
color:
Theme.of(context).extension<StackColors>()!.accentColorGreen,
width: 20,
height: 20,
),
Text(
"\tConnected",
style: STextStyles.smallMed12(context).copyWith(
color: Theme.of(context)
.extension<StackColors>()!
.accentColorGreen),
)
],
);
} }
} }
@ -157,6 +173,39 @@ class _DesktopMenuState extends ConsumerState<DesktopMenu> {
DMIController(), DMIController(),
]; ];
// Initialize the global event bus.
eventBus = GlobalEventBus.instance;
// Subscribe to the TorConnectionStatusChangedEvent.
_torConnectionStatusSubscription =
eventBus.on<TorConnectionStatusChangedEvent>().listen(
(event) async {
// Rebuild the widget.
setState(() {
_torConnectionStatus = event.newStatus;
});
// TODO implement spinner or animations and control from here
// switch (event.newStatus) {
// case TorConnectionStatus.disconnected:
// // if (_spinController.hasLoadedAnimation) {
// // _spinController.stop?.call();
// // }
// break;
// case TorConnectionStatus.connecting:
// // if (_spinController.hasLoadedAnimation) {
// // _spinController.repeat?.call();
// // }
// break;
// case TorConnectionStatus.connected:
// // if (_spinController.hasLoadedAnimation) {
// // _spinController.stop?.call();
// // }
// break;
// }
},
);
super.initState(); super.initState();
} }
@ -165,6 +214,10 @@ class _DesktopMenuState extends ConsumerState<DesktopMenu> {
for (var e in controllers) { for (var e in controllers) {
e.dispose(); e.dispose();
} }
// Clean up the subscription to the TorConnectionStatusChangedEvent.
_torConnectionStatusSubscription.cancel();
super.dispose(); super.dispose();
} }
@ -218,7 +271,7 @@ class _DesktopMenuState extends ConsumerState<DesktopMenu> {
.watch(selectedSettingsMenuItemStateProvider.state) .watch(selectedSettingsMenuItemStateProvider.state)
.state = 4; .state = 4;
}, },
child: _buildTorIcon(TorConnectionStatus.disconnected)), child: _buildTorIcon(TorService.sharedInstance.status)),
), ),
const SizedBox( const SizedBox(
height: 40, height: 40,

View file

@ -8,11 +8,17 @@
* *
*/ */
import 'dart:async';
import 'package:event_bus/event_bus.dart';
import 'package:flutter/gestures.dart'; import 'package:flutter/gestures.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart'; import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:flutter_svg/flutter_svg.dart'; import 'package:flutter_svg/flutter_svg.dart';
import 'package:stackwallet/providers/global/prefs_provider.dart'; import 'package:stackwallet/providers/global/prefs_provider.dart';
import 'package:stackwallet/services/event_bus/events/global/tor_connection_status_changed_event.dart';
import 'package:stackwallet/services/event_bus/global_event_bus.dart';
import 'package:stackwallet/services/tor_service.dart';
import 'package:stackwallet/themes/stack_colors.dart'; import 'package:stackwallet/themes/stack_colors.dart';
import 'package:stackwallet/utilities/assets.dart'; import 'package:stackwallet/utilities/assets.dart';
import 'package:stackwallet/utilities/text_styles.dart'; import 'package:stackwallet/utilities/text_styles.dart';
@ -23,6 +29,8 @@ import 'package:stackwallet/widgets/desktop/desktop_dialog_close_button.dart';
import 'package:stackwallet/widgets/desktop/secondary_button.dart'; import 'package:stackwallet/widgets/desktop/secondary_button.dart';
import 'package:stackwallet/widgets/rounded_white_container.dart'; import 'package:stackwallet/widgets/rounded_white_container.dart';
import '../../../../utilities/prefs.dart';
class TorSettings extends ConsumerStatefulWidget { class TorSettings extends ConsumerStatefulWidget {
const TorSettings({Key? key}) : super(key: key); const TorSettings({Key? key}) : super(key: key);
@ -33,13 +41,83 @@ class TorSettings extends ConsumerStatefulWidget {
} }
class _TorSettingsState extends ConsumerState<TorSettings> { class _TorSettingsState extends ConsumerState<TorSettings> {
// The Prefs instance.
final Prefs _prefs = Prefs.instance;
/// The global event bus.
EventBus eventBus = GlobalEventBus.instance;
/// Subscription to the TorConnectionStatusChangedEvent.
late StreamSubscription<TorConnectionStatusChangedEvent>
_torConnectionStatusSubscription;
/// The current status of the Tor connection.
TorConnectionStatus _torConnectionStatus = TorConnectionStatus.disconnected;
Widget _buildConnectButton(TorConnectionStatus status) {
switch (status) {
case TorConnectionStatus.disconnected:
return SecondaryButton(
label: "Connect to Tor",
width: 200,
buttonHeight: ButtonHeight.m,
onPressed: () {
// Toggle the useTor preference.
_prefs.useTor = true;
// Start the Tor service.
TorService.sharedInstance.start();
},
);
case TorConnectionStatus.connecting:
return AbsorbPointer(
child: SecondaryButton(
label: "Connecting to Tor",
width: 200,
buttonHeight: ButtonHeight.m,
onPressed: () {},
),
);
case TorConnectionStatus.connected:
return SecondaryButton(
label: "Disconnect from Tor",
width: 200,
buttonHeight: ButtonHeight.m,
onPressed: () {
// Toggle the useTor preference.
_prefs.useTor = false;
// Stop the Tor service.
TorService.sharedInstance.stop();
},
);
}
}
@override @override
void initState() { void initState() {
// Initialize the global event bus.
eventBus = GlobalEventBus.instance;
// Subscribe to the TorConnectionStatusChangedEvent.
_torConnectionStatusSubscription =
eventBus.on<TorConnectionStatusChangedEvent>().listen(
(event) async {
// Rebuild the widget.
setState(() {
_torConnectionStatus = event.newStatus;
});
},
);
super.initState(); super.initState();
} }
@override @override
void dispose() { void dispose() {
// Clean up the TorConnectionStatusChangedEvent subscription.
_torConnectionStatusSubscription.cancel();
super.dispose(); super.dispose();
} }
@ -72,7 +150,12 @@ class _TorSettingsState extends ConsumerState<TorSettings> {
Padding( Padding(
padding: const EdgeInsets.all(8.0), padding: const EdgeInsets.all(8.0),
child: SvgPicture.asset( child: SvgPicture.asset(
Assets.svg.disconnectedButton, _torConnectionStatus == TorConnectionStatus.connected
? Assets.svg.connectedButton
: _torConnectionStatus ==
TorConnectionStatus.connecting
? Assets.svg.connectingButton
: Assets.svg.disconnectedButton,
width: 48, width: 48,
height: 48, height: 48,
), ),
@ -176,12 +259,7 @@ class _TorSettingsState extends ConsumerState<TorSettings> {
), ),
Padding( Padding(
padding: const EdgeInsets.all(10.0), padding: const EdgeInsets.all(10.0),
child: SecondaryButton( child: _buildConnectButton(TorService.sharedInstance.status),
label: "Disconnect from Tor",
width: 200,
buttonHeight: ButtonHeight.m,
onPressed: () {},
),
), ),
const SizedBox( const SizedBox(
height: 30, height: 30,

View file

@ -72,6 +72,11 @@ class TorService {
// no exception or error so we can (probably?) assume tor // no exception or error so we can (probably?) assume tor
// has started successfully // has started successfully
_enabled = true; _enabled = true;
// Set the status to connected.
_status = TorConnectionStatus.connected;
// Fire a TorConnectionStatusChangedEvent on the event bus.
GlobalEventBus.instance.fire( GlobalEventBus.instance.fire(
TorConnectionStatusChangedEvent( TorConnectionStatusChangedEvent(
TorConnectionStatus.connected, TorConnectionStatus.connected,
@ -84,6 +89,11 @@ class TorService {
level: LogLevel.Warning, level: LogLevel.Warning,
); );
// _enabled should already be false // _enabled should already be false
// Set the status to disconnected.
_status = TorConnectionStatus.disconnected;
// Fire a TorConnectionStatusChangedEvent on the event bus.
GlobalEventBus.instance.fire( GlobalEventBus.instance.fire(
TorConnectionStatusChangedEvent( TorConnectionStatusChangedEvent(
TorConnectionStatus.disconnected, TorConnectionStatus.disconnected,