mirror of
https://github.com/cypherstack/stack_wallet.git
synced 2024-11-17 17:57:40 +00:00
desktop sync status styling and basic functionality
This commit is contained in:
parent
8b136b003c
commit
7203f09eb0
1 changed files with 223 additions and 53 deletions
|
@ -1,13 +1,24 @@
|
||||||
|
import 'dart:async';
|
||||||
|
|
||||||
|
import 'package:event_bus/event_bus.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/svg.dart';
|
import 'package:flutter_svg/svg.dart';
|
||||||
|
import 'package:stackwallet/pages/settings_views/wallet_settings_view/wallet_network_settings_view/wallet_network_settings_view.dart';
|
||||||
import 'package:stackwallet/pages_desktop_specific/home/my_stack_view/wallet_view/desktop_wallet_summary.dart';
|
import 'package:stackwallet/pages_desktop_specific/home/my_stack_view/wallet_view/desktop_wallet_summary.dart';
|
||||||
import 'package:stackwallet/pages_desktop_specific/home/my_stack_view/wallet_view/receive/desktop_receive.dart';
|
import 'package:stackwallet/pages_desktop_specific/home/my_stack_view/wallet_view/receive/desktop_receive.dart';
|
||||||
import 'package:stackwallet/pages_desktop_specific/home/my_stack_view/wallet_view/send/desktop_send.dart';
|
import 'package:stackwallet/pages_desktop_specific/home/my_stack_view/wallet_view/send/desktop_send.dart';
|
||||||
|
import 'package:stackwallet/providers/global/auto_swb_service_provider.dart';
|
||||||
import 'package:stackwallet/providers/providers.dart';
|
import 'package:stackwallet/providers/providers.dart';
|
||||||
|
import 'package:stackwallet/providers/ui/transaction_filter_provider.dart';
|
||||||
|
import 'package:stackwallet/services/event_bus/events/global/node_connection_status_changed_event.dart';
|
||||||
import 'package:stackwallet/services/event_bus/events/global/wallet_sync_status_changed_event.dart';
|
import 'package:stackwallet/services/event_bus/events/global/wallet_sync_status_changed_event.dart';
|
||||||
|
import 'package:stackwallet/services/event_bus/global_event_bus.dart';
|
||||||
|
import 'package:stackwallet/services/exchange/exchange_data_loading_service.dart';
|
||||||
import 'package:stackwallet/utilities/assets.dart';
|
import 'package:stackwallet/utilities/assets.dart';
|
||||||
import 'package:stackwallet/utilities/constants.dart';
|
import 'package:stackwallet/utilities/constants.dart';
|
||||||
|
import 'package:stackwallet/utilities/enums/backup_frequency_type.dart';
|
||||||
|
import 'package:stackwallet/utilities/logger.dart';
|
||||||
import 'package:stackwallet/utilities/text_styles.dart';
|
import 'package:stackwallet/utilities/text_styles.dart';
|
||||||
import 'package:stackwallet/utilities/theme/stack_colors.dart';
|
import 'package:stackwallet/utilities/theme/stack_colors.dart';
|
||||||
import 'package:stackwallet/widgets/custom_buttons/app_bar_icon_button.dart';
|
import 'package:stackwallet/widgets/custom_buttons/app_bar_icon_button.dart';
|
||||||
|
@ -16,16 +27,20 @@ import 'package:stackwallet/widgets/desktop/desktop_app_bar.dart';
|
||||||
import 'package:stackwallet/widgets/desktop/desktop_scaffold.dart';
|
import 'package:stackwallet/widgets/desktop/desktop_scaffold.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 'package:tuple/tuple.dart';
|
||||||
|
|
||||||
|
/// [eventBus] should only be set during testing
|
||||||
class DesktopWalletView extends ConsumerStatefulWidget {
|
class DesktopWalletView extends ConsumerStatefulWidget {
|
||||||
const DesktopWalletView({
|
const DesktopWalletView({
|
||||||
Key? key,
|
Key? key,
|
||||||
required this.walletId,
|
required this.walletId,
|
||||||
|
this.eventBus,
|
||||||
}) : super(key: key);
|
}) : super(key: key);
|
||||||
|
|
||||||
static const String routeName = "/desktopWalletView";
|
static const String routeName = "/desktopWalletView";
|
||||||
|
|
||||||
final String walletId;
|
final String walletId;
|
||||||
|
final EventBus? eventBus;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
ConsumerState<DesktopWalletView> createState() => _DesktopWalletViewState();
|
ConsumerState<DesktopWalletView> createState() => _DesktopWalletViewState();
|
||||||
|
@ -33,15 +48,69 @@ class DesktopWalletView extends ConsumerStatefulWidget {
|
||||||
|
|
||||||
class _DesktopWalletViewState extends ConsumerState<DesktopWalletView> {
|
class _DesktopWalletViewState extends ConsumerState<DesktopWalletView> {
|
||||||
late final String walletId;
|
late final String walletId;
|
||||||
|
late final EventBus eventBus;
|
||||||
|
|
||||||
|
late final bool _shouldDisableAutoSyncOnLogOut;
|
||||||
|
|
||||||
|
final _cnLoadingService = ExchangeDataLoadingService();
|
||||||
|
|
||||||
Future<void> onBackPressed() async {
|
Future<void> onBackPressed() async {
|
||||||
// TODO log out and close wallet before popping back
|
await _logout();
|
||||||
|
if (mounted) {
|
||||||
Navigator.of(context).pop();
|
Navigator.of(context).pop();
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Future<void> _logout() async {
|
||||||
|
final managerProvider =
|
||||||
|
ref.read(walletsChangeNotifierProvider).getManagerProvider(walletId);
|
||||||
|
if (_shouldDisableAutoSyncOnLogOut) {
|
||||||
|
// disable auto sync if it was enabled only when loading wallet
|
||||||
|
ref.read(managerProvider).shouldAutoSync = false;
|
||||||
|
}
|
||||||
|
ref.read(managerProvider.notifier).isActiveWallet = false;
|
||||||
|
ref.read(transactionFilterProvider.state).state = null;
|
||||||
|
if (ref.read(prefsChangeNotifierProvider).isAutoBackupEnabled &&
|
||||||
|
ref.read(prefsChangeNotifierProvider).backupFrequencyType ==
|
||||||
|
BackupFrequencyType.afterClosingAWallet) {
|
||||||
|
unawaited(ref.read(autoSWBServiceProvider).doBackup());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void _loadCNData() {
|
||||||
|
// unawaited future
|
||||||
|
if (ref.read(prefsChangeNotifierProvider).externalCalls) {
|
||||||
|
_cnLoadingService.loadAll(ref,
|
||||||
|
coin: ref
|
||||||
|
.read(walletsChangeNotifierProvider)
|
||||||
|
.getManager(walletId)
|
||||||
|
.coin);
|
||||||
|
} else {
|
||||||
|
Logging.instance.log("User does not want to use external calls",
|
||||||
|
level: LogLevel.Info);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
void initState() {
|
void initState() {
|
||||||
walletId = widget.walletId;
|
walletId = widget.walletId;
|
||||||
|
final managerProvider =
|
||||||
|
ref.read(walletsChangeNotifierProvider).getManagerProvider(walletId);
|
||||||
|
|
||||||
|
eventBus =
|
||||||
|
widget.eventBus != null ? widget.eventBus! : GlobalEventBus.instance;
|
||||||
|
|
||||||
|
ref.read(managerProvider).isActiveWallet = true;
|
||||||
|
if (!ref.read(managerProvider).shouldAutoSync) {
|
||||||
|
// enable auto sync if it wasn't enabled when loading wallet
|
||||||
|
ref.read(managerProvider).shouldAutoSync = true;
|
||||||
|
_shouldDisableAutoSyncOnLogOut = true;
|
||||||
|
} else {
|
||||||
|
_shouldDisableAutoSyncOnLogOut = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
ref.read(managerProvider).refresh();
|
||||||
|
|
||||||
super.initState();
|
super.initState();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -95,13 +164,16 @@ class _DesktopWalletViewState extends ConsumerState<DesktopWalletView> {
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
trailing: Row(
|
trailing: Row(
|
||||||
children: const [
|
children: [
|
||||||
NetworkInfoButton(),
|
NetworkInfoButton(
|
||||||
SizedBox(
|
walletId: walletId,
|
||||||
|
eventBus: eventBus,
|
||||||
|
),
|
||||||
|
const SizedBox(
|
||||||
width: 32,
|
width: 32,
|
||||||
),
|
),
|
||||||
WalletKeysButton(),
|
const WalletKeysButton(),
|
||||||
SizedBox(
|
const SizedBox(
|
||||||
width: 32,
|
width: 32,
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
|
@ -132,37 +204,6 @@ class _DesktopWalletViewState extends ConsumerState<DesktopWalletView> {
|
||||||
? WalletSyncStatus.syncing
|
? WalletSyncStatus.syncing
|
||||||
: WalletSyncStatus.synced,
|
: WalletSyncStatus.synced,
|
||||||
),
|
),
|
||||||
// Column(
|
|
||||||
// crossAxisAlignment: CrossAxisAlignment.start,
|
|
||||||
// mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
|
||||||
// children: [
|
|
||||||
// Row(
|
|
||||||
// children: [
|
|
||||||
// Text(
|
|
||||||
// "TODO: balance",
|
|
||||||
// style: STextStyles.desktopH3(context),
|
|
||||||
// ),
|
|
||||||
// const SizedBox(
|
|
||||||
// width: 8,
|
|
||||||
// ),
|
|
||||||
// Container(
|
|
||||||
// color: Colors.red,
|
|
||||||
// width: 20,
|
|
||||||
// height: 20,
|
|
||||||
// ),
|
|
||||||
// ],
|
|
||||||
// ),
|
|
||||||
// Text(
|
|
||||||
// "todo: fiat balance",
|
|
||||||
// style:
|
|
||||||
// STextStyles.desktopTextExtraSmall(context).copyWith(
|
|
||||||
// color: Theme.of(context)
|
|
||||||
// .extension<StackColors>()!
|
|
||||||
// .textSubtitle1,
|
|
||||||
// ),
|
|
||||||
// )
|
|
||||||
// ],
|
|
||||||
// ),
|
|
||||||
const Spacer(),
|
const Spacer(),
|
||||||
SecondaryButton(
|
SecondaryButton(
|
||||||
width: 180,
|
width: 180,
|
||||||
|
@ -195,7 +236,7 @@ class _DesktopWalletViewState extends ConsumerState<DesktopWalletView> {
|
||||||
const SizedBox(
|
const SizedBox(
|
||||||
width: 16,
|
width: 16,
|
||||||
),
|
),
|
||||||
Expanded(
|
const Expanded(
|
||||||
child: RecentDesktopTransactions(),
|
child: RecentDesktopTransactions(),
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
|
@ -284,7 +325,6 @@ class _MyWalletState extends State<MyWallet> {
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
const Spacer(),
|
|
||||||
],
|
],
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -461,30 +501,160 @@ class _RecentDesktopTransactionsState extends State<RecentDesktopTransactions> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class NetworkInfoButton extends StatelessWidget {
|
class NetworkInfoButton extends ConsumerStatefulWidget {
|
||||||
const NetworkInfoButton({Key? key}) : super(key: key);
|
const NetworkInfoButton({
|
||||||
|
Key? key,
|
||||||
|
required this.walletId,
|
||||||
|
this.eventBus,
|
||||||
|
}) : super(key: key);
|
||||||
|
|
||||||
|
final String walletId;
|
||||||
|
final EventBus? eventBus;
|
||||||
|
|
||||||
|
@override
|
||||||
|
ConsumerState<NetworkInfoButton> createState() => _NetworkInfoButtonState();
|
||||||
|
}
|
||||||
|
|
||||||
|
class _NetworkInfoButtonState extends ConsumerState<NetworkInfoButton> {
|
||||||
|
late final String walletId;
|
||||||
|
late final EventBus eventBus;
|
||||||
|
|
||||||
|
late WalletSyncStatus _currentSyncStatus;
|
||||||
|
late NodeConnectionStatus _currentNodeStatus;
|
||||||
|
|
||||||
|
late StreamSubscription<dynamic> _syncStatusSubscription;
|
||||||
|
late StreamSubscription<dynamic> _nodeStatusSubscription;
|
||||||
|
|
||||||
|
@override
|
||||||
|
void initState() {
|
||||||
|
walletId = widget.walletId;
|
||||||
|
final managerProvider =
|
||||||
|
ref.read(walletsChangeNotifierProvider).getManagerProvider(walletId);
|
||||||
|
|
||||||
|
eventBus =
|
||||||
|
widget.eventBus != null ? widget.eventBus! : GlobalEventBus.instance;
|
||||||
|
|
||||||
|
if (ref.read(managerProvider).isRefreshing) {
|
||||||
|
_currentSyncStatus = WalletSyncStatus.syncing;
|
||||||
|
_currentNodeStatus = NodeConnectionStatus.connected;
|
||||||
|
} else {
|
||||||
|
_currentSyncStatus = WalletSyncStatus.synced;
|
||||||
|
if (ref.read(managerProvider).isConnected) {
|
||||||
|
_currentNodeStatus = NodeConnectionStatus.connected;
|
||||||
|
} else {
|
||||||
|
_currentNodeStatus = NodeConnectionStatus.disconnected;
|
||||||
|
_currentSyncStatus = WalletSyncStatus.unableToSync;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
_syncStatusSubscription =
|
||||||
|
eventBus.on<WalletSyncStatusChangedEvent>().listen(
|
||||||
|
(event) async {
|
||||||
|
if (event.walletId == widget.walletId) {
|
||||||
|
setState(() {
|
||||||
|
_currentSyncStatus = event.newStatus;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
},
|
||||||
|
);
|
||||||
|
|
||||||
|
_nodeStatusSubscription =
|
||||||
|
eventBus.on<NodeConnectionStatusChangedEvent>().listen(
|
||||||
|
(event) async {
|
||||||
|
if (event.walletId == widget.walletId) {
|
||||||
|
setState(() {
|
||||||
|
_currentNodeStatus = event.newStatus;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
},
|
||||||
|
);
|
||||||
|
|
||||||
|
super.initState();
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
void dispose() {
|
||||||
|
_nodeStatusSubscription.cancel();
|
||||||
|
_syncStatusSubscription.cancel();
|
||||||
|
super.dispose();
|
||||||
|
}
|
||||||
|
|
||||||
|
Widget _buildNetworkIcon(WalletSyncStatus status, BuildContext context) {
|
||||||
|
const size = 24.0;
|
||||||
|
switch (status) {
|
||||||
|
case WalletSyncStatus.unableToSync:
|
||||||
|
return SvgPicture.asset(
|
||||||
|
Assets.svg.radioProblem,
|
||||||
|
color: Theme.of(context).extension<StackColors>()!.accentColorRed,
|
||||||
|
width: size,
|
||||||
|
height: size,
|
||||||
|
);
|
||||||
|
case WalletSyncStatus.synced:
|
||||||
|
return SvgPicture.asset(
|
||||||
|
Assets.svg.radio,
|
||||||
|
color: Theme.of(context).extension<StackColors>()!.accentColorGreen,
|
||||||
|
width: size,
|
||||||
|
height: size,
|
||||||
|
);
|
||||||
|
case WalletSyncStatus.syncing:
|
||||||
|
return SvgPicture.asset(
|
||||||
|
Assets.svg.radioSyncing,
|
||||||
|
color: Theme.of(context).extension<StackColors>()!.accentColorYellow,
|
||||||
|
width: size,
|
||||||
|
height: size,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Widget _buildText(WalletSyncStatus status, BuildContext context) {
|
||||||
|
String label;
|
||||||
|
Color color;
|
||||||
|
|
||||||
|
switch (status) {
|
||||||
|
case WalletSyncStatus.unableToSync:
|
||||||
|
label = "Unable to sync";
|
||||||
|
color = Theme.of(context).extension<StackColors>()!.accentColorRed;
|
||||||
|
break;
|
||||||
|
case WalletSyncStatus.synced:
|
||||||
|
label = "Synchronised";
|
||||||
|
color = Theme.of(context).extension<StackColors>()!.accentColorGreen;
|
||||||
|
break;
|
||||||
|
case WalletSyncStatus.syncing:
|
||||||
|
label = "Synchronising";
|
||||||
|
color = Theme.of(context).extension<StackColors>()!.accentColorYellow;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return Text(
|
||||||
|
label,
|
||||||
|
style: STextStyles.desktopMenuItemSelected(context).copyWith(
|
||||||
|
color: color,
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
return GestureDetector(
|
return GestureDetector(
|
||||||
|
onTap: () {
|
||||||
|
Navigator.of(context).pushNamed(
|
||||||
|
WalletNetworkSettingsView.routeName,
|
||||||
|
arguments: Tuple3(
|
||||||
|
walletId,
|
||||||
|
_currentSyncStatus,
|
||||||
|
_currentNodeStatus,
|
||||||
|
),
|
||||||
|
);
|
||||||
|
},
|
||||||
child: Container(
|
child: Container(
|
||||||
color: Colors.transparent,
|
color: Colors.transparent,
|
||||||
child: Row(
|
child: Row(
|
||||||
children: [
|
children: [
|
||||||
SvgPicture.asset(
|
_buildNetworkIcon(_currentSyncStatus, context),
|
||||||
Assets.svg.network,
|
|
||||||
width: 24,
|
|
||||||
height: 24,
|
|
||||||
color:
|
|
||||||
Theme.of(context).extension<StackColors>()!.accentColorGreen,
|
|
||||||
),
|
|
||||||
const SizedBox(
|
const SizedBox(
|
||||||
width: 6,
|
width: 6,
|
||||||
),
|
),
|
||||||
Text(
|
_buildText(_currentSyncStatus, context),
|
||||||
"Synchronised",
|
|
||||||
style: STextStyles.desktopMenuItemSelected(context),
|
|
||||||
)
|
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
|
Loading…
Reference in a new issue