CakeWallet/lib/src/screens/dashboard/widgets/menu_widget.dart
Matthew Fosse 62e0c2a592
litecoin mweb support (#1455)
* Fix stub creation

* Generate MWEB addresses

* Fix mweb address derivation

* Use camel-case

* Show utxos in tx list

* A few fixes

* Add spent processing

* Update balance

* Balance fixes

* Update address records

* Get rid of debounce hack

* Get sending up to the confirmation box

* Fee estimation

* Stop the daemon if plugin is unloaded

* Normal fee for non-mweb txns

* Fix fee estimation for send all

* Don't hash mweb addresses

* More fee fixes

* Broadcast mweb

* Remove test files

* One more

* Confirm sent txns

* Couple of fixes

* Resign inputs after mweb create

* Some more fixes

* Update balance after sending

* Correctly update address records

* Update confs

* [skip ci] updates

* [skip ci] add dep overrides

* working

* small fix

* merge fixes [skip ci]

* merge fixes [skip ci]

* [skip ci] minor fixes

* silent payment fixes [skip ci]

* updates [skip ci]

* save [skip ci]

* use mwebutxos box

* [skip ci] lots of fixes, still testing

* add rescan from height feature and test workflow build

* install go

* use sudo

* correct package name

* move building mweb higher for faster testing

* install fixes

* install later version of go

* go fixes

* testing

* testing

* testing

* testing

* testing

* should workgit add .github/workflows/pr_test_build.yml

* ???

* ??? pt.2

* should work, for real this time

* fix tx history not persisting + update build_mwebd script

* updates

* fix some rescan and address gen issues

* save [skip ci]

* fix unconfirmed balance not updating when receiving

* unspent coins / coin control fixes

* coin control fixes

* address balance and txCount fixes, try/catch electrum call

* fix txCount for addresses

* save [skip ci]

* potential fixes

* minor fix

* minor fix - 2

* sync status fixes, potential fix for background state issue

* workflow and script updates

* updates

* expirimental optimization

* [skip ci] minor enhancements

* workflow and script fixes

* workflow minor cleanup [skip ci]

* minor code cleanup & friendlier error message on failed tx's

* balance when sending fix

* experimental

* more experiments

* save

* updates

* coin control edge cases

* remove neutrino.db if no litecoin wallets left after deleting

* update translations

* updates

* minor fix

* [skip ci] update translations + minor fixes

* state fixes

* configure fix

* ui updates

* translation fixes

* [skip ci] addressbook updates

* fix popup

* fix popup2

* fix litecoin address book

* fix ios mwebd build script

* fix for building monero.com

* minor fix

* uncomment fix for state issues

* potential mweb sync fix (ios)

* remove print [skip ci]

* electrum stream potential fix

* fix ios build issues [skip ci]

* connection reliability updates, update kotlin code to match swift code, minor electrum error handling

* dep fixes

* minor fix

* more merge fixes

* bitcoin_flutter removal fixes

* [skip ci] fix always scan setting, swift updates

* updates

* fixes

* small fix

* small fix

* fix

* dart:convert != package:convert

* change address fixes

* update bitcoin_base to fix mweb address program checking

* fix ios xcode project [skip ci]

* updates

* more fixes

* more fixes

* ensure we don't initialize mweb until we really have to

* fix regression

* improve mweb reliability

* [skip ci] wip adress generation

* wip

* wip

* [skip ci] wip

* updates [skip ci]

* ios fixes

* fix workflows + ios fix

* test old mweb version

* update go version and mwebd hash

* review updates pt.1

* Update cw_bitcoin/lib/litecoin_wallet.dart

Co-authored-by: Omar Hatem <omarh.ismail1@gmail.com>

* remove non-litecoin address types regex [skip ci]

* more minor fixes

* remove duplicate [skip ci]

* Update lib/store/settings_store.dart

Co-authored-by: Omar Hatem <omarh.ismail1@gmail.com>

* script updates, swap params on createLitecoinWalletService

* topup fix

* [skip ci] wip

* [skip ci] testing

* [skip ci] file didn't get saved

* more address generation reliability fixes

* [skip ci] minor

* minor code cleanup

* hopefully prevents send issue

* [skip ci] wip address changes

* [skip ci] save

* save mweb addresses, auto-restart sync process if it gets stuck [skip ci]

* address generation issues mostly resolved

* more performance fixes

* [skip ci]

* this should maybe be refactored, pt.1

* separate mweb balances, pt.2

* [skip ci] save

* add translations [skip ci]

* fix sending with mweb amounts

* works for simple mweb-mweb case, further testing needed

* found an edge case

* [skip ci] make failed broadcast error message less serious

* minor

* capture all grpc errors and much better error handling overall

* [skip ci] minor

* prevent transactions with < 6 confirmations from being used + hide mweb balances if mweb is off

* fix

* merge fixes pt.1 [skip ci]

* fix mweb tags

* fix

* [skip ci] fix tag spacing

* fix transaction history not showing up

* fix mweb crash on non-fully deleted mweb cache, sync status ETA, other connection fixes

* [skip ci] minor code cleanup

* [skip ci] minor code cleanup

* additional cleanup

* silent payments eta fixes and updates

* revert sync eta changes into separate pr

* [skip ci] minor

* [skip ci] minor

* revert sync status title

* review fixes, additional cleanup

* [skip ci] minor

* [skip ci] minor

* [skip ci] minor

* trigger build

* review fixes, pt.2

* check if still processing utxos before updating sync status [skip ci]

* [skip ci] minor

* balance fix

* minor

* minor

* [skip ci] minor

* [skip ci] fix test net btc

* don't use mwebd for non-mweb tx's

* [skip ci] minor cleanup

* don't show all 1000+ mweb addresses on receive page

* minor cleanup + additional logging

---------

Co-authored-by: Hector Chu <hectorchu@gmail.com>
Co-authored-by: Omar Hatem <omarh.ismail1@gmail.com>
Co-authored-by: Czarek Nakamoto <cyjan@mrcyjanek.net>
2024-09-28 05:22:25 +03:00

255 lines
9.2 KiB
Dart

import 'package:cake_wallet/generated/i18n.dart';
import 'package:cake_wallet/src/widgets/setting_action_button.dart';
import 'package:cake_wallet/src/widgets/setting_actions.dart';
import 'package:cake_wallet/themes/extensions/menu_theme.dart';
import 'package:flutter/material.dart';
import 'package:cake_wallet/palette.dart';
import 'package:cake_wallet/view_model/dashboard/dashboard_view_model.dart';
import 'package:cw_core/wallet_type.dart';
import 'package:flutter_mobx/flutter_mobx.dart';
class MenuWidget extends StatefulWidget {
MenuWidget(this.dashboardViewModel);
final DashboardViewModel dashboardViewModel;
@override
MenuWidgetState createState() => MenuWidgetState();
}
class MenuWidgetState extends State<MenuWidget> {
MenuWidgetState()
: this.menuWidth = 0,
this.screenWidth = 0,
this.screenHeight = 0,
this.headerHeight = 120,
this.tileHeight = 60,
this.fromTopEdge = 50,
this.fromBottomEdge = 25,
this.moneroIcon = Image.asset('assets/images/monero_menu.png'),
this.bitcoinIcon = Image.asset('assets/images/bitcoin_menu.png'),
this.litecoinIcon = Image.asset('assets/images/litecoin_menu.png'),
this.havenIcon = Image.asset('assets/images/haven_menu.png'),
this.ethereumIcon = Image.asset('assets/images/eth_icon.png'),
this.nanoIcon = Image.asset('assets/images/nano_icon.png'),
this.bananoIcon = Image.asset('assets/images/nano_icon.png'),
this.bitcoinCashIcon = Image.asset('assets/images/bch_icon.png'),
this.polygonIcon = Image.asset('assets/images/matic_icon.png'),
this.solanaIcon = Image.asset('assets/images/sol_icon.png'),
this.tronIcon = Image.asset('assets/images/trx_icon.png'),
this.wowneroIcon = Image.asset('assets/images/wownero_icon.png');
final largeScreen = 731;
double menuWidth;
double screenWidth;
double screenHeight;
double headerHeight;
double tileHeight;
double fromTopEdge;
double fromBottomEdge;
Image moneroIcon;
Image bitcoinIcon;
Image litecoinIcon;
Image havenIcon;
Image ethereumIcon;
Image bitcoinCashIcon;
Image nanoIcon;
Image bananoIcon;
Image polygonIcon;
Image solanaIcon;
Image tronIcon;
Image wowneroIcon;
@override
void initState() {
menuWidth = 0;
screenWidth = 0;
screenHeight = 0;
headerHeight = 120;
tileHeight = 60;
fromTopEdge = 50;
fromBottomEdge = 25;
super.initState();
WidgetsBinding.instance.addPostFrameCallback(afterLayout);
}
void afterLayout(dynamic _) {
screenWidth = MediaQuery.of(context).size.width;
screenHeight = MediaQuery.of(context).size.height;
setState(() {
menuWidth = screenWidth;
if (screenHeight > largeScreen) {
final scale = screenHeight / largeScreen;
tileHeight *= scale;
headerHeight *= scale;
fromTopEdge *= scale;
fromBottomEdge *= scale;
}
});
}
@override
Widget build(BuildContext context) {
List<SettingActions> items = SettingActions.all;
if (!widget.dashboardViewModel.hasSilentPayments) {
items.removeWhere((element) => element.name(context) == S.of(context).silent_payments_settings);
}
// if (!widget.dashboardViewModel.hasMweb) {
// itemCount--;
// items.removeWhere((element) => element.name(context) == S.of(context).litecoin_mweb_settings);
// }
int itemCount = items.length;
moneroIcon = Image.asset('assets/images/monero_menu.png',
color: Theme.of(context).extension<CakeMenuTheme>()!.iconColor);
bitcoinIcon = Image.asset('assets/images/bitcoin_menu.png',
color: Theme.of(context).extension<CakeMenuTheme>()!.iconColor);
return Row(
mainAxisSize: MainAxisSize.max,
crossAxisAlignment: CrossAxisAlignment.center,
children: <Widget>[
Padding(
padding: EdgeInsets.only(left: 24),
child: Container(
height: 60,
width: 4,
decoration: BoxDecoration(
borderRadius: BorderRadius.all(Radius.circular(2)), color: PaletteDark.gray),
),
),
SizedBox(width: 12),
Expanded(
child: ClipRRect(
borderRadius:
BorderRadius.only(topLeft: Radius.circular(24), bottomLeft: Radius.circular(24)),
child: Container(
color: Theme.of(context).extension<CakeMenuTheme>()!.backgroundColor,
child: ListView.separated(
padding: EdgeInsets.only(top: 0),
itemBuilder: (_, index) {
if (index == 0) {
return Container(
height: headerHeight,
decoration: BoxDecoration(
gradient: LinearGradient(colors: [
Theme.of(context).extension<CakeMenuTheme>()!.headerFirstGradientColor,
Theme.of(context).extension<CakeMenuTheme>()!.headerSecondGradientColor,
], begin: Alignment.topLeft, end: Alignment.bottomRight),
),
padding: EdgeInsets.only(
left: 24, top: fromTopEdge, right: 24, bottom: fromBottomEdge),
child: Row(
mainAxisAlignment: MainAxisAlignment.start,
children: <Widget>[
_iconFor(type: widget.dashboardViewModel.type),
SizedBox(width: 12),
SingleChildScrollView(
child: Container(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
mainAxisAlignment: widget.dashboardViewModel.subname.isNotEmpty
? MainAxisAlignment.spaceBetween
: MainAxisAlignment.center,
children: <Widget>[
Text(
widget.dashboardViewModel.name,
style: TextStyle(
color: Colors.white,
fontSize: 16,
fontWeight: FontWeight.bold),
),
if (widget.dashboardViewModel.subname.isNotEmpty)
Observer(
builder: (_) => Text(
widget.dashboardViewModel.subname,
style: TextStyle(
color: Theme.of(context)
.extension<CakeMenuTheme>()!
.subnameTextColor,
fontWeight: FontWeight.w500,
fontSize: 12),
),
),
],
),
),
),
],
),
);
}
index--;
final item = items[index];
if (!widget.dashboardViewModel.hasMweb &&
item.name(context) == S.current.litecoin_mweb_settings) {
return const SizedBox();
}
final isLastTile = index == itemCount - 1;
return SettingActionButton(
isLastTile: isLastTile,
tileHeight: tileHeight,
selectionActive: false,
fromBottomEdge: fromBottomEdge,
fromTopEdge: fromTopEdge,
onTap: () => item.onTap.call(context),
image: item.image,
title: item.name.call(context),
);
},
separatorBuilder: (_, index) => Container(
height: 1,
color: Theme.of(context).extension<CakeMenuTheme>()!.dividerColor,
),
itemCount: itemCount + 1,
),
),
),
),
],
);
}
Image _iconFor({required WalletType type}) {
switch (type) {
case WalletType.monero:
return moneroIcon;
case WalletType.bitcoin:
return bitcoinIcon;
case WalletType.litecoin:
return litecoinIcon;
case WalletType.haven:
return havenIcon;
case WalletType.ethereum:
return ethereumIcon;
case WalletType.bitcoinCash:
return bitcoinCashIcon;
case WalletType.nano:
return nanoIcon;
case WalletType.banano:
return bananoIcon;
case WalletType.polygon:
return polygonIcon;
case WalletType.solana:
return solanaIcon;
case WalletType.tron:
return tronIcon;
case WalletType.wownero:
return wowneroIcon;
default:
throw Exception('No icon for ${type.toString()}');
}
}
}