Merge branch 'implementFigma'

This commit is contained in:
poka 2021-12-05 06:24:01 +01:00
commit 4bef232002
73 changed files with 6150 additions and 1585 deletions

Binary file not shown.

Before

Width:  |  Height:  |  Size: 6.9 KiB

After

Width:  |  Height:  |  Size: 6.8 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.9 KiB

After

Width:  |  Height:  |  Size: 5.0 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 6.0 KiB

After

Width:  |  Height:  |  Size: 5.6 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 6.9 KiB

After

Width:  |  Height:  |  Size: 6.6 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 6.1 KiB

After

Width:  |  Height:  |  Size: 5.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 6.3 KiB

After

Width:  |  Height:  |  Size: 5.7 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 6.1 KiB

After

Width:  |  Height:  |  Size: 5.4 KiB

BIN
assets/chests/secret_code.png Executable file → Normal file

Binary file not shown.

Before

Width:  |  Height:  |  Size: 6.6 KiB

After

Width:  |  Height:  |  Size: 7.6 KiB

BIN
assets/chests/vector.png Executable file → Normal file

Binary file not shown.

Before

Width:  |  Height:  |  Size: 331 B

After

Width:  |  Height:  |  Size: 6.9 KiB

BIN
assets/copy_key.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.9 KiB

BIN
assets/home/background.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 341 KiB

BIN
assets/home/background.png Executable file

Binary file not shown.

After

Width:  |  Height:  |  Size: 620 KiB

BIN
assets/home/bout_de_bulle.png Executable file

Binary file not shown.

After

Width:  |  Height:  |  Size: 630 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 124 KiB

BIN
assets/home/header.png Executable file

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.1 KiB

14
assets/home/header.svg Executable file

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 30 KiB

BIN
assets/home/loupe.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 42 KiB

1
assets/home/loupe.svg Executable file

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 57 KiB

BIN
assets/home/qrcode.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 11 KiB

BIN
assets/home/wallet.png Executable file

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.5 KiB

92
assets/home/wallet.svg Normal file
View File

@ -0,0 +1,92 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
version="1.1"
x="0px"
y="0px"
viewBox="0 0 100 125"
id="svg10"
sodipodi:docname="wallet.svg"
inkscape:version="0.92.5 (2060ec1f9f, 2020-04-08)">
<metadata
id="metadata16">
<rdf:RDF>
<cc:Work
rdf:about="">
<dc:format>image/svg+xml</dc:format>
<dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
<dc:title></dc:title>
</cc:Work>
</rdf:RDF>
</metadata>
<defs
id="defs14">
<clipPath
clipPathUnits="userSpaceOnUse"
id="clipPath138">
<rect
style="fill:#000000;fill-opacity:1"
id="rect140"
width="91.747101"
height="91.747101"
x="4.4194174"
y="957.15405" />
</clipPath>
</defs>
<sodipodi:namedview
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1"
objecttolerance="10"
gridtolerance="10"
guidetolerance="10"
inkscape:pageopacity="0"
inkscape:pageshadow="2"
inkscape:window-width="1920"
inkscape:window-height="1015"
id="namedview12"
showgrid="true"
inkscape:zoom="5.6568543"
inkscape:cx="35.337997"
inkscape:cy="80.718182"
inkscape:window-x="1920"
inkscape:window-y="0"
inkscape:window-maximized="1"
inkscape:current-layer="svg10" />
<g
transform="translate(0,-952.36218)"
id="g4"
clip-path="url(#clipPath138)"
inkscape:export-xdpi="96"
inkscape:export-ydpi="96"
style="fill:#ffffff">
<path
style="font-size:medium;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-indent:0;text-align:start;text-decoration:none;line-height:normal;letter-spacing:normal;word-spacing:normal;text-transform:none;direction:ltr;block-progression:tb;writing-mode:lr-tb;text-anchor:start;baseline-shift:baseline;opacity:1;color:#000000;fill:#ffffff;fill-opacity:1;stroke:none;stroke-width:4;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate;font-family:Sans;-inkscape-font-specification:Sans"
d="M 50.90625 6 A 2.0002 2.0002 0 0 0 49.84375 6.5 L 30.0625 24.46875 L 18.1875 24.46875 C 15.543683 24.44965 13.123155 25.17569 11.25 26.46875 C 9.3768448 27.76181 7.9999596 29.75493 8 32.09375 L 8.03125 86.625 C 8.03684 88.8921 9.3819629 90.8203 11.1875 92.0625 C 12.993037 93.3047 15.308353 94 17.84375 94 L 77.6875 94 C 80.644255 94 83.374448 92.089642 84.4375 89.25 C 86.113053 89.114967 87.744729 88.6459 89.125 87.6875 C 90.81563 86.5136 92 84.44345 92 82.03125 L 92 32.09375 C 92 30.15621 91.430591 28.26221 90.1875 26.8125 C 88.944409 25.36279 86.997793 24.47521 84.8125 24.46875 L 74.96875 24.4375 L 69.5 13.25 A 2.0002 2.0002 0 0 0 67.53125 12.125 A 2.0002 2.0002 0 0 0 66.78125 12.34375 L 60.46875 15.59375 L 52.71875 6.6875 A 2.0002 2.0002 0 0 0 50.90625 6 z M 51.03125 10.84375 L 56.8125 17.5 L 26.5 33.125 L 51.03125 10.84375 z M 66.8125 16.84375 L 75.1875 33.96875 L 33.5625 34 L 66.8125 16.84375 z M 76.9375 28.4375 L 84.8125 28.46875 C 86.009294 28.47275 86.654841 28.85275 87.15625 29.4375 C 87.657659 30.0223 88 30.92895 88 32.09375 L 88 50.1875 L 67.625 50.1875 C 65.302589 50.1875 63.593739 52.225 63.59375 54.4375 L 63.59375 64.5 C 63.593768 66.7125 65.302709 68.78125 67.625 68.78125 L 88 68.78125 L 88 82.03125 C 88 83.31875 87.603802 83.87855 86.84375 84.40625 C 86.37816 84.729568 85.69117 84.975519 84.90625 85.125 L 84.90625 73.5625 A 2.0002 2.0002 0 1 0 80.90625 73.5625 L 80.90625 86.625 C 80.90625 88.7156 79.289498 90 77.6875 90 L 17.84375 90 C 16.046389 90 14.457371 89.48295 13.4375 88.78125 C 12.417629 88.07965 12.033004 87.30545 12.03125 86.59375 L 12 36.84375 C 13.469144 37.606227 15.201391 38.000302 17.0625 38 L 78.5 37.96875 C 79.316994 37.96862 79.724605 38.2578 80.15625 38.84375 C 80.587895 39.4297 80.906252 40.37836 80.90625 41.34375 L 80.90625 44.53125 A 2.0002 2.0002 0 1 0 84.90625 44.53125 L 84.90625 41.34375 C 84.906254 39.6214 84.425391 37.89465 83.375 36.46875 C 82.541915 35.337841 81.241284 34.452882 79.71875 34.125 L 76.9375 28.4375 z M 18.15625 28.46875 A 2.0002 2.0002 0 0 0 18.1875 28.46875 L 25.6875 28.46875 L 19.59375 34 L 17.0625 34 C 15.604391 34.00024 14.294499 33.60485 13.4375 33.0625 C 12.580501 32.52015 12.218298 31.89481 12.15625 31.40625 A 2.0002 2.0002 0 0 0 12.15625 31.375 C 12.362153 30.832741 12.788717 30.262578 13.53125 29.75 C 14.615705 29.00139 16.267859 28.45508 18.15625 28.46875 z M 67.625 54.1875 L 88 54.1875 L 88 64.78125 L 67.65625 64.78125 C 67.655285 64.784472 67.64577 64.78125 67.625 64.78125 C 67.611788 64.759611 67.59375 64.685125 67.59375 64.5 L 67.59375 54.4375 C 67.593749 54.1412 67.708223 54.1875 67.625 54.1875 z M 71.5 55.6875 A 2.0002 2.0002 0 0 0 69.71875 57.71875 L 69.71875 61.25 A 2.0002 2.0002 0 1 0 73.71875 61.25 L 73.71875 57.71875 A 2.0002 2.0002 0 0 0 71.5 55.6875 z "
transform="translate(0,952.36218)"
id="path2" />
</g>
<text
x="0"
y="115"
fill="#000000"
font-size="5px"
font-weight="bold"
font-family="'Helvetica Neue', Helvetica, Arial-Unicode, Arial, Sans-serif"
id="text6">Created by counloucon</text>
<text
x="0"
y="120"
fill="#000000"
font-size="5px"
font-weight="bold"
font-family="'Helvetica Neue', Helvetica, Arial-Unicode, Arial, Sans-serif"
id="text8">from the Noun Project</text>
</svg>

After

Width:  |  Height:  |  Size: 5.7 KiB

BIN
assets/loupe-noire.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 27 KiB

BIN
assets/printer.png Executable file → Normal file

Binary file not shown.

Before

Width:  |  Height:  |  Size: 460 B

After

Width:  |  Height:  |  Size: 11 KiB

BIN
assets/vector_white.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 10 KiB

BIN
assets/walletOptions/android-checkmark.png Executable file → Normal file

Binary file not shown.

Before

Width:  |  Height:  |  Size: 264 B

After

Width:  |  Height:  |  Size: 11 KiB

BIN
assets/walletOptions/camera.png Executable file → Normal file

Binary file not shown.

Before

Width:  |  Height:  |  Size: 585 B

After

Width:  |  Height:  |  Size: 7.2 KiB

BIN
assets/walletOptions/clock.png Executable file → Normal file

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.0 KiB

After

Width:  |  Height:  |  Size: 19 KiB

BIN
assets/walletOptions/copy-white.png Executable file → Normal file

Binary file not shown.

Before

Width:  |  Height:  |  Size: 482 B

After

Width:  |  Height:  |  Size: 7.6 KiB

BIN
assets/walletOptions/edit.png Executable file → Normal file

Binary file not shown.

Before

Width:  |  Height:  |  Size: 284 B

After

Width:  |  Height:  |  Size: 11 KiB

BIN
assets/walletOptions/icon_oeuil.png Executable file → Normal file

Binary file not shown.

Before

Width:  |  Height:  |  Size: 719 B

After

Width:  |  Height:  |  Size: 7.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.9 KiB

After

Width:  |  Height:  |  Size: 8.8 KiB

BIN
assets/walletOptions/key.png Executable file → Normal file

Binary file not shown.

Before

Width:  |  Height:  |  Size: 492 B

After

Width:  |  Height:  |  Size: 4.7 KiB

BIN
assets/walletOptions/trash.png Executable file → Normal file

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.2 KiB

After

Width:  |  Height:  |  Size: 14 KiB

View File

@ -1,6 +1,7 @@
import 'dart:io';
import 'package:flutter/material.dart';
import 'package:gecko/models/chest_data.dart';
import 'package:gecko/models/g1_wallets_list.dart';
import 'package:gecko/models/wallet_data.dart';
import 'package:hive/hive.dart';
import 'package:logger/logger.dart';
@ -16,9 +17,10 @@ int ramSys;
Box<WalletData> walletBox;
Box<ChestData> chestBox;
Box configBox;
Box<G1WalletsList> g1WalletsBox;
// String cesiumPod = "https://g1.data.le-sou.org";
String cesiumPod = "https://g1.data.e-is.pro";
String cesiumPod = "https://g1.data.le-sou.org";
// String cesiumPod = "https://g1.data.e-is.pro";
// Responsive ratios
bool isTall;

View File

@ -23,16 +23,20 @@ import 'package:gecko/models/cesium_plus.dart';
import 'package:gecko/models/change_pin.dart';
import 'package:gecko/models/chest_data.dart';
import 'package:gecko/models/chest_provider.dart';
import 'package:gecko/models/g1_wallets_list.dart';
import 'package:gecko/models/generate_wallets.dart';
import 'package:gecko/models/history.dart';
import 'package:gecko/models/wallets_profiles.dart';
import 'package:gecko/models/home.dart';
import 'package:gecko/models/my_wallets.dart';
import 'package:gecko/models/search.dart';
import 'package:gecko/models/wallet_data.dart';
import 'package:gecko/models/wallet_options.dart';
import 'package:gecko/screens/home.dart';
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:gecko/screens/myWallets/wallets_home.dart';
import 'package:gecko/screens/search.dart';
import 'package:gecko/screens/search_result.dart';
import 'package:graphql_flutter/graphql_flutter.dart';
import 'package:hive_flutter/hive_flutter.dart';
import 'package:path_provider/path_provider.dart';
@ -41,17 +45,14 @@ import 'package:flutter/foundation.dart';
import 'package:responsive_framework/responsive_framework.dart';
import 'package:shared_preferences/shared_preferences.dart';
import 'package:sentry_flutter/sentry_flutter.dart';
import 'package:flutter_driver/driver_extension.dart';
const bool enableSentry = true;
Future<void> main() async {
enableFlutterDriverExtension();
WidgetsFlutterBinding.ensureInitialized();
HomeProvider _homeProvider = HomeProvider();
appPath = await getApplicationDocumentsDirectory();
await _homeProvider.createDefaultAvatar();
appVersion = await _homeProvider.getAppVersion();
prefs = await SharedPreferences.getInstance();
@ -59,15 +60,21 @@ Future<void> main() async {
await Hive.initFlutter(appPath.path);
Hive.registerAdapter(WalletDataAdapter());
Hive.registerAdapter(ChestDataAdapter());
Hive.registerAdapter(G1WalletsListAdapter());
Hive.registerAdapter(IdAdapter());
walletBox = await Hive.openBox<WalletData>("walletBox");
chestBox = await Hive.openBox<ChestData>("chestBox");
configBox = await Hive.openBox("configBox");
g1WalletsBox = await Hive.openBox<G1WalletsList>("g1WalletsBox");
g1WalletsBox.clear();
// final HiveStore _store =
// await HiveStore.open(path: '${appPath.path}/gqlCache');
// Get a valid GVA endpoint
endPointGVA = 'https://g1.librelois.fr/gva';
// endPointGVA = 'https://g1.librelois.fr/gva';
endPointGVA = 'https://duniter-g1.p2p.legal/gva';
// await _homeProvider.getValidEndpoint();
// if (endPointGVA == 'HS') {
@ -76,6 +83,8 @@ Future<void> main() async {
// _homeProvider.playSound('start', 0.2);
// }
HttpOverrides.global = MyHttpOverrides();
if (kReleaseMode && enableSentry) {
// CatcherOptions debugOptions = CatcherOptions(DialogReportMode(), [
// SentryHandler(SentryClient(SentryOptions(
@ -107,8 +116,6 @@ Future<void> main() async {
} else {
print('Debug mode enabled: No sentry alerte');
HttpOverrides.global = MyHttpOverrides();
runApp(Gecko(endPointGVA));
}
}
@ -134,54 +141,58 @@ class Gecko extends StatelessWidget {
// HistoryProvider _historyProvider = Provider.of<HistoryProvider>(context);
// HistoryProvider('').snackNode(context);
return MultiProvider(
providers: [
// Provider(create: (context) => HistoryProvider()),
ChangeNotifierProvider(create: (_) => HomeProvider()),
ChangeNotifierProvider(create: (_) => HistoryProvider('')),
ChangeNotifierProvider(create: (_) => MyWalletsProvider()),
ChangeNotifierProvider(create: (_) => ChestProvider()),
ChangeNotifierProvider(create: (_) => GenerateWalletsProvider()),
ChangeNotifierProvider(create: (_) => WalletOptionsProvider()),
ChangeNotifierProvider(create: (_) => ChangePinProvider()),
ChangeNotifierProvider(create: (_) => CesiumPlusProvider())
],
child: GraphQLProvider(
client: _client,
child: MaterialApp(
builder: (context, widget) => ResponsiveWrapper.builder(
BouncingScrollWrapper.builder(context, widget),
maxWidth: 1200,
minWidth: 480,
defaultScale: true,
breakpoints: [
const ResponsiveBreakpoint.resize(480, name: MOBILE),
const ResponsiveBreakpoint.autoScale(800, name: TABLET),
const ResponsiveBreakpoint.resize(1000, name: DESKTOP),
],
background: Container(color: backgroundColor)),
title: 'Ğecko',
theme: ThemeData(
appBarTheme: const AppBarTheme(
color: Color(0xffFFD58D),
foregroundColor: Color(0xFF000000),
),
primaryColor: const Color(0xffFFD58D),
textTheme: const TextTheme(
bodyText1: TextStyle(),
bodyText2: TextStyle(),
).apply(
bodyColor: const Color(0xFF000000),
),
colorScheme: ColorScheme.fromSwatch()
.copyWith(secondary: Colors.grey[850]),
providers: [
// Provider(create: (context) => HistoryProvider()),
ChangeNotifierProvider(create: (_) => HomeProvider()),
ChangeNotifierProvider(create: (_) => WalletsProfilesProvider('')),
ChangeNotifierProvider(create: (_) => MyWalletsProvider()),
ChangeNotifierProvider(create: (_) => ChestProvider()),
ChangeNotifierProvider(create: (_) => GenerateWalletsProvider()),
ChangeNotifierProvider(create: (_) => WalletOptionsProvider()),
ChangeNotifierProvider(create: (_) => ChangePinProvider()),
ChangeNotifierProvider(create: (_) => SearchProvider()),
ChangeNotifierProvider(create: (_) => CesiumPlusProvider())
],
child: GraphQLProvider(
client: _client,
child: MaterialApp(
builder: (context, widget) => ResponsiveWrapper.builder(
BouncingScrollWrapper.builder(context, widget),
maxWidth: 1200,
minWidth: 480,
defaultScale: true,
breakpoints: [
const ResponsiveBreakpoint.resize(480, name: MOBILE),
const ResponsiveBreakpoint.autoScale(800, name: TABLET),
const ResponsiveBreakpoint.resize(1000, name: DESKTOP),
],
background: Container(color: backgroundColor)),
title: 'Ğecko',
theme: ThemeData(
appBarTheme: const AppBarTheme(
color: Color(0xffFFD58D),
foregroundColor: Color(0xFF000000),
),
home: const HomeScreen(),
initialRoute: "/",
routes: {
'/mywallets': (context) => WalletsHome(),
},
primaryColor: const Color(0xffFFD58D),
textTheme: const TextTheme(
bodyText1: TextStyle(),
bodyText2: TextStyle(),
).apply(
bodyColor: const Color(0xFF000000),
),
colorScheme:
ColorScheme.fromSwatch().copyWith(secondary: Colors.grey[850]),
),
));
home: const HomeScreen(),
initialRoute: "/",
routes: {
'/mywallets': (context) => WalletsHome(),
'/search': (context) => const SearchScreen(),
'/searchResult': (context) => const SearchResultScreen(),
},
),
),
);
}
}

2050
lib/models/bip39_words.dart Normal file

File diff suppressed because it is too large Load Diff

View File

@ -1,15 +1,18 @@
import 'dart:convert';
import 'dart:io';
import 'package:dio/dio.dart';
import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
import 'package:gecko/globals.dart';
import 'package:http/http.dart' as http;
import 'package:path_provider/path_provider.dart';
// import 'package:http/http.dart' as http;
class CesiumPlusProvider with ChangeNotifier {
TextEditingController cesiumName = TextEditingController();
int iAvatar = 0;
bool isComplete = false;
Image defaultAvatar(double size) =>
Image.asset(('assets/icon_user.png'), height: size);
CancelToken avatarCancelToken = CancelToken();
Future<List> _buildQuery(_pubkey) async {
var queryGetAvatar = json.encode({
@ -61,45 +64,95 @@ class CesiumPlusProvider with ChangeNotifier {
Future<String> getName(String _pubkey) async {
String _name;
if (g1WalletsBox.get(_pubkey).csName != null) {
return g1WalletsBox.get(_pubkey).csName;
}
List queryOptions = await _buildQuery(_pubkey);
final response = await http.post((Uri.parse(queryOptions[0])),
body: queryOptions[1], headers: queryOptions[2]);
final responseJson = json.decode(response.body);
if (responseJson['hits']['hits'].toString() == '[]') {
var dio = Dio();
Response response;
try {
response = await dio.post(
queryOptions[0],
data: queryOptions[1],
options: Options(
headers: queryOptions[2],
sendTimeout: 3000,
receiveTimeout: 5000,
),
);
// response = await http.post((Uri.parse(queryOptions[0])),
// body: queryOptions[1], headers: queryOptions[2]);
} catch (e) {
log.e(e);
}
if (response.data['hits']['hits'].toString() == '[]') {
return '';
}
final bool _nameExist =
responseJson['hits']['hits'][0]['_source'].containsKey("title");
response.data['hits']['hits'][0]['_source'].containsKey("title");
if (!_nameExist) {
return '';
}
_name = responseJson['hits']['hits'][0]['_source']['title'];
_name = response.data['hits']['hits'][0]['_source']['title'];
g1WalletsBox.get(_pubkey).csName = _name;
return _name;
}
Future<List> getAvatar(String _pubkey) async {
Future<Image> getAvatar(String _pubkey, double size) async {
if (g1WalletsBox.get(_pubkey).avatar != null) {
return g1WalletsBox.get(_pubkey).avatar;
}
var dio = Dio();
// log.d(_pubkey);
List queryOptions = await _buildQuery(_pubkey);
final response = await http.post((Uri.parse(queryOptions[0])),
body: queryOptions[1], headers: queryOptions[2]);
final responseJson = json.decode(response.body);
if (responseJson['hits']['hits'].toString() == '[]') {
return [File(appPath.path + '/default_avatar.png')];
Response response;
try {
response = await dio
.post(queryOptions[0],
data: queryOptions[1],
options: Options(
headers: queryOptions[2],
sendTimeout: 4000,
receiveTimeout: 15000,
),
cancelToken: avatarCancelToken)
.timeout(
const Duration(seconds: 15),
);
// response = await http.post((Uri.parse(queryOptions[0])),
// body: queryOptions[1], headers: queryOptions[2]);
} catch (e) {
log.e(e);
}
final bool avatarExist =
responseJson['hits']['hits'][0]['_source'].containsKey("avatar");
if (!avatarExist) {
return [File(appPath.path + '/default_avatar.png')];
if (response.data['hits']['hits'].toString() == '[]' ||
!response.data['hits']['hits'][0]['_source'].containsKey("avatar")) {
return defaultAvatar(size);
}
final _avatar =
responseJson['hits']['hits'][0]['_source']['avatar']['_content'];
response.data['hits']['hits'][0]['_source']['avatar']['_content'];
var avatarFile =
File('${(await getTemporaryDirectory()).path}/avatar$iAvatar.png');
File('${(await getTemporaryDirectory()).path}/avatar_$_pubkey.png');
await avatarFile.writeAsBytes(base64.decode(_avatar));
iAvatar++;
isComplete = true;
return [avatarFile];
final finalAvatar = Image.file(
avatarFile,
height: size,
fit: BoxFit.fitWidth,
);
g1WalletsBox.get(_pubkey).avatar = finalAvatar;
return finalAvatar;
}
}

View File

@ -0,0 +1,74 @@
import 'package:flutter/material.dart';
import 'package:hive_flutter/hive_flutter.dart';
part 'g1_wallets_list.g.dart';
@HiveType(typeId: 2)
class G1WalletsList {
@HiveField(0)
String pubkey;
@HiveField(1)
double balance;
@HiveField(3)
Id id;
@HiveField(4)
Image avatar;
@HiveField(5)
String username;
@HiveField(6)
String csName;
@HiveField(7)
bool isMembre;
G1WalletsList({
this.pubkey,
this.balance,
this.id,
this.avatar,
this.username,
this.csName,
this.isMembre,
});
G1WalletsList.fromJson(Map<String, dynamic> json) {
pubkey = json['pubkey'];
balance = json['balance'];
id = json['id'] != null ? Id.fromJson(json['id']) : null;
}
Map<String, dynamic> toJson() {
final Map<String, dynamic> data = <String, dynamic>{};
data['pubkey'] = pubkey;
data['balance'] = balance;
if (id != null) {
data['id'] = id.toJson();
}
return data;
}
}
@HiveType(typeId: 3)
class Id {
bool isMember;
String username;
Id({this.isMember, this.username});
Id.fromJson(Map<String, dynamic> json) {
isMember = json['isMember'];
username = json['username'];
}
Map<String, dynamic> toJson() {
final Map<String, dynamic> data = <String, dynamic>{};
data['isMember'] = isMember;
data['username'] = username;
return data;
}
}

View File

@ -0,0 +1,90 @@
// GENERATED CODE - DO NOT MODIFY BY HAND
// ignore_for_file: unused_local_variable
part of 'g1_wallets_list.dart';
// **************************************************************************
// TypeAdapterGenerator
// **************************************************************************
class G1WalletsListAdapter extends TypeAdapter<G1WalletsList> {
@override
final int typeId = 2;
@override
G1WalletsList read(BinaryReader reader) {
final numOfFields = reader.readByte();
final fields = <int, dynamic>{
for (int i = 0; i < numOfFields; i++) reader.readByte(): reader.read(),
};
return G1WalletsList(
pubkey: fields[0] as String,
balance: fields[1] as double,
id: fields[3] as Id,
avatar: fields[4] as Image,
username: fields[5] as String,
csName: fields[6] as String,
isMembre: fields[7] as bool,
);
}
@override
void write(BinaryWriter writer, G1WalletsList obj) {
writer
..writeByte(7)
..writeByte(0)
..write(obj.pubkey)
..writeByte(1)
..write(obj.balance)
..writeByte(3)
..write(obj.id)
..writeByte(4)
..write(obj.avatar)
..writeByte(5)
..write(obj.username)
..writeByte(6)
..write(obj.csName)
..writeByte(7)
..write(obj.isMembre);
}
@override
int get hashCode => typeId.hashCode;
@override
bool operator ==(Object other) =>
identical(this, other) ||
other is G1WalletsListAdapter &&
runtimeType == other.runtimeType &&
typeId == other.typeId;
}
class IdAdapter extends TypeAdapter<Id> {
@override
final int typeId = 3;
@override
Id read(BinaryReader reader) {
final numOfFields = reader.readByte();
final fields = <int, dynamic>{
for (int i = 0; i < numOfFields; i++) reader.readByte(): reader.read(),
};
return Id();
}
@override
void write(BinaryWriter writer, Id obj) {
writer.writeByte(0);
}
@override
int get hashCode => typeId.hashCode;
@override
bool operator ==(Object other) =>
identical(this, other) ||
other is IdAdapter &&
runtimeType == other.runtimeType &&
typeId == other.typeId;
}

View File

@ -5,6 +5,7 @@ import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:gecko/globals.dart';
import 'package:gecko/models/bip39_words.dart';
import 'package:gecko/models/chest_data.dart';
import 'package:gecko/models/wallet_data.dart';
import 'package:pdf/pdf.dart';
@ -39,6 +40,21 @@ class GenerateWalletsProvider with ChangeNotifier {
bool canImport = false;
bool isPinChanged = false;
// Import Chest
TextEditingController cellController0 = TextEditingController();
TextEditingController cellController1 = TextEditingController();
TextEditingController cellController2 = TextEditingController();
TextEditingController cellController3 = TextEditingController();
TextEditingController cellController4 = TextEditingController();
TextEditingController cellController5 = TextEditingController();
TextEditingController cellController6 = TextEditingController();
TextEditingController cellController7 = TextEditingController();
TextEditingController cellController8 = TextEditingController();
TextEditingController cellController9 = TextEditingController();
TextEditingController cellController10 = TextEditingController();
TextEditingController cellController11 = TextEditingController();
bool isFirstTimeSentenceComplete = true;
Future storeHDWChest(
NewWallet _wallet, String _name, BuildContext context) async {
int chestNumber = 0;
@ -140,7 +156,7 @@ class GenerateWalletsProvider with ChangeNotifier {
Future<String> generateMnemonic() async {
try {
generatedMnemonic = await DubpRust.genMnemonic(language: Language.french);
actualWallet = await generateWallet(generatedMnemonic);
actualWallet = await generateWallet(generatedMnemonic, isImport: false);
walletIsGenerated = true;
} catch (e) {
log.e(e);
@ -148,7 +164,8 @@ class GenerateWalletsProvider with ChangeNotifier {
return generatedMnemonic;
}
Future<NewWallet> generateWallet(generatedMnemonic) async {
Future<NewWallet> generateWallet(String generatedMnemonic,
{@required bool isImport}) async {
try {
actualWallet = await DubpRust.genWalletFromMnemonic(
language: Language.french,
@ -159,8 +176,10 @@ class GenerateWalletsProvider with ChangeNotifier {
log.e(e);
}
mnemonicController.text = generatedMnemonic;
pin.text = actualWallet.pin;
if (!isImport) {
mnemonicController.text = generatedMnemonic;
pin.text = actualWallet.pin;
}
// notifyListeners();
return actualWallet;
@ -288,15 +307,9 @@ class GenerateWalletsProvider with ChangeNotifier {
notifyListeners();
}
void resetImportView() {
cesiumID.text = '';
cesiumPWD.text = '';
cesiumPubkey.text = '';
pin.text = '';
canImport = false;
isPinChanged = false;
isCesiumIDVisible = false;
isCesiumPWDVisible = false;
void resetCesiumImportView() {
cesiumID.text = cesiumPWD.text = cesiumPubkey.text = pin.text = '';
canImport = isPinChanged = isCesiumIDVisible = isCesiumPWDVisible = false;
actualWallet = null;
notifyListeners();
}
@ -315,6 +328,83 @@ class GenerateWalletsProvider with ChangeNotifier {
return _wordsList;
}
bool isBipWord(String word) {
notifyListeners();
// Needed for bad encoding of UTF-8
word = word.replaceAll('é', '');
word = word.replaceAll('è', '');
return bip39Words.contains(word);
}
bool isBipWordsList(List words) {
bool isValid = true;
for (String word in words) {
// Needed for bad encoding of UTF-8
word = word.replaceAll('é', '');
word = word.replaceAll('è', '');
if (!bip39Words.contains(word)) {
isValid = false;
}
}
return isValid;
}
void resetImportView() {
cellController0.text = cellController1.text = cellController2.text =
cellController3.text = cellController4.text = cellController5.text =
cellController6.text = cellController7.text = cellController8.text =
cellController9.text =
cellController10.text = cellController11.text = '';
isFirstTimeSentenceComplete = true;
notifyListeners();
}
bool isSentenceComplete(BuildContext context) {
if (isBipWordsList(
[
cellController0.text,
cellController1.text,
cellController2.text,
cellController3.text,
cellController4.text,
cellController5.text,
cellController6.text,
cellController7.text,
cellController8.text,
cellController9.text,
cellController10.text,
cellController11.text
],
)) {
if (isFirstTimeSentenceComplete) {
FocusScope.of(context).unfocus();
}
isFirstTimeSentenceComplete = false;
return true;
} else {
return false;
}
}
Future<bool> isSentenceValid() async {
String inputMnemonic =
'${cellController0.text} ${cellController1.text} ${cellController2.text} ${cellController3.text} ${cellController4.text} ${cellController5.text} ${cellController6.text} ${cellController7.text} ${cellController8.text} ${cellController9.text} ${cellController10.text} ${cellController11.text}';
// Needed for bad encoding of UTF-8
inputMnemonic = inputMnemonic.replaceAll('é', '');
inputMnemonic = inputMnemonic.replaceAll('è', '');
NewWallet generatedWallet =
await generateWallet(inputMnemonic, isImport: true);
if (generatedWallet == null) {
return false;
} else {
return true;
}
}
void reloadBuild() {
notifyListeners();
}

View File

@ -8,7 +8,7 @@ import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'dart:async';
import 'package:gecko/globals.dart';
import 'package:gecko/screens/history.dart';
import 'package:gecko/screens/old_history_pay.dart';
import 'package:gecko/screens/myWallets/wallets_home.dart';
import 'package:package_info/package_info.dart';
@ -21,7 +21,8 @@ class HomeProvider with ChangeNotifier {
Widget appBarExplorer =
Text('Explorateur', style: TextStyle(color: Colors.grey[850]));
List currentTab = [HistoryScreen(), WalletsHome()];
List currentTab = [OldHistoryScreen(), WalletsHome()];
bool isFirstBuild = true;
// AudioCache player = AudioCache(prefix: 'sounds/');
get currentIndex => _currentIndex;
@ -99,16 +100,6 @@ class HomeProvider with ChangeNotifier {
return _endpoint;
}
Future createDefaultAvatar() async {
File defaultAvatar = File(appPath.path + '/default_avatar.png');
final bool isAvatarExist = await defaultAvatar.exists();
if (!isAvatarExist) {
final byteData = await rootBundle.load('assets/icon_user.png');
await defaultAvatar.writeAsBytes(byteData.buffer
.asUint8List(byteData.offsetInBytes, byteData.lengthInBytes));
}
}
T getRandomElement<T>(List<T> list) {
final random = Random();
var i = random.nextInt(list.length);
@ -139,6 +130,22 @@ class HomeProvider with ChangeNotifier {
notifyListeners();
}
void snackNode(context) {
if (isFirstBuild) {
String _message;
if (endPointGVA == 'HS') {
_message =
"Aucun noeud Duniter disponible, veuillez réessayer ultérieurement";
} else {
_message = "Vous êtes connecté au noeud\n${endPointGVA.split('/')[2]}";
}
final snackBar = SnackBar(
content: Text(_message), duration: const Duration(seconds: 2));
isFirstBuild = false;
ScaffoldMessenger.of(context).showSnackBar(snackBar);
}
}
void rebuildWidget() {
notifyListeners();
}

View File

@ -71,8 +71,13 @@ class MyWalletsProvider with ChangeNotifier {
await walletBox.clear();
await chestBox.clear();
await configBox.delete('defaultWallet');
// await Future.delayed(const Duration(milliseconds: 50));
// notifyListeners();
Navigator.pop(context);
await Navigator.of(context).pushNamedAndRemoveUntil(
'/',
ModalRoute.withName('/'),
);
}
return 0;
} catch (e) {

View File

@ -29,14 +29,12 @@ const String getHistory = r'''
issuers
comment
outputs
writtenTime
}
sending {
currency
issuers
comment
outputs
writtenTime
}
}
currentUd {
@ -62,3 +60,36 @@ const String getBalance = r'''
}
}
''';
const String getWallets = r'''
query ($number: Int!, $cursor: String) {
wallets(pagination: {ord: ASC, pageSize: $number, cursor: $cursor}) {
pageInfo {
hasNextPage
endCursor
}
edges {
node {
script
balance {
amount
base
}
idty {
isMember
username
}
}
}
}
}
''';
const String getId = r'''
query ($pubkey: PubKeyGva!) {
idty(pubkey: $pubkey) {
isMember
username
}
}
''';

80
lib/models/search.dart Normal file
View File

@ -0,0 +1,80 @@
import 'package:dio/dio.dart';
import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
import 'package:gecko/globals.dart';
import 'package:gecko/models/g1_wallets_list.dart';
import 'package:gecko/models/wallets_profiles.dart';
class SearchProvider with ChangeNotifier {
TextEditingController searchController = TextEditingController();
List searchResult = [];
final cacheDuring = 20 * 60 * 1000; //First number is minutes
int cacheTime = 0;
void rebuildWidget() {
notifyListeners();
}
Future<List> searchBlockchain() async {
searchResult.clear();
int searchTime = DateTime.now().millisecondsSinceEpoch;
WalletsProfilesProvider _walletProfiles = WalletsProfilesProvider('pubkey');
if (cacheTime + cacheDuring <= searchTime) {
g1WalletsBox.clear();
// final url = Uri.parse('https://g1-stats.axiom-team.fr/data/forbes.json');
// final response = await http.get(url);
var dio = Dio();
Response response;
try {
response = await dio.get(
'https://g1-stats.axiom-team.fr/data/forbes.json',
options: Options(
sendTimeout: 5000,
receiveTimeout: 10000,
),
);
// response = await http.post((Uri.parse(queryOptions[0])),
// body: queryOptions[1], headers: queryOptions[2]);
} catch (e) {
log.e(e);
}
List<G1WalletsList> _listWallets = _parseG1Wallets(response.data);
Map<String, G1WalletsList> _mapWallets = {
for (var e in _listWallets) e.pubkey: e
};
await g1WalletsBox.putAll(_mapWallets);
cacheTime = DateTime.now().millisecondsSinceEpoch;
}
g1WalletsBox.toMap().forEach((key, value) {
if ((value.id != null &&
value.id.username != null &&
value.id.username
.toLowerCase()
.contains(searchController.text)) ||
value.pubkey.contains(searchController.text)) {
searchResult.add(value);
return;
}
});
if (searchResult.isEmpty &&
_walletProfiles.isPubkey(searchController.text)) {
searchResult = [G1WalletsList(pubkey: searchController.text)];
}
return searchResult;
}
}
List<G1WalletsList> _parseG1Wallets(var responseBody) {
final parsed = responseBody.cast<Map<String, dynamic>>();
return parsed
.map<G1WalletsList>((json) => G1WalletsList.fromJson(json))
.toList();
}

View File

@ -2,14 +2,12 @@ import 'package:dubp/dubp.dart';
import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
import 'package:gecko/globals.dart';
import 'package:gecko/models/home.dart';
import 'package:gecko/models/my_wallets.dart';
import 'package:gecko/models/wallet_data.dart';
import 'package:gecko/screens/history.dart';
import 'package:gecko/screens/wallet_view.dart';
import 'package:graphql_flutter/graphql_flutter.dart';
import 'package:jdenticon_dart/jdenticon_dart.dart';
import 'package:permission_handler/permission_handler.dart';
import 'package:provider/provider.dart';
import 'package:qrscan/qrscan.dart' as scanner;
import 'dart:math';
import 'package:intl/intl.dart';
@ -17,13 +15,13 @@ import 'package:truncate/truncate.dart';
import 'package:crypto/crypto.dart';
import 'package:fast_base58/fast_base58.dart';
class HistoryProvider with ChangeNotifier {
class WalletsProfilesProvider with ChangeNotifier {
WalletsProfilesProvider(this.pubkey);
String pubkey = '';
String pubkeyShort = '';
HistoryProvider(this.pubkey);
final TextEditingController outputPubkey = TextEditingController();
List transBC;
bool isFirstBuild = true;
String fetchMoreCursor;
Map pageInfo;
bool isHistoryScreen = false;
@ -31,6 +29,9 @@ class HistoryProvider with ChangeNotifier {
String rawSvg;
TextEditingController payAmount = TextEditingController();
TextEditingController payComment = TextEditingController();
num balance;
int nRepositories = 20;
int nPage = 1;
Future scan(context) async {
await Permission.camera.request();
@ -41,9 +42,14 @@ class HistoryProvider with ChangeNotifier {
log.e(e);
return 'false';
}
if (barcode != null) {
if (barcode != null && isPubkey(barcode)) {
outputPubkey.text = barcode;
isPubkey(context, barcode);
Navigator.push(
context,
MaterialPageRoute(builder: (context) {
return WalletViewScreen(pubkey: pubkey);
}),
);
} else {
return 'false';
}
@ -56,10 +62,17 @@ class HistoryProvider with ChangeNotifier {
WalletData defaultWallet = _myWalletModel.getDefaultWallet(currentChest);
String dewif = chestBox.get(currentChest).dewif;
int derivation;
if (chestBox.get(currentChest).isCesium) {
derivation = 0;
} else {
derivation = defaultWallet.derivation;
}
try {
await DubpRust.simplePaymentFromTransparentAccount(
accountIndex: defaultWallet.derivation,
accountIndex: derivation,
amount: double.parse(payAmount.text),
txComment: payComment.text,
dewif: dewif,
@ -74,9 +87,7 @@ class HistoryProvider with ChangeNotifier {
}
}
String isPubkey(context, pubkey, {bool goHistory}) {
HomeProvider _homeProvider =
Provider.of<HomeProvider>(context, listen: false);
bool isPubkey(pubkey) {
final RegExp regExp = RegExp(
r'^[a-zA-Z0-9]+$',
caseSensitive: false,
@ -86,36 +97,25 @@ class HistoryProvider with ChangeNotifier {
if (regExp.hasMatch(pubkey) == true &&
pubkey.length > 42 &&
pubkey.length < 45) {
log.d("C'est une pubkey !!!");
log.d("C'est une pubkey !");
this.pubkey = pubkey;
getShortPubkey(pubkey);
// getShortPubkey(pubkey);
outputPubkey.text = pubkey;
// outputPubkey.text = pubkey;
goHistory ??= false;
// Navigator.push(
// context,
// MaterialPageRoute(builder: (context) {
// return const WalletViewScreen();
// }),
// );
// notifyListeners();
if (goHistory) {
isHistoryScreen = true;
historySwitchButtun = "Payer";
} else {
isHistoryScreen = false;
historySwitchButtun = "Voir l'historique";
}
_homeProvider.handleSearchEnd();
Navigator.push(
context,
MaterialPageRoute(builder: (context) {
return HistoryScreen();
}),
);
notifyListeners();
return pubkey;
return true;
} else {
return false;
}
return '';
}
String getShortPubkey(String pubkey) {
@ -200,13 +200,25 @@ class HistoryProvider with ChangeNotifier {
FetchMoreOptions checkQueryResult(result, opts, _pubkey) {
final List<dynamic> blockchainTX =
(result.data['txsHistoryBc']['both']['edges'] as List<dynamic>);
// final List<dynamic> mempoolTX =
// (result.data['txsHistoryMp']['receiving'] as List<dynamic>);
pageInfo = result.data['txsHistoryBc']['both']['pageInfo'];
fetchMoreCursor = pageInfo['endCursor'];
if (fetchMoreCursor == null) nPage = 1;
if (nPage == 1) {
nRepositories = 40;
} else if (nPage == 2) {
nRepositories = 100;
}
log.d(nPage);
log.d(nRepositories);
nPage++;
if (fetchMoreCursor != null) {
opts = FetchMoreOptions(
variables: {'cursor': fetchMoreCursor},
variables: {'cursor': fetchMoreCursor, 'number': nRepositories},
updateQuery: (previousResultData, fetchMoreResultData) {
final List<dynamic> repos = [
...previousResultData['txsHistoryBc']['both']['edges']
@ -232,22 +244,6 @@ class HistoryProvider with ChangeNotifier {
return opts;
}
void snackNode(context) {
if (isFirstBuild) {
String _message;
if (endPointGVA == 'HS') {
_message =
"Aucun noeud Duniter disponible, veuillez réessayer ultérieurement";
} else {
_message = "Vous êtes connecté au noeud\n${endPointGVA.split('/')[2]}";
}
final snackBar = SnackBar(
content: Text(_message), duration: const Duration(seconds: 2));
isFirstBuild = false;
ScaffoldMessenger.of(context).showSnackBar(snackBar);
}
}
void resetdHistory() {
outputPubkey.text = '';
notifyListeners();
@ -260,6 +256,7 @@ class HistoryProvider with ChangeNotifier {
snackCopyKey(context) {
const snackBar = SnackBar(
padding: EdgeInsets.all(20),
content:
Text("Cette clé publique a été copié dans votre presse-papier."),
duration: Duration(seconds: 2));
@ -279,4 +276,27 @@ class HistoryProvider with ChangeNotifier {
String generateIdenticon(String _pubkey) {
return Jdenticon.toSvg(_pubkey);
}
// Future<num> getBalance(String _pubkey) async {
// final url = Uri.parse(
// '$endPointGVA?query={%20balance(script:%20%22$_pubkey%22)%20{%20amount%20base%20}%20}');
// final response = await http.get(url);
// final result = json.decode(response.body);
// if (result['data']['balance'] == null) {
// balance = 0.0;
// } else {
// balance = removeDecimalZero(result['data']['balance']['amount'] / 100);
// }
// return balance;
// }
Future<num> getBalance(String _pubkey) async {
while (balance == null) {
await Future.delayed(const Duration(milliseconds: 50));
}
return balance;
}
}

View File

@ -0,0 +1,54 @@
import 'package:flutter/services.dart';
import 'package:gecko/globals.dart';
import 'package:flutter/material.dart';
// import 'package:gecko/models/home.dart';
// import 'package:provider/provider.dart';
// ignore: must_be_immutable
class AvatarFullscreen extends StatelessWidget {
TextEditingController tplController = TextEditingController();
AvatarFullscreen(this.avatar, {this.title, this.color, Key key})
: super(key: key);
final Image avatar;
final String title;
final Color color;
@override
Widget build(BuildContext context) {
SystemChrome.setPreferredOrientations([DeviceOrientation.portraitUp]);
// HomeProvider _homeProvider = Provider.of<HomeProvider>(context);
return Scaffold(
appBar: AppBar(
elevation: 0,
backgroundColor: color ?? Colors.black,
toolbarHeight: 60 * ratio,
leading: IconButton(
icon: Icon(Icons.arrow_back, color: orangeC),
onPressed: () {
Navigator.pop(context);
}),
title: SizedBox(
height: 22,
child: Text(
title ?? 'Photo de profil',
style: TextStyle(color: orangeC),
),
)),
body: SafeArea(
child: SizedBox.expand(
child: Container(
color: color ?? Colors.black,
// alignment: Alignment.center,
// height: MediaQuery.of(context).size.height,
// width: MediaQuery.of(context).size.width,
child: Image(
image: avatar.image,
height: avatar.height,
fit: BoxFit.fitWidth),
),
),
),
);
}
}

View File

@ -34,14 +34,15 @@ class CommonElements {
margin: const BubbleEdges.fromLTRB(10, 0, 20, 10),
// nip: BubbleNip.leftTop,
child: RichText(
key: textKey,
text: TextSpan(
style: const TextStyle(
fontSize: 18.0,
color: Colors.black,
),
children: text,
)),
key: textKey,
text: TextSpan(
style: const TextStyle(
fontSize: 18.0,
color: Colors.black,
),
children: text,
),
),
);
}

View File

@ -1,124 +1,64 @@
import 'dart:io';
import 'package:flutter/services.dart';
import 'package:gecko/globals.dart';
import 'package:gecko/models/cesium_plus.dart';
import 'package:gecko/models/home.dart';
import 'package:gecko/models/my_wallets.dart';
import 'package:gecko/models/queries.dart';
import 'package:gecko/models/history.dart';
import 'package:gecko/models/wallets_profiles.dart';
import 'package:flutter/material.dart';
import 'package:flutter/foundation.dart';
import 'package:gecko/models/wallet_data.dart';
import 'package:gecko/screens/myWallets/unlocking_wallet.dart';
import 'package:gecko/screens/avatar_fullscreen.dart';
import 'package:gecko/screens/wallet_view.dart';
import 'dart:ui';
import 'package:graphql_flutter/graphql_flutter.dart';
import 'package:intl/intl.dart';
import 'package:provider/provider.dart';
import 'package:flutter_svg/flutter_svg.dart';
// ignore: must_be_immutable
class HistoryScreen extends StatelessWidget with ChangeNotifier {
final TextEditingController _outputPubkey = TextEditingController();
ScrollController scrollController = ScrollController();
final nRepositories = 20;
// HistoryProvider _historyProvider;
final _formKey = GlobalKey<FormState>();
final FocusNode _pubkeyFocus = FocusNode();
List cesiumData;
HistoryScreen({@required this.pubkey, this.avatar, this.username, Key key})
: super(key: key);
final ScrollController scrollController = ScrollController();
final double avatarsSize = 80;
final String pubkey;
final String username;
final Image avatar;
FetchMore fetchMore;
FetchMoreOptions opts;
final GlobalKey<ScaffoldState> _scaffoldKey = GlobalKey<ScaffoldState>();
HistoryScreen({Key key}) : super(key: key);
final GlobalKey<ScaffoldState> _scaffoldKey = GlobalKey<ScaffoldState>();
@override
Widget build(BuildContext context) {
SystemChrome.setPreferredOrientations([DeviceOrientation.portraitUp]);
HistoryProvider _historyProvider = Provider.of<HistoryProvider>(context);
HomeProvider _homeProvider = Provider.of<HomeProvider>(context);
_outputPubkey.text = _historyProvider.pubkey;
log.i('Build pubkey : ' + _historyProvider.pubkey);
WalletsProfilesProvider _historyProvider =
Provider.of<WalletsProfilesProvider>(context, listen: false);
CesiumPlusProvider _cesiumPlusProvider =
Provider.of<CesiumPlusProvider>(context, listen: false);
log.i('Build pubkey : ' + pubkey);
WidgetsBinding.instance.addPostFrameCallback((_) {});
_historyProvider.balance = _historyProvider.transBC = null;
return Scaffold(
key: _scaffoldKey,
appBar: AppBar(
elevation: 0,
toolbarHeight: 60 * ratio,
title: _homeProvider.appBarExplorer,
actions: [
Padding(
padding: const EdgeInsets.symmetric(horizontal: 16),
child: IconButton(
icon: _homeProvider.searchIcon,
color: Colors.grey[850],
onPressed: () {
if (_homeProvider.searchIcon.icon == Icons.search) {
_homeProvider.searchIcon = Icon(
Icons.close,
color: Colors.grey[850],
);
_homeProvider.appBarExplorer = TextField(
autofocus: true,
controller: _homeProvider.searchQuery,
onChanged: (text) {
log.d("Clé tappé: $text");
final String searchResult =
_historyProvider.isPubkey(context, text);
if (searchResult != '') {
_homeProvider.currentIndex = 0;
}
},
style: TextStyle(
color: Colors.grey[850],
),
decoration: InputDecoration(
prefixIcon:
Icon(Icons.search, color: Colors.grey[850]),
hintText: "Rechercher ...",
hintStyle: TextStyle(color: Colors.grey[850])),
);
_homeProvider.handleSearchStart();
} else {
_homeProvider.handleSearchEnd();
}
}))
],
backgroundColor: const Color(0xffFFD58D),
),
floatingActionButton: SizedBox(
height: 80.0,
width: 80.0,
child: FittedBox(
child: FloatingActionButton(
heroTag: "buttonScan",
onPressed: () async {
await _historyProvider.scan(context);
},
child: SizedBox(
height: 40.0,
width: 40.0,
child: Padding(
padding: const EdgeInsets.symmetric(horizontal: 3),
child: Image.asset('assets/qrcode-scan.png'))),
backgroundColor:
floattingYellow, //smoothYellow, //Color.fromARGB(500, 204, 255, 255),
),
title: const SizedBox(
height: 22,
child: Text('Historique des transactions'),
),
),
body: Column(children: <Widget>[
const SizedBox(height: 0),
if (_historyProvider.pubkey != '')
historyQuery(context, _historyProvider),
headerProfileView(context, _historyProvider, _cesiumPlusProvider),
historyQuery(context, _cesiumPlusProvider),
]));
}
Widget historyQuery(context, HistoryProvider _historyProvider) {
_pubkeyFocus.unfocus();
// HistoryProvider _historyProvider = Provider.of<HistoryProvider>(context);
CesiumPlusProvider _cesiumPlusProvider =
Provider.of<CesiumPlusProvider>(context);
bool _isFirstExec = true;
Widget historyQuery(context, CesiumPlusProvider _cesiumPlusProvider) {
WalletsProfilesProvider _historyProvider =
Provider.of<WalletsProfilesProvider>(context, listen: true);
return Expanded(
child: Column(
mainAxisAlignment: MainAxisAlignment.start,
@ -128,8 +68,8 @@ class HistoryScreen extends StatelessWidget with ChangeNotifier {
options: QueryOptions(
document: gql(getHistory),
variables: <String, dynamic>{
'pubkey': _historyProvider.pubkey,
'number': nRepositories,
'pubkey': pubkey,
'number': 10,
'cursor': null
},
),
@ -146,182 +86,47 @@ class HistoryScreen extends StatelessWidget with ChangeNotifier {
SizedBox(height: 50),
Text(
"Aucun noeud GVA valide n'a pu être trouvé.\nVeuillez réessayer ultérieurement.",
style: TextStyle(fontSize: 17.0),
style: TextStyle(fontSize: 18),
)
]);
} else if (result.data == null) {
return Column(children: const <Widget>[
SizedBox(height: 50),
Text(
"Aucune donnée à afficher.",
style: TextStyle(fontSize: 18),
)
]);
}
if (result.data == null && result.exception.toString() == null) {
return const Text('Aucune donnée à afficher.');
}
num balance;
if (result.data['balance'] == null) {
balance = 0.0;
_historyProvider.balance = 0.0;
} else {
balance = _historyProvider
_historyProvider.balance = _historyProvider
.removeDecimalZero(result.data['balance']['amount'] / 100);
}
opts = _historyProvider.checkQueryResult(
result, opts, _outputPubkey.text);
// _historyProvider.transBC = null;
if (result.isNotLoading) {
// log.d(result.data);
opts = _historyProvider.checkQueryResult(result, opts, pubkey);
}
// Build history list
return NotificationListener(
child: Builder(
builder: (context) => Expanded(
child: ListView(
key: const Key('listTransactions'),
controller: scrollController,
children: <Widget>[
const SizedBox(height: 20),
if (_historyProvider.pubkey != '')
Row(
mainAxisAlignment:
MainAxisAlignment.spaceBetween,
mainAxisSize: MainAxisSize.min,
crossAxisAlignment: CrossAxisAlignment.center,
children: [
if (_isFirstExec)
Container(
padding: const EdgeInsets.fromLTRB(
20, 0, 30, 0),
child: FutureBuilder(
future:
_cesiumPlusProvider.getAvatar(
_historyProvider.pubkey),
initialData: [
File(appPath.path +
'/default_avatar.png')
],
builder: (BuildContext context,
AsyncSnapshot<List> _avatar) {
cesiumData = _avatar.data;
// _cesiumPlusProvider.isComplete = true;
if (_avatar.connectionState !=
ConnectionState.done) {
return Image.file(
File(appPath.path +
'/default_avatar.png'),
height: avatarsSize);
}
if (_avatar.hasError) {
return Image.file(
File(appPath.path +
'/default_avatar.png'),
height: avatarsSize);
}
if (_avatar.hasData) {
return SingleChildScrollView(
padding:
const EdgeInsets.all(
0.0),
child: Image.file(
_avatar.data[0],
height: avatarsSize));
}
return Image.file(
File(appPath.path +
'/default_avatar.png'),
height: avatarsSize);
})),
GestureDetector(
key: const Key('copyPubkey'),
onTap: () {
Clipboard.setData(ClipboardData(
text: _historyProvider.pubkey));
_historyProvider.snackCopyKey(context);
},
child: Text(
_historyProvider.getShortPubkey(
_historyProvider.pubkey),
style: const TextStyle(
fontSize: 22,
fontWeight: FontWeight.w800,
fontFamily: 'Monospace')),
),
Container(
padding: const EdgeInsets.fromLTRB(
30, 0, 5, 0), // .only(right: 15),
child: Card(
child: Column(
children: <Widget>[
SvgPicture.string(
_historyProvider
.generateIdenticon(
_historyProvider
.pubkey),
fit: BoxFit.contain,
height: 64,
width: 64,
),
],
),
)),
const SizedBox(width: 0)
]),
if (_isFirstExec)
Row(
mainAxisAlignment:
MainAxisAlignment.spaceAround,
crossAxisAlignment: CrossAxisAlignment.center,
children: [
Container(
padding: const EdgeInsets.fromLTRB(
0, 0, 0, 0),
// padding: const EdgeInsets.,
child: FutureBuilder(
future: _cesiumPlusProvider.getName(
_historyProvider.pubkey),
initialData: '...',
builder: (context, snapshot) {
return Text(snapshot.data ?? '-',
style: const TextStyle(
fontSize: 20));
}))
]),
const SizedBox(height: 18),
if (_isFirstExec)
Container(
padding:
const EdgeInsets.fromLTRB(0, 0, 0, 0),
child: Text(balance.toString() + ' Ğ1',
textAlign: TextAlign.center,
style: const TextStyle(fontSize: 18.0))),
const SizedBox(height: 20),
ElevatedButton(
key: const Key('switchPayHistory'),
style: ElevatedButton.styleFrom(
elevation: 1,
primary: Colors.grey[50], // background
onPrimary: Colors.black, // foreground
),
onPressed: () {
_historyProvider.switchProfileView();
},
child: Text(
_historyProvider.historySwitchButtun,
style: TextStyle(
fontSize: 15, color: orangeC))),
// const Divider(
// color: Colors.grey,
// height: 5,
// thickness: 0.5,
// indent: 0,
// endIndent: 0,
// ),
_historyProvider.isHistoryScreen
? historyView(context, result)
: payView(context, _historyProvider),
],
))),
builder: (context) => Expanded(
child: ListView(
key: const Key('listTransactions'),
controller: scrollController,
children: <Widget>[historyView(context, result)],
),
),
),
onNotification: (t) {
if (t is ScrollEndNotification &&
scrollController.position.pixels >=
scrollController.position.maxScrollExtent * 0.7) {
scrollController.position.maxScrollExtent * 0.7 &&
_historyProvider.pageInfo['hasPreviousPage']) {
fetchMore(opts);
}
return true;
@ -332,125 +137,28 @@ class HistoryScreen extends StatelessWidget with ChangeNotifier {
));
}
Widget payView(context, HistoryProvider _historyProvider) {
MyWalletsProvider _myWalletProvider = MyWalletsProvider();
WalletData defaultWallet =
_myWalletProvider.getDefaultWallet(configBox.get('currentChest'));
return Stack(
clipBehavior: Clip.hardEdge,
children: <Widget>[
Form(
key: _formKey,
child: Column(
mainAxisSize: MainAxisSize.min,
children: <Widget>[
const SizedBox(height: 20),
const Text('Commentaire:', style: TextStyle(fontSize: 20.0)),
Padding(
padding: const EdgeInsets.all(8.0),
child: TextField(
controller: _historyProvider.payComment,
maxLines: 2,
textAlign: TextAlign.center,
decoration: const InputDecoration(),
style: const TextStyle(
fontSize: 22,
color: Colors.black,
fontWeight: FontWeight.bold))),
const SizedBox(height: 20),
const Text('Montant (DU/Ğ1):', style: TextStyle(fontSize: 20.0)),
Padding(
padding: const EdgeInsets.all(8.0),
child: TextFormField(
style: const TextStyle(fontSize: 22),
controller: _historyProvider.payAmount,
textAlign: TextAlign.center,
maxLines: 1,
keyboardType: TextInputType.number,
decoration: InputDecoration(
contentPadding: const EdgeInsets.symmetric(
vertical: 25.0, horizontal: 10.0),
border: OutlineInputBorder(
borderRadius: BorderRadius.circular(10.0)),
),
inputFormatters: <TextInputFormatter>[
FilteringTextInputFormatter.allow(RegExp(r'(^\d*\.?\d*)'))
],
),
),
Padding(
padding: const EdgeInsets.only(top: 15),
child: OutlinedButton(
style: OutlinedButton.styleFrom(
side: BorderSide(width: 2, color: orangeC)),
onPressed: () {
// if (_formKey.currentState.validate()) {
// _formKey.currentState.save();
// }
// _historyProvider.pay(payAmount.text, payComment.text);
Navigator.push(context,
MaterialPageRoute(builder: (context) {
return UnlockingWallet(
wallet: defaultWallet, action: "pay");
}));
},
child: Padding(
padding: const EdgeInsets.all(12),
child: Text("PAYER",
style: TextStyle(
fontSize: 25, color: Colors.grey[850]))),
))
],
),
),
],
);
}
Widget historyView(context, result) {
HistoryProvider _historyProvider = Provider.of<HistoryProvider>(context);
int keyID = 0;
WalletsProfilesProvider _historyProvider =
Provider.of<WalletsProfilesProvider>(context, listen: false);
return _historyProvider.transBC == null
? const Text('Aucune transaction à afficher.')
? Column(children: const <Widget>[
SizedBox(height: 50),
Text(
"Aucune transaction à afficher.",
style: TextStyle(fontSize: 18),
)
])
: Column(children: <Widget>[
for (var repository in _historyProvider.transBC)
Padding(
padding: const EdgeInsets.symmetric(horizontal: 5.0),
child: ListTile(
key: Key('transaction${keyID++}'),
contentPadding: const EdgeInsets.all(5.0),
leading: Text(repository[1].toString(),
style: TextStyle(
fontSize: 12,
color: Colors.grey[800],
fontWeight: FontWeight.w700),
textAlign: TextAlign.center),
title: Text(repository[3],
style: const TextStyle(
fontSize: 15.0, fontFamily: 'Monospace'),
textAlign: TextAlign.center),
subtitle: Text(repository[6] != '' ? repository[6] : '-',
style: const TextStyle(fontSize: 12.0),
textAlign: TextAlign.center),
trailing: Text("${repository[4]} Ğ1",
style: const TextStyle(fontSize: 14.0),
textAlign: TextAlign.justify),
dense: true,
isThreeLine: false,
onTap: () {
// this._outputPubkey.text = repository[2];
_historyProvider.isPubkey(context, repository[2]);
})),
if (result.isLoading)
getTransactionTile(context, _historyProvider),
if (result.isLoading &&
_historyProvider.pageInfo['hasPreviousPage'])
Row(
mainAxisAlignment: MainAxisAlignment.center,
children: const <Widget>[
CircularProgressIndicator(),
],
),
// if (_historyProvider.isTheEnd) // What I did before ...
if (!_historyProvider.pageInfo['hasPreviousPage'])
Column(
children: const <Widget>[
@ -463,4 +171,384 @@ class HistoryScreen extends StatelessWidget with ChangeNotifier {
)
]);
}
Widget getTransactionTile(
BuildContext context, WalletsProfilesProvider _historyProvider) {
CesiumPlusProvider _cesiumPlusProvider =
Provider.of<CesiumPlusProvider>(context, listen: false);
int keyID = 0;
String dateDelimiter;
String lastDateDelimiter;
const double _avatarSize = 200;
bool isTody = false;
bool isYesterday = false;
bool isThisWeek = false;
const Map<int, String> monthsInYear = {
1: "Janvier",
2: "Février",
3: "Mars",
4: "Avril",
5: "Mai",
6: "Juin",
7: "Juillet",
8: "Aout",
9: "Septembre",
10: "Octobre",
11: "Novembre",
12: "Décembre"
};
return Column(
children: _historyProvider.transBC.map((repository) {
DateTime now = DateTime.now();
DateTime date = DateTime.fromMillisecondsSinceEpoch(repository[0] * 1000);
String dateForm;
if ({4, 10, 11, 12}.contains(date.month)) {
dateForm = "${date.day} ${monthsInYear[date.month].substring(0, 3)}.";
} else if ({1, 2, 7, 9}.contains(date.month)) {
dateForm = "${date.day} ${monthsInYear[date.month].substring(0, 4)}.";
} else {
dateForm = "${date.day} ${monthsInYear[date.month]}";
}
int weekNumber(DateTime date) {
int dayOfYear = int.parse(DateFormat("D").format(date));
return ((dayOfYear - date.weekday + 10) / 7).floor();
}
if (DateTime(date.year, date.month, date.day) ==
DateTime(now.year, now.month, now.day) &&
!isTody) {
dateDelimiter = lastDateDelimiter = "Aujourd'hui";
isTody = true;
} else if (DateTime(date.year, date.month, date.day) ==
DateTime(now.year, now.month, now.day - 1) &&
!isYesterday) {
dateDelimiter = lastDateDelimiter = "Hier";
isYesterday = true;
} else if (weekNumber(date) == weekNumber(now) &&
date.year == now.year &&
lastDateDelimiter != "Cette semaine" &&
DateTime(date.year, date.month, date.day) !=
DateTime(now.year, now.month, now.day - 1) &&
!isThisWeek) {
dateDelimiter = lastDateDelimiter = "Cette semaine";
isThisWeek = true;
} else if (lastDateDelimiter != monthsInYear[date.month] &&
lastDateDelimiter != "${monthsInYear[date.month]} ${date.year}" &&
DateTime(date.year, date.month, date.day) !=
DateTime(now.year, now.month, now.day) &&
DateTime(date.year, date.month, date.day) !=
DateTime(now.year, now.month, now.day - 1) &&
!(weekNumber(date) == weekNumber(now) && date.year == now.year)) {
if (date.year == now.year) {
dateDelimiter = lastDateDelimiter = monthsInYear[date.month];
} else {
dateDelimiter =
lastDateDelimiter = "${monthsInYear[date.month]} ${date.year}";
}
} else {
dateDelimiter = null;
}
return Column(children: <Widget>[
if (dateDelimiter != null)
Padding(
padding: const EdgeInsets.symmetric(vertical: 30),
child: Text(
dateDelimiter,
style: TextStyle(
fontSize: 23, color: orangeC, fontWeight: FontWeight.w300),
),
),
Padding(
padding: const EdgeInsets.only(right: 0),
child:
// Row(children: [Column(children: [],)],)
ListTile(
key: Key('transaction${keyID++}'),
contentPadding: const EdgeInsets.only(
left: 20, right: 30, top: 15, bottom: 15),
leading: g1WalletsBox.get(repository[2])?.avatar == null
? FutureBuilder(
future: _cesiumPlusProvider.getAvatar(
repository[2], _avatarSize),
builder: (BuildContext context,
AsyncSnapshot<Image> _avatar) {
if (_avatar.connectionState !=
ConnectionState.done ||
_avatar.hasError) {
return Stack(children: [
_cesiumPlusProvider.defaultAvatar(_avatarSize),
Positioned(
top: 8,
right: 0,
width: 12,
height: 12,
child: CircularProgressIndicator(
strokeWidth: 1,
color: orangeC,
),
),
]);
}
if (_avatar.hasData) {
g1WalletsBox.get(repository[2]).avatar =
_avatar.data;
return ClipOval(child: _avatar.data);
} else {
g1WalletsBox.get(repository[2]).avatar =
_cesiumPlusProvider
.defaultAvatar(repository[2]);
return _cesiumPlusProvider
.defaultAvatar(_avatarSize);
}
})
: ClipOval(
child: Image(
image: g1WalletsBox.get(repository[2]).avatar.image,
height: _avatarSize,
),
),
title: Padding(
padding: EdgeInsets.only(
bottom: 5, top: repository[6] != '' ? 0 : 0),
child: Text(repository[3],
style: const TextStyle(
fontSize: 18, fontFamily: 'Monospace')),
),
subtitle: RichText(
text: TextSpan(
style: TextStyle(
fontSize: 16,
color: Colors.grey[700],
),
children: <TextSpan>[
TextSpan(
text: dateForm,
),
if (repository[6] != '')
TextSpan(
text: ' · ',
style: TextStyle(
fontSize: 20,
color: Colors.grey[550],
),
),
TextSpan(
text: repository[6],
style: TextStyle(
fontStyle: FontStyle.italic,
color: Colors.grey[600],
),
),
],
),
),
trailing: Text("${repository[4]} Ğ1",
style: const TextStyle(
fontSize: 18, fontWeight: FontWeight.w500),
textAlign: TextAlign.justify),
dense: false,
isThreeLine: false,
onTap: () {
_historyProvider.nPage = 1;
// _cesiumPlusProvider.avatarCancelToken.cancel('cancelled');
Navigator.push(
context,
MaterialPageRoute(builder: (context) {
return WalletViewScreen(pubkey: repository[2]);
}),
);
// Navigator.pop(context);
}),
),
]);
}).toList());
}
Widget headerProfileView(
BuildContext context,
WalletsProfilesProvider _historyProvider,
CesiumPlusProvider _cesiumPlusProvider) {
const double _avatarSize = 140;
return Column(children: <Widget>[
Container(
height: 10,
color: yellowC,
),
Container(
decoration: BoxDecoration(
gradient: LinearGradient(
begin: Alignment.topCenter,
end: Alignment.bottomCenter,
colors: [
yellowC,
const Color(0xFFE7811A),
],
)),
child: Padding(
padding: const EdgeInsets.only(left: 30, right: 40),
child: Row(children: <Widget>[
Column(
crossAxisAlignment: CrossAxisAlignment.center,
children: <Widget>[
Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
Row(children: [
GestureDetector(
key: const Key('copyPubkey'),
onTap: () {
Clipboard.setData(ClipboardData(text: pubkey));
_historyProvider.snackCopyKey(context);
},
child: Text(
_historyProvider.getShortPubkey(pubkey),
style: const TextStyle(
fontSize: 30,
fontWeight: FontWeight.w800,
),
),
),
]),
const SizedBox(height: 10),
if (username == null)
Query(
options: QueryOptions(
document: gql(getId),
variables: {
'pubkey': pubkey,
},
),
builder: (QueryResult result,
{VoidCallback refetch, FetchMore fetchMore}) {
if (result.isLoading || result.hasException) {
return const Text('...');
} else if (result.data['idty'] == null ||
result.data['idty']['username'] == null) {
return const Text('');
} else {
return SizedBox(
width: 230,
child: Text(
result?.data['idty']['username'] ?? '',
style: const TextStyle(
fontSize: 27,
color: Color(0xff814C00),
),
),
);
}
},
),
if (username != null)
SizedBox(
width: 230,
child: Text(
username,
style: const TextStyle(
fontSize: 27,
color: Color(0xff814C00),
),
),
),
const SizedBox(height: 25),
]),
FutureBuilder(
future: _historyProvider.getBalance(pubkey),
builder:
(BuildContext context, AsyncSnapshot<num> _balance) {
if (_balance.connectionState != ConnectionState.done ||
_balance.hasError) {
return const Text('...');
}
return Text(
"${_balance.data.toString()} Ğ1",
textAlign: TextAlign.center,
style: const TextStyle(
fontSize: 22, fontWeight: FontWeight.w500),
);
}),
const SizedBox(height: 30),
]),
const Spacer(),
Column(children: <Widget>[
if (avatar == null)
FutureBuilder(
future: _cesiumPlusProvider.getAvatar(pubkey, _avatarSize),
builder:
(BuildContext context, AsyncSnapshot<Image> _avatar) {
if (_avatar.connectionState != ConnectionState.done) {
return Stack(children: [
ClipOval(
child:
_cesiumPlusProvider.defaultAvatar(_avatarSize),
),
Positioned(
top: 15,
right: 45,
width: 51,
height: 51,
child: CircularProgressIndicator(
strokeWidth: 5,
color: orangeC,
),
),
]);
}
if (_avatar.hasData) {
return GestureDetector(
key: const Key('openAvatar'),
onTap: () {
Navigator.push(
context,
MaterialPageRoute(builder: (context) {
return AvatarFullscreen(_avatar.data);
}),
);
},
child: ClipOval(
child: Image(
image: _avatar.data.image,
height: _avatarSize,
fit: BoxFit.cover,
),
),
);
}
return ClipOval(
child: _cesiumPlusProvider.defaultAvatar(_avatarSize),
);
}),
if (avatar != null)
GestureDetector(
key: const Key('openAvatar'),
onTap: () {
Navigator.push(
context,
MaterialPageRoute(builder: (context) {
return AvatarFullscreen(avatar);
}),
);
},
child: ClipOval(
child: Image(
image: avatar.image,
height: _avatarSize,
fit: BoxFit.cover,
),
),
),
const SizedBox(height: 25),
]),
]),
),
),
]);
}
}

View File

@ -1,13 +1,16 @@
import 'package:bubble/bubble.dart';
import 'package:dubp/dubp.dart';
import 'package:gecko/globals.dart';
import 'package:gecko/models/chest_provider.dart';
import 'package:gecko/models/history.dart';
import 'package:gecko/models/home.dart';
import 'package:gecko/models/wallets_profiles.dart';
import 'package:flutter/material.dart';
import 'package:gecko/models/home.dart';
import 'package:gecko/models/my_wallets.dart';
import 'package:gecko/models/wallet_data.dart';
import 'package:gecko/screens/myWallets/restore_chest.dart';
import 'package:gecko/screens/myWallets/unlocking_wallet.dart';
import 'package:gecko/screens/onBoarding/0_no_keychain_found.dart';
import 'package:gecko/screens/onBoarding/1.dart';
import 'package:gecko/screens/search.dart';
import 'dart:ui';
import 'package:gecko/screens/settings.dart';
import 'package:flutter/services.dart';
@ -19,21 +22,14 @@ class HomeScreen extends StatelessWidget {
@override
Widget build(BuildContext context) {
SystemChrome.setPreferredOrientations([DeviceOrientation.portraitUp]);
HomeProvider _homeProvider = Provider.of<HomeProvider>(context);
HistoryProvider _historyProvider = Provider.of<HistoryProvider>(context);
HistoryProvider _historyStatic = HistoryProvider('');
// HomeProvider _homeProvider = Provider.of<HomeProvider>(context);
MyWalletsProvider _myWalletProvider =
Provider.of<MyWalletsProvider>(context);
Provider.of<ChestProvider>(context);
HomeProvider homeClass = HomeProvider();
final bool isWalletsExists = _myWalletProvider.checkIfWalletExist();
// walletBox.toMap().forEach((key, value) {
// if (value.chest == 0) {
// print('$key: ${value.derivation}');
// }
// });
isTall = false;
ratio = 1;
if (MediaQuery.of(context).size.height >= 930) {
@ -86,95 +82,225 @@ class HomeScreen extends StatelessWidget {
],
),
),
appBar: AppBar(
toolbarHeight: 60 * ratio,
leading: Builder(
builder: (context) => IconButton(
key: const Key('drawerMenu'),
icon: Icon(Icons.menu, color: Colors.grey[850]),
onPressed: () => Scaffold.of(context).openDrawer(),
)),
title: _homeProvider.appBarTitle,
actions: [
Padding(
padding: const EdgeInsets.symmetric(horizontal: 16),
child: IconButton(
key: const Key('searchIcon'),
icon: _homeProvider.searchIcon,
color: Colors.grey[850],
onPressed: () {
if (_homeProvider.searchIcon.icon == Icons.search) {
_homeProvider.searchIcon = Icon(
Icons.close,
color: Colors.grey[850],
);
_homeProvider.appBarTitle = TextField(
key: const Key('searchInput'),
autofocus: true,
controller: _homeProvider.searchQuery,
onChanged: (text) {
log.d("Clé tappé: $text");
final String searchResult =
_historyProvider.isPubkey(context, text);
if (searchResult != '') {
_homeProvider.currentIndex = 0;
}
},
style: TextStyle(
color: Colors.grey[850],
),
decoration: InputDecoration(
prefixIcon:
Icon(Icons.search, color: Colors.grey[850]),
hintText: "Rechercher ...",
hintStyle: TextStyle(color: Colors.grey[850])),
);
_homeProvider.handleSearchStart();
} else {
_homeProvider.handleSearchEnd();
}
}))
],
backgroundColor: const Color(0xffFFD58D),
),
backgroundColor: const Color(0xffF9F9F1),
body: Builder(
builder: (ctx) => StatefulWrapper(
onInit: () {
WidgetsBinding.instance.addPostFrameCallback((_) {
DubpRust.setup();
_historyStatic.snackNode(ctx);
});
},
onInit: () {
WidgetsBinding.instance.addPostFrameCallback((_) {
DubpRust.setup();
if (isWalletsExists) homeClass.snackNode(ctx);
});
},
child: isWalletsExists ? geckHome(context) : welcomeHome(context)
// bottomNavigationBar: BottomNavigationBar(
// backgroundColor: backgroundColor,
// fixedColor: Colors.grey[850],
// unselectedItemColor: const Color(0xffBD935C),
// type: BottomNavigationBarType.fixed,
// onTap: (index) {
// _homeProvider.currentIndex = index;
// },
// currentIndex: _homeProvider.currentIndex,
// items: [
// BottomNavigationBarItem(
// icon: Image.asset('assets/block-space-disabled.png', height: 26),
// activeIcon: Image.asset('assets/blockchain.png', height: 26),
// label: 'Explorateur',
// ),
// const BottomNavigationBarItem(
// icon: Icon(Icons.lock),
// label: 'Mes portefeuilles',
// ),
// ],
// ),
),
),
);
}
}
Widget geckHome(context) {
MyWalletsProvider _myWalletProvider = Provider.of<MyWalletsProvider>(context);
Provider.of<ChestProvider>(context);
WalletsProfilesProvider _historyProvider =
Provider.of<WalletsProfilesProvider>(context);
final double statusBarHeight = MediaQuery.of(context).padding.top;
return Container(
decoration: const BoxDecoration(
image: DecorationImage(
image: AssetImage("assets/home/background.jpg"),
fit: BoxFit.cover,
),
),
child:
Column(crossAxisAlignment: CrossAxisAlignment.start, children: <Widget>[
Stack(children: <Widget>[
Positioned(
top: statusBarHeight + 10,
left: 15,
child: Builder(
builder: (context) => IconButton(
key: const Key('drawerMenu'),
icon: const Icon(
Icons.menu,
color: Colors.white,
size: 35,
),
onPressed: () => Scaffold.of(context).openDrawer(),
),
),
),
const Align(
child:
Image(image: AssetImage('assets/home/header.png'), height: 210),
),
]),
Padding(
padding: EdgeInsets.only(top: 15 * ratio),
child: Row(
mainAxisAlignment: MainAxisAlignment.center,
children: const <Widget>[
Text(
"y'a pas de lézard ;-)",
textAlign: TextAlign.center,
style: TextStyle(
color: Colors.white,
fontSize: 24,
fontWeight: FontWeight.w700,
shadows: <Shadow>[
Shadow(
offset: Offset(0, 0),
blurRadius: 20,
color: Colors.black,
),
Shadow(
offset: Offset(0, 0),
blurRadius: 20,
color: Colors.black,
),
],
),
)
]),
),
Expanded(
flex: 1,
child: Container(
decoration: BoxDecoration(
gradient: LinearGradient(
begin: Alignment.topCenter,
end: Alignment.bottomCenter,
colors: [
Colors.transparent,
Colors.black.withOpacity(0.9),
],
),
),
child: Column(children: <Widget>[
const Spacer(),
Row(mainAxisAlignment: MainAxisAlignment.center, children: <Widget>[
Column(children: <Widget>[
Container(
child: ClipOval(
child: Material(
color: orangeC, // button color
child: InkWell(
child: const Padding(
padding: EdgeInsets.all(18),
child: Image(
image: AssetImage('assets/home/loupe.png'),
height: 70),
),
onTap: () {
Navigator.push(
context,
MaterialPageRoute(builder: (context) {
return const SearchScreen();
}),
);
}),
),
),
decoration: const BoxDecoration(
shape: BoxShape.circle,
color: Colors.black,
boxShadow: [
BoxShadow(
blurRadius: 2,
offset: Offset(1, 1.5),
spreadRadius: 0.5)
],
),
),
const SizedBox(height: 12),
const Text(
"Rechercher un\nportefeuille",
textAlign: TextAlign.center,
style: TextStyle(
color: Colors.white,
fontSize: 17,
fontWeight: FontWeight.w500),
)
]),
const SizedBox(width: 120),
Column(children: <Widget>[
Container(
child: ClipOval(
key: const Key('manageWallets'),
child: Material(
color: orangeC, // button color
child: InkWell(
child: const Padding(
padding: EdgeInsets.all(18),
child: Image(
image: AssetImage('assets/home/wallet.png'),
height: 75)),
onTap: () {
WalletData defaultWallet =
_myWalletProvider.getDefaultWallet(
configBox.get('currentChest'));
Navigator.push(
context,
MaterialPageRoute(
builder: (context) {
return UnlockingWallet(
wallet: defaultWallet,
action: "mywallets",
);
},
),
);
// Navigator.pushNamed(
// context, '/mywallets')));
}),
),
),
decoration: const BoxDecoration(
shape: BoxShape.circle,
color: Colors.black,
boxShadow: [
BoxShadow(
blurRadius: 2,
offset: Offset(1, 1.5),
spreadRadius: 0.5)
],
),
),
const SizedBox(height: 12),
const Text(
"Gérer mes\nportefeuilles",
textAlign: TextAlign.center,
style: TextStyle(
color: Colors.white,
fontSize: 17,
fontWeight: FontWeight.w500),
)
])
]),
Padding(
padding: const EdgeInsets.only(top: 20),
child: Row(
mainAxisAlignment: MainAxisAlignment.center,
children: const <Widget>[
SizedBox(width: 7),
Image(
image: AssetImage('assets/icon/gecko_final.png'),
height: 180),
]),
),
Padding(
padding: const EdgeInsets.only(top: 15),
child: Row(
mainAxisAlignment: MainAxisAlignment.center,
children: const <Widget>[
Text(
"y'a pas de lézard !",
textAlign: TextAlign.center,
style: TextStyle(
color: Colors.black,
fontSize: 17,
fontStyle: FontStyle.italic),
)
]),
),
Padding(
padding: EdgeInsets.only(top: isTall ? 100 : 60),
padding: const EdgeInsets.only(top: 40),
child: Row(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
@ -182,15 +308,14 @@ class HomeScreen extends StatelessWidget {
Container(
child: ClipOval(
child: Material(
color: const Color(0xffFFD58D), // button color
color: orangeC, // button color
child: InkWell(
splashColor: orangeC, // inkwell color
child: const Padding(
padding: EdgeInsets.all(22),
padding: EdgeInsets.all(18),
child: Image(
image: AssetImage(
'assets/qrcode-scan.png'),
height: 60)),
'assets/home/qrcode.png'),
height: 75)),
onTap: () async {
await _historyProvider.scan(context);
}),
@ -198,157 +323,194 @@ class HomeScreen extends StatelessWidget {
),
decoration: const BoxDecoration(
shape: BoxShape.circle,
color: Colors.white,
color: Colors.black,
boxShadow: [
BoxShadow(
color: Colors.grey,
blurRadius: 4.0,
offset: Offset(2.0, 2.5),
blurRadius: 2,
offset: Offset(1, 1.5),
spreadRadius: 0.5)
],
),
),
const SizedBox(height: 12),
const Text(
"Payer par QR-Code",
"Scanner un\nQR code",
textAlign: TextAlign.center,
style: TextStyle(color: Colors.black, fontSize: 16),
style: TextStyle(
color: Colors.white,
fontSize: 17,
fontWeight: FontWeight.w500),
)
])
]),
),
Padding(
padding: const EdgeInsets.only(top: 50),
child: Row(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Column(children: <Widget>[
Container(
child: ClipOval(
child: Material(
color: const Color(0xffFFD58D), // button color
child: InkWell(
splashColor: orangeC, // inkwell color
child: const Padding(
padding: EdgeInsets.symmetric(
horizontal: 20, vertical: 16),
child: Image(
image:
AssetImage('assets/blockchain.png'),
height: 70)),
onTap: () {
// Navigator.push(
// context,
// MaterialPageRoute(
// builder: (context) {
// return TemplateScreen();
// }),
// );
}),
),
),
decoration: const BoxDecoration(
shape: BoxShape.circle,
color: Colors.white,
boxShadow: [
BoxShadow(
color: Colors.grey,
blurRadius: 4.0,
offset: Offset(2.0, 2.5),
spreadRadius: 0.5)
],
),
),
const SizedBox(height: 12),
const Text(
"Explorer\n",
textAlign: TextAlign.center,
style: TextStyle(color: Colors.black, fontSize: 16),
)
]),
const SizedBox(width: 140),
Column(children: <Widget>[
Container(
child: ClipOval(
key: const Key('manageWallets'),
child: Material(
color: const Color(0xffFFD58D), // button color
child: InkWell(
splashColor: orangeC, // inkwell color
child: const Padding(
padding: EdgeInsets.all(23),
child: Image(
image: AssetImage('assets/lock.png'),
height: 57)),
onTap: () {
WalletData defaultWallet =
_myWalletProvider.getDefaultWallet(
configBox.get('currentChest'));
isWalletsExists
? Navigator.push(context,
MaterialPageRoute(builder: (context) {
return UnlockingWallet(
wallet: defaultWallet,
action: "mywallets",
);
}))
// Navigator.pushNamed(
// context, '/mywallets')
: Navigator.push(context,
MaterialPageRoute(builder: (context) {
return const NoKeyChainScreen();
}));
}),
),
),
decoration: const BoxDecoration(
shape: BoxShape.circle,
color: Colors.white,
boxShadow: [
BoxShadow(
color: Colors.grey,
blurRadius: 4.0,
offset: Offset(2.0, 2.5),
spreadRadius: 0.5)
],
),
),
const SizedBox(height: 12),
const Text(
"Gérer mes\nportefeuilles",
textAlign: TextAlign.center,
style: TextStyle(color: Colors.black, fontSize: 16),
)
])
]),
)
SizedBox(height: isTall ? 80 : 40)
]),
// bottomNavigationBar: BottomNavigationBar(
// backgroundColor: Color(0xffFFD58D),
// fixedColor: Colors.grey[850],
// unselectedItemColor: Color(0xffBD935C),
// type: BottomNavigationBarType.fixed,
// onTap: (index) {
// _homeProvider.currentIndex = index;
// },
// currentIndex: _homeProvider.currentIndex,
// items: [
// BottomNavigationBarItem(
// icon: Image.asset('assets/block-space-disabled.png', height: 26),
// activeIcon: Image.asset('assets/blockchain.png', height: 26),
// label: 'Explorateur',
// ),
// BottomNavigationBarItem(
// icon: Icon(Icons.lock),
// label: 'Mes portefeuilles',
// ),
// ],
// ),
),
)
]),
);
}
Widget welcomeHome(context) {
final double statusBarHeight = MediaQuery.of(context).padding.top;
return Container(
decoration: const BoxDecoration(
image: DecorationImage(
image: AssetImage("assets/home/background.jpg"),
fit: BoxFit.cover,
),
);
}
),
child:
Column(crossAxisAlignment: CrossAxisAlignment.start, children: <Widget>[
Stack(children: <Widget>[
Positioned(
top: statusBarHeight + 10,
left: 15,
child: Builder(
builder: (context) => IconButton(
key: const Key('drawerMenu'),
icon: const Icon(
Icons.menu,
color: Colors.white,
size: 35,
),
onPressed: () => Scaffold.of(context).openDrawer(),
),
),
),
const Align(
child:
Image(image: AssetImage('assets/home/header.png'), height: 210),
),
]),
Padding(
padding: EdgeInsets.only(top: 1 * ratio),
child: Row(
mainAxisAlignment: MainAxisAlignment.center,
children: const <Widget>[
Text(
"Lapplication de paiement Ğ1\nplus rapide quun reptile du Vietnam",
textAlign: TextAlign.center,
style: TextStyle(
color: Colors.white,
fontSize: 24,
fontWeight: FontWeight.w700,
shadows: <Shadow>[
Shadow(
offset: Offset(0, 0),
blurRadius: 20,
color: Colors.black,
),
Shadow(
offset: Offset(0, 0),
blurRadius: 20,
color: Colors.black,
),
],
),
)
]),
),
Expanded(
flex: 1,
child: Container(
decoration: BoxDecoration(
gradient: LinearGradient(
begin: Alignment.topCenter,
end: Alignment.bottomCenter,
colors: [
Colors.transparent,
Colors.black.withOpacity(0.9),
],
),
),
child: Center(
child: Column(children: <Widget>[
const Spacer(),
Row(children: <Widget>[
Expanded(
child: Stack(children: <Widget>[
const Padding(
padding: EdgeInsets.only(top: 55),
child: Image(
image: AssetImage('assets/home/gecko-bienvenue.png'),
height: 220,
),
),
Positioned(
left: 180,
child: bubbleSpeak("y'a pas de lézard !"),
),
const Positioned(
left: 200,
top: 60,
child: Image(
image: AssetImage('assets/home/bout_de_bulle.png'),
),
),
]),
),
]),
SizedBox(
width: 410,
height: 70,
child: ElevatedButton(
style: ElevatedButton.styleFrom(
elevation: 4,
primary: orangeC, // background
onPrimary: Colors.white, // foreground
),
onPressed: () {
Navigator.push(
context,
MaterialPageRoute(
builder: (context) {
return OnboardingStepOne();
},
),
);
},
child: const Text(
'Créer un portefeuille',
style:
TextStyle(fontSize: 24, fontWeight: FontWeight.w600),
),
),
),
SizedBox(height: 25 * ratio),
SizedBox(
width: 410,
height: 70,
child: OutlinedButton(
style: OutlinedButton.styleFrom(
side: BorderSide(width: 4, color: orangeC)),
onPressed: () {
Navigator.push(
context,
MaterialPageRoute(
builder: (context) {
return const RestoreChest();
},
),
);
},
child: Text(
"Restaurer mes portefeuilles",
style: TextStyle(
fontSize: 24,
color: orangeC,
fontWeight: FontWeight.w600),
),
),
),
SizedBox(height: isTall ? 100 : 50)
]),
),
))
]),
);
}
class StatefulWrapper extends StatefulWidget {
@ -374,3 +536,19 @@ class _StatefulWrapperState extends State<StatefulWrapper> {
return widget.child;
}
}
Widget bubbleSpeak(String text, {double long, Key textKey}) {
return Bubble(
padding: long == null
? const BubbleEdges.all(20)
: BubbleEdges.symmetric(horizontal: long, vertical: 30),
elevation: 5,
color: Colors.white,
child: Text(
text,
key: textKey,
style: const TextStyle(
color: Colors.black, fontSize: 21, fontWeight: FontWeight.w400),
),
);
}

View File

@ -5,10 +5,11 @@ import 'package:flutter/material.dart';
import 'package:gecko/globals.dart';
import 'package:gecko/models/chest_data.dart';
import 'package:gecko/models/chest_provider.dart';
import 'package:gecko/models/history.dart';
import 'package:gecko/models/wallets_profiles.dart';
import 'package:gecko/models/my_wallets.dart';
import 'package:gecko/models/queries.dart';
import 'package:gecko/models/wallet_options.dart';
import 'package:gecko/screens/history.dart';
import 'package:gecko/screens/myWallets/change_pin.dart';
import 'package:graphql_flutter/graphql_flutter.dart';
import 'package:provider/provider.dart';
@ -17,336 +18,404 @@ import 'package:flutter/services.dart';
int _nbrLinesName = 1;
bool _isNewNameValid = false;
Widget cesiumWalletOptions(BuildContext context, ChestData cesiumWallet,
MyWalletsProvider _myWalletProvider) {
SystemChrome.setPreferredOrientations([DeviceOrientation.portraitUp]);
WalletOptionsProvider _walletOptions =
Provider.of<WalletOptionsProvider>(context);
ChestProvider _chestProvider =
Provider.of<ChestProvider>(context, listen: false);
HistoryProvider _historyProvider = Provider.of<HistoryProvider>(context);
class CesiumWalletOptions extends StatelessWidget {
const CesiumWalletOptions(
{Key key, Key keyMyWallets, @required this.cesiumWallet})
: super(key: key);
final String shortPubkey =
_walletOptions.getShortPubkey(_walletOptions.pubkey.text);
final ChestData cesiumWallet;
if (_walletOptions.nameController.text == null || _isNewNameValid == false) {
_walletOptions.nameController.text = cesiumWallet.name;
} else {
cesiumWallet.name = _walletOptions.nameController.text;
}
@override
Widget build(BuildContext context) {
SystemChrome.setPreferredOrientations([DeviceOrientation.portraitUp]);
WalletOptionsProvider _walletOptions =
Provider.of<WalletOptionsProvider>(context, listen: false);
ChestProvider _chestProvider =
Provider.of<ChestProvider>(context, listen: false);
WalletsProfilesProvider _historyProvider =
Provider.of<WalletsProfilesProvider>(context, listen: false);
MyWalletsProvider _myWalletProvider =
Provider.of<MyWalletsProvider>(context, listen: false);
_walletOptions.nameController.text.length >= 15
? _nbrLinesName = 2
: _nbrLinesName = 1;
if (_walletOptions.nameController.text.length >= 26 && isTall) {
_nbrLinesName = 3;
}
final String shortPubkey =
_walletOptions.getShortPubkey(_walletOptions.pubkey.text);
return Scaffold(
resizeToAvoidBottomInset: false,
body: Builder(
builder: (ctx) => SafeArea(
child: Column(children: <Widget>[
Container(
height: isTall ? 30 : 15,
color: yellowC,
),
Container(
decoration: BoxDecoration(
gradient: LinearGradient(
begin: Alignment.topCenter,
end: Alignment.bottomCenter,
colors: [
yellowC,
const Color(0xfffafafa),
],
)),
child: Row(children: <Widget>[
const SizedBox(width: 25),
InkWell(
onTap: () async {
File newAvatar = await _walletOptions.changeAvatar();
if (newAvatar != null) {
cesiumWallet.imageFile = newAvatar;
}
_walletOptions.reloadBuild();
},
child: cesiumWallet.imageFile == null
? Image.asset(
'assets/chests/${cesiumWallet.imageName}',
width: 110,
)
: Image.file(cesiumWallet.imageFile, width: 110),
),
InkWell(
onTap: () async {
File newAvatar = await _walletOptions.changeAvatar();
if (newAvatar != null) {
cesiumWallet.imageFile = newAvatar;
}
_walletOptions.reloadBuild();
},
child: Column(children: <Widget>[
Image.asset(
'assets/walletOptions/camera.png',
),
const SizedBox(height: 100)
])),
Column(children: <Widget>[
Row(children: <Widget>[
Column(children: <Widget>[
SizedBox(
width: 260,
child: TextField(
key: const Key('walletName'),
autofocus: false,
focusNode: _walletOptions.walletNameFocus,
enabled: _walletOptions.isEditing,
controller: _walletOptions.nameController,
maxLines: _nbrLinesName,
textAlign: TextAlign.center,
decoration: const InputDecoration(
border: InputBorder.none,
focusedBorder: InputBorder.none,
enabledBorder: InputBorder.none,
disabledBorder: InputBorder.none,
contentPadding: EdgeInsets.all(15.0),
),
style: TextStyle(
fontSize: isTall ? 27 : 23,
color: Colors.black,
fontWeight: FontWeight.w400,
fontFamily: 'Monospace')),
),
SizedBox(height: isTall ? 5 : 0),
Query(
options: QueryOptions(
document: gql(getBalance),
variables: {
'pubkey': _walletOptions.pubkey.text,
},
// pollInterval: Duration(seconds: 1),
),
builder: (QueryResult result,
{VoidCallback refetch, FetchMore fetchMore}) {
if (result.hasException) {
return Text(result.exception.toString());
}
if (_walletOptions.nameController.text == null ||
_isNewNameValid == false) {
_walletOptions.nameController.text = cesiumWallet.name;
} else {
cesiumWallet.name = _walletOptions.nameController.text;
}
if (result.isLoading) {
return const Text('Loading');
}
_walletOptions.nameController.text.length >= 15
? _nbrLinesName = 2
: _nbrLinesName = 1;
if (_walletOptions.nameController.text.length >= 26 && isTall) {
_nbrLinesName = 3;
}
// List repositories = result.data['viewer']['repositories']['nodes'];
String wBalanceUD;
if (result.data['balance'] == null) {
wBalanceUD = '0.0';
} else {
int wBalanceG1 = result.data['balance']['amount'];
int currentUD = result.data['currentUd']['amount'];
double wBalanceUDBrut =
wBalanceG1 / currentUD; // .toString();
wBalanceUD = double.parse(
(wBalanceUDBrut).toStringAsFixed(2))
.toString();
}
return Row(children: <Widget>[
ImageFiltered(
imageFilter: ImageFilter.blur(
sigmaX: _walletOptions.isBalanceBlur ? 6 : 0,
sigmaY: _walletOptions.isBalanceBlur ? 5 : 0),
child: Text(wBalanceUD,
style: TextStyle(
fontSize: isTall ? 20 : 18,
color: Colors.black)),
),
Text(' DU',
style: TextStyle(
fontSize: isTall ? 20 : 18,
color: Colors.black))
]);
// Text(
// '$wBalanceUD DU',
// style: TextStyle(
// fontSize: 20, color: Colors.black),
// );
},
),
const SizedBox(height: 5),
InkWell(
key: const Key('displayBalance'),
onTap: () {
_walletOptions.bluringBalance();
},
child: Image.asset(
_walletOptions.isBalanceBlur
? 'assets/walletOptions/icon_oeuil.png'
: 'assets/walletOptions/icon_oeuil_close.png',
)),
]),
const SizedBox(width: 0),
Column(children: <Widget>[
InkWell(
key: const Key('renameWallet'),
onTap: () async {
_isNewNameValid = _walletOptions.editWalletName(
[cesiumWallet.key, 0],
isCesium: cesiumWallet.isCesium);
await Future.delayed(
const Duration(milliseconds: 30));
_walletOptions.walletNameFocus.requestFocus();
},
child: ClipRRect(
child: Image.asset(
_walletOptions.isEditing
? 'assets/walletOptions/android-checkmark.png'
: 'assets/walletOptions/edit.png',
width: 20,
height: 20),
)),
const SizedBox(
height: 60,
)
])
]),
]),
])),
SizedBox(height: 4 * ratio),
FutureBuilder(
future: _walletOptions.generateQRcode(_walletOptions.pubkey.text),
builder: (context, snapshot) {
return snapshot.data != null
? Image.memory(snapshot.data, height: isTall ? 300 : 270)
: const Text('-', style: TextStyle(fontSize: 20));
return WillPopScope(
onWillPop: () {
_walletOptions.isEditing = false;
_walletOptions.isBalanceBlur = true;
Navigator.popUntil(
context,
ModalRoute.withName('/'),
);
return Future<bool>.value(true);
},
child: Scaffold(
resizeToAvoidBottomInset: false,
appBar: AppBar(
toolbarHeight: 60 * ratio,
elevation: 0,
leading: IconButton(
icon: const Icon(Icons.arrow_back, color: Colors.black),
onPressed: () {
_walletOptions.isEditing = false;
_walletOptions.isBalanceBlur = true;
Navigator.popUntil(
context,
ModalRoute.withName('/'),
);
}),
SizedBox(height: 15 * ratio),
GestureDetector(
key: const Key('copyPubkey'),
onTap: () {
Clipboard.setData(
ClipboardData(text: _walletOptions.pubkey.text));
_walletOptions.snackCopyKey(ctx);
},
child: SizedBox(
height: 50,
title: SizedBox(
height: 22,
child: Consumer<WalletOptionsProvider>(
builder: (context, walletProvider, _) {
return Text(_walletOptions.nameController.text);
}),
),
),
body: Builder(
builder: (ctx) => SafeArea(
child: Column(children: <Widget>[
Consumer<WalletOptionsProvider>(
builder: (context, walletProvider, _) {
return Container(
decoration: BoxDecoration(
gradient: LinearGradient(
begin: Alignment.topCenter,
end: Alignment.bottomCenter,
colors: [
yellowC,
const Color(0xfffafafa),
],
)),
child: Row(children: <Widget>[
const SizedBox(width: 30),
Image.asset(
'assets/walletOptions/key.png',
const SizedBox(width: 25),
InkWell(
onTap: () async {
File newAvatar = await _walletOptions.changeAvatar();
if (newAvatar != null) {
cesiumWallet.imageFile = newAvatar;
}
_walletOptions.reloadBuild();
},
child: cesiumWallet.imageFile == null
? Image.asset(
'assets/chests/${cesiumWallet.imageName}',
width: 110,
)
: Image.file(cesiumWallet.imageFile, width: 110),
),
const SizedBox(width: 20),
Text("${shortPubkey.split(':')[0]}:",
style: const TextStyle(
fontSize: 22,
fontWeight: FontWeight.w800,
fontFamily: 'Monospace',
color: Colors.black)),
Text(shortPubkey.split(':')[1],
style: const TextStyle(
fontSize: 22,
fontWeight: FontWeight.w800,
fontFamily: 'Monospace')),
const SizedBox(width: 15),
SizedBox(
height: 40,
child: ElevatedButton(
style: ElevatedButton.styleFrom(
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(8),
),
elevation: 1,
primary: orangeC, // background
onPrimary: Colors.black, // foreground
InkWell(
onTap: () async {
File newAvatar = await _walletOptions.changeAvatar();
if (newAvatar != null) {
cesiumWallet.imageFile = newAvatar;
}
_walletOptions.reloadBuild();
},
child: Column(children: <Widget>[
Image.asset(
'assets/walletOptions/camera.png',
height: 40,
),
const SizedBox(height: 80)
])),
Column(children: <Widget>[
Row(children: <Widget>[
Column(children: <Widget>[
SizedBox(
width: 260,
child: TextField(
key: const Key('walletName'),
autofocus: false,
focusNode: _walletOptions.walletNameFocus,
enabled: _walletOptions.isEditing,
controller: _walletOptions.nameController,
maxLines: _nbrLinesName,
textAlign: TextAlign.center,
decoration: const InputDecoration(
border: InputBorder.none,
focusedBorder: InputBorder.none,
enabledBorder: InputBorder.none,
disabledBorder: InputBorder.none,
contentPadding: EdgeInsets.all(15.0),
),
style: TextStyle(
fontSize: isTall ? 27 : 23,
color: Colors.black,
fontWeight: FontWeight.w400,
fontFamily: 'Monospace')),
),
SizedBox(height: isTall ? 5 : 0),
Query(
options: QueryOptions(
document: gql(getBalance),
variables: {
'pubkey': _walletOptions.pubkey.text,
},
// pollInterval: Duration(seconds: 1),
),
onPressed: () {
Clipboard.setData(ClipboardData(
text: _walletOptions.pubkey.text));
_walletOptions.snackCopyKey(ctx);
builder: (QueryResult result,
{VoidCallback refetch, FetchMore fetchMore}) {
if (result.hasException) {
return Text(result.exception.toString());
}
if (result.isLoading) {
return const Text('Loading');
}
// List repositories = result.data['viewer']['repositories']['nodes'];
String wBalanceUD;
if (result.data['balance'] == null) {
wBalanceUD = '0.0';
} else {
int wBalanceG1 =
result.data['balance']['amount'];
int currentUD =
result.data['currentUd']['amount'];
double wBalanceUDBrut =
wBalanceG1 / currentUD; // .toString();
wBalanceUD = double.parse(
(wBalanceUDBrut).toStringAsFixed(2))
.toString();
}
return Row(children: <Widget>[
ImageFiltered(
imageFilter: ImageFilter.blur(
sigmaX:
_walletOptions.isBalanceBlur ? 6 : 0,
sigmaY:
_walletOptions.isBalanceBlur ? 5 : 0),
child: Text(wBalanceUD,
style: TextStyle(
fontSize: isTall ? 20 : 18,
color: Colors.black)),
),
Text(' DU',
style: TextStyle(
fontSize: isTall ? 20 : 18,
color: Colors.black))
]);
// Text(
// '$wBalanceUD DU',
// style: TextStyle(
// fontSize: 20, color: Colors.black),
// );
},
child: Row(children: <Widget>[
Image.asset(
'assets/walletOptions/copy-white.png',
),
const SizedBox(width: 7),
Text('Copier',
style: TextStyle(
fontSize: 15, color: Colors.grey[50]))
]))),
]))),
SizedBox(height: 10 * ratio),
InkWell(
key: const Key('displayHistory'),
onTap: () {
_historyProvider.isPubkey(ctx, _walletOptions.pubkey.text,
goHistory: true);
},
child: SizedBox(
height: 50,
child: Row(children: <Widget>[
const SizedBox(width: 30),
Image.asset(
'assets/walletOptions/clock.png',
),
const SizedBox(width: 22),
const Text('Historique des transactions',
style: TextStyle(fontSize: 20, color: Colors.black)),
]))),
SizedBox(height: 7 * ratio),
InkWell(
key: const Key('changePin'),
onTap: () async {
// await _chestProvider.changePin(context, cesiumWallet);
_myWalletProvider.pinCode = await Navigator.push(
context,
MaterialPageRoute(
builder: (context) {
return ChangePinScreen(
walletName: cesiumWallet.name,
walletProvider: _myWalletProvider,
),
const SizedBox(height: 5),
InkWell(
key: const Key('displayBalance'),
onTap: () {
_walletOptions.bluringBalance();
},
child: Image.asset(
_walletOptions.isBalanceBlur
? 'assets/walletOptions/icon_oeuil.png'
: 'assets/walletOptions/icon_oeuil_close.png',
height: 35,
),
),
]),
const SizedBox(width: 0),
Column(children: <Widget>[
InkWell(
key: const Key('renameWallet'),
onTap: () async {
_isNewNameValid = _walletOptions.editWalletName(
[cesiumWallet.key, 0],
isCesium: cesiumWallet.isCesium);
await Future.delayed(
const Duration(milliseconds: 30));
_walletOptions.walletNameFocus.requestFocus();
},
child: ClipRRect(
child: Image.asset(
_walletOptions.isEditing
? 'assets/walletOptions/android-checkmark.png'
: 'assets/walletOptions/edit.png',
width: 20,
height: 20),
)),
const SizedBox(
height: 60,
)
])
]),
]),
]),
);
}),
SizedBox(height: 4 * ratio),
FutureBuilder(
future:
_walletOptions.generateQRcode(_walletOptions.pubkey.text),
builder: (context, snapshot) {
return snapshot.data != null
? Image.memory(snapshot.data,
height: isTall ? 300 : 270)
: const Text('-', style: TextStyle(fontSize: 20));
}),
SizedBox(height: 15 * ratio),
GestureDetector(
key: const Key('copyPubkey'),
onTap: () {
Clipboard.setData(
ClipboardData(text: _walletOptions.pubkey.text));
_walletOptions.snackCopyKey(ctx);
},
child: SizedBox(
height: 50,
child: Row(children: <Widget>[
const SizedBox(width: 30),
Image.asset(
'assets/walletOptions/key.png',
height: 45,
),
const SizedBox(width: 20),
Text("${shortPubkey.split(':')[0]}:",
style: const TextStyle(
fontSize: 22,
fontWeight: FontWeight.w800,
fontFamily: 'Monospace',
color: Colors.black)),
Text(shortPubkey.split(':')[1],
style: const TextStyle(
fontSize: 22,
fontWeight: FontWeight.w800,
fontFamily: 'Monospace')),
const SizedBox(width: 15),
SizedBox(
height: 40,
child: ElevatedButton(
style: ElevatedButton.styleFrom(
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(8),
),
elevation: 1,
primary: orangeC, // background
onPrimary: Colors.black, // foreground
),
onPressed: () {
Clipboard.setData(ClipboardData(
text: _walletOptions.pubkey.text));
_walletOptions.snackCopyKey(ctx);
},
child: Row(children: <Widget>[
Image.asset(
'assets/walletOptions/copy-white.png',
height: 25,
),
const SizedBox(width: 7),
Text('Copier',
style: TextStyle(
fontSize: 15, color: Colors.grey[50]))
]))),
]))),
SizedBox(height: 10 * ratio),
InkWell(
key: const Key('displayHistory'),
onTap: () {
_historyProvider.nPage = 1;
Navigator.push(
context,
MaterialPageRoute(builder: (context) {
return HistoryScreen(
pubkey: _walletOptions.pubkey.text);
}),
);
},
child: SizedBox(
height: 50,
child: Row(children: <Widget>[
const SizedBox(width: 30),
Image.asset(
'assets/walletOptions/clock.png',
height: 45,
),
const SizedBox(width: 22),
const Text('Historique des transactions',
style:
TextStyle(fontSize: 20, color: Colors.black)),
]))),
SizedBox(height: 7 * ratio),
InkWell(
key: const Key('changePin'),
onTap: () async {
// await _chestProvider.changePin(context, cesiumWallet);
String newPin = await Navigator.push(
context,
MaterialPageRoute(
builder: (context) {
return ChangePinScreen(
walletName: cesiumWallet.name,
walletProvider: _myWalletProvider,
);
},
),
);
if (newPin != null) _myWalletProvider.pinCode = newPin;
},
child: SizedBox(
height: 50,
child: Row(children: <Widget>[
const SizedBox(width: 31),
Image.asset(
'assets/chests/secret_code.png',
height: 24,
),
const SizedBox(width: 20),
const Text('Changer mon code secret',
style: TextStyle(fontSize: 20, color: Colors.black)),
]),
),
);
},
child: SizedBox(
height: 50,
child: Row(children: <Widget>[
const SizedBox(width: 28),
Image.asset(
'assets/chests/secret_code.png',
),
const SizedBox(width: 18),
const Text('Changer mon code secret',
style: TextStyle(fontSize: 20, color: Colors.black)),
])),
),
SizedBox(height: 7 * ratio),
InkWell(
key: const Key('deleteWallet'),
onTap: () async {
await _chestProvider.deleteChest(context, cesiumWallet);
},
child: SizedBox(
height: 50,
child: Row(children: <Widget>[
const SizedBox(width: 33),
Image.asset(
'assets/walletOptions/trash.png',
height: 45,
),
const SizedBox(width: 21),
const Text(
'Supprimer ce coffre',
style: TextStyle(
fontSize: 20,
color: Color(0xffD80000),
),
),
]),
),
),
]),
),
SizedBox(height: 7 * ratio),
InkWell(
key: const Key('deleteWallet'),
onTap: () async {
await _chestProvider.deleteChest(context, cesiumWallet);
},
child: SizedBox(
height: 50,
child: Row(children: <Widget>[
const SizedBox(width: 33),
Image.asset(
'assets/walletOptions/trash.png',
),
const SizedBox(width: 25),
const Text(
'Supprimer ce coffre',
style: TextStyle(
fontSize: 20,
color: Color(0xffD80000),
),
),
]),
),
),
]),
),
),
),
);
);
}
}

View File

@ -34,20 +34,28 @@ class ChangePinScreen extends StatelessWidget with ChangeNotifier {
child: Scaffold(
resizeToAvoidBottomInset: false,
appBar: AppBar(
toolbarHeight: 60 * ratio,
leading: IconButton(
icon: const Icon(Icons.arrow_back, color: Colors.black),
onPressed: () {
_changePin.newPin.text = '';
Navigator.of(context).pop();
}),
title: SizedBox(
height: 22,
child: Text(walletName),
)),
toolbarHeight: 60 * ratio,
leading: IconButton(
icon: const Icon(Icons.arrow_back, color: Colors.black),
onPressed: () {
_changePin.newPin.text = '';
Navigator.of(context).pop();
}),
title: SizedBox(
height: 22,
child: Text(walletName),
),
),
body: Center(
child: SafeArea(
child: Column(children: <Widget>[
StatefulWrapper(
onInit: () async {
_newWalletFile =
await _changePin.changePin(walletProvider.pinCode);
},
child: Container(),
),
const SizedBox(height: 80),
Text(
'Choisissez un code secret autogénéré :',
@ -111,3 +119,27 @@ class ChangePinScreen extends StatelessWidget with ChangeNotifier {
);
}
}
class StatefulWrapper extends StatefulWidget {
final Function onInit;
final Widget child;
const StatefulWrapper({Key key, @required this.onInit, @required this.child})
: super(key: key);
@override
_StatefulWrapperState createState() => _StatefulWrapperState();
}
class _StatefulWrapperState extends State<StatefulWrapper> {
@override
void initState() {
if (widget.onInit != null) {
widget.onInit();
}
super.initState();
}
@override
Widget build(BuildContext context) {
return widget.child;
}
}

View File

@ -46,7 +46,7 @@ class ChestOptions extends StatelessWidget {
key: const Key('changePin'),
onTap: () async {
// await _chestProvider.changePin(context, cesiumWallet);
walletProvider.pinCode = await Navigator.push(
String pinResult = await Navigator.push(
context,
MaterialPageRoute(
builder: (context) {
@ -57,6 +57,10 @@ class ChestOptions extends StatelessWidget {
},
),
);
if (pinResult != null) {
walletProvider.pinCode = pinResult;
}
},
child: SizedBox(
height: 50,
@ -64,6 +68,7 @@ class ChestOptions extends StatelessWidget {
const SizedBox(width: 28),
Image.asset(
'assets/chests/secret_code.png',
height: 25,
),
const SizedBox(width: 18),
const Text('Changer mon code secret',
@ -79,11 +84,12 @@ class ChestOptions extends StatelessWidget {
child: SizedBox(
height: 50,
child: Row(children: <Widget>[
const SizedBox(width: 33),
const SizedBox(width: 30),
Image.asset(
'assets/walletOptions/trash.png',
height: 45,
),
const SizedBox(width: 24),
const SizedBox(width: 20),
const Text(
'Supprimer ce coffre',
style: TextStyle(

View File

@ -9,7 +9,8 @@ import 'package:carousel_slider/carousel_slider.dart';
import 'package:provider/provider.dart';
class ChooseChest extends StatefulWidget {
const ChooseChest({Key key}) : super(key: key);
const ChooseChest({this.action, Key key}) : super(key: key);
final String action;
@override
State<StatefulWidget> createState() {
@ -29,6 +30,8 @@ class _ChooseChestState extends State<ChooseChest> {
MyWalletsProvider _myWalletProvider =
Provider.of<MyWalletsProvider>(context);
log.d(widget.action);
return Scaffold(
appBar: AppBar(
toolbarHeight: 60 * ratio,
@ -113,13 +116,16 @@ class _ChooseChestState extends State<ChooseChest> {
WalletData defaultWallet =
_myWalletProvider.getDefaultWallet(currentChest);
_myWalletProvider.rebuildWidget();
Navigator.pushAndRemoveUntil(context,
MaterialPageRoute(builder: (context) {
return UnlockingWallet(
wallet: defaultWallet,
action: "mywallets",
);
}), ModalRoute.withName('/'));
Navigator.pushAndRemoveUntil(
context,
MaterialPageRoute(builder: (context) {
return UnlockingWallet(
wallet: defaultWallet,
action: widget.action ?? "mywallets",
);
}),
ModalRoute.withName('/'),
);
},
child: Text(
'Ouvrir ce coffre',

View File

@ -6,7 +6,7 @@ import 'package:flutter/services.dart';
import 'package:gecko/globals.dart';
import 'package:gecko/models/generate_wallets.dart';
import 'package:gecko/models/my_wallets.dart';
import 'package:gecko/models/wallet_options.dart';
import 'package:gecko/screens/myWallets/unlocking_wallet.dart';
import 'package:provider/provider.dart';
// ignore: must_be_immutable
@ -32,8 +32,6 @@ class ConfirmStoreWallet extends StatelessWidget with ChangeNotifier {
Provider.of<GenerateWalletsProvider>(context);
MyWalletsProvider _myWalletProvider =
Provider.of<MyWalletsProvider>(context);
WalletOptionsProvider _walletOptions =
Provider.of<WalletOptionsProvider>(context);
final int _currentChest = _myWalletProvider.getCurrentChest();
_mnemonicController.text = generatedMnemonic;
@ -136,7 +134,7 @@ class ConfirmStoreWallet extends StatelessWidget with ChangeNotifier {
onPressed: (_generateWalletProvider
.isAskedWordValid &&
walletName.text != '')
? () {
? () async {
_generateWalletProvider.storeHDWChest(
generatedWallet,
walletName.text,
@ -148,12 +146,19 @@ class ConfirmStoreWallet extends StatelessWidget with ChangeNotifier {
_myWalletProvider.listWallets =
_myWalletProvider
.readAllWallets(_currentChest);
scheduleMicrotask(() {
_walletOptions.reloadBuild();
_myWalletProvider.rebuildWidget();
});
Navigator.popUntil(
context, ModalRoute.withName('/'));
await Future.delayed(
const Duration(milliseconds: 50));
_myWalletProvider.rebuildWidget();
Navigator.pushAndRemoveUntil(context,
MaterialPageRoute(builder: (context) {
return UnlockingWallet(
wallet:
_myWalletProvider.getDefaultWallet(
configBox.get('currentChest'),
),
action: "mywallets",
);
}), ModalRoute.withName('/'));
}
: null,
child: const Text('Confirmer',

View File

@ -1,10 +1,8 @@
import 'package:flutter/services.dart';
import 'package:gecko/globals.dart';
import 'package:gecko/models/generate_wallets.dart';
import 'package:gecko/models/my_wallets.dart';
import 'package:gecko/screens/myWallets/confirm_wallet_storage.dart';
import 'package:flutter/material.dart';
import 'package:gecko/screens/myWallets/unlocking_wallet.dart';
import 'package:printing/printing.dart';
import 'package:provider/provider.dart';
import 'package:super_tooltip/super_tooltip.dart';
@ -29,8 +27,6 @@ class GenerateFastChestScreen extends StatelessWidget {
Provider.of<GenerateWalletsProvider>(context);
_generateWalletProvider.generateMnemonic();
MyWalletsProvider _myWalletClass = MyWalletsProvider();
return Scaffold(
appBar: AppBar(
toolbarHeight: 60 * ratio,
@ -122,14 +118,17 @@ class GenerateFastChestScreen extends StatelessWidget {
);
await Future.delayed(
const Duration(milliseconds: 20));
await Navigator.pushAndRemoveUntil(context,
MaterialPageRoute(builder: (context) {
return UnlockingWallet(
wallet: _myWalletClass.getDefaultWallet(
configBox.get('currentChest')),
action: "mywallets",
);
}), ModalRoute.withName('/'));
// if (_generateWalletProvider.hasBeenStored) {
// _generateWalletProvider.hasBeenStored = false;
// await Navigator.pushAndRemoveUntil(context,
// MaterialPageRoute(builder: (context) {
// return UnlockingWallet(
// wallet: _myWalletClass.getDefaultWallet(
// configBox.get('currentChest')),
// action: "mywallets",
// );
// }), ModalRoute.withName('/'));
// }
}
: null,
child: const Text('Enregistrer ce trousseau',

View File

@ -24,7 +24,7 @@ class ImportWalletScreen extends StatelessWidget {
return WillPopScope(
onWillPop: () {
_generateWalletProvider.resetImportView();
_generateWalletProvider.resetCesiumImportView();
return Future<bool>.value(true);
},
child: Scaffold(
@ -33,7 +33,7 @@ class ImportWalletScreen extends StatelessWidget {
leading: IconButton(
icon: const Icon(Icons.arrow_back, color: Colors.black),
onPressed: () {
_generateWalletProvider.resetImportView();
_generateWalletProvider.resetCesiumImportView();
Navigator.of(context).pop();
}),
title: const SizedBox(
@ -171,7 +171,8 @@ class ImportWalletScreen extends StatelessWidget {
.importCesiumWallet()
.then((value) {
_myWalletProvider.rebuildWidget();
_generateWalletProvider.resetImportView();
_generateWalletProvider
.resetCesiumImportView();
Navigator.popUntil(
context,
ModalRoute.withName('/'),

View File

@ -0,0 +1,184 @@
import 'package:bubble/bubble.dart';
import 'package:flutter/services.dart';
import 'package:gecko/globals.dart';
import 'package:flutter/material.dart';
import 'package:gecko/models/generate_wallets.dart';
import 'package:gecko/screens/common_elements.dart';
import 'package:gecko/screens/onBoarding/11.dart';
import 'package:provider/provider.dart';
// import 'package:gecko/models/home.dart';
// import 'package:provider/provider.dart';
class RestoreChest extends StatelessWidget {
const RestoreChest({Key key}) : super(key: key);
@override
Widget build(BuildContext context) {
SystemChrome.setPreferredOrientations([DeviceOrientation.portraitUp]);
GenerateWalletsProvider generateWalletProvider =
Provider.of<GenerateWalletsProvider>(context, listen: false);
generateWalletProvider.actualWallet = null;
return WillPopScope(
onWillPop: () {
generateWalletProvider.resetImportView();
return Future<bool>.value(true);
},
child: Scaffold(
appBar: AppBar(
toolbarHeight: 60 * ratio,
leading: IconButton(
icon: const Icon(Icons.arrow_back, color: Colors.black),
onPressed: () {
generateWalletProvider.resetImportView();
Navigator.of(context).pop();
}),
title: const SizedBox(
height: 22,
child: Text('Restaurer un coffre'),
)),
body: SafeArea(
child: Column(children: <Widget>[
SizedBox(height: isTall ? 30 : 15),
bubbleSpeak(
'Pour restaurer vos portefeuilles Gecko, rentrez dans les champs ci-dessous les 12 mots qui constituent votre phrase de restauration :'),
SizedBox(height: isTall ? 30 : 15),
Column(children: <Widget>[
Row(
mainAxisAlignment: MainAxisAlignment.spaceAround,
children: <Widget>[
arrayCell(context, generateWalletProvider.cellController0),
arrayCell(context, generateWalletProvider.cellController1),
arrayCell(context, generateWalletProvider.cellController2),
arrayCell(context, generateWalletProvider.cellController3),
]),
const SizedBox(height: 15),
Row(
mainAxisAlignment: MainAxisAlignment.spaceAround,
children: <Widget>[
arrayCell(context, generateWalletProvider.cellController4),
arrayCell(context, generateWalletProvider.cellController5),
arrayCell(context, generateWalletProvider.cellController6),
arrayCell(context, generateWalletProvider.cellController7),
]),
const SizedBox(height: 15),
Row(
mainAxisAlignment: MainAxisAlignment.spaceAround,
children: <Widget>[
arrayCell(context, generateWalletProvider.cellController8),
arrayCell(context, generateWalletProvider.cellController9),
arrayCell(context, generateWalletProvider.cellController10),
arrayCell(context, generateWalletProvider.cellController11),
]),
]),
// const Spacer(),
if (generateWalletProvider.isSentenceComplete(context))
Expanded(
child: Align(
alignment: Alignment.center,
child: SizedBox(
width: 410,
height: 70,
child: ElevatedButton(
style: ElevatedButton.styleFrom(
elevation: 4,
primary: orangeC, // background
onPrimary: Colors.white, // foreground
),
onPressed: () async {
if (await generateWalletProvider.isSentenceValid()) {
generateWalletProvider.resetImportView();
await Navigator.push(
context,
FaderTransition(
page: OnboardingStepThirteen(), isFast: true),
);
} else {
await badMnemonicPopup(context);
}
},
child: const Text(
'Restaurer ce coffre',
style:
TextStyle(fontSize: 24, fontWeight: FontWeight.w600),
),
),
),
// SizedBox(height: isTall ? 80 : 80),
))
]),
),
),
);
}
Widget bubbleSpeak(String text) {
return Bubble(
margin: const BubbleEdges.symmetric(horizontal: 20),
padding: BubbleEdges.all(isTall ? 25 : 15),
borderWidth: 1,
borderColor: Colors.black,
radius: Radius.zero,
color: Colors.white,
child: Text(
text,
key: const Key('importText'),
textAlign: TextAlign.justify,
style: const TextStyle(
color: Colors.black, fontSize: 19, fontWeight: FontWeight.w400),
),
);
}
Widget arrayCell(BuildContext context, TextEditingController cellCtl) {
GenerateWalletsProvider generateWalletProvider =
Provider.of<GenerateWalletsProvider>(context);
return Container(
width: 102,
height: 40 * ratio,
child: TextField(
autofocus: true,
controller: cellCtl,
textInputAction: TextInputAction.next,
onChanged: (v) {
bool isValid = generateWalletProvider.isBipWord(v);
if (isValid && generateWalletProvider.cellController11.text.isEmpty) {
FocusScope.of(context).nextFocus();
}
},
textAlign: TextAlign.center,
style: const TextStyle(fontSize: 20),
),
decoration: BoxDecoration(
border: Border.all(color: Colors.grey),
color: Colors.white,
borderRadius: BorderRadius.circular(3),
),
);
}
Future<bool> badMnemonicPopup(BuildContext context) async {
return showDialog<bool>(
context: context,
barrierDismissible: true, // user must tap button!
builder: (BuildContext context) {
return AlertDialog(
title: const Text('Phrase incorrecte'),
content: const Text(
'Votre phrase de restauration semble incorrecte, veuillez la corriger.'),
actions: <Widget>[
TextButton(
child: const Text("OK"),
onPressed: () {
Navigator.pop(context);
},
),
],
);
},
);
}
}

View File

@ -2,11 +2,12 @@ import 'dart:async';
import 'package:dubp/dubp.dart';
import 'package:flutter/services.dart';
import 'package:gecko/models/chest_data.dart';
import 'package:gecko/models/history.dart';
import 'package:gecko/models/wallets_profiles.dart';
import 'package:gecko/models/my_wallets.dart';
import 'package:gecko/models/wallet_data.dart';
import 'package:gecko/models/wallet_options.dart';
import 'package:flutter/material.dart';
import 'package:gecko/screens/myWallets/cesium_wallet_options.dart';
import 'package:gecko/screens/myWallets/choose_chest.dart';
import 'package:pin_code_fields/pin_code_fields.dart';
import 'package:provider/provider.dart';
@ -36,7 +37,6 @@ class UnlockingWallet extends StatelessWidget {
Provider.of<WalletOptionsProvider>(context);
int _pinLenght;
ChestData currentChest = chestBox.get(configBox.get('currentChest'));
if (currentChest.isCesium) {
@ -53,7 +53,7 @@ class UnlockingWallet extends StatelessWidget {
child: Column(children: <Widget>[
Expanded(
child: Column(children: <Widget>[
SizedBox(height: isTall ? 80 : 20),
SizedBox(height: isTall ? 100 : 20),
Row(mainAxisAlignment: MainAxisAlignment.center, children: <Widget>[
currentChest.imageFile == null
? Image.asset(
@ -87,7 +87,7 @@ class UnlockingWallet extends StatelessWidget {
fontWeight: FontWeight.w400),
)),
SizedBox(height: 40 * ratio),
pinForm(context, _pinLenght),
pinForm(context, _pinLenght, currentChest),
SizedBox(height: 3 * ratio),
InkWell(
key: const Key('chooseChest'),
@ -95,7 +95,7 @@ class UnlockingWallet extends StatelessWidget {
Navigator.push(
context,
MaterialPageRoute(builder: (context) {
return const ChooseChest();
return ChooseChest(action: action);
}),
);
},
@ -103,11 +103,14 @@ class UnlockingWallet extends StatelessWidget {
width: 400,
height: 70,
child: Center(
child: Text('Changer de coffre',
style: TextStyle(
fontSize: 22,
color: orangeC,
fontWeight: FontWeight.w600))),
child: Text(
'Changer de coffre',
style: TextStyle(
fontSize: 22,
color: orangeC,
fontWeight: FontWeight.w600),
),
),
)),
]),
),
@ -115,7 +118,7 @@ class UnlockingWallet extends StatelessWidget {
));
}
Widget pinForm(context, _pinLenght) {
Widget pinForm(context, _pinLenght, ChestData currentChest) {
// var _walletPin = '';
// ignore: close_sinks
StreamController<ErrorAnimationType> errorController =
@ -125,7 +128,8 @@ class UnlockingWallet extends StatelessWidget {
Provider.of<WalletOptionsProvider>(context);
MyWalletsProvider _myWalletProvider =
Provider.of<MyWalletsProvider>(context);
HistoryProvider _historyProvider = Provider.of<HistoryProvider>(context);
WalletsProfilesProvider _historyProvider =
Provider.of<WalletsProfilesProvider>(context);
FocusNode pinFocus = FocusNode();
@ -194,7 +198,16 @@ class UnlockingWallet extends StatelessWidget {
pinColor = Colors.green[400];
// await Future.delayed(Duration(milliseconds: 50));
if (action == "mywallets") {
Navigator.pushNamed(formKey.currentContext, '/mywallets');
currentChest.isCesium
? Navigator.push(
context,
MaterialPageRoute(builder: (context) {
return CesiumWalletOptions(
cesiumWallet: currentChest);
}),
)
: Navigator.pushNamed(
formKey.currentContext, '/mywallets');
} else if (action == "pay") {
resultPay =
await _historyProvider.pay(context, _pin.toUpperCase());
@ -212,6 +225,7 @@ class UnlockingWallet extends StatelessWidget {
}
Future<bool> _paymentsResult(context) {
if (resultPay != "Success") log.i(resultPay);
return showDialog<bool>(
context: context,
barrierDismissible: true, // user must tap button!

View File

@ -3,11 +3,12 @@ import 'dart:ui';
import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
import 'package:gecko/globals.dart';
import 'package:gecko/models/history.dart';
import 'package:gecko/models/my_wallets.dart';
import 'package:gecko/models/queries.dart';
import 'package:gecko/models/wallet_data.dart';
import 'package:gecko/models/wallet_options.dart';
import 'package:gecko/models/wallets_profiles.dart';
import 'package:gecko/screens/history.dart';
import 'package:graphql_flutter/graphql_flutter.dart';
import 'package:provider/provider.dart';
import 'package:flutter/services.dart';
@ -24,10 +25,12 @@ class WalletOptions extends StatelessWidget {
Widget build(BuildContext context) {
SystemChrome.setPreferredOrientations([DeviceOrientation.portraitUp]);
WalletOptionsProvider _walletOptions =
Provider.of<WalletOptionsProvider>(context);
Provider.of<WalletOptionsProvider>(context, listen: false);
WalletsProfilesProvider _historyProvider =
Provider.of<WalletsProfilesProvider>(context, listen: false);
MyWalletsProvider _myWalletProvider =
Provider.of<MyWalletsProvider>(context);
HistoryProvider _historyProvider = Provider.of<HistoryProvider>(context);
final int _currentChest = _myWalletProvider.getCurrentChest();
final String shortPubkey =
@ -57,299 +60,340 @@ class WalletOptions extends StatelessWidget {
log.d("Wallet options: $currentChest:${wallet.number}");
return WillPopScope(
onWillPop: () {
_walletOptions.isEditing = false;
_walletOptions.isBalanceBlur = true;
Navigator.popUntil(
context,
ModalRoute.withName('/mywallets'),
);
return Future<bool>.value(true);
},
child: Scaffold(
resizeToAvoidBottomInset: false,
appBar: AppBar(
toolbarHeight: 60 * ratio,
leading: IconButton(
icon: const Icon(Icons.arrow_back, color: Colors.black),
onPressed: () {
_walletOptions.isEditing = false;
_walletOptions.isBalanceBlur = true;
Navigator.popUntil(
context,
ModalRoute.withName('/mywallets'),
);
}),
title: SizedBox(
height: 22,
child: Text(_walletOptions.nameController.text),
)),
body: Builder(
builder: (ctx) => SafeArea(
child: Column(children: <Widget>[
Container(
height: isTall ? 15 : 0,
color: yellowC,
),
Container(
decoration: BoxDecoration(
gradient: LinearGradient(
begin: Alignment.topCenter,
end: Alignment.bottomCenter,
colors: [
yellowC,
const Color(0xfffafafa),
],
)),
child: Row(children: <Widget>[
const SizedBox(width: 25),
InkWell(
onTap: () async {
File newAvatar =
await _walletOptions.changeAvatar();
if (newAvatar != null) {
wallet.imageFile = newAvatar;
}
_walletOptions.reloadBuild();
},
child: wallet.imageFile == null
? Image.asset(
'assets/avatars/${wallet.imageName}',
width: 110,
)
: Image.file(
wallet.imageFile,
width: 110,
)),
InkWell(
onTap: () async {
File newAvatar =
await _walletOptions.changeAvatar();
if (newAvatar != null) {
wallet.imageFile = newAvatar;
}
_walletOptions.reloadBuild();
},
child: Column(children: <Widget>[
Image.asset(
'assets/walletOptions/camera.png',
),
const SizedBox(height: 100)
])),
Column(children: <Widget>[
Row(children: <Widget>[
Column(children: <Widget>[
SizedBox(
width: 260,
child: TextField(
key: const Key('walletName'),
autofocus: false,
focusNode: _walletOptions.walletNameFocus,
enabled: _walletOptions.isEditing,
controller: _walletOptions.nameController,
maxLines: _nbrLinesName,
textAlign: TextAlign.center,
decoration: const InputDecoration(
border: InputBorder.none,
focusedBorder: InputBorder.none,
enabledBorder: InputBorder.none,
disabledBorder: InputBorder.none,
contentPadding: EdgeInsets.all(15.0),
),
style: TextStyle(
fontSize: isTall ? 27 : 23,
color: Colors.black,
fontWeight: FontWeight.w400,
fontFamily: 'Monospace')),
),
SizedBox(height: isTall ? 5 : 0),
Query(
options: QueryOptions(
document: gql(getBalance),
variables: {
'pubkey': _walletOptions.pubkey.text,
},
// pollInterval: Duration(seconds: 1),
),
builder: (QueryResult result,
{VoidCallback refetch, FetchMore fetchMore}) {
if (result.hasException) {
return Text(result.exception.toString());
}
if (result.isLoading) {
return const Text('Loading');
}
// List repositories = result.data['viewer']['repositories']['nodes'];
String wBalanceUD;
if (result.data['balance'] == null) {
wBalanceUD = '0.0';
} else {
int wBalanceG1 =
result.data['balance']['amount'];
int currentUD =
result.data['currentUd']['amount'];
double wBalanceUDBrut =
wBalanceG1 / currentUD; // .toString();
wBalanceUD = double.parse(
(wBalanceUDBrut).toStringAsFixed(2))
.toString();
}
return Row(children: <Widget>[
ImageFiltered(
imageFilter: ImageFilter.blur(
sigmaX: _walletOptions.isBalanceBlur
? 6
: 0,
sigmaY: _walletOptions.isBalanceBlur
? 5
: 0),
child: Text(wBalanceUD,
style: TextStyle(
fontSize: isTall ? 20 : 18,
color: Colors.black)),
),
Text(' DU',
style: TextStyle(
fontSize: isTall ? 20 : 18,
color: Colors.black))
]);
// Text(
// '$wBalanceUD DU',
// style: TextStyle(
// fontSize: 20, color: Colors.black),
// );
},
),
const SizedBox(height: 5),
InkWell(
key: const Key('displayBalance'),
onTap: () {
_walletOptions.bluringBalance();
},
child: Image.asset(
_walletOptions.isBalanceBlur
? 'assets/walletOptions/icon_oeuil.png'
: 'assets/walletOptions/icon_oeuil_close.png',
)),
]),
const SizedBox(width: 0),
Column(children: <Widget>[
InkWell(
key: const Key('renameWallet'),
onTap: () async {
_isNewNameValid =
_walletOptions.editWalletName(wallet.id(),
isCesium: false);
await Future.delayed(
const Duration(milliseconds: 30));
_walletOptions.walletNameFocus.requestFocus();
},
child: ClipRRect(
child: Image.asset(
_walletOptions.isEditing
? 'assets/walletOptions/android-checkmark.png'
: 'assets/walletOptions/edit.png',
width: 20,
height: 20),
)),
const SizedBox(
height: 60,
onWillPop: () {
_walletOptions.isEditing = false;
_walletOptions.isBalanceBlur = true;
Navigator.popUntil(
context,
ModalRoute.withName('/mywallets'),
);
return Future<bool>.value(true);
},
child: Scaffold(
resizeToAvoidBottomInset: false,
appBar: AppBar(
toolbarHeight: 60 * ratio,
elevation: 0,
leading: IconButton(
icon: const Icon(Icons.arrow_back, color: Colors.black),
onPressed: () {
_walletOptions.isEditing = false;
_walletOptions.isBalanceBlur = true;
Navigator.popUntil(
context,
ModalRoute.withName('/mywallets'),
);
}),
title: SizedBox(
height: 22,
child: Consumer<WalletOptionsProvider>(
builder: (context, walletProvider, _) {
return Text(_walletOptions.nameController.text);
}),
),
),
body: Builder(
builder: (ctx) => SafeArea(
child: Column(children: <Widget>[
Container(
height: isTall ? 5 : 0,
color: yellowC,
),
Consumer<WalletOptionsProvider>(
builder: (context, walletProvider, _) {
return Container(
decoration: BoxDecoration(
gradient: LinearGradient(
begin: Alignment.topCenter,
end: Alignment.bottomCenter,
colors: [
yellowC,
const Color(0xfffafafa),
],
)),
child: Row(children: <Widget>[
const SizedBox(width: 25),
InkWell(
onTap: () async {
File newAvatar = await walletProvider.changeAvatar();
if (newAvatar != null) {
wallet.imageFile = newAvatar;
}
walletProvider.reloadBuild();
},
child: wallet.imageFile == null
? Image.asset(
'assets/avatars/${wallet.imageName}',
width: 110,
)
])
: Image.file(
wallet.imageFile,
width: 110,
),
),
InkWell(
onTap: () async {
File newAvatar = await walletProvider.changeAvatar();
if (newAvatar != null) {
wallet.imageFile = newAvatar;
}
walletProvider.reloadBuild();
},
child: Column(children: <Widget>[
Image.asset(
'assets/walletOptions/camera.png',
height: 40,
),
const SizedBox(height: 80)
])),
Column(children: <Widget>[
Row(children: <Widget>[
Column(children: <Widget>[
SizedBox(
width: 260,
child: TextField(
key: const Key('walletName'),
autofocus: false,
focusNode: walletProvider.walletNameFocus,
enabled: walletProvider.isEditing,
controller: walletProvider.nameController,
maxLines: _nbrLinesName,
textAlign: TextAlign.center,
decoration: const InputDecoration(
border: InputBorder.none,
focusedBorder: InputBorder.none,
enabledBorder: InputBorder.none,
disabledBorder: InputBorder.none,
contentPadding: EdgeInsets.all(15.0),
),
style: TextStyle(
fontSize: isTall ? 27 : 23,
color: Colors.black,
fontWeight: FontWeight.w400,
fontFamily: 'Monospace')),
),
SizedBox(height: isTall ? 5 : 0),
Query(
options: QueryOptions(
document: gql(getBalance),
variables: {
'pubkey': walletProvider.pubkey.text,
},
// pollInterval: Duration(seconds: 1),
),
builder: (QueryResult result,
{VoidCallback refetch, FetchMore fetchMore}) {
if (result.hasException) {
return Text(result.exception.toString());
}
if (result.isLoading) {
return const Text('Loading');
}
// List repositories = result.data['viewer']['repositories']['nodes'];
String wBalanceUD;
if (result.data['balance'] == null) {
wBalanceUD = '0.0';
} else if (result.hasException) {
wBalanceUD = '?';
} else {
int wBalanceG1 =
result.data['balance']['amount'];
int currentUD =
result.data['currentUd']['amount'];
double wBalanceUDBrut =
wBalanceG1 / currentUD; // .toString();
wBalanceUD = double.parse(
(wBalanceUDBrut).toStringAsFixed(2))
.toString();
}
return Row(children: <Widget>[
ImageFiltered(
imageFilter: ImageFilter.blur(
sigmaX:
walletProvider.isBalanceBlur ? 6 : 0,
sigmaY:
walletProvider.isBalanceBlur ? 5 : 0),
child: Text(
wBalanceUD,
style: TextStyle(
fontSize: isTall ? 20 : 18,
color: Colors.black),
),
),
Text(' DU',
style: TextStyle(
fontSize: isTall ? 20 : 18,
color: Colors.black))
]);
// Text(
// '$wBalanceUD DU',
// style: TextStyle(
// fontSize: 20, color: Colors.black),
// );
},
),
const SizedBox(height: 5),
InkWell(
key: const Key('displayBalance'),
onTap: () {
walletProvider.bluringBalance();
},
child: Image.asset(
walletProvider.isBalanceBlur
? 'assets/walletOptions/icon_oeuil.png'
: 'assets/walletOptions/icon_oeuil_close.png',
height: 35,
),
),
]),
const SizedBox(width: 0),
Column(children: <Widget>[
InkWell(
key: const Key('renameWallet'),
onTap: () async {
_isNewNameValid = walletProvider.editWalletName(
wallet.id(),
isCesium: false);
await Future.delayed(
const Duration(milliseconds: 30));
walletProvider.walletNameFocus.requestFocus();
},
child: ClipRRect(
child: Image.asset(
walletProvider.isEditing
? 'assets/walletOptions/android-checkmark.png'
: 'assets/walletOptions/edit.png',
width: 20,
height: 20),
)),
const SizedBox(
height: 60,
)
])
]),
])),
SizedBox(height: 4 * ratio),
FutureBuilder(
future: _walletOptions
.generateQRcode(_walletOptions.pubkey.text),
builder: (context, snapshot) {
return snapshot.data != null
? Image.memory(snapshot.data,
height: isTall ? 300 : 270)
: const Text('-', style: TextStyle(fontSize: 20));
}),
SizedBox(height: 15 * ratio),
GestureDetector(
]),
]),
);
}),
SizedBox(height: 4 * ratio),
FutureBuilder(
future:
_walletOptions.generateQRcode(_walletOptions.pubkey.text),
builder: (context, snapshot) {
return snapshot.data != null
? Image.memory(snapshot.data, height: isTall ? 300 : 270)
: const Text('-', style: TextStyle(fontSize: 20));
},
),
SizedBox(height: 15 * ratio),
Consumer<WalletOptionsProvider>(
builder: (context, walletProvider, _) {
return Column(children: [
GestureDetector(
key: const Key('copyPubkey'),
onTap: () {
Clipboard.setData(
ClipboardData(text: _walletOptions.pubkey.text));
_walletOptions.snackCopyKey(ctx);
ClipboardData(text: walletProvider.pubkey.text));
walletProvider.snackCopyKey(ctx);
},
child: SizedBox(
height: 50,
child: Row(children: <Widget>[
const SizedBox(width: 30),
Image.asset(
'assets/walletOptions/key.png',
height: 50,
child: Row(children: <Widget>[
const SizedBox(width: 30),
Image.asset(
'assets/walletOptions/key.png',
height: 45,
),
const SizedBox(width: 20),
Text("${shortPubkey.split(':')[0]}:",
style: const TextStyle(
fontSize: 22,
fontWeight: FontWeight.w800,
fontFamily: 'Monospace',
color: Colors.black)),
Text(shortPubkey.split(':')[1],
style: const TextStyle(
fontSize: 22,
fontWeight: FontWeight.w800,
fontFamily: 'Monospace')),
const SizedBox(width: 15),
SizedBox(
height: 40,
child: ElevatedButton(
style: ElevatedButton.styleFrom(
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(8),
),
elevation: 1,
primary: orangeC, // background
onPrimary: Colors.black, // foreground
),
onPressed: () {
Clipboard.setData(ClipboardData(
text: walletProvider.pubkey.text));
walletProvider.snackCopyKey(ctx);
},
child: Row(children: <Widget>[
Image.asset(
'assets/walletOptions/copy-white.png',
height: 25,
),
const SizedBox(width: 7),
Text(
'Copier',
style: TextStyle(
fontSize: 15, color: Colors.grey[50]),
)
]),
),
const SizedBox(width: 20),
Text("${shortPubkey.split(':')[0]}:",
style: const TextStyle(
fontSize: 22,
fontWeight: FontWeight.w800,
fontFamily: 'Monospace',
color: Colors.black)),
Text(shortPubkey.split(':')[1],
style: const TextStyle(
fontSize: 22,
fontWeight: FontWeight.w800,
fontFamily: 'Monospace')),
const SizedBox(width: 15),
SizedBox(
height: 40,
child: ElevatedButton(
style: ElevatedButton.styleFrom(
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(8),
),
elevation: 1,
primary: orangeC, // background
onPrimary: Colors.black, // foreground
),
onPressed: () {
Clipboard.setData(ClipboardData(
text: _walletOptions.pubkey.text));
_walletOptions.snackCopyKey(ctx);
},
child: Row(children: <Widget>[
Image.asset(
'assets/walletOptions/copy-white.png',
),
const SizedBox(width: 7),
Text('Copier',
style: TextStyle(
fontSize: 15,
color: Colors.grey[50]))
]))),
]))),
SizedBox(height: 10 * ratio),
InkWell(
),
]),
),
),
SizedBox(height: 10 * ratio),
InkWell(
key: const Key('displayHistory'),
onTap: () {
_historyProvider.isPubkey(ctx, _walletOptions.pubkey.text,
goHistory: true);
_historyProvider.nPage = 1;
Navigator.push(
context,
MaterialPageRoute(builder: (context) {
return HistoryScreen(
pubkey: walletProvider.pubkey.text,
avatar: wallet.imageFile == null
? Image.asset(
'assets/avatars/${wallet.imageName}',
width: 110,
)
: Image.file(
wallet.imageFile,
width: 110,
));
}),
);
},
child: SizedBox(
height: 50,
child: Row(children: <Widget>[
const SizedBox(width: 30),
Image.asset(
'assets/walletOptions/clock.png',
),
const SizedBox(width: 22),
const Text('Historique des transactions',
style:
TextStyle(fontSize: 20, color: Colors.black)),
]))),
SizedBox(height: 12 * ratio),
InkWell(
height: 50,
child: Row(children: <Widget>[
const SizedBox(width: 30),
Image.asset(
'assets/walletOptions/clock.png',
height: 45,
),
const SizedBox(width: 22),
const Text('Historique des transactions',
style:
TextStyle(fontSize: 20, color: Colors.black)),
]),
),
),
SizedBox(height: 12 * ratio),
InkWell(
key: const Key('setDefaultWallet'),
onTap: !_walletOptions.isDefaultWallet
onTap: !walletProvider.isDefaultWallet
? () {
defaultWallet = wallet;
chestBox.get(currentChest).defaultWallet =
@ -359,33 +403,37 @@ class WalletOptions extends StatelessWidget {
}
: null,
child: SizedBox(
height: 50,
child: Row(children: <Widget>[
const SizedBox(width: 31),
CircleAvatar(
backgroundColor: Colors.grey[
_walletOptions.isDefaultWallet ? 300 : 500],
child: Image.asset(
'assets/walletOptions/android-checkmark.png',
)),
const SizedBox(width: 22),
Text(
_walletOptions.isDefaultWallet
? 'Ce portefeuille est celui par defaut'
: 'Définir comme portefeuille par défaut',
style: TextStyle(
fontSize: 20,
color: _walletOptions.isDefaultWallet
? Colors.grey[500]
: Colors.black)),
]))),
SizedBox(height: 17 * ratio),
if (!_walletOptions.isDefaultWallet)
InkWell(
height: 50,
child: Row(children: <Widget>[
const SizedBox(width: 31),
CircleAvatar(
backgroundColor: Colors
.grey[walletProvider.isDefaultWallet ? 300 : 500],
child: Image.asset(
'assets/walletOptions/android-checkmark.png',
height: 25,
),
),
const SizedBox(width: 22),
Text(
walletProvider.isDefaultWallet
? 'Ce portefeuille est celui par defaut'
: 'Définir comme portefeuille par défaut',
style: TextStyle(
fontSize: 20,
color: walletProvider.isDefaultWallet
? Colors.grey[500]
: Colors.black)),
]),
),
),
SizedBox(height: 17 * ratio),
if (!walletProvider.isDefaultWallet)
InkWell(
key: const Key('deleteWallet'),
onTap: !_walletOptions.isDefaultWallet
onTap: !walletProvider.isDefaultWallet
? () async {
await _walletOptions.deleteWallet(
await walletProvider.deleteWallet(
context, wallet);
WidgetsBinding.instance.addPostFrameCallback((_) {
_myWalletProvider.listWallets =
@ -396,18 +444,23 @@ class WalletOptions extends StatelessWidget {
}
: null,
child: Row(children: <Widget>[
const SizedBox(width: 33),
const SizedBox(width: 30),
Image.asset(
'assets/walletOptions/trash.png',
height: 45,
),
const SizedBox(width: 24),
const SizedBox(width: 19),
const Text('Supprimer ce portefeuille',
style: TextStyle(
fontSize: 20, color: Color(0xffD80000))),
])),
]),
),
]),
),
]);
}),
]),
),
));
),
),
);
}
}

View File

@ -7,11 +7,9 @@ import 'package:gecko/models/wallet_data.dart';
import 'package:gecko/models/wallet_options.dart';
import 'package:flutter/material.dart';
import 'package:gecko/screens/common_elements.dart';
import 'package:gecko/screens/myWallets/cesium_wallet_options.dart';
import 'package:gecko/screens/myWallets/chest_options.dart';
import 'package:gecko/screens/myWallets/choose_chest.dart';
import 'package:gecko/screens/myWallets/wallet_options.dart';
import 'package:gecko/screens/onBoarding/0_no_keychain_found.dart';
import 'package:graphql_flutter/graphql_flutter.dart';
import 'package:provider/provider.dart';
@ -28,13 +26,8 @@ class WalletsHome extends StatelessWidget {
final int _currentChestNumber = myWalletProvider.getCurrentChest();
final ChestData _currentChest = chestBox.get(_currentChestNumber);
bool isWalletsExists;
if (!_currentChest.isCesium) {
myWalletProvider.listWallets =
myWalletProvider.readAllWallets(_currentChestNumber);
}
isWalletsExists = myWalletProvider.checkIfWalletExist();
myWalletProvider.listWallets =
myWalletProvider.readAllWallets(_currentChestNumber);
return WillPopScope(
onWillPop: () {
@ -61,12 +54,7 @@ class WalletsHome extends StatelessWidget {
backgroundColor: const Color(0xffFFD58D),
),
body: SafeArea(
child: !isWalletsExists
? const NoKeyChainScreen()
: _currentChest.isCesium
? cesiumWalletOptions(
context, _currentChest, myWalletProvider)
: myWalletsTiles(context),
child: myWalletsTiles(context),
),
),
);

View File

@ -0,0 +1,485 @@
import 'package:flutter/services.dart';
import 'package:gecko/globals.dart';
import 'package:gecko/models/cesium_plus.dart';
import 'package:gecko/models/home.dart';
import 'package:gecko/models/my_wallets.dart';
import 'package:gecko/models/queries.dart';
import 'package:gecko/models/wallets_profiles.dart';
import 'package:flutter/material.dart';
import 'package:flutter/foundation.dart';
import 'package:gecko/models/wallet_data.dart';
import 'package:gecko/screens/myWallets/unlocking_wallet.dart';
import 'package:gecko/screens/wallet_view.dart';
import 'dart:ui';
import 'package:graphql_flutter/graphql_flutter.dart';
import 'package:provider/provider.dart';
import 'package:flutter_svg/flutter_svg.dart';
// ignore: must_be_immutable
class OldHistoryScreen extends StatelessWidget with ChangeNotifier {
final TextEditingController _outputPubkey = TextEditingController();
ScrollController scrollController = ScrollController();
final nRepositories = 20;
// HistoryProvider _historyProvider;
final _formKey = GlobalKey<FormState>();
final FocusNode _pubkeyFocus = FocusNode();
final double avatarsSize = 80;
FetchMore fetchMore;
FetchMoreOptions opts;
final GlobalKey<ScaffoldState> _scaffoldKey = GlobalKey<ScaffoldState>();
OldHistoryScreen({Key key}) : super(key: key);
@override
Widget build(BuildContext context) {
SystemChrome.setPreferredOrientations([DeviceOrientation.portraitUp]);
WalletsProfilesProvider _historyProvider =
Provider.of<WalletsProfilesProvider>(context);
HomeProvider _homeProvider = Provider.of<HomeProvider>(context);
_outputPubkey.text = _historyProvider.pubkey;
log.i('Build pubkey : ' + _historyProvider.pubkey);
WidgetsBinding.instance.addPostFrameCallback((_) {});
return Scaffold(
key: _scaffoldKey,
appBar: AppBar(
toolbarHeight: 60 * ratio,
title: _homeProvider.appBarExplorer,
actions: [
Padding(
padding: const EdgeInsets.symmetric(horizontal: 16),
child: IconButton(
icon: _homeProvider.searchIcon,
color: Colors.grey[850],
onPressed: () {
if (_homeProvider.searchIcon.icon == Icons.search) {
_homeProvider.searchIcon = Icon(
Icons.close,
color: Colors.grey[850],
);
_homeProvider.appBarExplorer = TextField(
autofocus: true,
controller: _homeProvider.searchQuery,
onChanged: (text) {
log.d("Clé tappé: $text");
if (_historyProvider.isPubkey(text)) {
_homeProvider.currentIndex = 0;
Navigator.push(
context,
MaterialPageRoute(builder: (context) {
return WalletViewScreen(pubkey: text);
}),
);
}
},
style: TextStyle(
color: Colors.grey[850],
),
decoration: InputDecoration(
prefixIcon:
Icon(Icons.search, color: Colors.grey[850]),
hintText: "Rechercher ...",
hintStyle: TextStyle(color: Colors.grey[850])),
);
_homeProvider.handleSearchStart();
} else {
_homeProvider.handleSearchEnd();
}
}))
],
backgroundColor: const Color(0xffFFD58D),
),
floatingActionButton: SizedBox(
height: 80.0,
width: 80.0,
child: FittedBox(
child: FloatingActionButton(
heroTag: "buttonScan",
onPressed: () async {
await _historyProvider.scan(context);
},
child: SizedBox(
height: 40.0,
width: 40.0,
child: Padding(
padding: const EdgeInsets.symmetric(horizontal: 3),
child: Image.asset('assets/qrcode-scan.png'))),
backgroundColor:
floattingYellow, //smoothYellow, //Color.fromARGB(500, 204, 255, 255),
),
),
),
body: Column(children: <Widget>[
const SizedBox(height: 0),
if (_historyProvider.pubkey != '')
historyQuery(context, _historyProvider),
]));
}
Widget historyQuery(context, WalletsProfilesProvider _historyProvider) {
_pubkeyFocus.unfocus();
// HistoryProvider _historyProvider = Provider.of<HistoryProvider>(context);
CesiumPlusProvider _cesiumPlusProvider =
Provider.of<CesiumPlusProvider>(context);
bool _isFirstExec = true;
return Expanded(
child: Column(
mainAxisAlignment: MainAxisAlignment.start,
mainAxisSize: MainAxisSize.max,
children: <Widget>[
Query(
options: QueryOptions(
document: gql(getHistory),
variables: <String, dynamic>{
'pubkey': _historyProvider.pubkey,
'number': nRepositories,
'cursor': null
},
),
builder: (QueryResult result, {fetchMore, refetch}) {
if (result.isLoading && result.data == null) {
return const Center(
child: CircularProgressIndicator(),
);
}
if (result.hasException) {
log.e('Error GVA: ' + result.exception.toString());
return Column(children: const <Widget>[
SizedBox(height: 50),
Text(
"Aucun noeud GVA valide n'a pu être trouvé.\nVeuillez réessayer ultérieurement.",
style: TextStyle(fontSize: 17.0),
)
]);
}
if (result.data == null && result.exception.toString() == null) {
return const Text('Aucune donnée à afficher.');
}
num balance;
if (result.data['balance'] == null) {
balance = 0.0;
} else {
balance = _historyProvider
.removeDecimalZero(result.data['balance']['amount'] / 100);
}
opts = _historyProvider.checkQueryResult(
result, opts, _outputPubkey.text);
// _historyProvider.transBC = null;
// Build history list
return NotificationListener(
child: Builder(
builder: (context) => Expanded(
child: ListView(
key: const Key('listTransactions'),
controller: scrollController,
children: <Widget>[
const SizedBox(height: 20),
if (_historyProvider.pubkey != '')
Row(
mainAxisAlignment:
MainAxisAlignment.spaceBetween,
mainAxisSize: MainAxisSize.min,
crossAxisAlignment: CrossAxisAlignment.center,
children: [
if (_isFirstExec)
Container(
padding: const EdgeInsets.fromLTRB(
20, 0, 30, 0),
child: FutureBuilder(
future:
_cesiumPlusProvider.getAvatar(
_historyProvider.pubkey,
55),
builder: (BuildContext context,
AsyncSnapshot<Image> _avatar) {
if (_avatar.connectionState !=
ConnectionState.done ||
_avatar.hasError) {
return Stack(children: [
_cesiumPlusProvider
.defaultAvatar(55),
Positioned(
top: 8,
right: 0,
width: 12,
height: 12,
child:
CircularProgressIndicator(
strokeWidth: 1,
color: orangeC,
),
),
]);
}
if (_avatar.hasData) {
return ClipOval(
child: _avatar.data,
);
}
return _cesiumPlusProvider
.defaultAvatar(55);
}),
),
GestureDetector(
key: const Key('copyPubkey'),
onTap: () {
Clipboard.setData(ClipboardData(
text: _historyProvider.pubkey));
_historyProvider.snackCopyKey(context);
},
child: Text(
_historyProvider.getShortPubkey(
_historyProvider.pubkey),
style: const TextStyle(
fontSize: 22,
fontWeight: FontWeight.w800,
fontFamily: 'Monospace')),
),
Container(
padding: const EdgeInsets.fromLTRB(
30, 0, 5, 0), // .only(right: 15),
child: Card(
child: Column(
children: <Widget>[
SvgPicture.string(
_historyProvider
.generateIdenticon(
_historyProvider
.pubkey),
fit: BoxFit.contain,
height: 64,
width: 64,
),
],
),
)),
const SizedBox(width: 0)
]),
if (_isFirstExec)
Row(
mainAxisAlignment:
MainAxisAlignment.spaceAround,
crossAxisAlignment: CrossAxisAlignment.center,
children: [
Container(
padding:
const EdgeInsets.fromLTRB(0, 0, 0, 0),
// padding: const EdgeInsets.,
child: FutureBuilder(
future: _cesiumPlusProvider
.getName(_historyProvider.pubkey),
initialData: '...',
builder: (context, snapshot) {
return Text(snapshot.data ?? '-',
style: const TextStyle(
fontSize: 20));
}),
)
]),
const SizedBox(height: 18),
if (_isFirstExec)
Container(
padding:
const EdgeInsets.fromLTRB(0, 0, 0, 0),
child: Text(balance.toString() + ' Ğ1',
textAlign: TextAlign.center,
style: const TextStyle(fontSize: 18.0))),
const SizedBox(height: 20),
ElevatedButton(
key: const Key('switchPayHistory'),
style: ElevatedButton.styleFrom(
elevation: 1,
primary: Colors.grey[50], // background
onPrimary: Colors.black, // foreground
),
onPressed: () {
_historyProvider.switchProfileView();
},
child: Text(
_historyProvider.historySwitchButtun,
style: TextStyle(
fontSize: 15, color: orangeC))),
// const Divider(
// color: Colors.grey,
// height: 5,
// thickness: 0.5,
// indent: 0,
// endIndent: 0,
// ),
_historyProvider.isHistoryScreen
? historyView(context, result)
: payView(context, _historyProvider),
],
))),
onNotification: (t) {
if (t is ScrollEndNotification &&
scrollController.position.pixels >=
scrollController.position.maxScrollExtent * 0.7) {
fetchMore(opts);
}
return true;
});
},
),
],
));
}
Widget payView(context, WalletsProfilesProvider _historyProvider) {
MyWalletsProvider _myWalletProvider = MyWalletsProvider();
WalletData defaultWallet =
_myWalletProvider.getDefaultWallet(configBox.get('currentChest'));
return Stack(
clipBehavior: Clip.hardEdge,
children: <Widget>[
Form(
key: _formKey,
child: Column(
mainAxisSize: MainAxisSize.min,
children: <Widget>[
const SizedBox(height: 20),
const Text('Commentaire:', style: TextStyle(fontSize: 20.0)),
Padding(
padding: const EdgeInsets.all(8.0),
child: TextField(
controller: _historyProvider.payComment,
maxLines: 2,
textAlign: TextAlign.center,
decoration: const InputDecoration(),
style: const TextStyle(
fontSize: 22,
color: Colors.black,
fontWeight: FontWeight.bold))),
const SizedBox(height: 20),
const Text('Montant (DU/Ğ1):', style: TextStyle(fontSize: 20.0)),
Padding(
padding: const EdgeInsets.all(8.0),
child: TextFormField(
style: const TextStyle(fontSize: 22),
controller: _historyProvider.payAmount,
textAlign: TextAlign.center,
maxLines: 1,
keyboardType: TextInputType.number,
decoration: InputDecoration(
contentPadding: const EdgeInsets.symmetric(
vertical: 25.0, horizontal: 10.0),
border: OutlineInputBorder(
borderRadius: BorderRadius.circular(10.0)),
),
inputFormatters: <TextInputFormatter>[
FilteringTextInputFormatter.allow(RegExp(r'(^\d*\.?\d*)'))
],
),
),
Padding(
padding: const EdgeInsets.only(top: 15),
child: OutlinedButton(
style: OutlinedButton.styleFrom(
side: BorderSide(width: 2, color: orangeC)),
onPressed: () {
// if (_formKey.currentState.validate()) {
// _formKey.currentState.save();
// }
// _historyProvider.pay(payAmount.text, payComment.text);
Navigator.push(
context,
MaterialPageRoute(builder: (context) {
return UnlockingWallet(
wallet: defaultWallet, action: "pay");
}),
);
},
child: Padding(
padding: const EdgeInsets.all(12),
child: Text(
"PAYER",
style: TextStyle(fontSize: 25, color: Colors.grey[850]),
),
),
),
)
],
),
),
],
);
}
Widget historyView(context, result) {
WalletsProfilesProvider _historyProvider =
Provider.of<WalletsProfilesProvider>(context);
HomeProvider _homeProvider =
Provider.of<HomeProvider>(context, listen: false);
int keyID = 0;
return _historyProvider.transBC == null
? const Text('Aucune transaction à afficher.')
: Column(children: <Widget>[
for (var repository in _historyProvider.transBC)
Padding(
padding: const EdgeInsets.symmetric(horizontal: 5.0),
child: ListTile(
key: Key('transaction${keyID++}'),
contentPadding: const EdgeInsets.all(5.0),
leading: Text(repository[1].toString(),
style: TextStyle(
fontSize: 12,
color: Colors.grey[800],
fontWeight: FontWeight.w700),
textAlign: TextAlign.center),
title: Text(repository[3],
style: const TextStyle(
fontSize: 15.0, fontFamily: 'Monospace'),
textAlign: TextAlign.center),
subtitle: Text(repository[6] != '' ? repository[6] : '-',
style: const TextStyle(fontSize: 12.0),
textAlign: TextAlign.center),
trailing: Text("${repository[4]} Ğ1",
style: const TextStyle(fontSize: 14.0),
textAlign: TextAlign.justify),
dense: true,
isThreeLine: false,
onTap: () {
if (_historyProvider.isPubkey(repository[2])) {
_homeProvider.currentIndex = 0;
Navigator.push(
context,
MaterialPageRoute(builder: (context) {
return WalletViewScreen(pubkey: repository[2]);
}),
);
}
Navigator.pop(context);
}),
),
if (result.isLoading &&
_historyProvider.pageInfo['hasPreviousPage'])
Row(
mainAxisAlignment: MainAxisAlignment.center,
children: const <Widget>[
CircularProgressIndicator(),
],
),
// if (_historyProvider.isTheEnd) // What I did before ...
if (!_historyProvider.pageInfo['hasPreviousPage'])
Column(
children: const <Widget>[
SizedBox(height: 15),
Text("Début de l'historique.",
textAlign: TextAlign.center,
style: TextStyle(fontSize: 20)),
SizedBox(height: 15)
],
)
]);
}
}

View File

@ -4,7 +4,7 @@ import 'package:flutter/material.dart';
import 'package:flutter_svg/flutter_svg.dart';
import 'package:gecko/globals.dart';
import 'package:gecko/screens/common_elements.dart';
import 'package:gecko/screens/myWallets/import_wallet.dart';
import 'package:gecko/screens/myWallets/import_cesium_wallet.dart';
import 'package:gecko/screens/onBoarding/1.dart';
class NoKeyChainScreen extends StatelessWidget {

View File

@ -46,13 +46,10 @@ class OnboardingStepFiveteen extends StatelessWidget {
onPrimary: Colors.white, // foreground
),
onPressed: () {
Navigator.popUntil(
context,
ModalRoute.withName('/'),
);
Navigator.pushNamed(
Navigator.pushNamedAndRemoveUntil(
context,
'/mywallets',
ModalRoute.withName('/'),
);
},
child: const Text("Accéder à mes portefeuilles",

View File

@ -51,6 +51,7 @@ class OnboardingStepNine extends StatelessWidget {
},
child: Image.asset(
'assets/printer.png',
height: 35,
),
),
Expanded(
@ -133,55 +134,63 @@ Widget sentanceArray(BuildContext context) {
builder: (context, formatedArray) {
// print(formatedArray.data);
return Container(
padding: const EdgeInsets.symmetric(horizontal: 12),
child: Container(
decoration: BoxDecoration(
border: Border.all(color: Colors.black),
color: Colors.grey[300],
borderRadius: const BorderRadius.all(
Radius.circular(10),
)),
// color: Colors.grey[300],
padding: const EdgeInsets.all(20),
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
mainAxisSize: MainAxisSize.max,
crossAxisAlignment: CrossAxisAlignment.center,
children: <Widget>[
Row(children: <Widget>[
arrayCell(formatedArray.data[0]),
arrayCell(formatedArray.data[1]),
arrayCell(formatedArray.data[2]),
arrayCell(formatedArray.data[3]),
]),
const SizedBox(height: 15),
Row(children: <Widget>[
arrayCell(formatedArray.data[4]),
arrayCell(formatedArray.data[5]),
arrayCell(formatedArray.data[6]),
arrayCell(formatedArray.data[7]),
]),
const SizedBox(height: 15),
Row(children: <Widget>[
arrayCell(formatedArray.data[8]),
arrayCell(formatedArray.data[9]),
arrayCell(formatedArray.data[10]),
arrayCell(formatedArray.data[11]),
]),
])));
padding: const EdgeInsets.symmetric(horizontal: 12),
child: Container(
decoration: BoxDecoration(
border: Border.all(color: Colors.black),
color: Colors.grey[300],
borderRadius: const BorderRadius.all(
Radius.circular(10),
)),
// color: Colors.grey[300],
padding: const EdgeInsets.all(20),
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
mainAxisSize: MainAxisSize.max,
crossAxisAlignment: CrossAxisAlignment.center,
children: <Widget>[
Row(children: <Widget>[
arrayCell(formatedArray.data[0]),
arrayCell(formatedArray.data[1]),
arrayCell(formatedArray.data[2]),
arrayCell(formatedArray.data[3]),
]),
const SizedBox(height: 15),
Row(children: <Widget>[
arrayCell(formatedArray.data[4]),
arrayCell(formatedArray.data[5]),
arrayCell(formatedArray.data[6]),
arrayCell(formatedArray.data[7]),
]),
const SizedBox(height: 15),
Row(children: <Widget>[
arrayCell(formatedArray.data[8]),
arrayCell(formatedArray.data[9]),
arrayCell(formatedArray.data[10]),
arrayCell(formatedArray.data[11]),
]),
]),
),
);
});
}
Widget arrayCell(dataWord) {
return SizedBox(
width: 102,
child: Column(children: <Widget>[
Text(dataWord.split(':')[0], style: const TextStyle(fontSize: 14)),
const SizedBox(height: 2),
Text(dataWord.split(':')[1],
key: Key('word${dataWord.split(':')[0]}'),
style: const TextStyle(fontSize: 19, color: Colors.black)),
]));
width: 102,
child: Column(children: <Widget>[
Text(
dataWord.split(':')[0],
style: const TextStyle(fontSize: 14),
),
const SizedBox(height: 2),
Text(
dataWord.split(':')[1],
key: Key('word${dataWord.split(':')[0]}'),
style: const TextStyle(fontSize: 19, color: Colors.black),
),
]),
);
}
// ignore: must_be_immutable

109
lib/screens/search.dart Normal file
View File

@ -0,0 +1,109 @@
import 'package:flutter/services.dart';
import 'package:gecko/globals.dart';
import 'package:flutter/material.dart';
import 'package:gecko/models/search.dart';
import 'package:gecko/screens/search_result.dart';
import 'package:provider/provider.dart';
// import 'package:gecko/models/home.dart';
// import 'package:provider/provider.dart';
class SearchScreen extends StatelessWidget {
const SearchScreen({Key key}) : super(key: key);
@override
Widget build(BuildContext context) {
SystemChrome.setPreferredOrientations([DeviceOrientation.portraitUp]);
SearchProvider _searchProvider = Provider.of<SearchProvider>(context);
return WillPopScope(
onWillPop: () {
_searchProvider.searchController.text = '';
return Future<bool>.value(true);
},
child: Scaffold(
appBar: AppBar(
toolbarHeight: 60 * ratio,
title: const SizedBox(
height: 22,
child: Text('Rechercher'),
),
leading: IconButton(
icon: const Icon(Icons.arrow_back, color: Colors.black),
onPressed: () {
_searchProvider.searchController.text = '';
Navigator.of(context).pop();
}),
),
body: SafeArea(
child: Column(children: <Widget>[
SizedBox(height: isTall ? 200 : 100),
Padding(
padding: const EdgeInsets.symmetric(horizontal: 17),
child: TextField(
controller: _searchProvider.searchController,
autofocus: true,
maxLines: 1,
textAlign: TextAlign.left,
onChanged: (v) => _searchProvider.rebuildWidget(),
decoration: InputDecoration(
filled: true,
fillColor: Colors.white,
prefixIconConstraints: const BoxConstraints(
minHeight: 32,
),
prefixIcon: const Padding(
padding: EdgeInsets.symmetric(horizontal: 17),
child: Image(
image: AssetImage('assets/loupe-noire.png'),
height: 35),
),
border: OutlineInputBorder(
borderSide:
BorderSide(color: Colors.grey[500], width: 2),
borderRadius: BorderRadius.circular(8)),
focusedBorder: OutlineInputBorder(
borderSide:
BorderSide(color: Colors.grey[500], width: 2.5),
borderRadius: BorderRadius.circular(8),
),
contentPadding: const EdgeInsets.all(20),
),
style: const TextStyle(
fontSize: 20,
color: Colors.black,
fontWeight: FontWeight.w400,
),
),
),
const Spacer(flex: 1),
SizedBox(
width: 410,
height: 70,
child: ElevatedButton(
style: ElevatedButton.styleFrom(
elevation: 4,
primary: orangeC, // background
onPrimary: Colors.white, // foreground
),
onPressed: _searchProvider.searchController.text.length >= 2
? () {
Navigator.push(
context,
MaterialPageRoute(builder: (context) {
return const SearchResultScreen();
}),
);
}
: null,
child: const Text(
'Rechercher',
style: TextStyle(fontSize: 24, fontWeight: FontWeight.w600),
),
),
),
const Spacer(flex: 1),
]),
),
));
}
}

View File

@ -0,0 +1,184 @@
import 'package:flutter/services.dart';
import 'package:gecko/globals.dart';
import 'package:flutter/material.dart';
import 'package:gecko/models/cesium_plus.dart';
import 'package:gecko/models/g1_wallets_list.dart';
import 'package:gecko/models/wallets_profiles.dart';
import 'package:gecko/models/search.dart';
import 'package:gecko/screens/wallet_view.dart';
import 'package:provider/provider.dart';
class SearchResultScreen extends StatelessWidget {
const SearchResultScreen({Key key}) : super(key: key);
@override
Widget build(BuildContext context) {
SystemChrome.setPreferredOrientations([DeviceOrientation.portraitUp]);
SearchProvider _searchProvider =
Provider.of<SearchProvider>(context, listen: false);
CesiumPlusProvider _cesiumPlusProvider =
Provider.of<CesiumPlusProvider>(context, listen: false);
WalletsProfilesProvider _walletsProfilesClass =
Provider.of<WalletsProfilesProvider>(context, listen: false);
int keyID = 0;
double _avatarSize = 55;
return Scaffold(
appBar: AppBar(
toolbarHeight: 60 * ratio,
title: const SizedBox(
height: 22,
child: Text('Résultats de votre recherche'),
),
),
body: SafeArea(
child: Padding(
padding: const EdgeInsets.symmetric(horizontal: 20),
child:
Column(crossAxisAlignment: CrossAxisAlignment.start, children: <
Widget>[
const SizedBox(height: 30),
RichText(
text: TextSpan(
style: TextStyle(
fontSize: 18,
color: Colors.grey[700],
),
children: <TextSpan>[
const TextSpan(
text: "Résultats pour ",
),
TextSpan(
text: '"${_searchProvider.searchController.text}"',
style: const TextStyle(fontStyle: FontStyle.italic),
),
],
),
),
const SizedBox(height: 40),
const Text(
'Dans la blockchain Ğ1',
style: TextStyle(fontSize: 20),
),
const SizedBox(height: 20),
FutureBuilder(
future: _searchProvider.searchBlockchain(),
builder: (context, snapshot) {
if (snapshot.connectionState == ConnectionState.done) {
return Expanded(
child: ListView(children: <Widget>[
for (G1WalletsList g1Wallet in snapshot.data)
Padding(
padding: const EdgeInsets.symmetric(horizontal: 5),
child: ListTile(
key: Key('searchResult${keyID++}'),
horizontalTitleGap: 40,
contentPadding: const EdgeInsets.all(5),
leading: g1WalletsBox
.get(g1Wallet.pubkey)
?.avatar !=
null
? ClipOval(
child: g1WalletsBox
.get(g1Wallet.pubkey)
.avatar)
: FutureBuilder(
future: _cesiumPlusProvider.getAvatar(
g1Wallet.pubkey, _avatarSize),
builder: (BuildContext context,
AsyncSnapshot<Image> _avatar) {
if (_avatar.connectionState !=
ConnectionState.done ||
_avatar.hasError) {
return Stack(children: [
_cesiumPlusProvider
.defaultAvatar(_avatarSize),
Positioned(
top: 8,
right: 0,
width: 12,
height: 12,
child: CircularProgressIndicator(
strokeWidth: 1,
color: orangeC,
),
),
]);
}
if (_avatar.hasData) {
g1WalletsBox
.get(g1Wallet.pubkey)
.avatar = _avatar.data;
return ClipOval(child: _avatar.data);
} else {
g1WalletsBox
.get(g1Wallet.pubkey)
.avatar =
_cesiumPlusProvider
.defaultAvatar(_avatarSize);
return _cesiumPlusProvider
.defaultAvatar(_avatarSize);
}
}),
title: Row(children: <Widget>[
Text(
_walletsProfilesClass
.getShortPubkey(g1Wallet.pubkey),
style: const TextStyle(
fontSize: 18,
fontFamily: 'Monospace',
fontWeight: FontWeight.w500),
textAlign: TextAlign.center),
]),
subtitle: Row(children: <Widget>[
Text(g1Wallet?.id?.username ?? '',
style: const TextStyle(
fontSize: 18,
fontWeight: FontWeight.w500),
textAlign: TextAlign.center),
]),
dense: false,
isThreeLine: false,
onTap: () {
Navigator.push(
context,
MaterialPageRoute(builder: (context) {
_walletsProfilesClass.pubkey =
g1Wallet.pubkey;
return WalletViewScreen(
pubkey: g1Wallet.pubkey,
username: g1WalletsBox
.get(g1Wallet.pubkey)
?.id
?.username,
avatar: g1WalletsBox
.get(g1Wallet.pubkey)
?.avatar,
);
}),
);
}),
),
]),
);
}
return Center(
heightFactor: 5,
child: CircularProgressIndicator(
strokeWidth: 3,
backgroundColor: yellowC,
color: orangeC,
),
);
},
),
// Text(
// _searchProvider.searchResult.toString(),
// )
]),
),
),
);
}
}

View File

@ -1,13 +1,11 @@
import 'package:flutter/material.dart';
import 'package:dubp/dubp.dart';
import 'package:flutter/services.dart';
import 'package:gecko/models/home.dart';
import 'package:gecko/models/my_wallets.dart';
import 'package:gecko/screens/myWallets/generate_wallets.dart';
import 'dart:io';
import 'package:gecko/screens/myWallets/import_wallet.dart';
import 'package:gecko/screens/myWallets/import_cesium_wallet.dart';
import 'package:gecko/globals.dart';
import 'package:provider/provider.dart';
// ignore: must_be_immutable
class SettingsScreen extends StatelessWidget {
@ -29,7 +27,6 @@ class SettingsScreen extends StatelessWidget {
@override
Widget build(BuildContext context) {
SystemChrome.setPreferredOrientations([DeviceOrientation.portraitUp]);
HomeProvider _homeProvider = Provider.of<HomeProvider>(context);
// getAppDirectory();
return Scaffold(
@ -94,9 +91,7 @@ class SettingsScreen extends StatelessWidget {
),
onPressed: () async => {
log.i('Suppression de tous les wallets'),
await _myWallets
.deleteAllWallet(context)
.then((v) => _homeProvider.rebuildWidget())
await _myWallets.deleteAllWallet(context)
},
child: const Text("EFFACER TOUS MES PORTEFEUILLES",
style: TextStyle(fontSize: 20)))))),

View File

@ -1,6 +1,5 @@
import 'package:flutter/services.dart';
import 'package:gecko/globals.dart';
import 'package:gecko/screens/home.dart';
import 'package:flutter/material.dart';
// import 'package:gecko/models/home.dart';
// import 'package:provider/provider.dart';
@ -22,26 +21,6 @@ class TemplateScreen extends StatelessWidget {
height: 22,
child: Text('Template screen'),
)),
floatingActionButton: SizedBox(
height: 80.0,
width: 80.0,
child: FittedBox(
child: FloatingActionButton(
heroTag: "tplButton",
onPressed: () => Navigator.push(
context,
MaterialPageRoute(builder: (context) {
return const HomeScreen();
}),
),
child: SizedBox(
height: 40.0,
width: 40.0,
child: Icon(Icons.home, color: Colors.grey[850]),
),
backgroundColor:
floattingYellow, //smoothYellow, //Color.fromARGB(500, 204, 255, 255),
))),
body: SafeArea(
child: Column(children: <Widget>[
const SizedBox(height: 20),
@ -58,30 +37,6 @@ class TemplateScreen extends StatelessWidget {
color: Colors.black,
fontWeight: FontWeight.w400)),
const SizedBox(height: 20),
ElevatedButton(
style: ElevatedButton.styleFrom(
primary: yellowC, // background
onPrimary: Colors.black, // foreground
),
onPressed: () {
Navigator.push(
context,
MaterialPageRoute(builder: (context) {
return const HomeScreen();
}),
);
},
child: const Text('Retour Accueil',
style: TextStyle(fontSize: 20))),
const SizedBox(height: 20),
GestureDetector(
onTap: () {
Navigator.popUntil(
context,
ModalRoute.withName('/'),
);
},
child: const Icon(Icons.home))
]),
));
}

View File

@ -0,0 +1,502 @@
import 'dart:ui';
import 'package:flutter/services.dart';
import 'package:gecko/globals.dart';
import 'package:flutter/material.dart';
import 'package:gecko/models/cesium_plus.dart';
import 'package:gecko/models/my_wallets.dart';
import 'package:gecko/models/wallet_data.dart';
import 'package:gecko/models/wallets_profiles.dart';
import 'package:gecko/models/queries.dart';
import 'package:gecko/screens/avatar_fullscreen.dart';
import 'package:gecko/screens/common_elements.dart';
import 'package:gecko/screens/history.dart';
import 'package:gecko/screens/myWallets/unlocking_wallet.dart';
import 'package:graphql_flutter/graphql_flutter.dart';
import 'package:provider/provider.dart';
class WalletViewScreen extends StatelessWidget {
const WalletViewScreen(
{@required this.pubkey, this.username, this.avatar, Key key})
: super(key: key);
final String pubkey;
final String username;
final Image avatar;
final double buttonSize = 100;
final double buttonFontSize = 18;
@override
Widget build(BuildContext context) {
SystemChrome.setPreferredOrientations([DeviceOrientation.portraitUp]);
WalletsProfilesProvider _historyProvider =
Provider.of<WalletsProfilesProvider>(context, listen: false);
CesiumPlusProvider _cesiumPlusProvider =
Provider.of<CesiumPlusProvider>(context, listen: false);
return Scaffold(
resizeToAvoidBottomInset: true,
appBar: AppBar(
elevation: 0,
toolbarHeight: 60 * ratio,
title: const SizedBox(
height: 22,
child: Text('Voir un portefeuille'),
),
),
body: SafeArea(
child: Column(children: <Widget>[
headerProfileView(context, _historyProvider, _cesiumPlusProvider),
SizedBox(height: isTall ? 120 : 70),
Row(mainAxisAlignment: MainAxisAlignment.spaceAround, children: [
Column(children: <Widget>[
SizedBox(
height: buttonSize,
child: ClipOval(
child: Material(
color: const Color(0xffFFD58D), // button color
child: InkWell(
key: const Key('viewHistory'),
splashColor: orangeC, // inkwell color
child: const Padding(
padding: EdgeInsets.all(13),
child: Image(
image: AssetImage(
'assets/walletOptions/clock.png'),
height: 90)),
onTap: () {
_historyProvider.nPage = 1;
Navigator.push(
context,
FaderTransition(
page: HistoryScreen(
pubkey: pubkey,
username: username ??
g1WalletsBox.get(pubkey)?.username,
avatar: avatar ??
g1WalletsBox.get(pubkey)?.avatar,
),
isFast: false),
);
}),
),
),
),
const SizedBox(height: 9),
Text(
"Voir\nl'historique",
textAlign: TextAlign.center,
style: TextStyle(
fontSize: buttonFontSize, fontWeight: FontWeight.w500),
),
]),
Column(children: <Widget>[
SizedBox(
height: buttonSize,
child: ClipOval(
child: Material(
color: const Color(0xffFFD58D), // button color
child: InkWell(
key: const Key('copyKey'),
splashColor: orangeC, // inkwell color
child: const Padding(
padding: EdgeInsets.all(20),
child: Image(
image: AssetImage('assets/copy_key.png'),
height: 90)),
onTap: () {
Clipboard.setData(ClipboardData(text: pubkey));
_historyProvider.snackCopyKey(context);
}),
),
),
),
const SizedBox(height: 9),
Text(
"Copier\nla clef",
textAlign: TextAlign.center,
style: TextStyle(
fontSize: buttonFontSize, fontWeight: FontWeight.w500),
),
]),
]),
// FutureBuilder(
// future: _walletOptions.generateQRcode(_historyProvider.pubkey),
// builder: (context, snapshot) {
// return snapshot.data != null
// ? GestureDetector(
// key: const Key('openQrcode'),
// onTap: () {
// Navigator.push(
// context,
// MaterialPageRoute(builder: (context) {
// return AvatarFullscreen(
// Image.memory(snapshot.data),
// title: 'QrCode du profil',
// color: Colors.white,
// );
// }),
// );
// },
// child: Image.memory(snapshot.data, height: 60 * ratio),
// )
// : const Text('-', style: TextStyle(fontSize: 20));
// },
// ),
const Spacer(),
Container(
height: buttonSize,
decoration: BoxDecoration(
color: const Color(0xff7c94b6),
borderRadius: const BorderRadius.all(Radius.circular(100)),
border: Border.all(
color: const Color(0xFF6c4204),
width: 4,
),
),
child: ClipOval(
child: Material(
color: orangeC, // button color
child: InkWell(
key: const Key('pay'),
splashColor: yellowC, // inkwell color
child: const Padding(
padding: EdgeInsets.all(14),
child: Image(
image: AssetImage('assets/vector_white.png'),
)),
onTap: () {
paymentPopup(context, _historyProvider);
}),
),
),
),
const SizedBox(height: 9),
Text(
"Faire un\nvirement",
textAlign: TextAlign.center,
style: TextStyle(
fontSize: buttonFontSize, fontWeight: FontWeight.w500),
),
SizedBox(height: isTall ? 120 : 70)
]),
));
}
void paymentPopup(
BuildContext context, WalletsProfilesProvider _walletViewProvider) {
// WalletsProfilesProvider _walletViewProvider =
// Provider.of<WalletsProfilesProvider>(context);
const double shapeSize = 20;
MyWalletsProvider _myWalletProvider = MyWalletsProvider();
WalletData defaultWallet =
_myWalletProvider.getDefaultWallet(configBox.get('currentChest'));
showModalBottomSheet<void>(
shape: const RoundedRectangleBorder(
borderRadius: BorderRadius.only(
topRight: Radius.circular(shapeSize),
topLeft: Radius.circular(shapeSize),
),
),
isScrollControlled: true,
context: context,
builder: (BuildContext context) {
return Padding(
padding: EdgeInsets.only(
bottom: MediaQuery.of(context).viewInsets.bottom),
child: Container(
height: 400,
decoration: const ShapeDecoration(
color: Color(0xffffeed1),
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.only(
topRight: Radius.circular(shapeSize),
topLeft: Radius.circular(shapeSize),
),
),
),
child: Padding(
padding: const EdgeInsets.all(24),
child: Column(
mainAxisSize: MainAxisSize.min,
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
const Text(
'Effectuer un virement',
style: TextStyle(
fontSize: 26, fontWeight: FontWeight.w700),
),
const SizedBox(height: 20),
Text(
'Saisissez dans le champ ci-dessous le montant à virer de ... vers ...',
style: TextStyle(
fontSize: 19,
fontWeight: FontWeight.w500,
color: Colors.grey[600]),
),
const Spacer(),
Center(
child: Column(children: <Widget>[
TextField(
controller: _walletViewProvider.payAmount,
autofocus: true,
maxLines: 1,
textAlign: TextAlign.center,
keyboardType: TextInputType.number,
inputFormatters: <TextInputFormatter>[
FilteringTextInputFormatter.allow(
RegExp(r'^\d+\.?\d{0,2}')),
],
// onChanged: (v) => _searchProvider.rebuildWidget(),
decoration: InputDecoration(
hintText: '0.00',
suffix: const Text('DU/Ğ1'),
filled: true,
fillColor: Colors.transparent,
// border: OutlineInputBorder(
// borderSide:
// BorderSide(color: Colors.grey[500], width: 2),
// borderRadius: BorderRadius.circular(8)),
focusedBorder: OutlineInputBorder(
borderSide: BorderSide(
color: Colors.grey[500], width: 2),
borderRadius: BorderRadius.circular(8),
),
contentPadding: const EdgeInsets.all(20),
),
style: const TextStyle(
fontSize: 40,
color: Colors.black,
fontWeight: FontWeight.w600,
),
),
const SizedBox(height: 40),
// const Spacer(),
SizedBox(
width: double.infinity,
height: 60,
child: ElevatedButton(
style: ElevatedButton.styleFrom(
elevation: 4,
primary: orangeC, // background
onPrimary: Colors.white, // foreground
),
onPressed: () {
Navigator.push(
context,
MaterialPageRoute(
builder: (context) {
return UnlockingWallet(
wallet: defaultWallet, action: "pay");
},
),
);
},
child: const Text(
'Effectuer le virement',
style: TextStyle(
fontSize: 20, fontWeight: FontWeight.w600),
),
),
),
const SizedBox(height: 20),
]),
),
]),
),
),
);
}).then((value) => _walletViewProvider.payAmount.text = '');
}
Widget headerProfileView(
BuildContext context,
WalletsProfilesProvider _historyProvider,
CesiumPlusProvider _cesiumPlusProvider) {
const double _avatarSize = 140;
return Column(children: <Widget>[
Container(
height: 10,
color: yellowC,
),
Container(
decoration: BoxDecoration(
gradient: LinearGradient(
begin: Alignment.topCenter,
end: Alignment.bottomCenter,
colors: [
yellowC,
const Color(0xFFE7811A),
],
)),
child: Padding(
padding: const EdgeInsets.only(left: 30, right: 40),
child: Row(children: <Widget>[
Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
Row(children: [
GestureDetector(
key: const Key('copyPubkey'),
onTap: () {
Clipboard.setData(ClipboardData(text: pubkey));
_historyProvider.snackCopyKey(context);
},
child: Text(
_historyProvider.getShortPubkey(pubkey),
style: const TextStyle(
fontSize: 30,
fontWeight: FontWeight.w800,
),
),
),
]),
const SizedBox(height: 10),
if (username == null &&
g1WalletsBox.get(pubkey)?.username == null)
Query(
options: QueryOptions(
document: gql(getId),
variables: {
'pubkey': pubkey,
},
),
builder: (QueryResult result,
{VoidCallback refetch, FetchMore fetchMore}) {
if (result.isLoading || result.hasException) {
return const Text('...');
} else if (result.data['idty'] == null ||
result.data['idty']['username'] == null) {
g1WalletsBox.get(pubkey)?.username = '';
return const Text('');
} else {
g1WalletsBox.get(pubkey)?.username =
result?.data['idty']['username'] ?? '';
return SizedBox(
width: 230,
child: Text(
result?.data['idty']['username'] ?? '',
style: const TextStyle(
fontSize: 27,
color: Color(0xff814C00),
),
),
);
}
},
),
if (username == null &&
g1WalletsBox.get(pubkey)?.username != null)
SizedBox(
width: 230,
child: Text(
g1WalletsBox.get(pubkey)?.username,
style: const TextStyle(
fontSize: 27,
color: Color(0xff814C00),
),
),
),
if (username != null)
SizedBox(
width: 230,
child: Text(
username,
style: const TextStyle(
fontSize: 27,
color: Color(0xff814C00),
),
),
),
const SizedBox(height: 25),
FutureBuilder(
future: _cesiumPlusProvider.getName(pubkey),
initialData: '...',
builder: (context, snapshot) {
return SizedBox(
width: 230,
child: Text(
snapshot.data ?? '-',
style: const TextStyle(
fontSize: 18, color: Colors.black),
),
);
}),
const SizedBox(height: 30),
]),
const Spacer(),
Column(children: <Widget>[
if (avatar == null)
FutureBuilder(
future: _cesiumPlusProvider.getAvatar(pubkey, _avatarSize),
builder:
(BuildContext context, AsyncSnapshot<Image> _avatar) {
if (_avatar.connectionState != ConnectionState.done) {
return Stack(children: [
ClipOval(
child:
_cesiumPlusProvider.defaultAvatar(_avatarSize),
),
Positioned(
top: 15,
right: 45,
width: 51,
height: 51,
child: CircularProgressIndicator(
strokeWidth: 5,
color: orangeC,
),
),
]);
}
if (_avatar.hasData) {
return GestureDetector(
key: const Key('openAvatar'),
onTap: () {
Navigator.push(
context,
MaterialPageRoute(builder: (context) {
return AvatarFullscreen(_avatar.data);
}),
);
},
child: ClipOval(
child: Image(
image: _avatar.data.image,
height: _avatarSize,
fit: BoxFit.cover,
),
),
);
}
return ClipOval(
child: _cesiumPlusProvider.defaultAvatar(_avatarSize),
);
}),
if (avatar != null)
GestureDetector(
key: const Key('openAvatar'),
onTap: () {
Navigator.push(
context,
MaterialPageRoute(builder: (context) {
return AvatarFullscreen(avatar);
}),
);
},
child: ClipOval(
child: Image(
image: avatar.image,
height: _avatarSize,
fit: BoxFit.cover,
),
),
),
const SizedBox(height: 25),
]),
]),
),
),
]);
}
}

View File

@ -267,6 +267,13 @@ packages:
url: "https://pub.dartlang.org"
source: hosted
version: "0.5.6"
dio:
dependency: "direct main"
description:
name: dio
url: "https://pub.dartlang.org"
source: hosted
version: "4.0.4"
dubp:
dependency: "direct main"
description:
@ -544,6 +551,13 @@ packages:
url: "https://pub.dartlang.org"
source: hosted
version: "2.4.1"
infinite_scroll_pagination:
dependency: "direct main"
description:
name: infinite_scroll_pagination
url: "https://pub.dartlang.org"
source: hosted
version: "3.1.0"
integration_test:
dependency: "direct dev"
description: flutter
@ -878,6 +892,13 @@ packages:
url: "https://pub.dartlang.org"
source: hosted
version: "1.1.0"
pull_to_refresh:
dependency: "direct main"
description:
name: pull_to_refresh
url: "https://pub.dartlang.org"
source: hosted
version: "2.0.0"
qr:
dependency: transitive
description:
@ -1002,6 +1023,13 @@ packages:
description: flutter
source: sdk
version: "0.0.99"
sliver_tools:
dependency: transitive
description:
name: sliver_tools
url: "https://pub.dartlang.org"
source: hosted
version: "0.2.5"
source_gen:
dependency: transitive
description:

View File

@ -5,13 +5,16 @@ description: Pay with G1.
# pub.dev using `pub publish`. This is preferred for private packages.
publish_to: 'none' # Remove this line if you wish to publish to pub.dev
version: 0.0.2+11
version: 0.0.3+13
environment:
sdk: ">=2.7.0 <3.0.0"
dependencies:
assorted_layout_widgets: ^5.2.1
bubble: ^1.2.1
carousel_slider: ^4.0.0
confirm_dialog: ^1.0.0
crypto: ^3.0.1
dubp:
path: packages/dubp_rs
@ -21,14 +24,16 @@ dependencies:
flutter_driver:
sdk: flutter
flutter_launcher_icons: ^0.9.2
flutter_lints: ^1.0.4
flutter_logs: ^2.1.4
flutter_svg: ^0.22.0
graphql_flutter: ^5.0.0
hive: ^2.0.4
hive_flutter: ^1.1.0
http: ^0.13.0
http: ^0.13.4
image_gallery_saver: ^1.6.9
image_picker: ^0.8.4
infinite_scroll_pagination: ^3.1.0
intl: ^0.17.0
jdenticon_dart: ^2.0.0
logger: ^1.1.0
@ -38,7 +43,7 @@ dependencies:
permission_handler: 8.1.6
pin_code_fields: ^7.3.0
printing: ^5.6.0
provider: ^6.0.0
provider: ^6.0.1
qrscan: ^0.3.2
responsive_builder: ^0.4.1
responsive_framework: ^0.1.4
@ -48,15 +53,11 @@ dependencies:
super_tooltip: ^1.0.1
sync_http: ^0.3.0
test: ^1.17.10
# test_api: ^0.4.7
# test: ^1.19.3
truncate: ^3.0.1
unorm_dart: ^0.2.0
xml: ^5.3.0
assorted_layout_widgets: ^5.2.1
carousel_slider: ^4.0.0
flutter_lints: ^1.0.4
confirm_dialog: ^1.0.0
pull_to_refresh: ^2.0.0
dio: ^4.0.4
flutter_icons:
android: "ic_launcher"
@ -65,12 +66,12 @@ flutter_icons:
cupertino_icons: ^1.0.0
dev_dependencies:
build_runner: ^2.1.2
flutter_test:
sdk: flutter
hive_generator: ^1.1.1
integration_test:
sdk: flutter
hive_generator: ^1.1.1
build_runner: ^2.1.2
# The following section is specific to Flutter.
flutter:
@ -80,6 +81,7 @@ flutter:
- images/
- config/gva_endpoints.json
- assets/
- assets/home/
- assets/customs/
- assets/avatars/
- assets/chests/

View File

@ -20,8 +20,8 @@ if [[ $1 == "bundle" ]]; then
flutter build appbundle --release --target-platform android-arm,android-arm64 --build-name $VERSION --build-number $BUILD
else
# flutter build apk --release --split-per-abi --target-platform android-arm,android-arm64 --build-name $VERSION --build-number $BUILD
# flutter build apk --release --split-per-abi --build-name $VERSION --build-number $BUILD
flutter build apk --release --build-name $VERSION --build-number $BUILD
flutter build apk --release --split-per-abi --build-name $VERSION --build-number $BUILD
# flutter build apk --release --build-name $VERSION --build-number $BUILD
fi
if [[ -d $HOME/Téléchargements ]]; then

View File

@ -217,8 +217,9 @@ void main() {
{timeout = Timeout.none}) async {
expect(await getText('step9'),
"Super !\n\nJe vais maintenant créer votre code secret. \n\nVotre code secret chiffre votre trousseau de clefs, ce qui le rend inutilisable par dautres, par exemple si vous perdez votre téléphone ou si on vous le vole.");
await sleep(800);
await tapOn('goStep10');
await sleep(50);
await tapOn('goStep11');
while (await getText('generatedPin') == '') {