Skip to content

Commit

Permalink
Init work on adding wallet UI
Browse files Browse the repository at this point in the history
  • Loading branch information
AhmedHanafy725 committed Sep 17, 2024
1 parent ac1f9f4 commit aba01ef
Show file tree
Hide file tree
Showing 3 changed files with 188 additions and 1 deletion.
9 changes: 9 additions & 0 deletions app/lib/models/wallet.dart
Original file line number Diff line number Diff line change
Expand Up @@ -20,3 +20,12 @@ class Wallet {
String tfchainBalance;
final WalletType type;
}

class SimpleWallet {
SimpleWallet({
required this.name,
required this.secret,
});
final String name;
final String secret;
}
48 changes: 47 additions & 1 deletion app/lib/screens/wallet_screen.dart
Original file line number Diff line number Diff line change
@@ -1,9 +1,12 @@
import 'dart:ui';

import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:threebotlogin/helpers/globals.dart';
import 'package:threebotlogin/models/wallet.dart';
import 'package:threebotlogin/services/wallet_service.dart';
import 'package:threebotlogin/widgets/add_wallet.dart';
import 'package:threebotlogin/widgets/layout_drawer.dart';
import 'package:threebotlogin/widgets/wallet_card.dart';

Expand Down Expand Up @@ -50,7 +53,16 @@ class _WalletScreenState extends State<WalletScreen> {
);
}

return LayoutDrawer(titleText: 'Wallet', content: mainWidget);
return LayoutDrawer(
titleText: 'Wallet',
content: mainWidget,
appBarActions: [
IconButton(
// TODO: disable clicks till the wallets are loading.
onPressed: _openAddWalletOverlay,
icon: const Icon(Icons.add))
],
);
}

listMyWallets() async {
Expand All @@ -63,4 +75,38 @@ class _WalletScreenState extends State<WalletScreen> {
loading = false;
});
}

_openAddWalletOverlay() {
showModalBottomSheet(
isScrollControlled: true,
useSafeArea: true,
constraints: const BoxConstraints(maxWidth: double.infinity),
context: context,
builder: (ctx) => NewWallet(
onAddWallet: _addWallet,
));
}

Future<void> _addWallet(SimpleWallet wallet) async {
setState(() {
loading = true;
});

final w = await loadAddWallet(wallet.name, wallet.secret);
wallets.add(w);

setState(() {
loading = false;
});
}
}

Future<Wallet> loadAddWallet(String walletName, String walletSecret) async {
final chainUrl = Globals().chainUrl;
final Wallet wallet = await compute((void _) async {
final wallet = await loadWallet(
walletName, walletSecret, WalletType.Imported, chainUrl);
return wallet;
}, null);
return wallet;
}
132 changes: 132 additions & 0 deletions app/lib/widgets/add_wallet.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,132 @@
import 'package:bip39/bip39.dart';
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:threebotlogin/models/wallet.dart';
import 'package:threebotlogin/widgets/custom_dialog.dart';

class NewWallet extends StatefulWidget {
const NewWallet({
super.key,
required this.onAddWallet,
});
final Future<void> Function(SimpleWallet addedWallet) onAddWallet;

@override
State<StatefulWidget> createState() {
return _NewWalletState();
}
}

class _NewWalletState extends State<NewWallet> {
final _nameController = TextEditingController();
final _secretController = TextEditingController();

void _showDialog(String message) {
showDialog(
context: context,
builder: (BuildContext context) => CustomDialog(
image: Icons.error,
title: 'Invalid Input',
description: message,
actions: <Widget>[
TextButton(
child: const Text('Close'),
onPressed: () {
Navigator.pop(context);
setState(() {});
},
),
],
),
);
}

void _validateAddSubmitData() {
//TODO: validate name is not used
if (_nameController.text.trim().isEmpty) {
_showDialog("Name can't be empty");
return;
}
if (_secretController.text.trim().isEmpty) {
_showDialog("Secret can't be empty");
return;
}
if (!validateMnemonic(_secretController.text.trim())) {
_showDialog('Secret is invalid');
return;
}
// TODO: save the wallet to pkid

widget.onAddWallet(SimpleWallet(
name: _nameController.text.trim(),
secret: _secretController.text.trim()));
Navigator.pop(context);
}

@override
void dispose() {
_nameController.dispose();
_secretController.dispose();
super.dispose();
}

@override
Widget build(BuildContext context) {
final keyboardSpace = MediaQuery.of(context).viewInsets.bottom;
return LayoutBuilder(builder: (ctx, constraints) {
return SizedBox(
child: SingleChildScrollView(
child: Padding(
padding: EdgeInsets.fromLTRB(16, 16, 16, keyboardSpace + 16),
child: Column(
children: [
TextField(
style: Theme.of(context).textTheme.bodyMedium!.copyWith(
color: Theme.of(context).colorScheme.onBackground,
decorationColor:
Theme.of(context).colorScheme.onBackground),
maxLength: 50,
decoration: const InputDecoration(label: Text('Name')),
controller: _nameController,
),
TextField(
style: Theme.of(context).textTheme.bodyMedium!.copyWith(
color: Theme.of(context).colorScheme.onBackground,
decorationColor:
Theme.of(context).colorScheme.onBackground),
keyboardType: TextInputType.multiline,
maxLines: null,
decoration: const InputDecoration(
label: Text('Secret'),
),
controller: _secretController,
),
const SizedBox(
height: 30,
),
Row(
children: [
const Spacer(),
ElevatedButton(
onPressed: () {
Navigator.pop(context);
},
child: const Text('Cancel')),
const SizedBox(
width: 5,
),
ElevatedButton(
onPressed: _validateAddSubmitData,
child: const Text(
'Save')) //TODO: show loading when clicking on save
],
),
],
),
),
),
);
});
}
}

0 comments on commit aba01ef

Please sign in to comment.