From 64b66a57a878bfa334a5c41cd83286f176ca5d9a Mon Sep 17 00:00:00 2001 From: Aadeesh11 Date: Tue, 28 Dec 2021 02:23:38 +0530 Subject: [PATCH 1/6] Disabled Change Duration Popup, since we dont have the required mutation on backend. --- lib/views/hike_screen.dart | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/lib/views/hike_screen.dart b/lib/views/hike_screen.dart index c93f12df..ad61d78e 100644 --- a/lib/views/hike_screen.dart +++ b/lib/views/hike_screen.dart @@ -566,10 +566,12 @@ class _HikeScreenState extends State { text: 'Long Press on any hiker to hand over the beacon\n', style: TextStyle(fontSize: 16)), - TextSpan( - text: - 'Double tap on beacon to change the duration\n', - style: TextStyle(fontSize: 14)), + //TODO: enable this once backend has updated. + //Commented, since we dont have the neccessary mutation atm on backend to change the duration. + // TextSpan( + // text: + // 'Double tap on beacon to change the duration\n', + // style: TextStyle(fontSize: 14)), ]), ), ) @@ -616,7 +618,10 @@ class _HikeScreenState extends State { ? Fluttertoast.showToast( msg: 'Only beacon holder has access to change the duration') - : DialogBoxes.changeDurationDialog(context); + //TODO: enable this once backend has updated. + //Commented, since we dont have the neccessary mutation atm on backend to change the duration. + // : DialogBoxes.changeDurationDialog(context); + : Container(); }, child: Icon( Icons.room, From 97f96c1623e425d237275f962bb7dd9680970c46 Mon Sep 17 00:00:00 2001 From: Aadeesh11 Date: Wed, 26 Jan 2022 03:11:25 +0530 Subject: [PATCH 2/6] feat: Change beacon duration. And, rfrac: formatted some code. --- lib/components/beacon_card.dart | 2 +- lib/components/create_join_dialog.dart | 6 +- lib/components/dialog_boxes.dart | 128 +++++++++++++++++- lib/components/hike_button.dart | 2 +- lib/components/hike_screen_widget.dart | 11 +- lib/queries/beacon.dart | 34 +++++ lib/services/database_mutation_functions.dart | 32 +++++ lib/splash_screen.dart | 2 +- lib/utilities/indication_painter.dart | 15 +- lib/view_model/auth_screen_model.dart | 12 +- lib/view_model/hike_screen_model.dart | 7 +- lib/view_model/home_view_model.dart | 6 +- lib/views/auth_screen.dart | 8 +- lib/views/home.dart | 2 +- 14 files changed, 229 insertions(+), 38 deletions(-) diff --git a/lib/components/beacon_card.dart b/lib/components/beacon_card.dart index c14b483c..c2b6b936 100644 --- a/lib/components/beacon_card.dart +++ b/lib/components/beacon_card.dart @@ -167,7 +167,7 @@ class BeaconCustomWidgets { TextSpan( text: 'in ', style: TextStyle( - color: const Color(0xffb6b2df), + color: Color(0xffb6b2df), fontSize: 14.0, fontWeight: FontWeight.w400), ), diff --git a/lib/components/create_join_dialog.dart b/lib/components/create_join_dialog.dart index bcfa22d5..6c73438c 100644 --- a/lib/components/create_join_dialog.dart +++ b/lib/components/create_join_dialog.dart @@ -10,9 +10,9 @@ import 'package:sizer/sizer.dart'; class CreateJoinBeaconDialog { static Future createHikeDialog(BuildContext context, HomeViewModel model) { model.resultingDuration = Duration(minutes: 30); - model.durationController = new TextEditingController(); - model.startsAtDate = new TextEditingController(); - model.startsAtTime = new TextEditingController(); + model.durationController = TextEditingController(); + model.startsAtDate = TextEditingController(); + model.startsAtTime = TextEditingController(); return showDialog( context: context, builder: (context) => Dialog( diff --git a/lib/components/dialog_boxes.dart b/lib/components/dialog_boxes.dart index 6824be78..fabae08e 100644 --- a/lib/components/dialog_boxes.dart +++ b/lib/components/dialog_boxes.dart @@ -1,6 +1,7 @@ import 'package:beacon/components/hike_button.dart'; import 'package:beacon/locator.dart'; import 'package:beacon/utilities/constants.dart'; +import 'package:beacon/view_model/hike_screen_model.dart'; import 'package:flutter/material.dart'; import 'package:sizer/sizer.dart'; @@ -45,7 +46,14 @@ class DialogBoxes { ); } - static Future changeDurationDialog(BuildContext context) { + static Future changeDurationDialog( + BuildContext context, + HikeScreenViewModel model, + ) { + DateTime dateTime; + TimeOfDay timeOfDay; + var startsAtDate = TextEditingController(); + var startsAtTime = TextEditingController(); return showDialog( context: context, builder: (context) => Dialog( @@ -64,9 +72,92 @@ class DialogBoxes { child: Column( children: [ Text( - 'Change Beacon Duration', + 'Choose a date and time for the beacon to expire at.', style: TextStyle(color: kYellow, fontSize: 14.0), ), + Container( + height: 10.h, + child: Padding( + padding: const EdgeInsets.all(4.0), + child: InkWell( + onTap: () async { + dateTime = await showDatePicker( + context: context, + initialDate: DateTime.now(), + firstDate: DateTime.now(), + lastDate: DateTime(2100), + ); + startsAtDate.text = + dateTime.toString().substring(0, 10); + }, + child: TextFormField( + enabled: false, + controller: startsAtDate, + onChanged: (value) { + startsAtDate.text = + dateTime.toString().substring(0, 10); + }, + decoration: InputDecoration( + alignLabelWithHint: true, + errorStyle: TextStyle(color: Colors.red[800]), + floatingLabelBehavior: + FloatingLabelBehavior.always, + labelText: 'End Date', + labelStyle: TextStyle( + fontSize: labelsize, color: kYellow), + hintStyle: TextStyle( + fontSize: hintsize, color: hintColor), + hintText: 'Choose end date', + focusedBorder: InputBorder.none, + enabledBorder: InputBorder.none, + ), + ), + ), + ), + color: kLightBlue, + ), + SizedBox( + height: 2.h, + ), + Container( + height: 10.h, + child: Padding( + padding: const EdgeInsets.all(4.0), + child: InkWell( + onTap: () async { + timeOfDay = await showTimePicker( + context: context, + initialTime: TimeOfDay.now(), + ); + startsAtTime.text = + timeOfDay.toString().substring(10, 15); + }, + child: TextFormField( + enabled: false, + controller: startsAtTime, + onChanged: (value) { + startsAtTime.text = + timeOfDay.toString().substring(10, 15); + }, + decoration: InputDecoration( + alignLabelWithHint: true, + errorStyle: TextStyle(color: Colors.red[800]), + floatingLabelBehavior: + FloatingLabelBehavior.always, + labelText: 'End Time', + labelStyle: TextStyle( + fontSize: labelsize, color: kYellow), + hintStyle: TextStyle( + fontSize: hintsize, color: hintColor), + hintText: 'Choose End time', + focusedBorder: InputBorder.none, + enabledBorder: InputBorder.none, + ), + ), + ), + ), + color: kLightBlue, + ), ], ), ), @@ -81,11 +172,40 @@ class DialogBoxes { textSize: 18.0, textColor: Colors.white, buttonColor: kYellow, - onTap: () { + onTap: () async { + if (dateTime == null || timeOfDay == null) { + navigationService.showSnackBar("Enter date and time"); + return; + } + dateTime = DateTime( + dateTime.year, + dateTime.month, + dateTime.day, + timeOfDay.hour, + timeOfDay.minute, + ); + // localNotif.scheduleNotification(); + if (DateTime.fromMillisecondsSinceEpoch( + model.beacon.startsAt) + .isAfter(dateTime)) { + navigationService + .showSnackBar("Enter a valid date and time!!"); + return; + } // DateTime newTime = // DateTime.now().add(newDuration); // update time - Navigator.pop(context); + await databaseFunctions.init(); + final updatedBeacon = + await databaseFunctions.changeBeaconDuration( + model.beacon.id, + dateTime.millisecondsSinceEpoch, + ); + if (updatedBeacon != null) { + model.updateBeaconDuration( + dateTime.millisecondsSinceEpoch); + } + Navigator.pop(context, dateTime); }), ), ], diff --git a/lib/components/hike_button.dart b/lib/components/hike_button.dart index 5a9b4ba6..dcde7287 100644 --- a/lib/components/hike_button.dart +++ b/lib/components/hike_button.dart @@ -26,7 +26,7 @@ class HikeButton extends StatelessWidget { style: ElevatedButton.styleFrom( primary: buttonColor, shape: RoundedRectangleBorder( - borderRadius: new BorderRadius.circular(50.0), + borderRadius: BorderRadius.circular(50.0), side: BorderSide(color: borderColor)), ), child: Padding( diff --git a/lib/components/hike_screen_widget.dart b/lib/components/hike_screen_widget.dart index 1281e598..d9ebbc25 100644 --- a/lib/components/hike_screen_widget.dart +++ b/lib/components/hike_screen_widget.dart @@ -1,6 +1,7 @@ import 'dart:async'; import 'dart:io'; +import 'package:beacon/components/dialog_boxes.dart'; import 'package:beacon/components/hike_button.dart'; import 'package:beacon/locator.dart'; import 'package:beacon/models/beacon/beacon.dart'; @@ -244,14 +245,14 @@ class HikeScreenWidget { trailing: model.hikers[index].id == model.beacon.leader.id ? GestureDetector( onDoubleTap: () { - isLeader + !isLeader ? Fluttertoast.showToast( msg: 'Only beacon holder has access to change the duration') - //TODO: enable this once backend has updated. - //Commented, since we dont have the neccessary mutation atm on backend to change the duration. - // : DialogBoxes.changeDurationDialog(context); - : Container(); + : DialogBoxes.changeDurationDialog( + context, + model, + ); }, child: Icon( Icons.room, diff --git a/lib/queries/beacon.dart b/lib/queries/beacon.dart index 33f230a1..6dc150d6 100644 --- a/lib/queries/beacon.dart +++ b/lib/queries/beacon.dart @@ -43,6 +43,40 @@ class BeaconQueries { '''; } + String changeBeaconDuration(String id, int newExpiresAt) { + return ''' + mutation{ + changeBeaconDuration(newExpiresAt: $newExpiresAt, beaconID: "$id") + { + _id + title + shortcode + leader { + _id + name + } + location{ + lat + lon + } + followers { + _id + name + } + startsAt + expiresAt + landmarks { + title + location { + lat + lon + } + } + } + } + '''; + } + String updateLeaderLoc(String id, String lat, String lon) { return ''' mutation { diff --git a/lib/services/database_mutation_functions.dart b/lib/services/database_mutation_functions.dart index 6bfd28d4..64317ae3 100644 --- a/lib/services/database_mutation_functions.dart +++ b/lib/services/database_mutation_functions.dart @@ -30,6 +30,8 @@ class DataBaseMutationFunctions { const GraphQLError(message: 'Email address already exists'); GraphQLError wrongCredentials = const GraphQLError(message: 'Invalid credentials'); + GraphQLError beaconHasAlreadyExpired = const GraphQLError( + message: 'Beacon can not expire before it has started.'); bool encounteredExceptionOrError(OperationException exception, {bool showSnackBar = true}) { @@ -64,6 +66,12 @@ class DataBaseMutationFunctions { .showSnackBar("Account with this email already registered"); } return false; + } else if (exception.graphqlErrors[i].message == + beaconHasAlreadyExpired.message) { + if (showSnackBar) { + navigationService.showSnackBar(beaconHasAlreadyExpired.message); + } + return false; } } print("Something went wrong"); @@ -246,6 +254,30 @@ class DataBaseMutationFunctions { return null; } + Future changeBeaconDuration(String id, int newExpiresAt) async { + final QueryResult result = await clientAuth.mutate( + MutationOptions( + document: gql( + _beaconQuery.changeBeaconDuration( + id, + newExpiresAt, + ), + ), + ), + ); + if (result.hasException) { + navigationService.showSnackBar( + "Something went wrong: ${result.exception.graphqlErrors.first.message}"); + print("Something went wrong: ${result.exception}"); + } else if (result.data != null && result.isConcrete) { + final Beacon beacon = Beacon.fromJson( + result.data['changeBeaconDuration'] as Map, + ); + return beacon; + } + return null; + } + Future updateLeaderLoc(String id, LatLng latLng) async { final QueryResult result = await clientAuth.mutate(MutationOptions( document: gql(_beaconQuery.updateLeaderLoc( diff --git a/lib/splash_screen.dart b/lib/splash_screen.dart index 5a0e8175..07160035 100644 --- a/lib/splash_screen.dart +++ b/lib/splash_screen.dart @@ -97,7 +97,7 @@ class _SplashScreenState extends State { return Scaffold( key: const Key('SplashScreenScaffold'), body: Center( - child: new Image(image: new AssetImage('images/hikers_group.png')), + child: Image(image: AssetImage('images/hikers_group.png')), ), ); } diff --git a/lib/utilities/indication_painter.dart b/lib/utilities/indication_painter.dart index a82219a5..609155bb 100644 --- a/lib/utilities/indication_painter.dart +++ b/lib/utilities/indication_painter.dart @@ -19,7 +19,7 @@ class TabIndicationPainter extends CustomPainter { this.dy = 25.0, this.pageController}) : super(repaint: pageController) { - painter = new Paint() + painter = Paint() ..color = kBlue ..style = PaintingStyle.fill; } @@ -33,16 +33,15 @@ class TabIndicationPainter extends CustomPainter { double pageOffset = pos.extentBefore / fullExtent; bool left2right = dxEntry < dxTarget; - Offset entry = new Offset(left2right ? dxEntry : dxTarget, dy); - Offset target = new Offset(left2right ? dxTarget : dxEntry, dy); + Offset entry = Offset(left2right ? dxEntry : dxTarget, dy); + Offset target = Offset(left2right ? dxTarget : dxEntry, dy); - Path path = new Path(); + Path path = Path(); path.addArc( - new Rect.fromCircle(center: entry, radius: radius), 0.5 * pi, 1 * pi); - path.addRect( - new Rect.fromLTRB(entry.dx, dy - radius, target.dx, dy + radius)); + Rect.fromCircle(center: entry, radius: radius), 0.5 * pi, 1 * pi); + path.addRect(Rect.fromLTRB(entry.dx, dy - radius, target.dx, dy + radius)); path.addArc( - new Rect.fromCircle(center: target, radius: radius), 1.5 * pi, 1 * pi); + Rect.fromCircle(center: target, radius: radius), 1.5 * pi, 1 * pi); canvas.translate(size.width * pageOffset, 0.0); canvas.drawShadow(path, kLightBlue, 3.0, true); diff --git a/lib/view_model/auth_screen_model.dart b/lib/view_model/auth_screen_model.dart index 47b7c274..1b7ef3f7 100644 --- a/lib/view_model/auth_screen_model.dart +++ b/lib/view_model/auth_screen_model.dart @@ -10,7 +10,7 @@ class AuthViewModel extends BaseModel { AutovalidateMode loginValidate = AutovalidateMode.disabled; AutovalidateMode signupValidate = AutovalidateMode.disabled; - final GlobalKey scaffoldKey = new GlobalKey(); + final GlobalKey scaffoldKey = GlobalKey(); final FocusNode emailLogin = FocusNode(); final FocusNode passwordLogin = FocusNode(); @@ -19,15 +19,15 @@ class AuthViewModel extends BaseModel { final FocusNode email = FocusNode(); final FocusNode name = FocusNode(); - TextEditingController loginEmailController = new TextEditingController(); - TextEditingController loginPasswordController = new TextEditingController(); + TextEditingController loginEmailController = TextEditingController(); + TextEditingController loginPasswordController = TextEditingController(); bool obscureTextLogin = true; bool obscureTextSignup = true; - TextEditingController signupEmailController = new TextEditingController(); - TextEditingController signupNameController = new TextEditingController(); - TextEditingController signupPasswordController = new TextEditingController(); + TextEditingController signupEmailController = TextEditingController(); + TextEditingController signupNameController = TextEditingController(); + TextEditingController signupPasswordController = TextEditingController(); PageController pageController = PageController(); diff --git a/lib/view_model/hike_screen_model.dart b/lib/view_model/hike_screen_model.dart index 0ba58aad..6856f5cc 100644 --- a/lib/view_model/hike_screen_model.dart +++ b/lib/view_model/hike_screen_model.dart @@ -42,7 +42,7 @@ class HikeScreenViewModel extends BaseModel { PolylinePoints polylinePoints = PolylinePoints(); final GlobalKey landmarkFormKey = GlobalKey(); ScrollController scrollController = ScrollController(); - Location loc = new Location(); + Location loc = Location(); GraphQLClient graphQlClient; PanelController panelController = PanelController(); final List mergedStreamSubscriptions = []; @@ -371,6 +371,11 @@ class HikeScreenViewModel extends BaseModel { setState(ViewState.idle); } + void updateBeaconDuration(int newExpiresAt) { + beacon.expiresAt = newExpiresAt; + notifyListeners(); + } + Future createLandmark( var title, var loc, diff --git a/lib/view_model/home_view_model.dart b/lib/view_model/home_view_model.dart index 8b3bc782..c05ac5d8 100644 --- a/lib/view_model/home_view_model.dart +++ b/lib/view_model/home_view_model.dart @@ -19,9 +19,9 @@ class HomeViewModel extends BaseModel { bool hasStarted; //commenting out since its value isnt used anywhere. //TextEditingController _titleController = new TextEditingController(); - TextEditingController durationController = new TextEditingController(); - TextEditingController startsAtDate = new TextEditingController(); - TextEditingController startsAtTime = new TextEditingController(); + TextEditingController durationController = TextEditingController(); + TextEditingController startsAtDate = TextEditingController(); + TextEditingController startsAtTime = TextEditingController(); String enteredPasskey; createHikeRoom() async { diff --git a/lib/views/auth_screen.dart b/lib/views/auth_screen.dart index 5eb67f3b..3c81c812 100644 --- a/lib/views/auth_screen.dart +++ b/lib/views/auth_screen.dart @@ -63,7 +63,7 @@ class _AuthScreenState extends State builder: (context, model, child) { return (model.isBusy) ? Scaffold(body: Center(child: CircularProgressIndicator())) - : new Scaffold( + : Scaffold( key: model.scaffoldKey, resizeToAvoidBottomInset: true, body: Container( @@ -115,12 +115,12 @@ class _AuthScreenState extends State } }, children: [ - new ConstrainedBox( + ConstrainedBox( constraints: const BoxConstraints.expand(), child: _buildSignIn(context, model), ), - new ConstrainedBox( + ConstrainedBox( constraints: const BoxConstraints.expand(), child: _buildSignUp(context, model), @@ -439,7 +439,7 @@ class _AuthScreenState extends State ), Container( // margin: EdgeInsets.only(top: 300.0), - decoration: new BoxDecoration( + decoration: BoxDecoration( borderRadius: BorderRadius.all(Radius.circular(5.0)), ), child: HikeButton( diff --git a/lib/views/home.dart b/lib/views/home.dart index cb1e46d4..b6c51cef 100644 --- a/lib/views/home.dart +++ b/lib/views/home.dart @@ -62,7 +62,7 @@ class _MainScreenState extends State with TickerProviderStateMixin { return WillPopScope( onWillPop: _onPopHome, child: BaseView(builder: (context, model, child) { - TabController tabController = new TabController(length: 2, vsync: this); + TabController tabController = TabController(length: 2, vsync: this); return model.isBusy ? Scaffold(body: Center(child: CircularProgressIndicator())) : Scaffold( From 976b2456c3baba7f194017bbc7e5f25a0599469d Mon Sep 17 00:00:00 2001 From: Aadeesh11 Date: Fri, 28 Jan 2022 16:10:23 +0530 Subject: [PATCH 3/6] UI improvement. --- lib/components/dialog_boxes.dart | 269 +++++++++++++++---------------- 1 file changed, 134 insertions(+), 135 deletions(-) diff --git a/lib/components/dialog_boxes.dart b/lib/components/dialog_boxes.dart index fabae08e..853726bf 100644 --- a/lib/components/dialog_boxes.dart +++ b/lib/components/dialog_boxes.dart @@ -61,152 +61,151 @@ class DialogBoxes { borderRadius: BorderRadius.circular(10.0), ), child: Container( - height: 500, child: Padding( - padding: const EdgeInsets.symmetric(horizontal: 32, vertical: 16), + padding: const EdgeInsets.symmetric(horizontal: 32), child: Column( + mainAxisSize: MainAxisSize.min, children: [ - Flexible( - child: Container( - color: kLightBlue, - child: Column( - children: [ - Text( - 'Choose a date and time for the beacon to expire at.', - style: TextStyle(color: kYellow, fontSize: 14.0), - ), - Container( - height: 10.h, - child: Padding( - padding: const EdgeInsets.all(4.0), - child: InkWell( - onTap: () async { - dateTime = await showDatePicker( - context: context, - initialDate: DateTime.now(), - firstDate: DateTime.now(), - lastDate: DateTime(2100), - ); - startsAtDate.text = - dateTime.toString().substring(0, 10); - }, - child: TextFormField( - enabled: false, - controller: startsAtDate, - onChanged: (value) { - startsAtDate.text = - dateTime.toString().substring(0, 10); - }, - decoration: InputDecoration( - alignLabelWithHint: true, - errorStyle: TextStyle(color: Colors.red[800]), - floatingLabelBehavior: - FloatingLabelBehavior.always, - labelText: 'End Date', - labelStyle: TextStyle( - fontSize: labelsize, color: kYellow), - hintStyle: TextStyle( - fontSize: hintsize, color: hintColor), - hintText: 'Choose end date', - focusedBorder: InputBorder.none, - enabledBorder: InputBorder.none, - ), - ), - ), - ), - color: kLightBlue, - ), - SizedBox( - height: 2.h, - ), - Container( - height: 10.h, - child: Padding( - padding: const EdgeInsets.all(4.0), - child: InkWell( - onTap: () async { - timeOfDay = await showTimePicker( - context: context, - initialTime: TimeOfDay.now(), - ); - startsAtTime.text = - timeOfDay.toString().substring(10, 15); - }, - child: TextFormField( - enabled: false, - controller: startsAtTime, - onChanged: (value) { - startsAtTime.text = - timeOfDay.toString().substring(10, 15); - }, - decoration: InputDecoration( - alignLabelWithHint: true, - errorStyle: TextStyle(color: Colors.red[800]), - floatingLabelBehavior: - FloatingLabelBehavior.always, - labelText: 'End Time', - labelStyle: TextStyle( - fontSize: labelsize, color: kYellow), - hintStyle: TextStyle( - fontSize: hintsize, color: hintColor), - hintText: 'Choose End time', - focusedBorder: InputBorder.none, - enabledBorder: InputBorder.none, - ), - ), - ), - ), - color: kLightBlue, + SizedBox( + height: 2.h, + ), + Container( + child: Text( + 'Choose End Date-Time', + style: TextStyle(color: kYellow, fontSize: 15.0), + ), + ), + SizedBox( + height: 2.h, + ), + Container( + color: kLightBlue, + height: 10.h, + child: Padding( + padding: const EdgeInsets.all(4.0), + child: InkWell( + onTap: () async { + dateTime = await showDatePicker( + context: context, + initialDate: DateTime.now(), + firstDate: DateTime.now(), + lastDate: DateTime(2100), + ); + startsAtDate.text = + dateTime.toString().substring(0, 10); + }, + child: TextFormField( + enabled: false, + controller: startsAtDate, + onChanged: (value) { + startsAtDate.text = + dateTime.toString().substring(0, 10); + }, + decoration: InputDecoration( + alignLabelWithHint: true, + errorStyle: TextStyle(color: Colors.red[800]), + floatingLabelBehavior: FloatingLabelBehavior.always, + labelText: 'End Date', + labelStyle: + TextStyle(fontSize: labelsize, color: kYellow), + hintStyle: + TextStyle(fontSize: hintsize, color: hintColor), + hintText: 'Choose end date', + focusedBorder: InputBorder.none, + enabledBorder: InputBorder.none, ), - ], + ), ), ), ), SizedBox( - height: 3.h, + height: 2.h, ), - Flexible( - child: HikeButton( - buttonWidth: optbwidth, - text: 'Done', - textSize: 18.0, - textColor: Colors.white, - buttonColor: kYellow, + Container( + height: 10.h, + child: Padding( + padding: const EdgeInsets.all(4.0), + child: InkWell( onTap: () async { - if (dateTime == null || timeOfDay == null) { - navigationService.showSnackBar("Enter date and time"); - return; - } - dateTime = DateTime( - dateTime.year, - dateTime.month, - dateTime.day, - timeOfDay.hour, - timeOfDay.minute, - ); - // localNotif.scheduleNotification(); - if (DateTime.fromMillisecondsSinceEpoch( - model.beacon.startsAt) - .isAfter(dateTime)) { - navigationService - .showSnackBar("Enter a valid date and time!!"); - return; - } - // DateTime newTime = - // DateTime.now().add(newDuration); - // update time - await databaseFunctions.init(); - final updatedBeacon = - await databaseFunctions.changeBeaconDuration( - model.beacon.id, - dateTime.millisecondsSinceEpoch, + timeOfDay = await showTimePicker( + context: context, + initialTime: TimeOfDay.now(), ); - if (updatedBeacon != null) { - model.updateBeaconDuration( - dateTime.millisecondsSinceEpoch); - } - Navigator.pop(context, dateTime); - }), + startsAtTime.text = + timeOfDay.toString().substring(10, 15); + }, + child: TextFormField( + enabled: false, + controller: startsAtTime, + onChanged: (value) { + startsAtTime.text = + timeOfDay.toString().substring(10, 15); + }, + decoration: InputDecoration( + alignLabelWithHint: true, + errorStyle: TextStyle(color: Colors.red[800]), + floatingLabelBehavior: FloatingLabelBehavior.always, + labelText: 'End Time', + labelStyle: + TextStyle(fontSize: labelsize, color: kYellow), + hintStyle: + TextStyle(fontSize: hintsize, color: hintColor), + hintText: 'Choose End time', + focusedBorder: InputBorder.none, + enabledBorder: InputBorder.none, + ), + ), + ), + ), + color: kLightBlue, + ), + SizedBox( + height: 4.h, + ), + HikeButton( + buttonWidth: optbwidth, + text: 'Done', + textSize: 18.0, + textColor: Colors.white, + buttonColor: kYellow, + onTap: () async { + if (dateTime == null || timeOfDay == null) { + navigationService.showSnackBar("Enter date and time"); + return; + } + dateTime = DateTime( + dateTime.year, + dateTime.month, + dateTime.day, + timeOfDay.hour, + timeOfDay.minute, + ); + // localNotif.scheduleNotification(); + if (DateTime.fromMillisecondsSinceEpoch( + model.beacon.startsAt) + .isAfter(dateTime)) { + navigationService + .showSnackBar("Enter a valid date and time!!"); + return; + } + // DateTime newTime = + // DateTime.now().add(newDuration); + // update time + await databaseFunctions.init(); + final updatedBeacon = + await databaseFunctions.changeBeaconDuration( + model.beacon.id, + dateTime.millisecondsSinceEpoch, + ); + if (updatedBeacon != null) { + model.updateBeaconDuration( + dateTime.millisecondsSinceEpoch); + } + Navigator.pop(context, dateTime); + }, + ), + SizedBox( + height: 2.h, ), ], ), From 1c4098f636c07b5586bebcffeacdab9f25c292bc Mon Sep 17 00:00:00 2001 From: Aadeesh11 Date: Wed, 16 Feb 2022 21:11:54 +0530 Subject: [PATCH 4/6] feat: added FAB to change beacon duration. --- lib/components/dialog_boxes.dart | 35 ++++++++++++++++++++-- lib/components/hike_screen_widget.dart | 21 +++++++++++++ lib/view_model/hike_screen_model.dart | 7 +++-- lib/views/hike_screen.dart | 41 ++++++++++++++++++-------- 4 files changed, 87 insertions(+), 17 deletions(-) diff --git a/lib/components/dialog_boxes.dart b/lib/components/dialog_boxes.dart index 853726bf..ceb846ee 100644 --- a/lib/components/dialog_boxes.dart +++ b/lib/components/dialog_boxes.dart @@ -71,7 +71,7 @@ class DialogBoxes { ), Container( child: Text( - 'Choose End Date-Time', + 'Change End Date-Time', style: TextStyle(color: kYellow, fontSize: 15.0), ), ), @@ -160,7 +160,38 @@ class DialogBoxes { color: kLightBlue, ), SizedBox( - height: 4.h, + height: 2.h, + ), + HikeButton( + buttonWidth: optbwidth, + text: 'Disable', + textSize: 16.0, + textColor: Colors.white, + buttonColor: kYellow, + onTap: () async { + await databaseFunctions.init(); + var timeNow = DateTime.now() + .add( + Duration( + seconds: 1, + ), + ) + .millisecondsSinceEpoch; + final updatedBeacon = + await databaseFunctions.changeBeaconDuration( + model.beacon.id, + timeNow, + ); + if (updatedBeacon != null) { + model.updateBeaconDuration( + timeNow, + ); + } + Navigator.pop(context, timeNow); + }, + ), + SizedBox( + height: 2.h, ), HikeButton( buttonWidth: optbwidth, diff --git a/lib/components/hike_screen_widget.dart b/lib/components/hike_screen_widget.dart index 55bc6ea8..f5fc5484 100644 --- a/lib/components/hike_screen_widget.dart +++ b/lib/components/hike_screen_widget.dart @@ -32,6 +32,7 @@ class HikeScreenWidget { static Widget shareButton(BuildContext context, String passkey) { return FloatingActionButton( + tooltip: 'Add people to the beacon!', onPressed: () { showDialog( context: context, @@ -105,6 +106,7 @@ class HikeScreenWidget { List beaconRoute, ) { return FloatingActionButton( + tooltip: 'Share image of the map!', heroTag: 'shareRouteTag', //had to pass this tag else we would get error since there will be two FAB in the same subtree with the same tag. onPressed: () async { @@ -280,6 +282,25 @@ class HikeScreenWidget { ); } + static Widget changeDurationFAB( + BuildContext context, HikeScreenViewModel model) { + return FloatingActionButton( + tooltip: 'Change beacon\'s duration!', + heroTag: + 'changeDurationTag', //had to pass this tag else we would get error since there will be many FAB in the same subtree with the same tag. + onPressed: () async { + await DialogBoxes.changeDurationDialog( + context, + model, + ); + }, + backgroundColor: kYellow, + child: Icon( + Icons.alarm_outlined, + ), + ); + } + static void showCreateLandMarkDialogueDialog( BuildContext context, var landmarkFormKey, diff --git a/lib/view_model/hike_screen_model.dart b/lib/view_model/hike_screen_model.dart index a76fa456..400e28ac 100644 --- a/lib/view_model/hike_screen_model.dart +++ b/lib/view_model/hike_screen_model.dart @@ -403,9 +403,12 @@ class HikeScreenViewModel extends BaseModel { setState(ViewState.idle); } - void updateBeaconDuration(int newExpiresAt) { + void updateBeaconDuration(int newExpiresAt) async { beacon.expiresAt = newExpiresAt; + navigationService + .showSnackBar('Yay! Duration has been changed successfully.'); notifyListeners(); + await hiveDb.putBeaconInBeaconBox(beacon.id, beacon); } Future createLandmark( @@ -428,8 +431,6 @@ class HikeScreenViewModel extends BaseModel { )); beacon.landmarks.add(value); await hiveDb.putBeaconInBeaconBox(beacon.id, beacon); - print(hiveDb.beaconsBox.get(beacon.id).landmarks.length.toString() + - 'asdasdasd'); notifyListeners(); }); } diff --git a/lib/views/hike_screen.dart b/lib/views/hike_screen.dart index e2768bd6..87c1a5c6 100644 --- a/lib/views/hike_screen.dart +++ b/lib/views/hike_screen.dart @@ -153,9 +153,11 @@ class _HikeScreenState extends State { tilt: CAMERA_TILT, bearing: CAMERA_BEARING), onMapCreated: (GoogleMapController controller) { - setState(() { - model.mapController.complete(controller); - }); + setState( + () { + model.mapController.complete(controller); + }, + ); // setPolyline(); }, onTap: (loc) async { @@ -175,11 +177,12 @@ class _HikeScreenState extends State { }), ), Align( - alignment: Alignment(0.9, -0.98), - child: model.isBeaconExpired - ? Container() - : HikeScreenWidget.shareButton( - context, widget.beacon.shortcode)), + alignment: Alignment(0.9, -0.98), + child: model.isBeaconExpired + ? Container() + : HikeScreenWidget.shareButton( + context, widget.beacon.shortcode), + ), Align( alignment: Alignment(-0.9, -0.98), child: FloatingActionButton( @@ -198,14 +201,28 @@ class _HikeScreenState extends State { //show the routeSharebutton only when beacon is active(?) and mapcontroller is ready. Align( alignment: screenHeight > 800 - ? Alignment(0.9, -0.8) - : Alignment(0.9, -0.77), + ? Alignment(0.9, -0.82) + : Alignment(0.9, -0.79), child: AnimatedOpacity( duration: Duration(milliseconds: 500), opacity: model.mapController.isCompleted ? 1.0 : 0.0, - child: HikeScreenWidget.shareRouteButton(context, - model.beacon, model.mapController, model.route), + child: HikeScreenWidget.shareRouteButton( + context, + model.beacon, + model.mapController, + model.route, + ), + ), + ), + if (model.isLeader && !model.isBeaconExpired) + Align( + alignment: screenHeight > 800 + ? Alignment(0.9, -0.65) + : Alignment(0.9, -0.6), + child: HikeScreenWidget.changeDurationFAB( + context, + model, ), ), ], From ccbe36b055250dd64eebf2d58718138ab8f99d03 Mon Sep 17 00:00:00 2001 From: Aadeesh11 Date: Fri, 24 Jun 2022 14:34:10 +0530 Subject: [PATCH 5/6] CI fixes. --- lib/components/loading_screen.dart | 16 +++++++--------- lib/views/home.dart | 5 ++++- pubspec.lock | 24 ++++++++++++------------ 3 files changed, 23 insertions(+), 22 deletions(-) diff --git a/lib/components/loading_screen.dart b/lib/components/loading_screen.dart index 9d8ccfe6..7633bc75 100644 --- a/lib/components/loading_screen.dart +++ b/lib/components/loading_screen.dart @@ -19,20 +19,18 @@ class LoadingScreen extends StatelessWidget { ), child: Column( children: [ - Expanded( - flex: 3, - child: SizedBox() - ), + Expanded(flex: 3, child: SizedBox()), Expanded( flex: 1, child: Padding( padding: const EdgeInsets.all(8.0), - child: SpinKitThreeBounce(color: kYellow,size: 40,), - ) - ), + child: SpinKitThreeBounce( + color: kYellow, + size: 40, + ), + )), ], - ) - ), + )), ), ); } diff --git a/lib/views/home.dart b/lib/views/home.dart index 1ce8efe7..39bfd0c4 100644 --- a/lib/views/home.dart +++ b/lib/views/home.dart @@ -99,7 +99,10 @@ class _MainScreenState extends State with TickerProviderStateMixin { onPressed: () => showDialog( context: context, builder: (context) => AlertDialog( - shape: RoundedRectangleBorder( borderRadius: BorderRadius.circular(10.0),), + shape: RoundedRectangleBorder( + borderRadius: + BorderRadius.circular(10.0), + ), actionsAlignment: MainAxisAlignment.spaceEvenly, title: Text( diff --git a/pubspec.lock b/pubspec.lock index 64290fe6..047276ce 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -648,13 +648,6 @@ packages: url: "https://pub.dartlang.org" source: hosted version: "0.12.11" - material_color_utilities: - dependency: transitive - description: - name: material_color_utilities - url: "https://pub.dartlang.org" - source: hosted - version: "0.1.3" meta: dependency: transitive description: @@ -774,6 +767,13 @@ packages: url: "https://pub.dartlang.org" source: hosted version: "2.0.5" + pedantic: + dependency: transitive + description: + name: pedantic + url: "https://pub.dartlang.org" + source: hosted + version: "1.11.1" petitparser: dependency: transitive description: @@ -1065,21 +1065,21 @@ packages: name: test url: "https://pub.dartlang.org" source: hosted - version: "1.19.5" + version: "1.17.12" test_api: dependency: transitive description: name: test_api url: "https://pub.dartlang.org" source: hosted - version: "0.4.8" + version: "0.4.3" test_core: dependency: transitive description: name: test_core url: "https://pub.dartlang.org" source: hosted - version: "0.4.9" + version: "0.4.2" timezone: dependency: transitive description: @@ -1177,7 +1177,7 @@ packages: name: url_launcher_web url: "https://pub.dartlang.org" source: hosted - version: "2.0.8" + version: "2.0.6" url_launcher_windows: dependency: transitive description: @@ -1257,4 +1257,4 @@ packages: version: "3.1.0" sdks: dart: ">=2.15.0 <3.0.0" - flutter: ">=2.10.0" + flutter: ">=2.8.0" From 776f2ad3641dabf25e2bc9bcbc8a7f4241f764c2 Mon Sep 17 00:00:00 2001 From: Aadeesh11 <66922161+Aadeesh11@users.noreply.github.com> Date: Fri, 24 Jun 2022 22:03:36 +0530 Subject: [PATCH 6/6] Update pubspec.lock --- pubspec.lock | 1 - 1 file changed, 1 deletion(-) diff --git a/pubspec.lock b/pubspec.lock index b9260147..9ea8baac 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -1184,7 +1184,6 @@ packages: name: url_launcher_web url: "https://pub.dartlang.org" source: hosted - version: "2.0.6" version: "2.0.12" url_launcher_windows: dependency: transitive