stack_wallet/lib/widgets/desktop/desktop_tor_status_button.dart

176 lines
5.3 KiB
Dart

import 'dart:async';
import 'package:event_bus/event_bus.dart';
import 'package:flutter/material.dart';
import 'package:flutter_native_splash/cli_commands.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:flutter_svg/flutter_svg.dart';
import '../../pages_desktop_specific/desktop_menu_item.dart';
import '../../services/event_bus/events/global/tor_connection_status_changed_event.dart';
import '../../services/event_bus/global_event_bus.dart';
import '../../services/tor_service.dart';
import '../../themes/stack_colors.dart';
import '../../utilities/assets.dart';
import '../../utilities/text_styles.dart';
class DesktopTorStatusButton extends ConsumerStatefulWidget {
const DesktopTorStatusButton({
super.key,
this.onPressed,
required this.transitionDuration,
this.controller,
this.labelLength = 125,
});
final VoidCallback? onPressed;
final Duration transitionDuration;
final DMIController? controller;
final double labelLength;
@override
ConsumerState<DesktopTorStatusButton> createState() =>
_DesktopTorStatusButtonState();
}
class _DesktopTorStatusButtonState extends ConsumerState<DesktopTorStatusButton>
with SingleTickerProviderStateMixin {
late final AnimationController animationController;
late final DMIController? controller;
late final double labelLength;
/// The global event bus.
late final EventBus eventBus;
/// The subscription to the TorConnectionStatusChangedEvent.
late final StreamSubscription<TorConnectionStatusChangedEvent>
_torConnectionStatusSubscription;
/// The current status of the Tor connection.
late TorConnectionStatus _torConnectionStatus;
Color _color(TorConnectionStatus status) {
switch (status) {
case TorConnectionStatus.disconnected:
return Theme.of(context).extension<StackColors>()!.textSubtitle3;
case TorConnectionStatus.connecting:
return Theme.of(context).extension<StackColors>()!.accentColorYellow;
case TorConnectionStatus.connected:
return Theme.of(context).extension<StackColors>()!.accentColorGreen;
}
}
bool _iconOnly = false;
void toggle() {
setState(() {
_iconOnly = !_iconOnly;
});
if (_iconOnly) {
animationController.reverse();
} else {
animationController.forward();
}
}
@override
void initState() {
labelLength = widget.labelLength;
controller = widget.controller;
// Initialize the global event bus.
eventBus = GlobalEventBus.instance;
// Initialize the TorConnectionStatus.
_torConnectionStatus = ref.read(pTorService).status;
// Subscribe to the TorConnectionStatusChangedEvent.
_torConnectionStatusSubscription =
eventBus.on<TorConnectionStatusChangedEvent>().listen(
(event) async {
// Rebuild the widget.
setState(() {
_torConnectionStatus = event.newStatus;
});
},
);
controller?.toggle = toggle;
animationController = AnimationController(
vsync: this,
duration: widget.transitionDuration,
)..forward();
super.initState();
}
@override
void dispose() {
// Clean up the subscription to the TorConnectionStatusChangedEvent.
_torConnectionStatusSubscription.cancel();
controller?.dispose();
animationController.dispose();
super.dispose();
}
@override
Widget build(BuildContext context) {
return TextButton(
style: Theme.of(context)
.extension<StackColors>()!
.getDesktopMenuButtonStyle(context),
onPressed: widget.onPressed,
child: Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Padding(
padding: const EdgeInsets.symmetric(
vertical: 16,
),
child: Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
AnimatedContainer(
duration: widget.transitionDuration,
width: _iconOnly ? 0 : 16,
),
SvgPicture.asset(
Assets.svg.tor,
color: _color(_torConnectionStatus),
width: 20,
height: 20,
),
AnimatedOpacity(
duration: widget.transitionDuration,
opacity: _iconOnly ? 0 : 1.0,
child: SizeTransition(
sizeFactor: animationController,
axis: Axis.horizontal,
axisAlignment: -1,
child: Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
const SizedBox(
width: 12,
),
Text(
_torConnectionStatus.name.capitalize(),
style: STextStyles.smallMed12(context).copyWith(
color: _color(_torConnectionStatus),
),
),
const SizedBox(
width: 21,
),
],
),
),
),
],
),
),
],
),
);
}
}