From b42177e3a328fc1e123ca9f809978dcccf5b4f64 Mon Sep 17 00:00:00 2001 From: Bayarbileg <bayarbileg.batbileg@edu.unige.ch> Date: Wed, 20 Jan 2021 23:33:29 +0100 Subject: [PATCH 1/6] changed checkCode to Trace --- lib/QR.dart | 4 ++-- lib/models/Event.dart | 4 ++-- lib/utils.dart | 6 +++--- 3 files changed, 7 insertions(+), 7 deletions(-) diff --git a/lib/QR.dart b/lib/QR.dart index 5711640..b5af542 100644 --- a/lib/QR.dart +++ b/lib/QR.dart @@ -39,7 +39,7 @@ class QR extends StatelessWidget { var seed = _getSeed(event.name, event.location, event.salt, event.notifKey); KeyPair keyPair = _keyGen(seed); - event.checkCode = _getCheckCode(seed); + event.trace = _getTrace(seed); event.publicKey = keyPair.pk; event.secretKey = keyPair.sk; event.infected = false; @@ -114,7 +114,7 @@ class QR extends StatelessWidget { // Rend un checkCode qui permet de vérifier si l'événement est infecté. // Le checkCode est envoyé au backend que si l'événement est infécté. // On le stocke quand même dans l'événement. - static String _getCheckCode(seed) { + static String _getTrace(seed) { Uint8List authorityPublicKey = Uint8List.fromList(hex.decode( 'e4d2e06641730ce7c9986b1e7e91bf41bb3b8cc1d76d249fa99d0d8925e87a5c')); var checkCode = diff --git a/lib/models/Event.dart b/lib/models/Event.dart index 6b9856f..f61e6ab 100644 --- a/lib/models/Event.dart +++ b/lib/models/Event.dart @@ -32,7 +32,7 @@ class Event extends HiveObject { @HiveField(10) List<int> _publicKey; @HiveField(11) - String checkCode; + String trace; // Un événement créé par l'utilisateur. Event({ @@ -44,7 +44,7 @@ class Event extends HiveObject { @required this.startDate, // valeur par defaut -> now this.endDate, this.infected, - this.checkCode, + this.trace, // @required this.participant, }); diff --git a/lib/utils.dart b/lib/utils.dart index dfcdf28..87c0644 100644 --- a/lib/utils.dart +++ b/lib/utils.dart @@ -25,7 +25,7 @@ void printBox(String boxname) { print("|-- \t secretKey : ${ev.secretKey == null ? "null" : ev.secretKey}"); print("|-- \t salt : ${ev.salt == null ? "null" : ev.salt}"); print("|-- \t publicKey : ${ev.publicKey == null ? "null" : ev.publicKey}"); - print("|-- \t checkCode : ${ev.checkCode == null ? "null" : ev.checkCode}"); + print("|-- \t checkCode : ${ev.trace == null ? "null" : ev.trace}"); print( "===============================================================================================================\n"); } @@ -46,7 +46,7 @@ void verifyCheckCodeForEvents() async { Box<Event> eventBox = Hive.box<Event>('event'); for (var event in eventBox.values) { - if (checkCodeList.contains(event.checkCode)) { + if (checkCodeList.contains(event.trace)) { event.infected = true; event.save(); //TODO: Call notification for infected event @@ -73,7 +73,7 @@ Future<List> fetchCheckCodes() async { // POST - checkCode Future<void> sendCheckCode(Event event, context) async { var message = { - 'secretKey': event.checkCode, + 'secretKey': event.trace, 'startTime': event.startDate.millisecondsSinceEpoch.toString(), 'endTime': event.endDate != null ? event.endDate.millisecondsSinceEpoch.toString() -- GitLab From 8f0ba961e30fc9d1862d563baa4f5f674aeb90f7 Mon Sep 17 00:00:00 2001 From: Bayarbileg <bayarbileg.batbileg@edu.unige.ch> Date: Fri, 22 Jan 2021 18:52:29 +0100 Subject: [PATCH 2/6] added publicKey to Json as it should be in CrNo --- lib/QR.dart | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/lib/QR.dart b/lib/QR.dart index d2a348b..b5af542 100644 --- a/lib/QR.dart +++ b/lib/QR.dart @@ -33,8 +33,7 @@ class QR extends StatelessWidget { }); factory QR.fromEvent(Event event) { - if (event.notifKey.isEmpty) { - // remplissage de la classe Event lorsqu'elle est pas complète + if (event.notifKey == null) { // remplissage de la classe Event lorsqu'elle est pas complète event.salt = _salt(); event.notifKey = _notifkey(); var seed = @@ -98,7 +97,7 @@ class QR extends StatelessWidget { 'startDate': startDate, 'endDate': endDate, 'notificationKey': notifKey, - 'publicKey': publicKey, + 'publicKey' : publicKey, }; } @@ -135,7 +134,7 @@ class QR extends StatelessWidget { child: QrImage( data: jsonEncode(_codeWrapperQR()), version: QrVersions.auto, - size: MediaQuery.of(context).size.width * 0.48, + size: 200, foregroundColor: Theme.of(context).primaryColorLight, ), decoration: BoxDecoration( -- GitLab From 9a996299966e64cf314ab0ea9ea40889a24214a3 Mon Sep 17 00:00:00 2001 From: Bayarbileg <bayarbileg.batbileg@edu.unige.ch> Date: Fri, 22 Jan 2021 19:48:07 +0100 Subject: [PATCH 3/6] Button to export data made --- lib/journal.dart | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/lib/journal.dart b/lib/journal.dart index d872274..3109f5d 100644 --- a/lib/journal.dart +++ b/lib/journal.dart @@ -109,6 +109,21 @@ class _JournalState extends State<Journal> with TickerProviderStateMixin { onPressed: Navigator.of(context).pop, ), actions: <Widget>[ + Padding( + padding: EdgeInsets.only(right: 20.0), + child: GestureDetector( + onTap: () => showDialog( + context: context, + builder: (BuildContext context) => new AlertDialog( + title: Text('implement export function here'), + ), + ), + child: Icon( + Icons.import_export, + color: Theme.of(context).accentColor, + ), + ), + ), Padding( padding: EdgeInsets.only(right: 20.0), child: GestureDetector( -- GitLab From ca3f182fdd50f3250681629b54780c0bdf391115 Mon Sep 17 00:00:00 2001 From: Bayarbileg <bayarbileg.batbileg@edu.unige.ch> Date: Sun, 24 Jan 2021 11:57:26 +0100 Subject: [PATCH 4/6] changes for demo version fo the app uses trace sharing --- lib/QR.dart | 15 ++++++++++----- lib/boutonScan.dart | 25 +++++++++++-------------- lib/journal.dart | 3 +++ lib/main.dart | 14 ++++++++++---- lib/models/Event.dart | 27 ++++++++++++++++----------- lib/utils.dart | 26 +++++++++++++++++++++++--- test/qr_test.dart | 2 +- 7 files changed, 74 insertions(+), 38 deletions(-) diff --git a/lib/QR.dart b/lib/QR.dart index b5af542..27c1220 100644 --- a/lib/QR.dart +++ b/lib/QR.dart @@ -19,6 +19,7 @@ class QR extends StatelessWidget { final Uint8List publicKey; final Uint8List secretKey; final Uint8List salt; + final String trace; QR._({ this.name, @@ -30,10 +31,12 @@ class QR extends StatelessWidget { this.publicKey, this.secretKey, this.salt, + this.trace, }); factory QR.fromEvent(Event event) { - if (event.notifKey == null) { // remplissage de la classe Event lorsqu'elle est pas complète + if (event.notifKey.isEmpty) { + // remplissage de la classe Event lorsqu'elle est pas complète event.salt = _salt(); event.notifKey = _notifkey(); var seed = @@ -55,6 +58,7 @@ class QR extends StatelessWidget { publicKey: event.publicKey, secretKey: event.secretKey, salt: event.salt, + trace: event.trace, ); } @@ -103,11 +107,12 @@ class QR extends StatelessWidget { // On wrap le contenu en le signant le seed avec la clé secrète String _codeWrapperQR() { - var content = _contentQR(); - return json.encode({ + Map<String, dynamic> content = _contentQR(); + return jsonEncode({ 'signature': CryptoSign.signDetached( - Uint8List.fromList(utf8.encode(json.encode(content))), secretKey), + Uint8List.fromList(utf8.encode(jsonEncode(content))), secretKey), 'content': content, + 'trace' : trace, }); } @@ -132,7 +137,7 @@ class QR extends StatelessWidget { width: MediaQuery.of(context).size.width, height: MediaQuery.of(context).size.height * 0.60, child: QrImage( - data: jsonEncode(_codeWrapperQR()), + data: _codeWrapperQR(), version: QrVersions.auto, size: 200, foregroundColor: Theme.of(context).primaryColorLight, diff --git a/lib/boutonScan.dart b/lib/boutonScan.dart index 516bbb3..ae48883 100644 --- a/lib/boutonScan.dart +++ b/lib/boutonScan.dart @@ -6,6 +6,7 @@ import 'package:flutter_barcode_scanner/flutter_barcode_scanner.dart'; import 'package:hive/hive.dart'; import 'package:toast/toast.dart'; import 'package:validators/validators.dart'; +import 'utils.dart'; import 'models/Event.dart'; @@ -58,25 +59,22 @@ class BoutonScanState extends State<BoutonScan> { // Ici on exécute le code pour décoder la classe protobuff obtenue d'un URL de crowdnotifier/notifyMe. try { addition = Event.fromURL(qrContent); - print("Event in scan:" + addition.created.toString()); - event.add(addition); } on FormatException catch (e) { Toast.show(e.message, context); } catch (e) { - Toast.show(e, context); + Toast.show(e.message, context); } } else if (isJSON(qrContent)) { // Ici on tente de décoder en JSON try { addition = Event.fromJson(jsonDecode(qrContent)); - event.add(addition); - } on PlatformException { - Toast.show("Failed to get platform version.", context); - } on FormatException { - Toast.show("Format Exception", context); + } on PlatformException catch(e) { + Toast.show("Failed to get platform version > ${e.message}", context); + } on FormatException catch(e) { + Toast.show("Format Exception > ${e.message}", context); } } else { - Toast.show("invlaid QR Code", context); + Toast.show("invalid QR Code", context); } return addition; @@ -86,11 +84,10 @@ class BoutonScanState extends State<BoutonScan> { String res; res = await FlutterBarcodeScanner.scanBarcode( "#FFFFFF00", "Cancel", true, ScanMode.QR); - - final addedEvent = parseQRContent(res); - - if (addedEvent != null) { - Toast.show("Added event at: " + addedEvent.location, context); + final parsedEvent = parseQRContent(res); + await event.add(parsedEvent); + if (parsedEvent != null) { + Toast.show("Added event is: " + parsedEvent.name, context); } } } diff --git a/lib/journal.dart b/lib/journal.dart index 3109f5d..a5fc0ba 100644 --- a/lib/journal.dart +++ b/lib/journal.dart @@ -237,6 +237,9 @@ class _JournalState extends State<Journal> with TickerProviderStateMixin { color: Colors.green, size: 35, ), + // Fonctionnalite utilise pour debug a ne pas decommenter pour demo + // onTap: () => sendCheckCode(event,context), + // onLongPress: () async => await Hive.box<Event>('event').deleteAll(Hive.box<Event>('event').keys), ), ), ); diff --git a/lib/main.dart b/lib/main.dart index 9f78df2..7568706 100644 --- a/lib/main.dart +++ b/lib/main.dart @@ -7,6 +7,7 @@ import 'journal.dart'; import 'package:naca/models/Event.dart'; import "package:naca/models/User.dart"; import 'package:intl/date_symbol_data_local.dart'; +import 'package:flutter/services.dart'; void main() async { // We init the Hive @@ -19,13 +20,18 @@ void main() async { await Hive.openBox<User>('user'); Sodium.init(); // Init le package Sodium - initUser(); // function to initialize only one user, since we have no login screen... - initializeDateFormatting('fr').then((_) => runApp(CovidApp())); + await initUser(); // function to initialize only one user, since we have no login screen... + await initializeDateFormatting('fr').then((_) => runApp(CovidApp())); } class CovidApp extends StatelessWidget { @override Widget build(BuildContext context) { + // On force ici le mode portrait pour ne pas laisser l'app tourner et creer des overflows. + SystemChrome.setPreferredOrientations([ + DeviceOrientation.portraitUp, + DeviceOrientation.portraitDown, + ]); return MaterialApp( routes: { '/journal': (context) => Journal(), @@ -44,10 +50,10 @@ class CovidApp extends StatelessWidget { } } -void initUser() { +Future<void> initUser() async { Box<User> userBox = Hive.box<User>('user'); if (userBox.length == 0) { User user = new User(firstname: 'UserFirstName', lastname: 'UserLastName'); - userBox.put('mainUser', user); + await userBox.put('mainUser', user); } } diff --git a/lib/models/Event.dart b/lib/models/Event.dart index 47136c3..26a7a7c 100644 --- a/lib/models/Event.dart +++ b/lib/models/Event.dart @@ -3,6 +3,7 @@ import 'dart:typed_data'; import 'package:hive/hive.dart'; import 'package:meta/meta.dart'; import 'package:naca/proto_out/qr.pbserver.dart'; +import 'package:naca/utils.dart'; part 'Event.g.dart'; @@ -46,7 +47,7 @@ class Event extends HiveObject { this.infected, this.trace, // @required this.participant, - }) { + }){ _notifKey = []; _publicKey = []; _secretKey = []; @@ -87,14 +88,14 @@ class Event extends HiveObject { // Factory prennant un JSON en entrée pour créer un EventCreated factory Event.fromJson(Map<String, dynamic> json) { - return Event( + return new Event( name: json['content']['name'], location: json['content']['location'], - context: json['content']['context'], - startDate: json['content']['startDate'], - endDate: json['content']['endDate'], - created: false, + context: json['content']['contexte'], + startDate: DateTime.parse(json['content']['startDate']), + endDate : json['content']['endDate'] == 'null' ? null : DateTime.parse(json['content']['endDate']), infected: false, + trace: json['trace'], ) .._notifKey = json['content']['notificationKey']?.cast<int>() .._publicKey = json['content']['publicKey']?.cast<int>(); @@ -116,7 +117,9 @@ class Event extends HiveObject { final byteList = base64Url.decode(normalizedBase64String); - final protobufOutput = QRCodeWrapper.fromBuffer(byteList).content; + final protoBuf = QRCodeWrapper.fromBuffer(byteList); + + final protobufOutput = protoBuf.content; return Event( name: protobufOutput.hasName() ? protobufOutput.name : "No name", @@ -136,9 +139,11 @@ class Event extends HiveObject { : null, created: false, infected: false, - ).._notifKey = protobufOutput.hasNotificationKey() - ? protobufOutput.notificationKey - : null; - // manque ici peut etre le publicKey... a voir... + ) + .._notifKey = protobufOutput.hasNotificationKey() + ? protobufOutput.notificationKey + : null + .._publicKey = protoBuf.hasPublicKey() ? protoBuf.publicKey : null; + // On ne peut pas verifier l'infectiosité de l'événement si l'événement a été crée par CrNo. } } diff --git a/lib/utils.dart b/lib/utils.dart index 87c0644..e4d9b0e 100644 --- a/lib/utils.dart +++ b/lib/utils.dart @@ -1,5 +1,4 @@ import 'dart:convert'; - import 'package:hive/hive.dart'; import 'package:toast/toast.dart'; import 'models/Event.dart'; @@ -31,6 +30,29 @@ void printBox(String boxname) { } } +// Print a given event +void printAnEvent(Event event){ + var ev = event; + print( + "Evenement =================================================================================================="); + print("|-- \t Nom : ${ev.name}"); + print("|-- \t Location : ${ev.location}"); + print("|-- \t Contexte : ${ev.context}"); + print("|-- \t StartDate : ${ev.startDate}"); + + print("|-- \t EndDate : ${ev.endDate == null ? "null" : ev.endDate}"); + print("|-- \t Created : ${ev.created}"); + + print("|-- \t Infected : ${ev.infected == null ? "null" : ev.infected}"); + print("|-- \t notifKey : ${ev.notifKey == null ? "null" : ev.notifKey}"); + print("|-- \t secretKey : ${ev.secretKey == null ? "null" : ev.secretKey}"); + print("|-- \t salt : ${ev.salt == null ? "null" : ev.salt}"); + print("|-- \t publicKey : ${ev.publicKey == null ? "null" : ev.publicKey}"); + print("|-- \t checkCode : ${ev.trace == null ? "null" : ev.trace}"); + print( + "===============================================================================================================\n"); +} + // Extension de DateTime pour savoir si 2 dates sont du même jour d'après l'année, le mois et le jour extension DateOnlyCompare on DateTime { bool isSameDate(DateTime other) { @@ -96,8 +118,6 @@ Future<void> sendCheckCode(Event event, context) async { Toast.show('Event ${event.name} signaled as infected', context, duration: 5); } else { - // print(message); - throw Exception(response.body); } } diff --git a/test/qr_test.dart b/test/qr_test.dart index 960a53c..bb0d580 100644 --- a/test/qr_test.dart +++ b/test/qr_test.dart @@ -12,7 +12,7 @@ void main() async { setUp(() async { eventDB = await Hive.openBox<Event>('event'); - eventDB.clear(); + await eventDB.clear(); }); test('Une clé publique est generée', () { -- GitLab From 00a23861d588c70c80458abbb3c8865ec98137da Mon Sep 17 00:00:00 2001 From: Bayarbileg <bayarbileg.batbileg@edu.unige.ch> Date: Sun, 24 Jan 2021 17:56:25 +0100 Subject: [PATCH 5/6] tests fixed --- lib/boutonScan.dart | 33 +++++++++++++++++---------------- lib/journal.dart | 4 ++-- lib/models/Event.dart | 1 - lib/utils.dart | 2 ++ test/HiveDB_test.dart | 26 ++++++++++++++++---------- test/scanner_test.dart | 29 +++++++++++++---------------- 6 files changed, 50 insertions(+), 45 deletions(-) diff --git a/lib/boutonScan.dart b/lib/boutonScan.dart index ae48883..79262b8 100644 --- a/lib/boutonScan.dart +++ b/lib/boutonScan.dart @@ -1,13 +1,10 @@ import 'dart:convert'; import 'package:flutter/material.dart'; -import 'package:flutter/services.dart'; import 'package:flutter_barcode_scanner/flutter_barcode_scanner.dart'; import 'package:hive/hive.dart'; import 'package:toast/toast.dart'; import 'package:validators/validators.dart'; -import 'utils.dart'; - import 'models/Event.dart'; class BoutonScan extends StatefulWidget { @@ -53,28 +50,32 @@ class BoutonScanState extends State<BoutonScan> { ); } + void showErr(){ + + } + Event parseQRContent(String qrContent) { Event addition; if (isURL(qrContent)) { // Ici on exécute le code pour décoder la classe protobuff obtenue d'un URL de crowdnotifier/notifyMe. - try { + // try { addition = Event.fromURL(qrContent); - } on FormatException catch (e) { - Toast.show(e.message, context); - } catch (e) { - Toast.show(e.message, context); - } + // } on FormatException catch (e) { + //Toast.show(e.message, context); + // } catch (e) { + //Toast.show(e.message, context); + // } } else if (isJSON(qrContent)) { // Ici on tente de décoder en JSON - try { + // try { addition = Event.fromJson(jsonDecode(qrContent)); - } on PlatformException catch(e) { - Toast.show("Failed to get platform version > ${e.message}", context); - } on FormatException catch(e) { - Toast.show("Format Exception > ${e.message}", context); - } + // } on PlatformException catch(e) { + //Toast.show("Failed to get platform version > ${e.message}", context); + // } on FormatException catch(e) { + //Toast.show("Format Exception > ${e.message}", context); + // } } else { - Toast.show("invalid QR Code", context); + //Toast.show("invalid QR Code", context); } return addition; diff --git a/lib/journal.dart b/lib/journal.dart index a5fc0ba..0c34f0d 100644 --- a/lib/journal.dart +++ b/lib/journal.dart @@ -238,8 +238,8 @@ class _JournalState extends State<Journal> with TickerProviderStateMixin { size: 35, ), // Fonctionnalite utilise pour debug a ne pas decommenter pour demo - // onTap: () => sendCheckCode(event,context), - // onLongPress: () async => await Hive.box<Event>('event').deleteAll(Hive.box<Event>('event').keys), + onTap: () => sendCheckCode(event,context), + onLongPress: () async => await Hive.box<Event>('event').deleteAll(Hive.box<Event>('event').keys), ), ), ); diff --git a/lib/models/Event.dart b/lib/models/Event.dart index 26a7a7c..5539604 100644 --- a/lib/models/Event.dart +++ b/lib/models/Event.dart @@ -3,7 +3,6 @@ import 'dart:typed_data'; import 'package:hive/hive.dart'; import 'package:meta/meta.dart'; import 'package:naca/proto_out/qr.pbserver.dart'; -import 'package:naca/utils.dart'; part 'Event.g.dart'; diff --git a/lib/utils.dart b/lib/utils.dart index e4d9b0e..a951f12 100644 --- a/lib/utils.dart +++ b/lib/utils.dart @@ -121,3 +121,5 @@ Future<void> sendCheckCode(Event event, context) async { throw Exception(response.body); } } + + diff --git a/test/HiveDB_test.dart b/test/HiveDB_test.dart index d091b2e..af04485 100644 --- a/test/HiveDB_test.dart +++ b/test/HiveDB_test.dart @@ -23,14 +23,17 @@ void main() async { event = await Hive.openBox<Event>('event'); await event.clear(); jsonQR = { - 'publicKey': null, + 'signature': null, 'content': { 'name': 'Anniversaire Xoeseko', 'location': 'Grand Rue', - 'startDate': DateTime(2020, 14, 12), - 'endDate': DateTime(2020, 15, 12), + 'contexte': 'anniversaire', + 'startDate': DateTime(2020, 14, 12).toString(), + 'endDate': DateTime(2020, 15, 12).toString(), 'notifKey': null, + 'publicKey': null, }, + 'trace': 'traceCode', }; url = @@ -43,28 +46,31 @@ void main() async { // Testing CRUD on EventCreated DB // Create & Read test('Create Event from JSON and URL', () { - var eventFromJSON = Event.fromJson(jsonQR); + var eventFromJSON1 = Event.fromJson(jsonQR); var eventFromURL = Event.fromURL(url); var eventFromJSON2 = Event.fromJson(jsonQR); //Create - event.put('eventFromJson1', eventFromJSON); + event.put('eventFromJson1', eventFromJSON1); event.put('eventFromJson2', eventFromJSON2); event.put('eventFromURL', eventFromURL); //Read var resURL = event.get('eventFromURL'); //Update - var resEventFromJSON = event.get('eventFromJson1'); - resEventFromJSON.location = 'Grand Rue 75, Morges'; - resEventFromJSON.save(); + var resEventFromJSON1 = event.get('eventFromJson1'); + resEventFromJSON1.location = 'Grand Rue 75, Morges'; + resEventFromJSON1.save(); //Delete eventFromJSON2.delete(); + // Only json1 and url should be in the box. + expect(event.keys.contains('eventFromJson1'), true); // checking the key for JSON1 + expect(event.keys.contains('eventFromURL'), true); // checking the key for URL expect(eventFromURL.location, 'Covid-party'); //checks field of URL expect(resURL.name, 'Anniversaire'); // checks Read expect(event.length, 2); // checks & delete - expect(eventFromJSON.location, 'Grand Rue 75, Morges'); //checks update + expect(eventFromJSON1.location, 'Grand Rue 75, Morges'); //checks update }); }); @@ -72,7 +78,7 @@ void main() async { test('A random character string throws format exception', () { expect(() => Event.fromURL('blatently false url'), throwsException); }); - test('A wrong url thwos a format exception', () { + test('A wrong url throws a format exception', () { expect(() => Event.fromURL('example.com/balblabla'), throwsException); }); }); diff --git a/test/scanner_test.dart b/test/scanner_test.dart index 9c74cd7..b91102e 100644 --- a/test/scanner_test.dart +++ b/test/scanner_test.dart @@ -1,15 +1,11 @@ -// import 'package:flutter_barcode_scanner/flutter_barcode_scanner.dart'; import 'package:flutter_test/flutter_test.dart'; import 'package:hive/hive.dart'; import 'package:hive_flutter/hive_flutter.dart'; -// import 'package:mockito/mockito.dart'; import 'package:naca/boutonScan.dart'; import 'package:naca/models/Event.dart'; - void main() async { await Hive.initFlutter(); Hive.registerAdapter<Event>(EventAdapter()); - BoutonScanState testButton; setUp(() async { testButton = new BoutonScanState(); @@ -23,18 +19,19 @@ void main() async { // }); test('our json string returns', () { - expect( - () => testButton.parseQRContent( - '''{"publicKey":[43,99,99,221,127,216,39,53,168,211,227,71,21,225,102,48,217,11,114,234,36,39,203,92,204,17,126,118,64,236,8,66], - "content":{ - "nomEvent":"test", - "location":"qwqw", - "eventContext":"qwqw", - "eventStartDate":"2020-12-31 00:00:00.000", - "eventEndDate":"2021-01-01 00:00:00.000", - "notificationKey":[104,223,191,105,46,157,243,188,221,21,49,213,113,181,58,188,141,81,246,227,147,84,227,141,121,135,182,165,150,23,190,164]} - }'''), - returnsNormally); + expect(() => testButton.parseQRContent('''{ + "signature": [7, 136, 232, 147, 233, 31, 57, 223, 214, 162, 68, 71, 229, 136, 123, 156, 59, 81, 173, 252, 142, 177, 167, 66, 112, 123, 240, 190, 202, 61, 4, 147, 215, 141, 118, 209, 180, 119, 74, 25, 7, 16, 110, 107, 33, 140, 123, 142, 173, 223, 226, 145, 84, 226, 82, 231, 188, 45, 92, 244, 145, 28, 115, 3], + "content": { + "name": "ParsingTestEvent", + "location": "Home", + "contexte": "Testing", + "startDate": "2021-01-24 13:17:00.000", + "endDate": "2021-01-24 17:17:00.000", + "notifKey": [201, 105, 132, 150, 212, 167, 127, 2, 83, 96, 35, 234, 80, 51, 195, 36, 224, 89, 66, 49, 230, 5, 89, 216, 72, 248, 159, 95, 131, 117, 165, 232], + "publicKey": [149, 155, 197, 20, 150, 236, 143, 128, 57, 245, 130, 57, 9, 23, 157, 164, 211, 77, 112, 30, 13, 152, 196, 253, 252, 68, 84, 239, 20, 117, 99, 11] + }, + "trace": "IMO_LcKNw7LDmHPDp8OQw6Qdw6RtAMOTZ0RaGMK1MyHDrsObwo1JLMKZf8O4wr8NSsOjLMKiDsKIw5nDhcK5EMOqw5E0BmHDj8OMw43Dj8ONUhdPasOxwoHCjBHDucOOwqTCmcKTwo7ChB_Cv8KYZCRwCWNpw4jCu1vCkXHDjF8swqtlU8OtNzHCvSxiw7DCgz7DmCUNC8O3LzLDkcK2YMKrwrwIwpPDosKwHsK1PMK8w5dmczXDpgTCisKLw7Ubw7rDknl9woQvXcKzVsOlLsKiw6M2BHHDgEHCjC1gw5lHw6fDi08_asO1IBV6w5IGwrLCosO4VMOEwrPCrMOWRRPCrMK7FHxgw4ZrPHAvPMKGfMK7w4sYQcOQe03DqTjCgRtiLy_Di0jDpsKJAsOzw63CtsOxwqpLJsK8YcO6woTDgBbDtXfDocKTwpXDhMO6aWo2wqrCj2LCnF7CkcK4TMOuwr7CrMK0SMK5w69qc3PCli4JaEURAlrDtsOrG2QswogvwrbDsT5uw4w_CMObFXnDhl_ChcO_csKxScKlwpzCkcKAwoDDp2bDicOdK30lKcK1Cg0NK8O0wqzDsH5gCMORwpwDw7gpHA_DpGTDkSQuw7zDnn7DqBRIZ2pXwojCocKuwrcxGQ7Ct8KyFH_CkBcFIsOtOzYcGhDDmyg=" +}'''), returnsNormally); }); }); // Le test suivant n'ext pas executé car ce n'est pas possible de faker une méthode statique. -- GitLab From 4299451a28c51935b18d5ec50a4c94df459a2f45 Mon Sep 17 00:00:00 2001 From: Bayarbileg <bayarbileg.batbileg@edu.unige.ch> Date: Mon, 25 Jan 2021 11:08:25 +0100 Subject: [PATCH 6/6] Peaufinage code journal --- lib/journal.dart | 170 ++++++++++++++++++++++++++++------------------- 1 file changed, 100 insertions(+), 70 deletions(-) diff --git a/lib/journal.dart b/lib/journal.dart index 0c34f0d..7ced9ce 100644 --- a/lib/journal.dart +++ b/lib/journal.dart @@ -22,42 +22,11 @@ class _JournalState extends State<Journal> with TickerProviderStateMixin { @override void initState() { super.initState(); - final _selectedDay = DateTime.now(); - final eventBox = Hive.box<Event>('event'); - final allEvents = eventBox.values; - final userBox = Hive.box<User>('user'); + final allEvents = Hive.box<Event>('event').values; - _events = Map(); - _selectedEvents = List(); - - // Fonction triant les evenements par jour de creation. Exemple : '17 janvier' -> [event1,event2] - allEvents.forEach((event) { - var existingDate = _events.keys.firstWhere( - (key) => key.isSameDate(event.startDate), - orElse: () => null); - if (existingDate != null) { - _events[existingDate].add(event); - } else { - _events[event.startDate] = [event]; - } - - // On utilise la boucle aussi pour rajouter les evenements du jour actuel dans la liste 'selectedEvents' - if (event.startDate.isSameDate(_selectedDay)) { - _selectedEvents.add(event); - } - }); - - // Premiere fois que l'utilisateur accede au journal, on affiche les infos des evenements. - if (userBox.get('mainUser').seenJournal == false) { - userBox.get('mainUser').seenJournal = true; - - WidgetsBinding.instance.addPostFrameCallback((_) async { - await showDialog( - context: context, - builder: (BuildContext context) => _buildAboutDialog(context), - ); - }); - } + _events = _filterEventsPerDay(allEvents); + _selectedEvents = _filterEventsToday(allEvents); + _loadAboutDialogFirstTime(); _calendarController = CalendarController(); _animationController = AnimationController( @@ -88,6 +57,52 @@ class _JournalState extends State<Journal> with TickerProviderStateMixin { verifyCheckCodeForEvents(); } + void _onRefreshEvents() { + verifyCheckCodeForEvents(); + setState(() {}); + } + + // Fonction triant les evenements par jour de creation. Exemple : '17 janvier' -> [event1,event2] + Map _filterEventsPerDay(Iterable<Event> allEvents) { + Map<DateTime, List<dynamic>> filteredEvents = new Map<DateTime, List<dynamic>>(); + allEvents.forEach((Event event) { + var existingDate = filteredEvents.keys.firstWhere( + (key) => key.isSameDate(event.startDate), + orElse: () => null); + if (existingDate != null) { + filteredEvents[existingDate].add(event); + } else { + filteredEvents[event.startDate] = [event]; + } + }); + return filteredEvents; + } + + //Fonction permettant de fitrer les evenements pour ceux d'aujourd'hui + List _filterEventsToday(Iterable<Event> allEvents) { + List<Event> todaysEvents = new List<Event>(); + allEvents.forEach((Event event) { + if (event.startDate.isSameDate(DateTime.now())) { + todaysEvents.add(event); + } + }); + return todaysEvents; + } + + // Premiere fois que l'utilisateur accede au journal, on affiche le dialogue de notation + void _loadAboutDialogFirstTime() { + Box<User> userBox = Hive.box<User>('user'); + if (userBox.get('mainUser').seenJournal == false) { + userBox.get('mainUser').seenJournal = true; + WidgetsBinding.instance.addPostFrameCallback((_) async { + await showDialog( + context: context, + builder: (BuildContext context) => _buildAboutDialog(context), + ); + }); + } + } + @override Widget build(BuildContext context) { return Scaffold( @@ -108,36 +123,7 @@ class _JournalState extends State<Journal> with TickerProviderStateMixin { ), onPressed: Navigator.of(context).pop, ), - actions: <Widget>[ - Padding( - padding: EdgeInsets.only(right: 20.0), - child: GestureDetector( - onTap: () => showDialog( - context: context, - builder: (BuildContext context) => new AlertDialog( - title: Text('implement export function here'), - ), - ), - child: Icon( - Icons.import_export, - color: Theme.of(context).accentColor, - ), - ), - ), - Padding( - padding: EdgeInsets.only(right: 20.0), - child: GestureDetector( - onTap: () => showDialog( - context: context, - builder: (BuildContext context) => _buildAboutDialog(context), - ), - child: Icon( - Icons.info, - color: Theme.of(context).accentColor, - ), - ), - ), - ], + actions: _buildAppBarButtons(), ), body: Container( child: Column( @@ -189,12 +175,12 @@ class _JournalState extends State<Journal> with TickerProviderStateMixin { // Build EventList Widget _buildEventList() { return ListView( - children: _selectedEvents.map((event) => eventTile(event)).toList(), + children: _selectedEvents.map((event) => _eventTile(event)).toList(), ); } // Build eventTile - Card - Widget eventTile(Event event) { + Widget _eventTile(Event event) { return Container( margin: const EdgeInsets.symmetric(horizontal: 20.0, vertical: 5.0), child: Card( @@ -237,9 +223,10 @@ class _JournalState extends State<Journal> with TickerProviderStateMixin { color: Colors.green, size: 35, ), - // Fonctionnalite utilise pour debug a ne pas decommenter pour demo - onTap: () => sendCheckCode(event,context), - onLongPress: () async => await Hive.box<Event>('event').deleteAll(Hive.box<Event>('event').keys), + // Fonctionnalite utilise pour debug a ne pas decommenter pour demo + onTap: () => sendCheckCode(event, context), + onLongPress: () async => await Hive.box<Event>('event') + .deleteAll(Hive.box<Event>('event').keys), ), ), ); @@ -280,4 +267,47 @@ class _JournalState extends State<Journal> with TickerProviderStateMixin { ], ); } + + List<Widget> _buildAppBarButtons() { + return <Widget>[ + Padding( + padding: EdgeInsets.only(right: 20.0), + child: GestureDetector( + onTap: () => _onRefreshEvents(), + child: Icon( + Icons.refresh, + color: Theme.of(context).accentColor, + ), + ), + ), + Padding( + padding: EdgeInsets.only(right: 20.0), + child: GestureDetector( + onTap: () => showDialog( + context: context, + builder: (BuildContext context) => new AlertDialog( + title: Text('implement export function here'), + ), + ), + child: Icon( + Icons.import_export, + color: Theme.of(context).accentColor, + ), + ), + ), + Padding( + padding: EdgeInsets.only(right: 20.0), + child: GestureDetector( + onTap: () => showDialog( + context: context, + builder: (BuildContext context) => _buildAboutDialog(context), + ), + child: Icon( + Icons.info, + color: Theme.of(context).accentColor, + ), + ), + ), + ]; + } } -- GitLab