Skip to content
New issue

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

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

Already on GitHub? Sign in to your account

feat: Allow leader to change beacon duration, and deactivate the beacon. #97

Open
wants to merge 10 commits into
base: main
Choose a base branch
from
2 changes: 1 addition & 1 deletion lib/components/beacon_card.dart
Original file line number Diff line number Diff line change
Expand Up @@ -167,7 +167,7 @@ class BeaconCustomWidgets {
TextSpan(
text: 'in ',
style: TextStyle(
color: const Color(0xffb6b2df),
color: Color(0xffb6b2df),
fontSize: 14.0,
fontWeight: FontWeight.w400),
),
Expand Down
6 changes: 3 additions & 3 deletions lib/components/create_join_dialog.dart
Original file line number Diff line number Diff line change
Expand Up @@ -12,9 +12,9 @@ class CreateJoinBeaconDialog {
BuildContext context, HomeViewModel model, Function reloadList) {
bool isSmallSized = MediaQuery.of(context).size.height < 800;
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) => GestureDetector(
Expand Down
202 changes: 176 additions & 26 deletions lib/components/dialog_boxes.dart
Original file line number Diff line number Diff line change
@@ -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';

Expand Down Expand Up @@ -45,48 +46,197 @@ class DialogBoxes {
);
}

static Future changeDurationDialog(BuildContext context) {
static Future<DateTime> changeDurationDialog(
BuildContext context,
HikeScreenViewModel model,
) {
DateTime dateTime;
TimeOfDay timeOfDay;
var startsAtDate = TextEditingController();
var startsAtTime = TextEditingController();
return showDialog(
context: context,
builder: (context) => Dialog(
shape: RoundedRectangleBorder(
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: <Widget>[
Flexible(
child: Container(
color: kLightBlue,
child: Column(
children: <Widget>[
Text(
'Change Beacon Duration',
style: TextStyle(color: kYellow, fontSize: 14.0),
SizedBox(
height: 2.h,
),
Container(
child: Text(
'Change 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,
onTap: () {
// DateTime newTime =
// DateTime.now().add(newDuration);
// update time
Navigator.pop(context);
}),
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,
),
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,
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,
),
],
),
Expand Down
2 changes: 1 addition & 1 deletion lib/components/hike_button.dart
Original file line number Diff line number Diff line change
Expand Up @@ -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(
Expand Down
32 changes: 27 additions & 5 deletions lib/components/hike_screen_widget.dart
Original file line number Diff line number Diff line change
@@ -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';
Expand Down Expand Up @@ -31,6 +32,7 @@ class HikeScreenWidget extends ChangeNotifier {

static Widget shareButton(BuildContext context, String passkey) {
return FloatingActionButton(
tooltip: 'Add people to the beacon!',
onPressed: () {
showDialog(
context: context,
Expand Down Expand Up @@ -104,6 +106,7 @@ class HikeScreenWidget extends ChangeNotifier {
List<LatLng> 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 {
Expand Down Expand Up @@ -240,14 +243,14 @@ class HikeScreenWidget extends ChangeNotifier {
trailing: model.hikers[index].id == model.beacon.leader.id
? GestureDetector(
onDoubleTap: () {
Aadeesh11 marked this conversation as resolved.
Show resolved Hide resolved
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,
Expand All @@ -269,6 +272,25 @@ class HikeScreenWidget extends ChangeNotifier {
);
}

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,
Expand Down
34 changes: 34 additions & 0 deletions lib/queries/beacon.dart
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,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 {
Expand Down
Loading