Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Redesign receive screen #593

Merged
merged 2 commits into from
Oct 23, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 6 additions & 1 deletion lib/l10n/app_en.arb
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,7 @@
},
"addTimelockLabel": "Add Timelock (Optional)",
"address": "Address",
"addressList": "Address list",
"addressCopied": "Address copied!",
"advancedSettings": "Advanced Settings",
"amount": "Amount",
Expand Down Expand Up @@ -179,6 +180,8 @@
"feesPayed": "Fees payed",
"forgetPassword": "Did you forget your password?, You can delete your wallet and configure a new one!",
"from": "from",
"generateAddressWarning": "You are about to generate a new address",
"generateAddressWarningMessage": "A new address will be generated and ready to be used. The main address displayed in the navigation will be updated to the new one.",
"genNewAddressLabel": "Generate new Address",
"generateMnemonic01": "These {mnemonicLength} apparently random words are your secret recovery phrase. They will allow you to recover your Wit coins if you uninstall this app or forget your wallet lock password.",
"generateMnemonic02": "You must write down your secret recovery phrase on a piece of paper and store it somewhere safe. Do not store it in a file in your device or anywhere else electronically. If you lose your secret recovery phrase, you may permanently lose access to your wallet and your Wit coins.",
Expand Down Expand Up @@ -338,5 +341,7 @@
"withdrawalAddress": "Withdrawal address",
"xprvInputHint": "Your Xprv key (starts with xprv...)",
"xprvOrigin": "Xprv Origin",
"yourMessage": "Your message..."
"yourMessage": "Your message...",
"addressBalanceDescription": "Received payments totalling",
"loading": "Loading"
}
7 changes: 6 additions & 1 deletion lib/l10n/app_es.arb
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,7 @@
},
"addTimelockLabel": "Añadir Timelock (Opcional)",
"address": "Dirección",
"addressList": "Lista de direcciones",
"addressCopied": "¡Dirección copiada!",
"advancedSettings": "Configuración avanzada",
"amount": "Cantidad",
Expand Down Expand Up @@ -179,6 +180,8 @@
"feesPayed": "Comisiones pagadas",
"forgetPassword": "¿Has olvidado tu contraseña?, ¡Puedes borrar tu monedero y configurar uno nuevo!",
"from": "de",
"generateAddressWarning": "Estás a punto de generar una nueva dirección",
"generateAddressWarningMessage": "Una nueva dirección estará disponible para su uso. La dirección mostrada en la barra de navegación se actualizará a la nueva dirección generada.",
"genNewAddressLabel": "Generar nueva dirección",
"generateMnemonic01": "Estas {mnemonicLength} palabras aparentemente aleatorias son tu frase de recuperación secreta. Te permitirán recuperar tus monedas Wit si desinstalas esta aplicación o olvidas la contraseña de bloqueo de tu cartera.",
"generateMnemonic02": "Debes escribir tu frase de recuperación secreta en un papel y almacenarla en un lugar seguro. No la almacenes en un archivo en tu dispositivo ni en ningún otro lugar electrónico. Si pierdes tu frase de recuperación secreta, podrías perder permanentemente el acceso a tu cartera y tus monedas Wit.",
Expand Down Expand Up @@ -338,5 +341,7 @@
"withdrawalAddress": "Withdrawal address",
"xprvInputHint": "Tu clave Xprv (comienza con xprv...)",
"xprvOrigin": "Origen de Xprv",
"yourMessage": "Tu mensaje..."
"yourMessage": "Tu mensaje...",
"addressBalanceDescription": "Recibió pagos por un total de",
"loading": "Cargando"
}
2 changes: 1 addition & 1 deletion lib/screens/login/view/init_screen.dart
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,7 @@ class InitScreenState extends State<InitScreen> with TickerProviderStateMixin {
color: extendedTheme.spinnerColor,
strokeWidth: 2,
value: null,
semanticsLabel: 'Circular progress indicator',
semanticsLabel: localization.loading,
))
],
actions: [],
Expand Down
56 changes: 56 additions & 0 deletions lib/screens/receive_transaction/address_list_view.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:my_wit_wallet/util/get_localization.dart';
import 'package:my_wit_wallet/screens/dashboard/bloc/dashboard_bloc.dart';
import 'package:my_wit_wallet/util/storage/database/wallet.dart';
import 'package:my_wit_wallet/widgets/address_list.dart';
import 'package:my_wit_wallet/widgets/closable_view.dart';

typedef void VoidCallback();

class AddressListView extends StatefulWidget {
final ScrollController scrollController;
final VoidCallback close;
final Wallet currentWallet;

AddressListView(
{Key? key,
required this.scrollController,
required this.close,
required this.currentWallet})
: super(key: key);
@override
State<StatefulWidget> createState() => AddressListViewState();
}

class AddressListViewState extends State<AddressListView> {
@override
void initState() {
super.initState();
}

@override
Widget build(BuildContext context) {
final theme = Theme.of(context);
return BlocBuilder<DashboardBloc, DashboardState>(
builder: (previous, current) {
return ClosableView(closeSetting: widget.close, children: [
Row(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
localization.generatedAddresses,
style: theme.textTheme.titleLarge,
textAlign: TextAlign.start,
),
],
),
SizedBox(height: 16),
AddressList(
currentWallet: widget.currentWallet,
),
]);
},
);
}
}
189 changes: 120 additions & 69 deletions lib/screens/receive_transaction/receive_tx_screen.dart
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,13 @@ import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:my_wit_wallet/theme/extended_theme.dart';
import 'package:my_wit_wallet/screens/receive_transaction/address_list_view.dart';
import 'package:my_wit_wallet/util/get_localization.dart';
import 'package:my_wit_wallet/bloc/explorer/explorer_bloc.dart';
import 'package:my_wit_wallet/shared/api_database.dart';
import 'package:my_wit_wallet/theme/colors.dart';
import 'package:my_wit_wallet/widgets/PaddedButton.dart';
import 'package:my_wit_wallet/widgets/address_list.dart';
import 'package:font_awesome_flutter/font_awesome_flutter.dart';
import 'package:my_wit_wallet/widgets/dashed_rect.dart';
import 'package:my_wit_wallet/widgets/qr/qr_address_generator.dart';
import 'package:my_wit_wallet/util/storage/database/wallet.dart';
Expand All @@ -19,6 +20,7 @@ import 'package:my_wit_wallet/shared/locator.dart';
import 'package:my_wit_wallet/util/preferences.dart';
import 'package:my_wit_wallet/util/storage/database/account.dart';
import 'package:my_wit_wallet/widgets/snack_bars.dart';
import 'package:my_wit_wallet/widgets/witnet/transactions/value_transfer/modals/new_address_modal.dart';

class ReceiveTransactionScreen extends StatefulWidget {
static final route = '/receive-transaction';
Expand All @@ -33,6 +35,11 @@ class ReceiveTransactionScreenState extends State<ReceiveTransactionScreen>
late AnimationController _loadingController;
bool isLoading = false;
bool enableButton = true;
bool showAddressList = false;
ScrollController scrollController = ScrollController(keepScrollOffset: false);
ApiDatabase db = Locator.instance.get<ApiDatabase>();
Wallet get currentWallet => db.walletStorage.currentWallet;
bool get isHdWallet => currentWallet.walletType == WalletType.hd;

@override
void initState() {
Expand All @@ -53,6 +60,18 @@ class ReceiveTransactionScreenState extends State<ReceiveTransactionScreen>
super.dispose();
}

void _showAddressList() {
setState(() {
showAddressList = true;
});
}

void _hideAddressList() {
setState(() {
showAddressList = false;
});
}

List<Widget> _actions() {
final theme = Theme.of(context);
return [
Expand All @@ -71,57 +90,87 @@ class ReceiveTransactionScreenState extends State<ReceiveTransactionScreen>
theme, localization.copyAddressConfirmed));
}
}),
BlocListener<ExplorerBloc, ExplorerState>(
listener: (BuildContext context, ExplorerState state) {},
child:
BlocBuilder<ExplorerBloc, ExplorerState>(builder: (context, state) {
ApiDatabase db = Locator.instance.get<ApiDatabase>();
Wallet currentWallet = db.walletStorage.currentWallet;
bool isHdWallet = currentWallet.walletType == WalletType.hd;
if (isHdWallet) {
return PaddedButton(
onPressed: () async {
ApiDatabase db = Locator.instance.get<ApiDatabase>();

Wallet currentWallet = db.walletStorage.currentWallet;
int extAccountsLength = currentWallet.externalAccounts.length;
Account ac =
await Locator.instance.get<ApiCrypto>().generateAccount(
currentWallet,
KeyType.external,
extAccountsLength,
);
setState(() {
currentWallet.externalAccounts[extAccountsLength] = ac;
});
await db.addAccount(ac);
await db.loadWalletsDatabase();
await ApiPreferences.setCurrentAddress(AddressEntry(
walletId: ac.walletId,
addressIdx: int.parse(ac.path.split('/').last),
keyType: '0',
));
BlocProvider.of<DashboardBloc>(context)
.add(DashboardUpdateWalletEvent(
currentWallet: currentWallet,
currentAddress: ac.address,
));
BlocProvider.of<ExplorerBloc>(context)
.add(SyncSingleAccountEvent(ExplorerStatus.singleSync, ac));
},
padding: EdgeInsets.only(top: 8),
text: localization.genNewAddressLabel,
SizedBox(height: 8),
isHdWallet
? PaddedButton(
padding: EdgeInsets.zero,
text: localization.addressList,
type: ButtonType.secondary,
enabled: state.status != ExplorerStatus.singleSync,
);
} else {
return Container();
}
}),
),
enabled: enableButton,
isLoading: isLoading,
onPressed: _showAddressList)
: Container(),
];
}

void _generateNewAddress() async {
ApiDatabase db = Locator.instance.get<ApiDatabase>();
Wallet currentWallet = db.walletStorage.currentWallet;
int extAccountsLength = currentWallet.externalAccounts.length;
Account ac = await Locator.instance.get<ApiCrypto>().generateAccount(
currentWallet,
KeyType.external,
extAccountsLength,
);
setState(() {
currentWallet.externalAccounts[extAccountsLength] = ac;
});
await db.addAccount(ac);
await db.loadWalletsDatabase();
await ApiPreferences.setCurrentAddress(AddressEntry(
walletId: ac.walletId,
addressIdx: int.parse(ac.path.split('/').last),
keyType: '0',
));
BlocProvider.of<DashboardBloc>(context).add(DashboardUpdateWalletEvent(
currentWallet: currentWallet,
currentAddress: ac.address,
));
BlocProvider.of<ExplorerBloc>(context)
.add(SyncSingleAccountEvent(ExplorerStatus.singleSync, ac));
}

void _showNewAddressModal() {
final theme = Theme.of(context);
buildNewAddressModal(
theme: theme,
onAction: () => {
_generateNewAddress(),
Navigator.popUntil(
context, ModalRoute.withName(ReceiveTransactionScreen.route)),
ScaffoldMessenger.of(context).clearSnackBars(),
},
context: context,
originRouteName: ReceiveTransactionScreen.route,
originRoute: ReceiveTransactionScreen());
}

Widget _buildGenerateNewAddressBtn() {
return BlocListener<ExplorerBloc, ExplorerState>(
listener: (BuildContext context, ExplorerState state) {},
child:
BlocBuilder<ExplorerBloc, ExplorerState>(builder: (context, state) {
if (isHdWallet) {
return PaddedButton(
onPressed: _showNewAddressModal,
padding: EdgeInsets.only(top: 8),
text: localization.genNewAddressLabel,
label: localization.genNewAddressLabel,
type: ButtonType.iconButton,
iconSize: 20,
icon: Icon(
FontAwesomeIcons.arrowsRotate,
size: 20,
),
enabled: state.status != ExplorerStatus.singleSync,
);
} else {
return Container();
}
}),
);
}

_setCurrentWallet(Wallet? currentWallet, Account currentAccount) {
setState(() {
selectedAccount = currentAccount;
Expand All @@ -130,17 +179,23 @@ class ReceiveTransactionScreenState extends State<ReceiveTransactionScreen>

Widget _buildReceiveTransactionScreen() {
final theme = Theme.of(context);
ApiDatabase db = Locator.instance.get<ApiDatabase>();
final extendedTheme = theme.extension<ExtendedTheme>()!;

return Padding(
padding: EdgeInsets.only(left: 8, right: 8),
child: Column(
children: [
QrAddressGenerator(
data: selectedAccount!.address,
),
SizedBox(height: 24),
Stack(children: [
Padding(
padding: EdgeInsets.only(top: 24, right: 40, left: 40),
child: QrAddressGenerator(
data: selectedAccount!.address,
),
),
Positioned(
right: 0, top: 0, child: _buildGenerateNewAddressBtn()),
]),
SizedBox(height: 16),
DashedRect(
color: WitnetPallet.brightCyan,
textStyle: extendedTheme.monoLargeText,
Expand All @@ -150,25 +205,19 @@ class ReceiveTransactionScreenState extends State<ReceiveTransactionScreen>
),
SizedBox(height: 24),
..._actions(),
SizedBox(height: 16),
Row(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
localization.generatedAddresses,
style: theme.textTheme.titleLarge,
textAlign: TextAlign.start,
),
],
),
SizedBox(height: 8),
AddressList(
currentWallet: db.walletStorage.currentWallet,
),
SizedBox(height: 24),
],
));
}

Widget _buildAddressList() {
ApiDatabase db = Locator.instance.get<ApiDatabase>();
return AddressListView(
scrollController: scrollController,
currentWallet: db.walletStorage.currentWallet,
close: _hideAddressList);
}

BlocListener _dashboardBlocListener() {
return BlocListener<DashboardBloc, DashboardState>(
listener: (BuildContext context, DashboardState state) {
Expand All @@ -185,7 +234,9 @@ class ReceiveTransactionScreenState extends State<ReceiveTransactionScreen>
return BlocBuilder<DashboardBloc, DashboardState>(
builder: (BuildContext context, DashboardState state) {
return DashboardLayout(
dashboardChild: _buildReceiveTransactionScreen(),
dashboardChild: showAddressList
? _buildAddressList()
: _buildReceiveTransactionScreen(),
actions: [],
);
},
Expand Down
2 changes: 1 addition & 1 deletion lib/util/storage/database/wallet.dart
Original file line number Diff line number Diff line change
Expand Up @@ -118,7 +118,7 @@ class Wallet {

Map<int, Account> orderAccountsByIndex(Map<int, Account> accountMap) {
return Map.fromEntries(accountMap.entries.toList()
..sort((e1, e2) => e1.key.compareTo(e2.key)));
..sort((e1, e2) => e2.key.compareTo(e1.key)));
}

List<String> addressList(KeyType keyType) {
Expand Down
Loading
Loading