1125 lines
37 KiB
Dart
1125 lines
37 KiB
Dart
import 'dart:io';
|
|
import 'dart:typed_data';
|
|
import 'package:camera_camera/camera_camera.dart';
|
|
import 'package:flutter/material.dart';
|
|
import 'package:flutter_map/flutter_map.dart';
|
|
import 'package:flutter_map_location_marker/flutter_map_location_marker.dart';
|
|
import 'package:geojson_vi/geojson_vi.dart';
|
|
import 'package:geolocator/geolocator.dart';
|
|
import 'package:get/get.dart';
|
|
import 'package:intl/intl.dart';
|
|
import 'package:latlong2/latlong.dart';
|
|
import 'package:rogapp/main.dart';
|
|
import 'package:rogapp/model/destination.dart';
|
|
import 'package:rogapp/model/gps_data.dart';
|
|
import 'package:rogapp/pages/camera/camera_page.dart';
|
|
import 'package:rogapp/pages/index/index_controller.dart';
|
|
import 'package:rogapp/routes/app_pages.dart';
|
|
import 'package:rogapp/services/DatabaseService.dart';
|
|
import 'package:rogapp/services/destination_service.dart';
|
|
import 'package:rogapp/services/external_service.dart';
|
|
import 'package:rogapp/services/location_service.dart';
|
|
import 'package:rogapp/services/maxtrix_service.dart';
|
|
import 'package:rogapp/services/perfecture_service.dart';
|
|
import 'package:rogapp/utils/database_gps.dart';
|
|
import 'package:rogapp/utils/database_helper.dart';
|
|
import 'package:rogapp/utils/location_controller.dart';
|
|
import 'package:rogapp/widgets/bottom_sheet_new.dart';
|
|
import 'dart:async';
|
|
|
|
import 'package:modal_bottom_sheet/modal_bottom_sheet.dart';
|
|
import 'package:rogapp/widgets/debug_widget.dart';
|
|
import 'package:shared_preferences/shared_preferences.dart';
|
|
|
|
import 'package:image_gallery_saver/image_gallery_saver.dart';
|
|
|
|
class DestinationController extends GetxController {
|
|
late LocationSettings locationSettings;
|
|
|
|
Timer? _GPStimer;
|
|
|
|
var destinationCount = 0.obs;
|
|
List<Destination> destinations = <Destination>[].obs;
|
|
double currentLat = 0.0;
|
|
double currentLon = 0.0;
|
|
DateTime lastGPSCollectedTime = DateTime.now();
|
|
|
|
bool shouldShowBottomSheet = true;
|
|
|
|
static bool gps_push_started = false;
|
|
static bool game_started = false;
|
|
static bool ready_for_goal = false;
|
|
|
|
bool skip_10s = false;
|
|
|
|
List<Destination> currentSelectedDestinations = <Destination>[].obs;
|
|
|
|
var isInCheckin = false.obs;
|
|
var isInRog = false.obs;
|
|
var isAtStart = false.obs;
|
|
var isAtGoal = false.obs;
|
|
var isPhotoShoot = false.obs;
|
|
DateTime lastGoalAt = DateTime.now().subtract(const Duration(days: 1));
|
|
//List<Rogaining> rogainings = <Rogaining>[].obs;
|
|
|
|
bool checkingIn = false;
|
|
var isGpsSelected = true.obs;
|
|
BuildContext? context;
|
|
|
|
List<String> gps = <String>["-- stating --"].obs;
|
|
List<String> locationPermission = <String>[" -- starting -- "].obs;
|
|
|
|
var travelMode = 0.obs;
|
|
|
|
bool skipGps = false;
|
|
|
|
Map<String, dynamic> matrix = {};
|
|
|
|
final photos = <File>[].obs;
|
|
|
|
final IndexController indexController = Get.find<IndexController>();
|
|
final LocationController locationController = Get.put(LocationController());
|
|
final DatabaseService dbService = DatabaseService();
|
|
|
|
int _start = 0;
|
|
int chekcs = 0;
|
|
var rogainingCounted = false.obs;
|
|
|
|
String getFormatedTime(DateTime datetime) {
|
|
return DateFormat('yyyy-MM-dd HH:mm:ss').format(datetime);
|
|
}
|
|
|
|
Destination festuretoDestination(GeoJSONFeature fs) {
|
|
GeoJSONMultiPoint mp = fs.geometry as GeoJSONMultiPoint;
|
|
LatLng pt = LatLng(mp.coordinates[0][1], mp.coordinates[0][0]);
|
|
|
|
//print("----- ${indexController.currentFeature[0].properties} -----");
|
|
|
|
return Destination(
|
|
name: fs.properties!["location_name"],
|
|
sub_loc_id: fs.properties!["sub_loc_id"],
|
|
address: fs.properties!["address"],
|
|
phone: fs.properties!["phone"],
|
|
email: fs.properties!["email"],
|
|
webcontents: fs.properties!["webcontents"],
|
|
videos: fs.properties!["videos"],
|
|
category: fs.properties!["category"],
|
|
series: 1,
|
|
lat: pt.latitude,
|
|
lon: pt.longitude,
|
|
location_id: fs.properties!["location_id"],
|
|
list_order: 1,
|
|
photos: fs.properties!["photos"],
|
|
checkin_radious: fs.properties!["checkin_radius"],
|
|
auto_checkin: fs.properties!["auto_checkin"] == true ? 1 : 0,
|
|
cp: fs.properties!["cp"],
|
|
checkin_point: fs.properties!["checkin_point"],
|
|
buy_point: fs.properties!["buy_point"],
|
|
selected: false,
|
|
checkedin: false,
|
|
hidden_location: fs.properties!["hidden_location"] == true ? 1 : 0,
|
|
tags: fs.properties!["tags"]);
|
|
}
|
|
|
|
Future<void> startTimerLocation(GeoJSONFeature fs, double distance) async {
|
|
//print("---- in startTimer ----");
|
|
// print("---- is in rog is $is_in_rog ----");
|
|
double checkinRadious = fs.properties!['checkin_radius'] ?? double.infinity;
|
|
if (checkinRadious >= distance) {
|
|
indexController.currentFeature.clear();
|
|
Destination d = festuretoDestination(fs);
|
|
// print("----- destination lenght is ${destinations.length} -----");
|
|
indexController.currentFeature.add(fs);
|
|
//print("---- before calling startTimer ----");
|
|
await startTimer(d, distance);
|
|
return;
|
|
}
|
|
}
|
|
|
|
Future<void> startTimer(Destination d, double distance) async {
|
|
//print("=== passed dest is ${d.location_id} ${d.checkedin} ====");
|
|
skipGps = true;
|
|
//print("---- in startTimer ----");
|
|
|
|
DatabaseHelper db = DatabaseHelper.instance;
|
|
List<Destination> ds = await db.getDestinationByLatLon(d.lat!, d.lon!);
|
|
Destination? dss;
|
|
if (ds.isNotEmpty) {
|
|
dss = ds.first;
|
|
}
|
|
|
|
double checkinRadious = d.checkin_radious ?? double.infinity;
|
|
bool autoCheckin = d.auto_checkin == 0 ? false : true;
|
|
bool buyPoint = dss != null && dss.buy_point != null && dss.buy_point! > 0
|
|
? true
|
|
: false;
|
|
bool buyPointImageAdded =
|
|
dss != null && dss.buypoint_image != null ? true : false;
|
|
bool buyPointCanceled =
|
|
dss != null && dss.buy_point != null && dss.buy_point == 0
|
|
? true
|
|
: false;
|
|
bool locationAlreadyCheckedIn =
|
|
ds.isNotEmpty && ds[0].checkedin == true ? true : false;
|
|
bool isuserLoggedIn = indexController.currentUser.isNotEmpty ? true : false;
|
|
//make current destination
|
|
// print("---- checkin_radious $checkinRadious ----");
|
|
// print("---- distance $distance ----");
|
|
if (checkinRadious >= distance || checkinRadious == -1) {
|
|
//currentSelectedDestinations.add(d);
|
|
indexController.currentDestinationFeature.clear();
|
|
indexController.currentDestinationFeature.add(d);
|
|
|
|
// print(
|
|
// "---- checked in as ${indexController.currentDestinationFeature[0].checkedin.toString()} ----");
|
|
} else {
|
|
skipGps = false;
|
|
return;
|
|
}
|
|
|
|
if (isPhotoShoot.value == true) {
|
|
photos.clear();
|
|
if (shouldShowBottomSheet) {
|
|
shouldShowBottomSheet = false;
|
|
if (d.cp == -1) return;
|
|
await showModalBottomSheet(
|
|
constraints:
|
|
BoxConstraints.loose(Size(Get.width, Get.height * 0.75)),
|
|
context: Get.context!,
|
|
isScrollControlled: true,
|
|
builder: ((context) => CameraPage(destination: d)))
|
|
.whenComplete(() {
|
|
shouldShowBottomSheet = true;
|
|
skipGps = false;
|
|
chekcs = 0;
|
|
isInCheckin.value = false;
|
|
});
|
|
}
|
|
return;
|
|
}
|
|
|
|
if (ds.isEmpty) {
|
|
// print("----- in location popup cp - ${d.cp}----");
|
|
if (d.cp == -1 && DateTime.now().difference(lastGoalAt).inHours >= 24) {
|
|
chekcs = 1;
|
|
//start
|
|
// print("~~~~ calling start ~~~~");
|
|
// print("---- in start -----");
|
|
chekcs = 1;
|
|
isInCheckin.value = true;
|
|
isAtStart.value = true;
|
|
if (shouldShowBottomSheet) {
|
|
shouldShowBottomSheet = false;
|
|
if (d.cp == -1) return;
|
|
await showModalBottomSheet(
|
|
constraints:
|
|
BoxConstraints.loose(Size(Get.width, Get.height * 0.85)),
|
|
context: Get.context!,
|
|
isScrollControlled: true,
|
|
builder: ((context) => BottomSheetNew(
|
|
destination: d,
|
|
))).whenComplete(() {
|
|
shouldShowBottomSheet = true;
|
|
skipGps = false;
|
|
chekcs = 0;
|
|
isAtStart.value = false;
|
|
isInCheckin.value = false;
|
|
});
|
|
}
|
|
return;
|
|
} else if (isInRog.value == true &&
|
|
indexController.rogMode.value == 1 &&
|
|
d.cp != -1) {
|
|
// print("----- in location popup checkin cp - ${d.cp}----");
|
|
chekcs = 2;
|
|
isInCheckin.value = true;
|
|
if (shouldShowBottomSheet) {
|
|
shouldShowBottomSheet = false;
|
|
if (d.cp == -1) return;
|
|
await showModalBottomSheet(
|
|
constraints:
|
|
BoxConstraints.loose(Size(Get.width, Get.height * 0.75)),
|
|
context: Get.context!,
|
|
isScrollControlled: true,
|
|
builder: ((context) => BottomSheetNew(
|
|
destination: d,
|
|
))).whenComplete(() {
|
|
shouldShowBottomSheet = true;
|
|
skipGps = false;
|
|
chekcs = 0;
|
|
isInCheckin.value = false;
|
|
});
|
|
}
|
|
return;
|
|
}
|
|
}
|
|
|
|
// print("---- location checkin radious ${d.checkin_radious} ----");
|
|
// print("---- already checked in $locationAlreadyCheckedIn ----");
|
|
if ((checkinRadious >= distance || checkinRadious == -1) &&
|
|
locationAlreadyCheckedIn == false &&
|
|
isInRog.value == true) {
|
|
if (autoCheckin) {
|
|
if (!checkingIn) {
|
|
//print(
|
|
// "@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ make checkin ${d.sub_loc_id}@@@@@@@@@@@");
|
|
makeCheckin(d, true, "");
|
|
if (d.cp != -1) {
|
|
rogainingCounted.value = true;
|
|
}
|
|
skipGps = false;
|
|
}
|
|
return;
|
|
} else {
|
|
// print("--- hidden loc ${d.hidden_location} ----");
|
|
// ask for checkin
|
|
if (d.hidden_location != null &&
|
|
d.hidden_location == 0 &&
|
|
isInRog.value == true &&
|
|
d.cp != -1) {
|
|
chekcs = 3;
|
|
isInCheckin.value = true;
|
|
photos.clear();
|
|
// print("--- calling checkin ---");
|
|
if (shouldShowBottomSheet) {
|
|
shouldShowBottomSheet = false;
|
|
if (d.cp == -1) return;
|
|
await showModalBottomSheet(
|
|
constraints:
|
|
BoxConstraints.loose(Size(Get.width, Get.height * 0.75)),
|
|
context: Get.context!,
|
|
isScrollControlled: true,
|
|
builder: ((context) => CameraPage(
|
|
destination: d,
|
|
))).whenComplete(() {
|
|
shouldShowBottomSheet = true;
|
|
skipGps = false;
|
|
rogainingCounted.value = true;
|
|
chekcs = 0;
|
|
isInCheckin.value = false;
|
|
});
|
|
}
|
|
return;
|
|
} else if (isInRog.value == true && d.cp != -1) {
|
|
chekcs = 4;
|
|
isInCheckin.value = true;
|
|
if (shouldShowBottomSheet) {
|
|
shouldShowBottomSheet = false;
|
|
if (d.cp == -1) return;
|
|
await showMaterialModalBottomSheet(
|
|
expand: true,
|
|
context: Get.context!,
|
|
backgroundColor: Colors.transparent,
|
|
builder: (context) => BottomSheetNew(
|
|
destination: d,
|
|
)).whenComplete(() {
|
|
shouldShowBottomSheet = true;
|
|
skipGps = false;
|
|
chekcs = 0;
|
|
isInCheckin.value = false;
|
|
});
|
|
}
|
|
return;
|
|
}
|
|
}
|
|
} else if ((checkinRadious >= distance || checkinRadious == -1) &&
|
|
locationAlreadyCheckedIn == true &&
|
|
buyPointImageAdded == false &&
|
|
ds.isNotEmpty &&
|
|
buyPoint == true &&
|
|
buyPointCanceled == false &&
|
|
isInRog.value == true) {
|
|
chekcs = 5;
|
|
isInCheckin.value = true;
|
|
photos.clear();
|
|
//print("--- open buy point $buyPointImageAdded ${d.buypoint_image} ----");
|
|
if (shouldShowBottomSheet) {
|
|
shouldShowBottomSheet = false;
|
|
if (d.cp == -1) return;
|
|
await showModalBottomSheet(
|
|
constraints:
|
|
BoxConstraints.loose(Size(Get.width, Get.height * 0.75)),
|
|
context: Get.context!,
|
|
isScrollControlled: true,
|
|
builder: ((context) => CameraPage(
|
|
buyPointPhoto: true,
|
|
destination: d,
|
|
dbDest: ds.first,
|
|
))).whenComplete(() {
|
|
shouldShowBottomSheet = true;
|
|
skipGps = false;
|
|
rogainingCounted.value = true;
|
|
chekcs = 0;
|
|
isInCheckin.value = false;
|
|
});
|
|
}
|
|
return;
|
|
}
|
|
// print("---- cp --- ${d.cp} -----");
|
|
// print("--- at goal $is_at_goal ---");
|
|
// print("--- rog counted $rogaining_counted ---");
|
|
// print("--- loc already checked in $locationAlreadyCheckedIn ---");
|
|
// print(
|
|
// "==== date diff is ${DateTime.now().difference(last_goal_at).inHours} ====");
|
|
if (isuserLoggedIn &&
|
|
d.cp == -1 &&
|
|
locationAlreadyCheckedIn &&
|
|
skip_10s == false) {
|
|
//check for rogaining
|
|
if (isAtGoal.value == false && rogainingCounted.value) {
|
|
//goal
|
|
//print("---- in goal -----");
|
|
chekcs = 5;
|
|
isAtGoal.value = true;
|
|
photos.clear();
|
|
if (shouldShowBottomSheet) {
|
|
shouldShowBottomSheet = false;
|
|
if (d.cp == -1) return;
|
|
await showModalBottomSheet(
|
|
constraints:
|
|
BoxConstraints.loose(Size(Get.width, Get.height * 0.75)),
|
|
context: Get.context!,
|
|
isScrollControlled: true,
|
|
builder: ((context) => CameraPage(
|
|
destination: d,
|
|
))).whenComplete(() {
|
|
shouldShowBottomSheet = true;
|
|
skipGps = false;
|
|
chekcs = 0;
|
|
isAtGoal.value = false;
|
|
});
|
|
}
|
|
return;
|
|
} else if (isInRog.value == false &&
|
|
indexController.rogMode.value == 1 &&
|
|
DateTime.now().difference(lastGoalAt).inHours >= 24) {
|
|
//start
|
|
//print("---- in start -----");
|
|
chekcs = 6;
|
|
isAtStart.value = true;
|
|
if (shouldShowBottomSheet) {
|
|
shouldShowBottomSheet = false;
|
|
if (d.cp == -1) return;
|
|
await showModalBottomSheet(
|
|
constraints:
|
|
BoxConstraints.loose(Size(Get.width, Get.height * 0.75)),
|
|
context: Get.context!,
|
|
isScrollControlled: true,
|
|
builder: ((context) => BottomSheetNew(
|
|
destination: d,
|
|
))).whenComplete(() {
|
|
shouldShowBottomSheet = true;
|
|
//print("----- finished start -------");
|
|
skipGps = false;
|
|
chekcs = 0;
|
|
isAtStart.value = false;
|
|
});
|
|
}
|
|
return;
|
|
}
|
|
}
|
|
//print("==== _chekcs $chekcs ====");
|
|
if (chekcs == 0) {
|
|
skipGps = false;
|
|
}
|
|
return;
|
|
}
|
|
|
|
Future<void> resetRogaining({bool isgoal = false}) async {
|
|
//print("----- resetting --------");
|
|
|
|
isInCheckin.value = false;
|
|
isInRog.value = false;
|
|
isAtStart.value = false;
|
|
isAtGoal.value = false;
|
|
isGpsSelected.value = true;
|
|
skipGps = false;
|
|
ready_for_goal = false;
|
|
|
|
_start = 0;
|
|
chekcs = 0;
|
|
rogainingCounted.value = false;
|
|
|
|
DatabaseHelper db = DatabaseHelper.instance;
|
|
|
|
if (isgoal == false) {
|
|
await db.deleteAllDestinations();
|
|
await db.deleteAllRogaining();
|
|
}
|
|
|
|
int? latgoal = await db.latestGoal();
|
|
if (latgoal != null) {
|
|
lastGoalAt = DateTime.fromMicrosecondsSinceEpoch(latgoal);
|
|
//print("===== last goal : $last_goal_at =====");
|
|
}
|
|
dbService.updateDatabase();
|
|
}
|
|
|
|
void deleteAllDestinations() {
|
|
DatabaseHelper db = DatabaseHelper.instance;
|
|
db.deleteAllDestinations().then((value) {
|
|
populateDestinations();
|
|
});
|
|
}
|
|
|
|
void openCamera(BuildContext context, Destination? destination) {
|
|
photos.clear();
|
|
Navigator.push(
|
|
context,
|
|
MaterialPageRoute(
|
|
builder: (_) => CameraCamera(
|
|
resolutionPreset: ResolutionPreset.medium,
|
|
onFile: (file) {
|
|
photos.add(file);
|
|
Navigator.pop(context);
|
|
//print("----image file is : $file----");
|
|
//setState(() {});
|
|
},
|
|
)));
|
|
}
|
|
|
|
void getRoutePoints() {
|
|
indexController.routePoints = [];
|
|
indexController.routePointLenght.value = 0;
|
|
DestinationService.getDestinationLine(destinations, matrix)?.then((value) {
|
|
indexController.routePoints = value;
|
|
indexController.routePointLenght.value =
|
|
indexController.routePoints.length;
|
|
});
|
|
}
|
|
|
|
Future<Destination?> getDestinationForLatLong(double lat, double long) async {
|
|
for (final d in destinations) {
|
|
if (lat == d.lat && long == d.lon) {
|
|
return d;
|
|
}
|
|
}
|
|
return null;
|
|
}
|
|
|
|
Future<void> callforCheckin(Destination d) async {
|
|
bool autoCheckin = d.auto_checkin == 0 ? false : true;
|
|
//print("---- f- checkin ${d.sub_loc_id} ----");
|
|
if (autoCheckin) {
|
|
if (!checkingIn) {
|
|
makeCheckin(d, true, "");
|
|
if (d.cp != -1) {
|
|
rogainingCounted.value = true;
|
|
}
|
|
}
|
|
} else {
|
|
//print("--- hidden loc ${d.hidden_location} ----");
|
|
// ask for checkin
|
|
//print("is rog ---- ${is_in_rog.value} ----");
|
|
if (d.hidden_location != null &&
|
|
d.hidden_location == 0 &&
|
|
isInRog.value == true &&
|
|
d.cp != -1) {
|
|
chekcs = 3;
|
|
isInCheckin.value = true;
|
|
photos.clear();
|
|
await showModalBottomSheet(
|
|
constraints:
|
|
BoxConstraints.loose(Size(Get.width, Get.height * 0.75)),
|
|
context: Get.context!,
|
|
isScrollControlled: true,
|
|
builder: ((context) => CameraPage(
|
|
manulaCheckin: true,
|
|
destination: d,
|
|
))).whenComplete(() async {
|
|
if (d.buy_point != null && d.buy_point! > 0) {
|
|
skipGps = true;
|
|
photos.clear();
|
|
DatabaseHelper db = DatabaseHelper.instance;
|
|
List<Destination> ds =
|
|
await db.getDestinationByLatLon(d.lat!, d.lon!);
|
|
Destination? dss;
|
|
if (ds.isNotEmpty) {
|
|
dss = ds.first;
|
|
}
|
|
|
|
await showModalBottomSheet(
|
|
constraints:
|
|
BoxConstraints.loose(Size(Get.width, Get.height * 0.75)),
|
|
context: Get.context!,
|
|
isScrollControlled: true,
|
|
builder: ((context) => CameraPage(
|
|
buyPointPhoto: true,
|
|
destination: d,
|
|
dbDest: dss,
|
|
))).whenComplete(() {
|
|
skipGps = false;
|
|
rogainingCounted.value = true;
|
|
chekcs = 0;
|
|
isInCheckin.value = false;
|
|
Get.back();
|
|
});
|
|
} else {
|
|
skipGps = false;
|
|
chekcs = 0;
|
|
isInCheckin.value = false;
|
|
}
|
|
});
|
|
} else {
|
|
Get.snackbar("始まっていない", "ロゲイニングを始める必要があります");
|
|
}
|
|
}
|
|
}
|
|
|
|
Future<void> addGPStoDB(double la, double ln, {isCheckin = 0}) async {
|
|
//print("in addGPStoDB ${indexController.currentUser}");
|
|
try {
|
|
GpsDatabaseHelper db = GpsDatabaseHelper.instance;
|
|
final team_name = indexController.currentUser[0]["user"]['team_name'];
|
|
final event_code = indexController.currentUser[0]["user"]["event_code"];
|
|
GpsData gps_data = GpsData(
|
|
id: 0,
|
|
team_name: team_name,
|
|
event_code: event_code,
|
|
lat: la,
|
|
lon: ln,
|
|
is_checkin: isCheckin,
|
|
created_at: DateTime.now().millisecondsSinceEpoch);
|
|
var res = await db.insertGps(gps_data);
|
|
} catch (err) {
|
|
print("errr ready gps ${err}");
|
|
return;
|
|
}
|
|
}
|
|
|
|
Future<void> checkForCheckin() async {
|
|
//print("--- Start of checkForCheckin function ---");
|
|
dbService.updateDatabase();
|
|
await Future.delayed(const Duration(milliseconds: 3000));
|
|
game_started = true;
|
|
|
|
try {
|
|
indexController.locations[0].features.forEach((fs) async {
|
|
GeoJSONMultiPoint mp = fs!.geometry as GeoJSONMultiPoint;
|
|
LatLng pt = LatLng(mp.coordinates[0][1], mp.coordinates[0][0]);
|
|
|
|
double latFs = pt.latitude;
|
|
double lonFs = pt.longitude;
|
|
var distanceFs = const Distance();
|
|
double distFs = distanceFs.as(LengthUnit.Meter, LatLng(latFs, lonFs),
|
|
LatLng(currentLat, currentLon));
|
|
Destination des = festuretoDestination(fs);
|
|
|
|
if (distFs <= des.checkin_radious! && skipGps == false) {
|
|
await startTimerLocation(fs, distFs);
|
|
// Note: You cannot break out of forEach. If you need to stop processing, you might have to reconsider using forEach.
|
|
}
|
|
});
|
|
|
|
if (gps_push_started == false) {
|
|
pushGPStoServer();
|
|
}
|
|
//print("--- 123 ---- $skip_gps----");
|
|
} catch (e) {
|
|
//print("An error occurred: $e");
|
|
await checkForCheckin();
|
|
} finally {
|
|
//print("--- End of checkForCheckin function, calling recursively ---");
|
|
await checkForCheckin();
|
|
}
|
|
}
|
|
|
|
Future<void> pushGPStoServer() async {
|
|
// print(
|
|
// "^^^^^^^^ ${DateFormat('kk:mm:ss \n EEE d MMM').format(DateTime.now())}");
|
|
try {
|
|
gps_push_started = true;
|
|
ExternalService().pushGPS();
|
|
} catch (e) {
|
|
//print("An error occurred: $e");
|
|
//await pushGPStoServer();
|
|
} finally {
|
|
//print("--- End of pushGPStoServer function, calling recursively ---");
|
|
await Future.delayed(const Duration(seconds: 5 * 60));
|
|
await pushGPStoServer();
|
|
}
|
|
}
|
|
|
|
void addToRogaining(double lat, double lon, int destinationId) async {
|
|
DatabaseHelper db = DatabaseHelper.instance;
|
|
List<Destination> d = await db.getDestinationById(destinationId);
|
|
if (d.isEmpty) {
|
|
Destination df = festuretoDestination(indexController.currentFeature[0]);
|
|
//print("--- made checkin ${df.location_id} ----");
|
|
makeCheckin(df, true, "");
|
|
}
|
|
isInRog.value = true;
|
|
|
|
//saveGameState();
|
|
}
|
|
|
|
Future<void> cancelBuyPoint(Destination destination) async {
|
|
DatabaseHelper db = DatabaseHelper.instance;
|
|
await db.updateCancelBuyPoint(destination);
|
|
populateDestinations();
|
|
}
|
|
|
|
_saveImageFromPath(String imagePath) async {
|
|
// Read the image file from the given path
|
|
File imageFile = File(imagePath);
|
|
Uint8List imageBytes = await imageFile.readAsBytes();
|
|
|
|
// Save the image to the gallery
|
|
final result = await ImageGallerySaver.saveImage(imageBytes);
|
|
//print("--- save result --- ${result}");
|
|
}
|
|
|
|
Future<void> makeBuyPoint(Destination destination, String imageurl) async {
|
|
DatabaseHelper db = DatabaseHelper.instance;
|
|
await db.updateBuyPoint(destination, imageurl);
|
|
populateDestinations();
|
|
await _saveImageFromPath(imageurl);
|
|
|
|
if (indexController.currentUser.isNotEmpty) {
|
|
double cpNum = destination.cp!;
|
|
|
|
int userId = indexController.currentUser[0]["user"]["id"];
|
|
//print("--- Pressed -----");
|
|
String team = indexController.currentUser[0]["user"]['team_name'];
|
|
//print("--- _team : ${_team}-----");
|
|
String eventCode = indexController.currentUser[0]["user"]["event_code"];
|
|
//print("--- _event_code : ${_event_code}-----");
|
|
String token = indexController.currentUser[0]["token"];
|
|
//print("--- _token : ${_token}-----");
|
|
DateTime now = DateTime.now();
|
|
String formattedDate = DateFormat('yyyy-MM-dd HH:mm:ss').format(now);
|
|
|
|
//print("------ checkin event $eventCode ------");
|
|
ExternalService()
|
|
.makeCheckpoint(userId, token, formattedDate, team, cpNum.round(),
|
|
eventCode, imageurl)
|
|
.then((value) {
|
|
//print("------Ext service check point $value ------");
|
|
});
|
|
}
|
|
}
|
|
|
|
Future<void> makeCheckin(
|
|
Destination destination, bool action, String imageurl) async {
|
|
// print("~~~~ calling checkin function ~~~~");
|
|
// print(
|
|
// "@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ ressssss ${destination.sub_loc_id}@@@@@@@@@@@");
|
|
DatabaseHelper db = DatabaseHelper.instance;
|
|
List<Destination> ddd =
|
|
await db.getDestinationByLatLon(destination.lat!, destination.lon!);
|
|
|
|
if (ddd.isEmpty) {
|
|
destination.checkedin = true;
|
|
destination.checkin_image = imageurl;
|
|
await db.insertDestination(destination);
|
|
// print("~~~~ inserted into db ~~~~");
|
|
}
|
|
|
|
await _saveImageFromPath(imageurl);
|
|
|
|
populateDestinations();
|
|
|
|
/// post to NATNAT
|
|
if (indexController.currentUser.isNotEmpty) {
|
|
double cpNum = destination.cp!;
|
|
|
|
int userId = indexController.currentUser[0]["user"]["id"];
|
|
//print("--- Pressed -----");
|
|
String team = indexController.currentUser[0]["user"]['team_name'];
|
|
//print("--- _team : ${_team}-----");
|
|
String eventCode = indexController.currentUser[0]["user"]["event_code"];
|
|
//print("--- _event_code : ${_event_code}-----");
|
|
String token = indexController.currentUser[0]["token"];
|
|
//print("--- _token : ${_token}-----");
|
|
DateTime now = DateTime.now();
|
|
String formattedDate = DateFormat('yyyy-MM-dd HH:mm:ss').format(now);
|
|
|
|
await addGPStoDB(currentLat, currentLon, isCheckin: 1);
|
|
|
|
// print("------ checkin event $eventCode ------");
|
|
ExternalService()
|
|
.makeCheckpoint(userId, token, formattedDate, team, cpNum.round(),
|
|
eventCode, imageurl)
|
|
.then((value) {
|
|
// print("------Ext service check point $value ------");
|
|
});
|
|
}
|
|
dbService.updateDatabase();
|
|
}
|
|
|
|
Future<void> removeCheckin(int cp) {
|
|
dbService.updateDatabase();
|
|
return ExternalService().removeCheckin(cp);
|
|
}
|
|
|
|
Future<void> startGame() async {
|
|
//print("------ starting game ------");
|
|
if (game_started == false) {
|
|
await checkForCheckin();
|
|
}
|
|
}
|
|
|
|
@override
|
|
void onInit() async {
|
|
super.onInit();
|
|
locationController.locationMarkerPositionStream.listen(
|
|
(locationMarkerPosition) {
|
|
if (locationMarkerPosition != null) {
|
|
handleLocationUpdate(locationMarkerPosition);
|
|
}
|
|
}, onError: (err) {
|
|
print("Error: $err");
|
|
});
|
|
|
|
startGame();
|
|
}
|
|
|
|
@override
|
|
void onClose() {
|
|
locationController.stopPositionStream();
|
|
}
|
|
|
|
void handleLocationUpdate(LocationMarkerPosition? position) async {
|
|
try {
|
|
if (position != null) {
|
|
if (distanceToStart() >= 150) {
|
|
ready_for_goal = true;
|
|
}
|
|
|
|
var distance = const Distance();
|
|
double distanceToDest = distance.as(
|
|
LengthUnit.Meter,
|
|
LatLng(position.latitude, position.longitude),
|
|
LatLng(currentLat, currentLon));
|
|
|
|
Duration difference =
|
|
lastGPSCollectedTime.difference(DateTime.now()).abs();
|
|
if (difference.inSeconds >= 10 || distanceToDest >= 10) {
|
|
// print(
|
|
// "^^^^^^^^ GPS data collected ${DateFormat('kk:mm:ss \n EEE d MMM').format(DateTime.now())}, ^^^ ${position.latitude}, ${position.longitude}");
|
|
|
|
LogManager().addLog(
|
|
"GPS : $currentLat, $currentLon - ${DateTime.now().hour}:${DateTime.now().minute}:${DateTime.now().second}:${DateTime.now().microsecond}");
|
|
if (isInRog.value) {
|
|
await addGPStoDB(position.latitude, position.longitude);
|
|
lastGPSCollectedTime = DateTime.now();
|
|
}
|
|
}
|
|
}
|
|
} finally {
|
|
if (position != null &&
|
|
(position.latitude != 0 && position.longitude != 0)) {
|
|
currentLat = position.latitude;
|
|
currentLon = position.longitude;
|
|
}
|
|
}
|
|
}
|
|
|
|
double distanceToStart() {
|
|
if (indexController.locations.isEmpty) {
|
|
return 1000000000;
|
|
}
|
|
//print("=== gfs len == ${indexController.locations[0].collection.length}");
|
|
double distanceToDest = double.infinity;
|
|
if (indexController.locations[0].features.isEmpty) {
|
|
return distanceToDest;
|
|
}
|
|
GeoJSONFeature? gfs = indexController.locations[0].features.firstWhere(
|
|
(element) => festuretoDestination(element!).cp == -1,
|
|
orElse: () => null, // Provide a null value if no element is found
|
|
);
|
|
|
|
//print("gfs : ${gfs}");
|
|
|
|
if (gfs == null) {
|
|
return distanceToDest;
|
|
}
|
|
|
|
Destination des = festuretoDestination(gfs);
|
|
|
|
//print("=== gfs == ${des.toMap()}");
|
|
|
|
var distance = const Distance();
|
|
distanceToDest = distance.as(LengthUnit.Meter,
|
|
LatLng(currentLat, currentLon), LatLng(des.lat!, des.lon!));
|
|
//print("==== dist==${distanceToDest}");
|
|
return distanceToDest;
|
|
}
|
|
|
|
int getForcedChckinDistance(Destination dest) {
|
|
if (dest.checkin_radious == -1) {
|
|
return 10000000000000000;
|
|
}
|
|
|
|
int _retValue = 100;
|
|
if (dest.cp == -1) {
|
|
return 500;
|
|
}
|
|
Destination? ds;
|
|
GeoJSONFeature? gfs = indexController.locations[0].features.firstWhere(
|
|
(element) => festuretoDestination(element!).cp == -1,
|
|
orElse: () => null, // Provide a null value if no element is found
|
|
);
|
|
|
|
if (gfs == null) {
|
|
return _retValue;
|
|
}
|
|
|
|
ds = festuretoDestination(gfs);
|
|
var distance = const Distance();
|
|
double distanceToDest = distance.as(LengthUnit.Meter,
|
|
LatLng(dest.lat!, dest.lon!), LatLng(ds.lat!, ds.lon!));
|
|
if (distanceToDest <= 500) {
|
|
return 500;
|
|
}
|
|
//print("==== forced dist ==${distanceToDest}");
|
|
return _retValue;
|
|
}
|
|
|
|
readUserToken() async {
|
|
final SharedPreferences prefs = await SharedPreferences.getInstance();
|
|
indexController.userToken = prefs.getString("user_token");
|
|
}
|
|
|
|
@override
|
|
void onReady() async {
|
|
await readUserToken();
|
|
final token = indexController.userToken;
|
|
if (token != null && token.isNotEmpty) {
|
|
await indexController.loadUserDetailsForToken(token);
|
|
fixMapBound(token);
|
|
return;
|
|
}
|
|
|
|
Get.toNamed(AppPages.LOGIN)!.then((value) {
|
|
if (indexController.currentUser.isNotEmpty) {
|
|
final tk = indexController.currentUser[0]["token"];
|
|
fixMapBound(tk);
|
|
} else {
|
|
Get.toNamed(AppPages.TRAVEL);
|
|
PerfectureService.getSubExt("9").then((value) {
|
|
if (value != null) {
|
|
LatLngBounds bnds = LatLngBounds(
|
|
LatLng(value[1], value[0]), LatLng(value[3], value[2]));
|
|
indexController.mapController
|
|
.fitBounds(bnds); //.centerZoomFitBounds(bnds);
|
|
}
|
|
});
|
|
}
|
|
});
|
|
super.onReady();
|
|
}
|
|
|
|
void fixMapBound(String token) {
|
|
//String _token = indexController.currentUser[0]["token"];
|
|
indexController.switchPage(AppPages.INDEX);
|
|
LocationService.getLocationsExt(token).then((value) {
|
|
if (value != null) {
|
|
//print("--- loc ext is - $value ----");
|
|
LatLngBounds bnds = LatLngBounds(
|
|
LatLng(value[1], value[0]), LatLng(value[3], value[2]));
|
|
//print("--- bnds is - $bnds ----");
|
|
indexController.mapController.fitBounds(
|
|
bnds,
|
|
);
|
|
indexController.currentBound.clear();
|
|
indexController.currentBound.add(bnds);
|
|
indexController.loadLocationsBound();
|
|
centerMapToCurrentLocation();
|
|
}
|
|
});
|
|
}
|
|
|
|
void centerMapToCurrentLocation() {
|
|
print("center is ${currentLon}, ${currentLon}");
|
|
if (currentLat != 0 || currentLon != 0) {
|
|
indexController.mapController.move(LatLng(currentLat, currentLon), 17.0);
|
|
}
|
|
}
|
|
|
|
void connectionChanged(String val) {
|
|
//print('----- %%%%%%%%%%%%%%%%%%%%% ----- $val');
|
|
Map<String, dynamic> res = {};
|
|
if (val == "wifi" || val == "mobile") {
|
|
String token = indexController.currentUser[0]["token"];
|
|
DatabaseHelper db = DatabaseHelper.instance;
|
|
db.allRogianing().then((value) {
|
|
value.forEach((e) async {
|
|
if (e.rog_action_type == 0) {
|
|
res = await ExternalService().startRogaining();
|
|
} else if (e.rog_action_type == 1) {
|
|
var datetime = DateTime.fromMicrosecondsSinceEpoch(e.checkintime!);
|
|
res = await ExternalService().makeCheckpoint(
|
|
e.user_id!,
|
|
token,
|
|
getFormatedTime(datetime),
|
|
e.team_name!,
|
|
e.cp_number!,
|
|
e.event_code!,
|
|
e.image!);
|
|
} else if (e.rog_action_type == 2) {
|
|
var datetime = DateTime.fromMicrosecondsSinceEpoch(e.checkintime!);
|
|
res = await ExternalService().makeGoal(
|
|
e.user_id!,
|
|
token,
|
|
e.team_name!,
|
|
e.image!,
|
|
getFormatedTime(datetime),
|
|
e.event_code!);
|
|
}
|
|
|
|
if (res.isNotEmpty) {
|
|
db.deleteRogaining(e.id!);
|
|
}
|
|
});
|
|
});
|
|
}
|
|
}
|
|
|
|
void checkPermission() async {
|
|
LocationPermission permission = await Geolocator.checkPermission();
|
|
if (permission != LocationPermission.whileInUse ||
|
|
permission != LocationPermission.always) {
|
|
locationPermission.clear();
|
|
locationPermission.add(permission.name);
|
|
permission = await Geolocator.requestPermission();
|
|
}
|
|
}
|
|
|
|
Destination? destinationById(int id) {
|
|
Destination? d;
|
|
//print("--- target des - $id ----");
|
|
for (Destination ss in destinations) {
|
|
//print("--- des - ${ss.location_id} ----");
|
|
if (ss.location_id == id) {
|
|
d = ss;
|
|
break;
|
|
}
|
|
}
|
|
return d;
|
|
}
|
|
|
|
void deleteDestination(Destination d) {
|
|
//int id = destinations[index].location_id!;
|
|
//print("---- index ${destinations[index].location_id!}-----");
|
|
for (Destination ss in destinations) {
|
|
if (ss.location_id == d.location_id) {
|
|
destinations.remove(ss);
|
|
break;
|
|
}
|
|
}
|
|
DatabaseHelper db = DatabaseHelper.instance;
|
|
db.deleteDestination(d.location_id!).then((value) {
|
|
populateDestinations();
|
|
});
|
|
dbService.updateDatabase();
|
|
}
|
|
|
|
void deleteDBDestinations() {
|
|
DatabaseHelper db = DatabaseHelper.instance;
|
|
db.deleteAllDestinations().then((value) {
|
|
populateDestinations();
|
|
});
|
|
dbService.updateDatabase();
|
|
}
|
|
|
|
// ---------- database ------------------///
|
|
|
|
void addDestinations(Destination dest) {
|
|
DatabaseHelper db = DatabaseHelper.instance;
|
|
db.getDestinationByLatLon(dest.lat!, dest.lon!).then((value) {
|
|
if (value.isNotEmpty) {
|
|
db.deleteDestination(value[0].location_id!).then((value) {
|
|
db.insertDestination(dest).then((value) {
|
|
//print(
|
|
// "----- destination controller deleted and inserted destination id $value ---- :::::");
|
|
populateDestinations();
|
|
});
|
|
});
|
|
} else {
|
|
db.insertDestination(dest).then((value) {
|
|
//print("----- destination controller added as new $value--- :::::");
|
|
populateDestinations();
|
|
});
|
|
}
|
|
});
|
|
dbService.updateDatabase();
|
|
}
|
|
|
|
void toggleSelection(Destination dest) async {
|
|
DatabaseHelper db = DatabaseHelper.instance;
|
|
await db.toggleSelecttion(dest);
|
|
destinations.clear();
|
|
db.getDestinations().then((value) {
|
|
destinationCount.value = 0;
|
|
currentSelectedDestinations.clear();
|
|
for (Destination d in value) {
|
|
//print("------ destination controller populating destination-------- ${d.checkedin}-------- :::::");
|
|
//print("-----populated----- ${d.toMap()}");
|
|
if (d.selected!) {
|
|
currentSelectedDestinations.add(d);
|
|
}
|
|
destinations.add(d);
|
|
}
|
|
destinationCount.value = destinations.length;
|
|
});
|
|
}
|
|
|
|
buildShowDialog(BuildContext context) {
|
|
return showDialog(
|
|
context: context,
|
|
barrierDismissible: false,
|
|
builder: (BuildContext context) {
|
|
return const Center(
|
|
child: CircularProgressIndicator(),
|
|
);
|
|
});
|
|
}
|
|
|
|
void destinationMatrixFromCurrentPoint(List<Destination> points) {
|
|
//buildShowDialog(Get.context!);
|
|
MatrixService.getDestinations(points).then((mat) {
|
|
//print(" matrix is ------- $mat");
|
|
matrix = mat;
|
|
|
|
try {
|
|
indexController.routePoints = [];
|
|
indexController.routePointLenght.value = 0;
|
|
DestinationService.getDestinationLine(points, matrix)?.then((value) {
|
|
indexController.routePoints = value;
|
|
indexController.routePointLenght.value =
|
|
indexController.routePoints.length;
|
|
//Get.toNamed(AppPages.TRAVEL);
|
|
});
|
|
destinationCount.value = destinations.length;
|
|
} catch (_) {
|
|
skipGps = false;
|
|
return;
|
|
} finally {
|
|
//Get.back();
|
|
}
|
|
});
|
|
}
|
|
|
|
void populateDestinations() {
|
|
DatabaseHelper db = DatabaseHelper.instance;
|
|
destinations.clear();
|
|
db.getDestinations().then((value) {
|
|
destinationCount.value = 0;
|
|
for (Destination d in value) {
|
|
destinations.add(d);
|
|
}
|
|
if (destinations.isEmpty) {
|
|
rogainingCounted.value = false;
|
|
}
|
|
});
|
|
}
|
|
|
|
void makeOrder(Destination d, int dir) {
|
|
DatabaseHelper db = DatabaseHelper.instance;
|
|
db.updateOrder(d, dir).then((value) {
|
|
populateDestinations();
|
|
});
|
|
}
|
|
}
|