diff --git a/lib/common/state/game/game_binding.dart b/lib/common/state/game/game_binding.dart new file mode 100644 index 0000000..58c14c4 --- /dev/null +++ b/lib/common/state/game/game_binding.dart @@ -0,0 +1,12 @@ +import 'package:get/get.dart'; +import 'package:rogapp/common/state/game/game_controller.dart'; +import 'package:rogapp/screens/auth/controller/auth_controller.dart'; + +class GameBinding extends Bindings{ + @override + void dependencies() { + Get.lazyPut(() => AuthController()); + Get.put(GameController()); + } + +} \ No newline at end of file diff --git a/lib/common/state/game/game_controller.dart b/lib/common/state/game/game_controller.dart new file mode 100644 index 0000000..7736c80 --- /dev/null +++ b/lib/common/state/game/game_controller.dart @@ -0,0 +1,25 @@ +import 'package:get/get.dart'; +import 'package:rogapp/model/user.dart'; +import 'package:rogapp/routes/app_pages.dart'; +import 'package:rogapp/screens/auth/controller/auth_controller.dart'; + +class GameController extends GetxController{ + + AuthController authController = Get.find(); + + @override + void onInit() { + ever(authController.authList, changeInAuth); + super.onInit(); + } + + void changeInAuth(List change){ + if(change.isNotEmpty){ + Get.toNamed(AppPages.S_HOME); + } + else{ + Get.toNamed(AppPages.S_LOGIN); + } + } + +} \ No newline at end of file diff --git a/lib/common/ui/widgets/uis.dart b/lib/common/ui/widgets/uis.dart index daf0d64..0aeadd2 100644 --- a/lib/common/ui/widgets/uis.dart +++ b/lib/common/ui/widgets/uis.dart @@ -9,6 +9,7 @@ class UIs{ size:30, color: Pallete.WHITE_COLOR, ), + automaticallyImplyLeading:false, centerTitle: true, ); } diff --git a/lib/main.dart b/lib/main.dart index 9660469..444e5ed 100644 --- a/lib/main.dart +++ b/lib/main.dart @@ -6,6 +6,7 @@ import 'package:flutter_map_tile_caching/flutter_map_tile_caching.dart'; import 'package:get/get.dart'; import 'package:google_fonts/google_fonts.dart'; import 'package:permission_handler/permission_handler.dart'; +import 'package:rogapp/common/state/game/game_binding.dart'; import 'package:rogapp/pages/index/index_binding.dart'; import 'package:rogapp/routes/app_pages.dart'; import 'package:rogapp/theme/theme.dart'; @@ -53,7 +54,7 @@ class MyApp extends StatelessWidget { opaqueRoute: Get.isOpaqueRouteDefault, popGesture: Get.isPopGestureEnable, transitionDuration: const Duration(milliseconds: 230), - //initialBinding: IndexBinding(), //HomeBinding(), + initialBinding: GameBinding(), initialRoute: AppPages.S_LOGIN, getPages: AppPages.routes, enableLog: true, diff --git a/lib/model/location_response.dart b/lib/model/location_response.dart new file mode 100644 index 0000000..7ab1a9d --- /dev/null +++ b/lib/model/location_response.dart @@ -0,0 +1,591 @@ +// ignore_for_file: public_member_api_docs, sort_constructors_first +import 'dart:convert'; + +import 'package:flutter/foundation.dart'; +import 'package:unicode/unicode.dart'; + +class LocationResponse { + List? features; + String? type; + + LocationResponse({ + this.features, + this.type, + }); + + LocationResponse copyWith({ + List? features, + String? type, + }) { + return LocationResponse( + features: features ?? this.features, + type: type ?? this.type, + ); + } + + Map toMap() { + return { + 'features': features?.map((x) => x.toMap()).toList(), + 'type': type, + }; + } + + factory LocationResponse.fromMap(Map map) { + return LocationResponse( + features: List.from(map['features']?.map((x) => Feature.fromMap(x)) ?? const []), + type: map['type'], + ); + } + + String toJson() => json.encode(toMap()); + + factory LocationResponse.fromJson(String source) => + LocationResponse.fromMap(json.decode(source)); + + @override + String toString() => 'LocationResponse(features: $features, type: $type)'; + + @override + bool operator ==(Object other) { + if (identical(this, other)) return true; + + return other is LocationResponse && + listEquals(other.features, features) && + other.type == type; + } + + @override + int get hashCode => features.hashCode ^ type.hashCode; +} + +class Feature { + Geometry? geometry; + int? id; + Properties? properties; + String? type; + int? location_id; + double? latitude; + double? longitude; + + Feature({ + this.geometry, + this.id, + this.properties, + this.type, + this.location_id, + this.latitude, + this.longitude + }); + + + Map toMap() { + return { + 'id': id, + 'geometry': geometry?.toJson(), + 'properties': properties?.toJson(), + 'type': type, + // Use the first coordinate as latitude and longitude. + // You may need to adjust this based on your actual data structure. + 'location_id': properties?.location_id, + 'latitude': geometry?.coordinates?.first?.last, + 'longitude': geometry?.coordinates?.first?.first, + }; + } + + // factory Feature.fromMap(Map map) { + // return Feature( + // geometry: Geometry.fromMap(map['geometry']), + // id: map['id'], + // properties: Properties.fromMap(map['properties']), + // type: map['type'], + // ); + // } + + factory Feature.fromMap(Map map) { + Geometry? geometry = map['geometry'] != null + ? Geometry.fromMap(map['geometry']) + : null; + double? latitude = geometry?.coordinates?.isNotEmpty ?? false ? geometry!.coordinates![0][0] : null; + double? longitude = geometry?.coordinates?.isNotEmpty ?? false ? geometry!.coordinates![0][1] : null; + + return Feature( + id: map['id'] as int?, + geometry: Geometry.fromMap(map['geometry']), + properties: Properties.fromMap(map['properties']), + type: map['type'], + location_id: Properties.fromMap(map['properties']).location_id, + latitude: latitude, + longitude: longitude, + ); + } + + + String toJson() => json.encode(toMap()); + + factory Feature.fromJson(String source) => + Feature.fromMap(json.decode(source)); + + @override + String toString() { + return 'Feature(geometry: $geometry, id: $id, properties: $properties, type: $type)'; + } + + @override + bool operator ==(Object other) { + if (identical(this, other)) return true; + + return other is Feature && + other.geometry == geometry && + other.id == id && + other.properties == properties && + other.type == type; + } + + @override + int get hashCode { + return geometry.hashCode ^ id.hashCode ^ properties.hashCode ^ type.hashCode; + } +} + +class Geometry { + List>? coordinates; + String? type; + + Geometry({ + this.coordinates, + this.type, + }); + + Geometry copyWith({ + List>? coordinates, + String? type, + }) { + return Geometry( + coordinates: coordinates ?? this.coordinates, + type: type ?? this.type, + ); + } + + Map toMap() { + return { + 'coordinates': coordinates, + 'type': type, + }; + } + + factory Geometry.fromMap(Map map) { + return Geometry( + coordinates: map['coordinates'] != null + ? List>.from( + map['coordinates'].map((x) => List.from(x.map((x) => x.toDouble())))) + : null, + type: map['type'], + ); + } + + String toJson() => json.encode(toMap()); + + factory Geometry.fromJson(String source) => + Geometry.fromMap(json.decode(source) as Map); + + @override + String toString() => 'Geometry(coordinates: $coordinates, type: $type)'; + + @override + bool operator ==(covariant Geometry other) { + if (identical(this, other)) return true; + + return listEquals(other.coordinates, coordinates) && other.type == type; + } + + @override + int get hashCode => coordinates.hashCode ^ type.hashCode; +} + +class Properties { + final int location_id; + final String? sub_loc_id; + final double? cp; + final String? location_name; + final String? category; + final String? subcategory; + final String? zip; + final String? address; + final String? prefecture; + final String? area; + final String? city; + final double? latitude; + final double? longitude; + final String? photos; + final String? videos; + final String? webcontents; + final String? status; + final String? portal; + final String? group; + final String? phone; + final String? fax; + final String? email; + final String? facility; + final String? remark; + final String? tags; + final dynamic? event_name; + final bool? event_active; + final bool? hidden_location; + final bool? auto_checkin; + final double? checkin_radius; + final double? checkin_point; + final double? buy_point; + final String? evaluation_value; + final bool? shop_closed; + final bool? shop_shutdown; + final String? opening_hours_mon; + final String? opening_hours_tue; + final String? opening_hours_wed; + final String? opening_hours_thu; + final String? opening_hours_fri; + final String? opening_hours_sat; + final String? opening_hours_sun; + final String? parammeters; + Properties({ + required this.location_id, + this.sub_loc_id, + this.cp, + this.location_name, + this.category, + this.subcategory, + this.zip, + this.address, + this.prefecture, + this.area, + this.city, + this.latitude, + this.longitude, + this.photos, + this.videos, + this.webcontents, + this.status, + this.portal, + this.group, + this.phone, + this.fax, + this.email, + this.facility, + this.remark, + this.tags, + this.event_name, + this.event_active, + this.hidden_location, + this.auto_checkin, + this.checkin_radius, + this.checkin_point, + this.buy_point, + this.evaluation_value, + this.shop_closed, + this.shop_shutdown, + this.opening_hours_mon, + this.opening_hours_tue, + this.opening_hours_wed, + this.opening_hours_thu, + this.opening_hours_fri, + this.opening_hours_sat, + this.opening_hours_sun, + this.parammeters, + }); + + +String toJson() => json.encode(toMap()); + + Properties copyWith({ + int? location_id, + String? sub_loc_id, + double? cp, + String? location_name, + String? category, + String? subcategory, + String? zip, + String? address, + String? prefecture, + String? area, + String? city, + double? latitude, + double? longitude, + String? photos, + String? videos, + String? webcontents, + String? status, + String? portal, + String? group, + String? phone, + String? fax, + String? email, + String? facility, + String? remark, + String? tags, + dynamic? event_name, + bool? event_active, + bool? hidden_location, + bool? auto_checkin, + double? checkin_radius, + double? checkin_point, + double? buy_point, + String? evaluation_value, + bool? shop_closed, + bool? shop_shutdown, + String? opening_hours_mon, + String? opening_hours_tue, + String? opening_hours_wed, + String? opening_hours_thu, + String? opening_hours_fri, + String? opening_hours_sat, + String? opening_hours_sun, + String? parammeters, + }) { + return Properties( + location_id: location_id ?? this.location_id, + sub_loc_id: sub_loc_id ?? this.sub_loc_id, + cp: cp ?? this.cp, + location_name: location_name ?? this.location_name, + category: category ?? this.category, + subcategory: subcategory ?? this.subcategory, + zip: zip ?? this.zip, + address: address ?? this.address, + prefecture: prefecture ?? this.prefecture, + area: area ?? this.area, + city: city ?? this.city, + latitude: latitude ?? this.latitude, + longitude: longitude ?? this.longitude, + photos: photos ?? this.photos, + videos: videos ?? this.videos, + webcontents: webcontents ?? this.webcontents, + status: status ?? this.status, + portal: portal ?? this.portal, + group: group ?? this.group, + phone: phone ?? this.phone, + fax: fax ?? this.fax, + email: email ?? this.email, + facility: facility ?? this.facility, + remark: remark ?? this.remark, + tags: tags ?? this.tags, + event_name: event_name ?? this.event_name, + event_active: event_active ?? this.event_active, + hidden_location: hidden_location ?? this.hidden_location, + auto_checkin: auto_checkin ?? this.auto_checkin, + checkin_radius: checkin_radius ?? this.checkin_radius, + checkin_point: checkin_point ?? this.checkin_point, + buy_point: buy_point ?? this.buy_point, + evaluation_value: evaluation_value ?? this.evaluation_value, + shop_closed: shop_closed ?? this.shop_closed, + shop_shutdown: shop_shutdown ?? this.shop_shutdown, + opening_hours_mon: opening_hours_mon ?? this.opening_hours_mon, + opening_hours_tue: opening_hours_tue ?? this.opening_hours_tue, + opening_hours_wed: opening_hours_wed ?? this.opening_hours_wed, + opening_hours_thu: opening_hours_thu ?? this.opening_hours_thu, + opening_hours_fri: opening_hours_fri ?? this.opening_hours_fri, + opening_hours_sat: opening_hours_sat ?? this.opening_hours_sat, + opening_hours_sun: opening_hours_sun ?? this.opening_hours_sun, + parammeters: parammeters ?? this.parammeters, + ); + } + + Map toMap() { + return { + 'location_id': location_id, + 'sub_loc_id': sub_loc_id, + 'cp': cp, + 'location_name': location_name, + 'category': category, + 'subcategory': subcategory, + 'zip': zip, + 'address': address, + 'prefecture': prefecture, + 'area': area, + 'city': city, + 'latitude': latitude, + 'longitude': longitude, + 'photos': photos, + 'videos': videos, + 'webcontents': webcontents, + 'status': status, + 'portal': portal, + 'group': group, + 'phone': phone, + 'fax': fax, + 'email': email, + 'facility': facility, + 'remark': remark, + 'tags': tags, + 'event_name': event_name, + 'event_active': event_active, + 'hidden_location': hidden_location, + 'auto_checkin': auto_checkin, + 'checkin_radius': checkin_radius, + 'checkin_point': checkin_point, + 'buy_point': buy_point, + 'evaluation_value': evaluation_value, + 'shop_closed': shop_closed, + 'shop_shutdown': shop_shutdown, + 'opening_hours_mon': opening_hours_mon, + 'opening_hours_tue': opening_hours_tue, + 'opening_hours_wed': opening_hours_wed, + 'opening_hours_thu': opening_hours_thu, + 'opening_hours_fri': opening_hours_fri, + 'opening_hours_sat': opening_hours_sat, + 'opening_hours_sun': opening_hours_sun, + 'parammeters': parammeters, + }; + } + + factory Properties.fromMap(Map map) { + return Properties( + location_id: map['location_id'] as int, + sub_loc_id: map['sub_loc_id'] != null ? map['sub_loc_id'] as String : null, + cp: map['cp'] != null ? map['cp'] as double : null, + location_name: map['location_name'] != null ? map['location_name'] as String : null, + category: map['category'] != null ? map['category'] as String : null, + subcategory: map['subcategory'] != null ? map['subcategory'] as String : null, + zip: map['zip'] != null ? map['zip'] as String : null, + address: map['address'] != null ? map['address'] as String : null, + prefecture: map['prefecture'] != null ? map['prefecture'] as String : null, + area: map['area'] != null ? map['area'] as String : null, + city: map['city'] != null ? map['city'] as String : null, + latitude: map['latitude'] != null ? map['latitude'] as double : null, + longitude: map['longitude'] != null ? map['longitude'] as double : null, + photos: map['photos'] != null ? map['photos'] as String : null, + videos: map['videos'] != null ? map['videos'] as String : null, + webcontents: map['webcontents'] != null ? map['webcontents'] as String : null, + status: map['status'] != null ? map['status'] as String : null, + portal: map['portal'] != null ? map['portal'] as String : null, + group: map['group'] != null ? map['group'] as String : null, + phone: map['phone'] != null ? map['phone'] as String : null, + fax: map['fax'] != null ? map['fax'] as String : null, + email: map['email'] != null ? map['email'] as String : null, + facility: map['facility'] != null ? map['facility'] as String : null, + remark: map['remark'] != null ? map['remark'] as String : null, + tags: map['tags'] != null ? map['tags'] as String : null, + event_name: map['event_name'] != null ? map['event_name'] as dynamic : null, + event_active: map['event_active'] != null ? map['event_active'] as bool : null, + hidden_location: map['hidden_location'] != null ? map['hidden_location'] as bool : null, + auto_checkin: map['auto_checkin'] != null ? map['auto_checkin'] as bool : null, + checkin_radius: map['checkin_radius'] != null ? map['checkin_radius'] as double : null, + checkin_point: map['checkin_point'] != null ? map['checkin_point'] as double : null, + buy_point: map['buy_point'] != null ? map['buy_point'] as double : null, + evaluation_value: map['evaluation_value'] != null ? map['evaluation_value'] as String : null, + shop_closed: map['shop_closed'] != null ? map['shop_closed'] as bool : null, + shop_shutdown: map['shop_shutdown'] != null ? map['shop_shutdown'] as bool : null, + opening_hours_mon: map['opening_hours_mon'] != null ? map['opening_hours_mon'] as String : null, + opening_hours_tue: map['opening_hours_tue'] != null ? map['opening_hours_tue'] as String : null, + opening_hours_wed: map['opening_hours_wed'] != null ? map['opening_hours_wed'] as String : null, + opening_hours_thu: map['opening_hours_thu'] != null ? map['opening_hours_thu'] as String : null, + opening_hours_fri: map['opening_hours_fri'] != null ? map['opening_hours_fri'] as String : null, + opening_hours_sat: map['opening_hours_sat'] != null ? map['opening_hours_sat'] as String : null, + opening_hours_sun: map['opening_hours_sun'] != null ? map['opening_hours_sun'] as String : null, + parammeters: map['parammeters'] != null ? map['parammeters'] as String : null, + ); + } + + factory Properties.fromJson(String source) => Properties.fromMap(json.decode(source) as Map); + + @override + String toString() { + return 'Properties(location_id: $location_id, sub_loc_id: $sub_loc_id, cp: $cp, location_name: $location_name, category: $category, subcategory: $subcategory, zip: $zip, address: $address, prefecture: $prefecture, area: $area, city: $city, latitude: $latitude, longitude: $longitude, photos: $photos, videos: $videos, webcontents: $webcontents, status: $status, portal: $portal, group: $group, phone: $phone, fax: $fax, email: $email, facility: $facility, remark: $remark, tags: $tags, event_name: $event_name, event_active: $event_active, hidden_location: $hidden_location, auto_checkin: $auto_checkin, checkin_radius: $checkin_radius, checkin_point: $checkin_point, buy_point: $buy_point, evaluation_value: $evaluation_value, shop_closed: $shop_closed, shop_shutdown: $shop_shutdown, opening_hours_mon: $opening_hours_mon, opening_hours_tue: $opening_hours_tue, opening_hours_wed: $opening_hours_wed, opening_hours_thu: $opening_hours_thu, opening_hours_fri: $opening_hours_fri, opening_hours_sat: $opening_hours_sat, opening_hours_sun: $opening_hours_sun, parammeters: $parammeters)'; + } + + @override + bool operator ==(covariant Properties other) { + if (identical(this, other)) return true; + + return + other.location_id == location_id && + other.sub_loc_id == sub_loc_id && + other.cp == cp && + other.location_name == location_name && + other.category == category && + other.subcategory == subcategory && + other.zip == zip && + other.address == address && + other.prefecture == prefecture && + other.area == area && + other.city == city && + other.latitude == latitude && + other.longitude == longitude && + other.photos == photos && + other.videos == videos && + other.webcontents == webcontents && + other.status == status && + other.portal == portal && + other.group == group && + other.phone == phone && + other.fax == fax && + other.email == email && + other.facility == facility && + other.remark == remark && + other.tags == tags && + other.event_name == event_name && + other.event_active == event_active && + other.hidden_location == hidden_location && + other.auto_checkin == auto_checkin && + other.checkin_radius == checkin_radius && + other.checkin_point == checkin_point && + other.buy_point == buy_point && + other.evaluation_value == evaluation_value && + other.shop_closed == shop_closed && + other.shop_shutdown == shop_shutdown && + other.opening_hours_mon == opening_hours_mon && + other.opening_hours_tue == opening_hours_tue && + other.opening_hours_wed == opening_hours_wed && + other.opening_hours_thu == opening_hours_thu && + other.opening_hours_fri == opening_hours_fri && + other.opening_hours_sat == opening_hours_sat && + other.opening_hours_sun == opening_hours_sun && + other.parammeters == parammeters; + } + + @override + int get hashCode { + return location_id.hashCode ^ + sub_loc_id.hashCode ^ + cp.hashCode ^ + location_name.hashCode ^ + category.hashCode ^ + subcategory.hashCode ^ + zip.hashCode ^ + address.hashCode ^ + prefecture.hashCode ^ + area.hashCode ^ + city.hashCode ^ + latitude.hashCode ^ + longitude.hashCode ^ + photos.hashCode ^ + videos.hashCode ^ + webcontents.hashCode ^ + status.hashCode ^ + portal.hashCode ^ + group.hashCode ^ + phone.hashCode ^ + fax.hashCode ^ + email.hashCode ^ + facility.hashCode ^ + remark.hashCode ^ + tags.hashCode ^ + event_name.hashCode ^ + event_active.hashCode ^ + hidden_location.hashCode ^ + auto_checkin.hashCode ^ + checkin_radius.hashCode ^ + checkin_point.hashCode ^ + buy_point.hashCode ^ + evaluation_value.hashCode ^ + shop_closed.hashCode ^ + shop_shutdown.hashCode ^ + opening_hours_mon.hashCode ^ + opening_hours_tue.hashCode ^ + opening_hours_wed.hashCode ^ + opening_hours_thu.hashCode ^ + opening_hours_fri.hashCode ^ + opening_hours_sat.hashCode ^ + opening_hours_sun.hashCode ^ + parammeters.hashCode; + } +} + + diff --git a/lib/model/user.dart b/lib/model/user.dart new file mode 100644 index 0000000..f861b41 --- /dev/null +++ b/lib/model/user.dart @@ -0,0 +1,45 @@ +class AuthResponse { + final User user; + final String token; + + AuthResponse({required this.user, required this.token}); + + factory AuthResponse.fromJson(Map json) { + return AuthResponse( + user: User.fromJson(json['user']), + token: json['token'], + ); + } +} + +class User { + final int id; + final String email; + final bool isRogaining; + final String group; + final String zekkenNumber; + final String eventCode; + final String teamName; + + User({ + required this.id, + required this.email, + required this.isRogaining, + required this.group, + required this.zekkenNumber, + required this.eventCode, + required this.teamName, + }); + + factory User.fromJson(Map json) { + return User( + id: json['id'], + email: json['email'], + isRogaining: json['is_rogaining'], + group: json['group'], + zekkenNumber: json['zekken_number'], + eventCode: json['event_code'], + teamName: json['team_name'], + ); + } +} diff --git a/lib/pages/camera/camera_page.dart b/lib/pages/camera/camera_page.dart index 3eedf42..59a7e98 100644 --- a/lib/pages/camera/camera_page.dart +++ b/lib/pages/camera/camera_page.dart @@ -4,12 +4,13 @@ import 'package:flutter/material.dart'; import 'package:get/get.dart'; import 'package:intl/intl.dart'; import 'package:rogapp/model/destination.dart'; +import 'package:rogapp/model/location_response.dart'; import 'package:rogapp/pages/destination/destination_controller.dart'; import 'package:rogapp/pages/index/index_controller.dart'; import 'package:rogapp/services/external_service.dart'; class CameraPage extends StatelessWidget { - Destination? destination; + Feature? destination; CameraPage({Key? key, this.destination}) : super(key: key); DestinationController destinationController = Get.find(); IndexController indexController = Get.find(); @@ -135,7 +136,7 @@ class CameraPage extends StatelessWidget { appBar: destinationController.is_in_rog.value && destinationController.rogaining_counted.value == true ? AppBar( - title: destination!.cp == -1 ? + title: destination!.properties!.cp == -1 ? Text("finishing_rogaining".tr) : Text("cp_pls_take_photo".tr) diff --git a/lib/pages/destination/destination_controller.dart b/lib/pages/destination/destination_controller.dart index 6c3d0d4..ed263da 100644 --- a/lib/pages/destination/destination_controller.dart +++ b/lib/pages/destination/destination_controller.dart @@ -221,14 +221,14 @@ class DestinationController extends GetxController { chekcs = 3; is_in_checkin.value = true; photos.clear(); - showModalBottomSheet(context: Get.context!, isScrollControlled: true, - builder:((context) => CameraPage(destination: d,)) - ).whenComplete((){ - skip_gps = false; - rogaining_counted.value =true; - chekcs = 0; - is_in_checkin.value = false; - }); + // showModalBottomSheet(context: Get.context!, isScrollControlled: true, + // builder:((context) => CameraPage(destination: d,)) + // ).whenComplete((){ + // skip_gps = false; + // rogaining_counted.value =true; + // chekcs = 0; + // is_in_checkin.value = false; + // }); } else if(is_in_rog.value == true && d.cp != -1){ chekcs = 4; @@ -267,13 +267,13 @@ class DestinationController extends GetxController { chekcs = 5; is_at_goal.value = true; photos.clear(); - showModalBottomSheet(context: Get.context!, isScrollControlled: true, - builder:((context) => CameraPage(destination: d,)) - ).whenComplete((){ - skip_gps = false; - chekcs = 0; - is_at_goal.value = false; - }); + // showModalBottomSheet(context: Get.context!, isScrollControlled: true, + // builder:((context) => CameraPage(destination: d,)) + // ).whenComplete((){ + // skip_gps = false; + // chekcs = 0; + // is_at_goal.value = false; + // }); } else if(is_in_rog.value == false && indexController.rog_mode == 1 && DateTime.now().difference(last_goal_at).inHours >= 24){ //start diff --git a/lib/pages/destination_map/destination_map_page.dart b/lib/pages/destination_map/destination_map_page.dart index 8f16599..49b4ab5 100644 --- a/lib/pages/destination_map/destination_map_page.dart +++ b/lib/pages/destination_map/destination_map_page.dart @@ -91,7 +91,7 @@ class DestinationMapPage extends StatelessWidget { ), ), ), - Container( color: Colors.yellow, child: Text(TextUtils.getDisplayText(d), style: TextStyle(fontSize: 15.0, fontWeight: FontWeight.bold, overflow: TextOverflow.visible),)), + //Container( color: Colors.yellow, child: Text(TextUtils.getDisplayText(d), style: TextStyle(fontSize: 15.0, fontWeight: FontWeight.bold, overflow: TextOverflow.visible),)), ], ), ); diff --git a/lib/routes/app_pages.dart b/lib/routes/app_pages.dart index b6de674..a67b50e 100644 --- a/lib/routes/app_pages.dart +++ b/lib/routes/app_pages.dart @@ -6,7 +6,6 @@ import 'package:rogapp/pages/changepassword/change_password_page.dart'; import 'package:rogapp/pages/city/city_page.dart'; import 'package:rogapp/pages/destination/destination_binding.dart'; import 'package:rogapp/pages/destination/destination_page.dart'; -import 'package:rogapp/pages/home/home_binding.dart'; import 'package:rogapp/pages/home/home_page.dart'; import 'package:rogapp/pages/index/index_page.dart'; @@ -26,6 +25,8 @@ import 'package:rogapp/screens/home/home_screen.dart'; import 'package:rogapp/spa/spa_binding.dart'; import 'package:rogapp/spa/spa_page.dart'; +import '../screens/home/home_binding.dart'; + part 'app_routes.dart'; @@ -70,7 +71,7 @@ class AppPages { GetPage( name: Routes.S_HOME, page: () => HomeScreen(), - //binding: IndexBinding(), + binding: HomeBinding() ), GetPage( name: Routes.S_LOGIN, diff --git a/lib/screens/auth/controller/auth_controller.dart b/lib/screens/auth/controller/auth_controller.dart new file mode 100644 index 0000000..0595d48 --- /dev/null +++ b/lib/screens/auth/controller/auth_controller.dart @@ -0,0 +1,45 @@ +import 'dart:convert' as convert; + +import 'package:get/get.dart'; +import 'package:rogapp/model/user.dart'; +import 'package:rogapp/utils/const.dart'; +import 'package:http/http.dart' as http; + +class AuthController extends GetxController{ + var isLoading = false.obs; + var authList = List.empty(growable: true).obs; + + void signinUser(String email, String password) async { + try{ + isLoading(true); + String serverUrl = ConstValues.currentServer(); + String url = '$serverUrl/api/login/'; + final http.Response response = await http.post( + Uri.parse(url), + headers: { + 'Content-Type': 'application/json; charset=UTF-8', + }, + body: convert.jsonEncode({ + 'email': email, + 'password': password + }), + ); + if (response.statusCode == 200) { + print(response.body); + AuthResponse authResponse = AuthResponse.fromJson(convert.jsonDecode(convert.utf8.decode(response.body.codeUnits))); + print(authResponse.user.eventCode.toString()); + authList.assign(authResponse); + } + else{ + throw("Unable to Login, please check your creadentials"); + } + } + catch(e){ + Get.snackbar("Error", e.toString(), snackPosition: SnackPosition.BOTTOM); + } + finally{ + isLoading(false); + } + } + +} \ No newline at end of file diff --git a/lib/screens/auth/views/login/login_screen.dart b/lib/screens/auth/views/login/login_screen.dart index 4d896ba..c4dfb20 100644 --- a/lib/screens/auth/views/login/login_screen.dart +++ b/lib/screens/auth/views/login/login_screen.dart @@ -5,6 +5,7 @@ import 'package:rogapp/common/ui/widgets/uis.dart'; import 'package:rogapp/routes/app_pages.dart'; import 'package:rogapp/screens/auth/common/uis/auth_text_field.dart'; import 'package:rogapp/screens/auth/common/uis/rounded_small_button.dart'; +import 'package:rogapp/screens/auth/controller/auth_controller.dart'; import 'package:rogapp/theme/theme.dart'; class LoginScreen extends StatelessWidget { @@ -12,15 +13,17 @@ class LoginScreen extends StatelessWidget { final passwordController = TextEditingController(); LoginScreen({super.key}); - void login(){ - } - + final AuthController authController = Get.find(); @override Widget build(BuildContext context) { return Scaffold( appBar: UIs.appBar(), - body: Center( + body: Obx((){ + if(authController.isLoading.value) { + return const Center(child: CircularProgressIndicator(),); + } else { + return Center( child: SingleChildScrollView( child: Padding( padding: const EdgeInsets.all(8.0), @@ -39,7 +42,10 @@ class LoginScreen extends StatelessWidget { const SizedBox(height: 40,), Align( alignment: Alignment.topRight, - child: RoundedSmallButton(onTap: login, label: 'Done',), + child: RoundedSmallButton(onTap: (){ + authController.signinUser(emailController.text, passwordController.text); + }, + label: 'Done',), ), const SizedBox(height: 40,), RichText( @@ -61,7 +67,9 @@ class LoginScreen extends StatelessWidget { ), ), ), - ) + ); + } + }), ); } } \ No newline at end of file diff --git a/lib/screens/home/home_binding.dart b/lib/screens/home/home_binding.dart index e69de29..2b538d3 100644 --- a/lib/screens/home/home_binding.dart +++ b/lib/screens/home/home_binding.dart @@ -0,0 +1,12 @@ +import 'package:get/get.dart'; +import 'package:rogapp/screens/home/home_controller.dart'; +import 'package:rogapp/screens/home/location_controller.dart'; + +class HomeBinding extends Bindings{ + @override + void dependencies() { + Get.put(HomeController()); + Get.put(LocationController()); + } + +} \ No newline at end of file diff --git a/lib/screens/home/home_controller.dart b/lib/screens/home/home_controller.dart index e69de29..bb16d45 100644 --- a/lib/screens/home/home_controller.dart +++ b/lib/screens/home/home_controller.dart @@ -0,0 +1,124 @@ +import 'dart:async'; + +import 'package:connectivity_plus/connectivity_plus.dart'; +import 'package:flutter_map/flutter_map.dart'; +import 'package:get/get.dart'; +import 'package:latlong2/latlong.dart'; +import 'package:rogapp/model/location_response.dart'; +import 'package:rogapp/screens/auth/controller/auth_controller.dart'; +import 'package:rogapp/screens/home/location_controller.dart'; +import 'package:rogapp/utils/const.dart'; +import 'package:http/http.dart' as http; +import 'dart:convert' as convert; + +import 'package:rogapp/utils/db_helper.dart'; + +class HomeController extends GetxController{ + var isLoading = false.obs; + List currentBound = [].obs; + List currentFeaturesforBound = [].obs; + List currentFeature = [].obs; + MapController mapController = MapController(); + + late StreamSubscription _connectivitySubscription; + ConnectivityResult connectionStatus = ConnectivityResult.none; + var connectionStatusName = "".obs; + final Connectivity _connectivity = Connectivity(); + + AuthController authController = Get.find(); + DatabaseHelper dbaseHelper = DatabaseHelper.instance; + + @override + void onInit() { + super.onInit(); + _connectivitySubscription = _connectivity.onConnectivityChanged.listen(_updateConnectionStatus); + dbaseHelper.deleteAll().then((value){ + fetchBoundForuser(authController.authList[0].token); + loadLocationsForBound().then((_){ + fetchLocalLocationForBound(mapController.bounds!); + }); + }); + } + + Future _updateConnectionStatus(ConnectivityResult result) async { + connectionStatus = result; + connectionStatusName.value = result.name; + } + + void fetchLocalLocationForBound(LatLngBounds bound) async { + final locations = await dbaseHelper.getFeaturesWithinBounds(bound); + currentFeaturesforBound.assignAll(locations); + print("loading locations ${currentFeaturesforBound.length} ------"); + } + + Future loadLocationsForBound() async { + LatLngBounds bounds = mapController.bounds!; + String serverUrl = ConstValues.currentServer(); + try{ + isLoading(true); + if(bounds.southWest != null && bounds.northEast != null){ + bool _rog = authController.authList[0].user.isRogaining; + String r = _rog == true ? 'True': 'False'; + var grp = authController.authList[0].user.eventCode; + final url = '$serverUrl/api/inbound?rog=${r}&grp=$grp&ln1=${bounds.southWest!.longitude}&la1=${bounds.southWest!.latitude}&ln2=${bounds.northWest.longitude}&la2=${bounds.northWest.latitude}&ln3=${bounds.northEast!.longitude}&la3=${bounds.northEast!.latitude}&ln4=${bounds.southEast.longitude}&la4=${bounds.southEast.latitude}'; + final response = await http.get(Uri.parse(url), + headers: { + 'Content-Type': 'application/json; charset=UTF-8', + }, + ); + if (response.statusCode == 200) { + // Parse JSON response + LocationResponse locationResponse = LocationResponse.fromMap(convert.jsonDecode(convert.utf8.decode(response.body.codeUnits))); + + // For each feature in the location response + for (var feature in locationResponse.features!) { + await dbaseHelper.insertFeature(feature.toMap()); + } + } + else{ + throw("Unable to load locations, please try again ..."); + } + } + } + catch(e, st){ + Get.snackbar("Error", e.toString(), snackPosition: SnackPosition.BOTTOM); + } + finally{ + isLoading(false); + } + } + + void fetchBoundForuser(String usertoken) async { + try{ + isLoading(true); + String serverUrl = ConstValues.currentServer(); + String url = '$serverUrl/api/locsext/'; + final http.Response response = await http.post( + Uri.parse(url), + headers: { + 'Content-Type': 'application/json; charset=UTF-8', + 'Authorization': 'Token $usertoken' + }, + body: convert.jsonEncode({ + 'token': usertoken, + }), + ); + if (response.statusCode == 200) { + final ext = convert.json.decode(convert.utf8.decode(response.body.codeUnits)); + LatLngBounds bnds = LatLngBounds(LatLng(ext[1], ext[0]), LatLng(ext[3], ext[2])); + currentBound.assign(bnds); + mapController.fitBounds(bnds); + } + else{ + throw("Unable to query current bound, please try again ..."); + } + } + catch(e){ + Get.snackbar("Error", e.toString(), snackPosition: SnackPosition.BOTTOM); + } + finally{ + isLoading(false); + } + } + +} diff --git a/lib/screens/home/home_screen.dart b/lib/screens/home/home_screen.dart index f118f9f..1403902 100644 --- a/lib/screens/home/home_screen.dart +++ b/lib/screens/home/home_screen.dart @@ -1,10 +1,183 @@ +import 'dart:async'; + 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:get/get.dart'; +import 'package:latlong2/latlong.dart'; +import 'package:rogapp/common/ui/widgets/uis.dart'; +import 'package:rogapp/model/location_response.dart'; +import 'package:rogapp/screens/home/home_controller.dart'; +import 'package:rogapp/screens/home/location_controller.dart'; +import 'package:rogapp/theme/theme.dart'; +import 'package:rogapp/utils/db_helper.dart'; +import 'package:rogapp/utils/text_util.dart'; +import 'package:rogapp/widgets/base_layer_widget.dart'; +import 'package:rogapp/widgets/bottom_sheet_new.dart'; +import 'package:sqflite/sqflite.dart'; class HomeScreen extends StatelessWidget { - const HomeScreen({super.key}); + HomeScreen({super.key}); + StreamSubscription? subscription; + final HomeController homeController = Get.find(); + final LocationController locationController = Get.find(); + + final double zoomThreshold = 0.08; + final double boundsThreshold = 0.0005; + + LatLngBounds? lastBounds; + double? lastZoom; + + + Widget getMarkerShape(Feature i, BuildContext context){ + + //print("lat is ${p.geoSerie!.geoPoints[0].latitude} and lon is ${p.geoSerie!.geoPoints[0].longitude}"); + RegExp regex = RegExp(r'([.]*0)(?!.*\d)'); + return Row( + mainAxisAlignment: MainAxisAlignment.start, + children: [ + InkWell( + onTap: () { + homeController.currentFeature.assign(i); + if(homeController.currentFeature != null) { + showModalBottomSheet( + context: context, + isScrollControlled: true, + isDismissible: true, + builder:((context) => BottomSheetNew()) + //builder:((context) => BottomSheetWidget()) + ).whenComplete((){ + locationController.skip_gps = false; + }); + } + + + + + }, + child: Container( + height: 32, + width: 32, + decoration: BoxDecoration( + shape: BoxShape.circle, + color: Colors.transparent, + border: Border.all( + color: i.properties!.buy_point! > 0 ? Colors.blue : Colors.red, + width: 3, + style: BorderStyle.solid + ) + ), + child: Stack( + alignment: Alignment.center, + children: [ + Icon(Icons.circle,size: 6.0,), + i.properties!.cp == -1 ? + Transform.rotate( + alignment: Alignment.centerLeft, + origin: Offset.fromDirection(1, 26), + angle: 270 * pi / 180, + child: Icon(Icons.play_arrow_outlined, color: Colors.red, size: 70,)): + Container(color: Colors.transparent,), + ], + ) + ), + ), + Container(color: Colors.white, child: Text(TextUtils.getDisplayTextForFeature(i), style: TextStyle(fontSize: 16, fontWeight: FontWeight.bold, color:Colors.red,))), + ], + ); + } + @override Widget build(BuildContext context) { - return Placeholder(); + return Scaffold( + appBar: AppBar( + actions: [ + TextButton(onPressed: () async { + DatabaseHelper dbaseHelper = DatabaseHelper.instance; + final res = await dbaseHelper.getFeatureByLatLon(35.807369, 137.240684); + print(res[0].toString()); + }, + child: const Text("Click", style: TextStyle(color: Colors.white),)) + ], + ), + body: Obx(() => + FlutterMap( + mapController: homeController.mapController, + options: MapOptions( + onMapReady: (){ + homeController.mapController!.mapEventStream.listen((MapEvent mapEvent) { + if (mapEvent is MapEventMoveStart) { + } + if (mapEvent is MapEventMoveEnd) { + LatLngBounds bounds = homeController.mapController!.bounds!; + homeController.currentBound.assign(bounds); + final _cz = homeController.mapController.zoom; + } + }); + } , + onPositionChanged: (position, hasGesture){ + if (hasGesture) { + LatLngBounds currentBounds = position.bounds!; + + if (lastBounds != null && lastZoom != null) { + // Compute difference between last bounds and current bounds + double boundsDifference = lastBounds!.north - currentBounds.north + + lastBounds!.south - currentBounds.south + + lastBounds!.east - currentBounds.east + + lastBounds!.west - currentBounds.west; + + // Compute difference between last zoom and current zoom + double zoomDifference = lastZoom! - position.zoom!; + + if (boundsDifference.abs() > boundsThreshold || zoomDifference.abs() > zoomThreshold) { + LatLngBounds bounds = homeController.mapController!.bounds!; + homeController.currentBound.assign(bounds); + print('----threshold reached ---'); + homeController.fetchLocalLocationForBound(bounds); + //loadData(position.bounds); // Load new data when either threshold is exceeded + } + } else { + LatLngBounds bounds = homeController.mapController!.bounds!; + homeController.currentBound.assign(bounds); + homeController.fetchLocalLocationForBound(bounds); + //loadData(position.bounds); // Load new data if this is the first time + } + + lastBounds = currentBounds; // Update the last bounds + lastZoom = position.zoom; // Update the last zoom + + } + }, + bounds: homeController.currentBound.isNotEmpty ? homeController.currentBound[0]: LatLngBounds.fromPoints([LatLng(35.03999881162295, 136.40587119778962), LatLng(36.642756778706904, 137.95226720406063)]), + zoom: 14, + maxZoom:18.4, + interactiveFlags: InteractiveFlag.pinchZoom | InteractiveFlag.drag, + ), + children: [ + const BaseLayer(), + CurrentLocationLayer(), + homeController.currentFeaturesforBound.isNotEmpty ? + MarkerLayer( + markers:homeController.currentFeaturesforBound.map((i) { + RegExp regex = RegExp(r'([.]*0)(?!.*\d)'); + return Marker( + anchorPos: AnchorPos.exactly(Anchor(108.0, 18.0)), + height: 32.0, + width: 120.0, + point: LatLng(i.latitude!, i.longitude!), + builder: (ctx){ + return getMarkerShape(i, context); + }, + ); + }).toList(), + ) + : + Center(child: CircularProgressIndicator()), + ], + + ) + ), + ); } } \ No newline at end of file diff --git a/lib/screens/home/location_controller.dart b/lib/screens/home/location_controller.dart new file mode 100644 index 0000000..fb0b71a --- /dev/null +++ b/lib/screens/home/location_controller.dart @@ -0,0 +1,318 @@ +import 'dart:async'; +import 'dart:io'; + +import 'package:flutter/foundation.dart'; +import 'package:flutter/material.dart'; +import 'package:geolocator/geolocator.dart'; +import 'package:get/get.dart'; +import 'package:latlong2/latlong.dart'; +import 'package:modal_bottom_sheet/modal_bottom_sheet.dart'; +import 'package:rogapp/model/location_response.dart'; +import 'package:rogapp/pages/camera/camera_page.dart'; +import 'package:rogapp/screens/auth/controller/auth_controller.dart'; +import 'package:rogapp/screens/home/home_controller.dart'; +import 'package:rogapp/utils/checkin_db_helper.dart'; +import 'package:rogapp/widgets/bottom_sheet_new.dart'; + +class LocationController extends GetxController{ + + HomeController homeController = Get.find(); + AuthController authController = Get.find(); + CheckinDBHelper checkinDBHelper = CheckinDBHelper.instance; + + + late LocationSettings locationSettings; + List locationPermission = [" -- starting -- "].obs; + double current_lat = 0.0; + double current_lon = 0.0; + var is_gps_selected = true.obs; + var is_checkingIn = false.obs; + var moveMapwithGPS = false.obs; + bool skip_gps = false; + var is_photo_shoot = false.obs; + final photos = [].obs; + Timer? _timer; + int _start = 0; + int chekcs = 0; + var rogaining_counted = false.obs; + + var is_in_checkin = false.obs; + var is_in_rog = false.obs; + var is_at_start = false.obs; + var is_at_goal = false.obs; + DateTime last_goal_at = DateTime.now().subtract(Duration(days:1)); + bool skip_10s = false; + + bool checking_in = false; + BuildContext? context; + + @override + void onInit() { + initGPS(); + super.onInit(); + } + + 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(); + } + } + + + void initGPS(){ + checkPermission(); + + //print("------ in iniit"); + + if (defaultTargetPlatform == TargetPlatform.android) { + locationSettings = AndroidSettings( + accuracy: LocationAccuracy.bestForNavigation, + distanceFilter: 0, + forceLocationManager: true, + intervalDuration: const Duration(seconds: 1), + foregroundNotificationConfig: const ForegroundNotificationConfig( + notificationText: + "Thi app will continue to receive your location even when you aren't using it", + notificationTitle: "Running in Background", + enableWakeLock: true, + ) + ); + } else if (defaultTargetPlatform == TargetPlatform.iOS || defaultTargetPlatform == TargetPlatform.macOS) { + locationSettings = AppleSettings( + accuracy: LocationAccuracy.bestForNavigation, + activityType: ActivityType.fitness, + distanceFilter: 0, + pauseLocationUpdatesAutomatically: false, + // Only set to true if our app will be started up in the background. + showBackgroundLocationIndicator: true + ); + } else { + locationSettings = const LocationSettings( + accuracy: LocationAccuracy.high, + distanceFilter: 0, + ); + } + + try { + + StreamSubscription positionStream = Geolocator.getPositionStream(locationSettings: locationSettings).listen( + + (Position? position) { + current_lat = position != null ? position.latitude : 0; + current_lon = position != null ? position.longitude : 0; + + print('current GPS point is - $current_lat, $current_lon'); + + if(is_gps_selected.value){ + double czoom = homeController.mapController.zoom; + if(moveMapwithGPS.value){ + homeController.mapController.move(LatLng(position!.latitude, position!.longitude), czoom); + } + + + //gps.clear(); + //gps.add("-- lat : ${position.latitude}, lon : ${position.longitude} --"); + if(is_checkingIn.value ==false || skip_gps == false){ + print("--- calling checkFoCheckin ---"); + checkFoCheckin(); + } + //checkForCheckin(position!.latitude, position.longitude); + + } + //print(position == null ? 'Unknown' : 'current position is ${position.latitude.toString()}, ${position.longitude.toString()}'); + }); + } catch (err){ + locationPermission.clear(); + locationPermission.add(err.toString()); + } + + //ever(indexController.connectionStatusName, connectionChanged); + } + + void checkFoCheckin(){ + + for(final f in homeController.currentFeaturesforBound){ + + if(skip_gps) return; + + var distance = Distance(); + var dist = distance.as(LengthUnit.Meter, LatLng(f.latitude!, f.longitude!), LatLng(current_lat, current_lon)); + + if(dist <= 250 && is_checkingIn.value == false){ + startTimer(f, dist); + } + + } + } + + void startTimer(Feature d, double distance) async { + skip_gps = true; + print("---- in startTimer ----"); + double checkin_radious = d.properties!.checkin_radius ?? double.infinity; + bool auto_checkin = d.properties!.auto_checkin == 0 ? false : true; + bool location_already_checked_in = await checkinDBHelper.exists(d.location_id!); + bool isUser_logged_in = authController.authList.length > 0 ? true : false; + //make current destination + print("---- locationid : ${d.location_id} checkin radius ---- ${checkin_radious} --- distance : ${distance} ----"); + print("---- distance ${distance} ----"); + if(checkin_radious >= distance){ + //currentSelectedDestinations.add(d); + homeController.currentFeature.assign(d); + } + else { + skip_gps = false; + return; + } + + if(is_photo_shoot.value == true){ + photos.clear(); + showModalBottomSheet(context: Get.context!, isScrollControlled: true, + builder:((context) => CameraPage()) + ).whenComplete((){ + skip_gps = false; + chekcs = 0; + is_in_checkin.value = false; + }); + return; + } + + List ds = homeController.currentFeature; + if(ds.isNotEmpty){ + if(d.properties!.cp == -1 && DateTime.now().difference(last_goal_at).inHours >= 24){ + chekcs = 1; + //start + print("---- in start -----"); + chekcs = 1; + is_in_checkin.value = true; + is_at_start.value = true; + showModalBottomSheet(context: Get.context!, isScrollControlled: true, + builder:((context) => BottomSheetNew()) + ).whenComplete((){ + skip_gps = false; + chekcs = 0; + is_at_start.value = false; + is_in_checkin.value = false; + }); + } + else if(is_in_rog.value == true) + { + print("----- in location popup checkin cp - ${d.properties!.cp}----"); + chekcs = 2; + is_in_checkin.value = true; + showModalBottomSheet(context: Get.context!, isScrollControlled: true, + builder:((context) => BottomSheetNew()) + ).whenComplete((){ + skip_gps = false; + chekcs =0; + is_in_checkin.value = false; + }); + } + } + + print("---- location checkin radious ${d.properties!.checkin_radius} ----"); + print("---- already checked in ${location_already_checked_in} ----"); + if(checkin_radious >= distance && location_already_checked_in == false){ + if(auto_checkin){ + if(!checking_in){ + makeCheckin(d, true,""); + if(d.properties!.cp != -1){ + rogaining_counted.value =true; + } + skip_gps = false; + } + } + else{ + print("--- hidden loc ${d.properties!.hidden_location} ----"); + // ask for checkin + if(d.properties!.hidden_location != null && d.properties!.hidden_location == 0 && d.properties!.cp != -1){ + chekcs = 3; + is_in_checkin.value = true; + photos.clear(); + showModalBottomSheet(context: Get.context!, isScrollControlled: true, + builder:((context) => CameraPage(destination: d,)) + ).whenComplete((){ + skip_gps = false; + rogaining_counted.value =true; + chekcs = 0; + is_in_checkin.value = false; + }); + } + else if(is_in_rog.value == true && d.properties!.cp != -1){ + chekcs = 4; + is_in_checkin.value = true; + showMaterialModalBottomSheet( + expand: true, + context: Get.context!, + backgroundColor: Colors.transparent, + builder: (context) => BottomSheetNew() + ).whenComplete(() { + skip_gps = false; + chekcs = 0; + is_in_checkin.value = false; + }); + // showModalBottomSheet(context: Get.context!, isScrollControlled: true, + // builder:((context) => BottomSheetNew()) + // ).whenComplete((){ + // skip_gps = false; + // chekcs = 0; + // is_in_checkin.value = false; + // }); + } + + } + } + if(isUser_logged_in && d.properties!.cp == -1 && location_already_checked_in && skip_10s == false){ + //check for rogaining + if(is_at_goal.value == false && rogaining_counted.value){ + //goal + print("---- in goal -----"); + chekcs = 5; + is_at_goal.value = true; + photos.clear(); + showModalBottomSheet(context: Get.context!, isScrollControlled: true, + builder:((context) => CameraPage(destination: d,)) + ).whenComplete((){ + skip_gps = false; + chekcs = 0; + is_at_goal.value = false; + }); + } + else if(is_in_rog.value == false && DateTime.now().difference(last_goal_at).inHours >= 24){ + //start + print("---- in start -----"); + chekcs = 6; + is_at_start.value = true; + showModalBottomSheet(context: Get.context!, isScrollControlled: true, + builder:((context) => BottomSheetNew()) + ).whenComplete((){ + print("----- finished start -------"); + skip_gps = false; + chekcs = 0; + is_at_start.value = false; + }); + } + } + print("==== _chekcs ${chekcs} ===="); + if(chekcs == 0){ + skip_gps = false; + } + } + + void makeCheckin(Feature destination, bool action, String imageurl) async { + + } + + void addToRogaining(double lat, double lon, int destination_id) async { + + } + + void destinationMatrixFromCurrentPoint(List ls){ + + } + + +} \ No newline at end of file diff --git a/lib/services/external_service.dart b/lib/services/external_service.dart index 3c87132..43bbe34 100644 --- a/lib/services/external_service.dart +++ b/lib/services/external_service.dart @@ -6,6 +6,8 @@ import 'package:rogapp/model/destination.dart'; import 'package:rogapp/model/rog.dart'; import 'package:rogapp/pages/destination/destination_controller.dart'; import 'package:rogapp/pages/index/index_controller.dart'; +import 'package:rogapp/screens/auth/controller/auth_controller.dart'; +import 'package:rogapp/screens/home/home_controller.dart'; import 'package:rogapp/utils/database_helper.dart'; import 'package:sqflite/sqlite_api.dart'; import 'dart:convert'; @@ -31,17 +33,19 @@ class ExternalService { Future> StartRogaining() async { - final IndexController indexController = Get.find(); + //final IndexController indexController = Get.find(); + final homeController = Get.find(); + final authController = Get.find(); Map _res = {}; - int user_id = indexController.currentUser[0]["user"]["id"]; + int user_id = authController.authList[0].user.id; //print("--- Pressed -----"); - String _team = indexController.currentUser[0]["user"]['team_name']; + String _team = authController.authList[0].user.teamName; //print("--- _team : ${_team}-----"); - String _event_code = indexController.currentUser[0]["user"]["event_code"]; + String _event_code = authController.authList[0].user.eventCode; - if(indexController.connectionStatusName != "wifi" && indexController.connectionStatusName != "mobile"){ + if(homeController.connectionStatusName != "wifi" && homeController.connectionStatusName != "mobile"){ DatabaseHelper db = DatabaseHelper.instance; Rog _rog = Rog( id:1, diff --git a/lib/utils/checkin_db_helper.dart b/lib/utils/checkin_db_helper.dart new file mode 100644 index 0000000..375536b --- /dev/null +++ b/lib/utils/checkin_db_helper.dart @@ -0,0 +1,82 @@ +import 'package:sqflite/sqflite.dart'; +import 'package:path/path.dart'; + +class CheckinDBHelper { + static final _databaseName = "EventDatabase.db"; + static final _databaseVersion = 1; + + static final table = 'event_table'; + + static final columnLocationId = 'location_id'; + static final columnOrderId = 'order_id'; + static final columnCheckinTime = 'checkin_time'; + static final columnEventName = 'event_name'; + + // make this a singleton class + CheckinDBHelper._privateConstructor(); + static final CheckinDBHelper instance = CheckinDBHelper._privateConstructor(); + + // only have a single app-wide reference to the database + static Database? _database; + Future get database async { + if (_database != null) return _database!; + _database = await _initDatabase(); + return _database!; + } + + // this opens the database (and creates it if it doesn't exist) + _initDatabase() async { + String path = join(await getDatabasesPath(), _databaseName); + return await openDatabase(path, + version: _databaseVersion, + onCreate: _onCreate); + } + + // SQL code to create the database table + Future _onCreate(Database db, int version) async { + await db.execute(''' + CREATE TABLE $table ( + $columnLocationId INTEGER PRIMARY KEY, + $columnOrderId INTEGER NOT NULL, + $columnCheckinTime TEXT NOT NULL, + $columnEventName TEXT NOT NULL + ) + '''); + } + + // Helper methods + + Future insert(Map row) async { + Database db = await instance.database; + return await db.insert(table, row); + } + + Future exists(int locationId) async { + Database db = await instance.database; + List> rows = await db.query( + table, + where: '$columnLocationId = ?', + whereArgs: [locationId], + ); + return rows.isNotEmpty; + } + + Future>> queryAllRows() async { + Database db = await instance.database; + return await db.query(table); + } + + Future>> queryRowsByLocation(int locationId) async { + Database db = await instance.database; + return await db.query(table, + where: '$columnLocationId = ?', + whereArgs: [locationId], + ); + } + + Future update(Map row) async { + Database db = await instance.database; + int id = row[columnLocationId]; + return await db.update(table, row, where: '$columnLocationId = ?', whereArgs: [id]); + } +} diff --git a/lib/utils/db_helper.dart b/lib/utils/db_helper.dart new file mode 100644 index 0000000..54b8538 --- /dev/null +++ b/lib/utils/db_helper.dart @@ -0,0 +1,170 @@ +import 'package:flutter_map/flutter_map.dart'; +import 'package:rogapp/model/location_response.dart'; +import 'package:sqflite/sqflite.dart'; +import 'package:path/path.dart'; +import 'package:path_provider/path_provider.dart'; +import 'dart:io'; +import 'dart:convert'; // for jsonEncode + +class DatabaseHelper { + static const _databaseName = "FeatureDatabase.db"; + static const _databaseVersion = 1; + + // Singleton class + DatabaseHelper._(); + static final DatabaseHelper instance = DatabaseHelper._(); + + Database? _database; + Future get database async { + if (_database != null) return _database!; + _database = await _initDatabase(); + return _database!; + } + + Future _initDatabase() async { + Directory documentsDirectory = await getApplicationDocumentsDirectory(); + String path = join(documentsDirectory.path, _databaseName); + return await openDatabase( + path, + version: _databaseVersion, + onCreate: _onCreate, + ); + } + + Future _onCreate(Database db, int version) async { + await db.execute(''' + CREATE TABLE features ( + id INTEGER PRIMARY KEY, + geometry TEXT NOT NULL, + properties TEXT NOT NULL, + type TEXT NOT NULL, + location_id, + latitude REAL NOT NULL, + longitude REAL NOT NULL + ) + '''); + } + + // Database insert operation + Future insertFeature(Map feature) async { + // Get a reference to the database. + final db = await database; + + // Insert the feature into the correct table. + await db.insert( + 'features', + feature, + conflictAlgorithm: ConflictAlgorithm.replace, + ); + } + + // Database get operation + Future> getFeatures() async { + Database db = await database; + final List> maps = await db.query('features'); + + return List.generate(maps.length, (i) { + return Feature( + id: maps[i]['id'], + geometry: Geometry.fromMap(jsonDecode(maps[i]['geometry'])), + properties: Properties.fromMap(jsonDecode(maps[i]['properties'])), + type: maps[i]['type'], + location_id: Properties.fromMap(jsonDecode(maps[i]['properties'])).location_id, + latitude: Geometry.fromMap(jsonDecode(maps[i]['geometry'])).coordinates![0][1], + longitude: Geometry.fromMap(jsonDecode(maps[i]['geometry'])).coordinates![0][0] + ); + }); + } + + // Database delete operation + Future deleteFeature(int id) async { + Database db = await database; + await db.delete( + 'features', + where: "id = ?", + whereArgs: [id], + ); + } + + Future deleteAll() async { + // Get a reference to the database. + final db = await database; + + // Delete all rows. + await db.rawDelete('DELETE FROM features'); + } + + // Database search by location_id + Future> getFeatureByLocationId(int locationId) async { + Database db = await database; + final List> maps = await db.query( + 'features', + where: "location_id = ?", + whereArgs: [locationId], + ); + + return List.generate(maps.length, (i) { + return Feature( + id: maps[i]['id'], + geometry: Geometry.fromMap(jsonDecode(maps[i]['geometry'])), + properties: Properties.fromMap(jsonDecode(maps[i]['properties'])), + type: maps[i]['type'], + location_id: Properties.fromMap(jsonDecode(maps[i]['properties'])).location_id, + latitude: Geometry.fromMap(jsonDecode(maps[i]['geometry'])).coordinates![0][1], + longitude: Geometry.fromMap(jsonDecode(maps[i]['geometry'])).coordinates![0][0] + ); + }); + } + + // Database search by latitude and longitude + Future> getFeatureByLatLon(double latitude, double longitude) async { + Database db = await database; + final List> maps = await db.query( + 'features', + where: "latitude = ? AND longitude = ?", + whereArgs: [latitude, longitude], + ); + + return List.generate(maps.length, (i) { + return Feature( + id: maps[i]['id'], + geometry: Geometry.fromMap(jsonDecode(maps[i]['geometry'])), + properties: Properties.fromMap(jsonDecode(maps[i]['properties'])), + type: maps[i]['type'], + location_id: Properties.fromMap(jsonDecode(maps[i]['properties'])).location_id, + latitude: Geometry.fromMap(jsonDecode(maps[i]['geometry'])).coordinates![0][1], + longitude: Geometry.fromMap(jsonDecode(maps[i]['geometry'])).coordinates![0][0] + ); + }); + } + + Future> getFeaturesWithinBounds(LatLngBounds bounds) async { + final db = await database; + + final List> maps = await db.query( + 'features', + where: 'latitude BETWEEN ? AND ? AND longitude BETWEEN ? AND ?', + whereArgs: [ + bounds.southWest!.latitude, + bounds.northEast!.latitude, + bounds.southWest!.longitude, + bounds.northEast!.longitude, + ], + ); + + return List.generate(maps.length, (i) { + return Feature( + id: maps[i]['id'], + geometry: Geometry.fromMap(jsonDecode(maps[i]['geometry'])), + properties: Properties.fromMap(jsonDecode(maps[i]['properties'])), + type: maps[i]['type'], + location_id: Properties.fromMap(jsonDecode(maps[i]['properties'])).location_id, + latitude: Geometry.fromMap(jsonDecode(maps[i]['geometry'])).coordinates![0][1], + longitude: Geometry.fromMap(jsonDecode(maps[i]['geometry'])).coordinates![0][0] + ); + }); + } + + + +} diff --git a/lib/utils/text_util.dart b/lib/utils/text_util.dart index 725ec4e..14d534f 100644 --- a/lib/utils/text_util.dart +++ b/lib/utils/text_util.dart @@ -1,6 +1,7 @@ import 'package:geojson/geojson.dart'; import 'package:rogapp/model/destination.dart'; +import 'package:rogapp/model/location_response.dart'; class TextUtils{ @@ -18,22 +19,25 @@ class TextUtils{ } - static String getDisplayText(Destination dp){ + static String getDisplayText(Feature dp){ RegExp regex = RegExp(r'([.]*0)(?!.*\d)'); String txt = ""; - if(dp.cp! > 0){ - txt = "${dp.cp.toString().replaceAll(regex, '')}"; - if(dp.checkin_point != null && dp.checkin_point! > 0){ - txt = txt + "{${dp.checkin_point.toString().replaceAll(regex, '')}}"; + if(dp.properties!.cp! > 0){ + txt = "${dp.properties!.cp.toString().replaceAll(regex, '')}"; + if(dp.properties!.checkin_point != null && dp.properties!.checkin_point! > 0){ + txt = txt + "{${dp.properties!.checkin_point.toString().replaceAll(regex, '')}}"; } - if(dp.buy_point != null && dp.buy_point! > 0){ - print("^^^^^^^^^ ${dp.sub_loc_id}^^^^^^^^^^"); - txt = "#${dp.cp.toString().replaceAll(regex, '')}(${dp.checkin_point.toString().replaceAll(regex, '')}+${dp.buy_point.toString().replaceAll(regex, '')})"; + if(dp.properties!.buy_point != null && dp.properties!.buy_point! > 0){ + txt = "#${dp.properties!.cp.toString().replaceAll(regex, '')}(${dp.properties!.checkin_point.toString().replaceAll(regex, '')}+${dp.properties!.buy_point.toString().replaceAll(regex, '')})"; } } return txt; } + static String getDisplayTextForFeature(Feature f){ + return "${f.properties!.sub_loc_id}"; + } + // static String getDisplayText(String num){ // RegExp regex = RegExp(r'([.]*0)(?!.*\d)'); // return "${num.replaceAll(regex, '')}"; diff --git a/lib/widgets/bottom_sheet_new.dart b/lib/widgets/bottom_sheet_new.dart index 10cdebf..d1cd5cb 100644 --- a/lib/widgets/bottom_sheet_new.dart +++ b/lib/widgets/bottom_sheet_new.dart @@ -1,6 +1,4 @@ import 'package:flutter/material.dart'; -import 'package:flutter/services.dart'; -import 'package:flutter_map/plugin_api.dart'; import 'package:geojson/geojson.dart'; import 'package:geolocator/geolocator.dart'; import 'package:get/get.dart'; @@ -9,11 +7,13 @@ import 'package:image_picker/image_picker.dart'; import 'package:latlong2/latlong.dart'; import 'package:modal_bottom_sheet/modal_bottom_sheet.dart'; import 'package:rogapp/model/destination.dart'; -import 'package:rogapp/pages/camera/camera_page.dart'; -import 'package:rogapp/pages/destination/destination_controller.dart'; -import 'package:rogapp/pages/index/index_controller.dart'; +import 'package:rogapp/model/location_response.dart'; import 'package:rogapp/routes/app_pages.dart'; +import 'package:rogapp/screens/auth/controller/auth_controller.dart'; +import 'package:rogapp/screens/home/home_controller.dart'; +import 'package:rogapp/screens/home/location_controller.dart'; import 'package:rogapp/services/external_service.dart'; +import 'package:rogapp/utils/checkin_db_helper.dart'; import 'package:rogapp/utils/const.dart'; import 'package:rogapp/utils/database_helper.dart'; import 'package:rogapp/utils/text_util.dart'; @@ -23,23 +23,26 @@ import 'package:url_launcher/url_launcher.dart'; class BottomSheetNew extends GetView { BottomSheetNew({ Key? key }) : super(key: key); - final IndexController indexController = Get.find(); - final DestinationController destinationController = Get.find(); + //final IndexController indexController = Get.find(); + //final DestinationController destinationController = Get.find(); + HomeController homeController = Get.find(); + LocationController locationController = Get.find(); + AuthController authController = Get.find(); + CheckinDBHelper checkinDBHelper = CheckinDBHelper.instance; Image getImage(){ String server_url = ConstValues.currentServer(); - if(indexController.rog_mode == 1){ //print("----- rogaining mode 1"); - if(indexController.currentDestinationFeature.length <= 0 || indexController.currentDestinationFeature[0].photos! == ""){ + if(homeController.currentFeature.isEmpty || homeController.currentFeature[0].properties!.photos == ""){ return Image(image: AssetImage('assets/images/empty_image.png')); } else{ //print("@@@@@@@@@@@@@ rog mode -------------------- ${indexController.currentDestinationFeature[0].photos} @@@@@@@@@@@"); - String _photo = indexController.currentDestinationFeature[0].photos!; + String _photo = homeController.currentFeature[0].properties!.photos!; if(_photo.contains('http')){ return Image(image: NetworkImage( - indexController.currentDestinationFeature[0].photos!, + homeController.currentFeature[0].properties!.photos!, ), errorBuilder: (BuildContext context, Object exception, StackTrace? stackTrace) { return Image.asset("assets/images/empty_image.png"); @@ -48,7 +51,7 @@ class BottomSheetNew extends GetView { } else { return Image(image: NetworkImage( - '${server_url}/media/compressed/' + indexController.currentDestinationFeature[0].photos!, + '${server_url}/media/compressed/' + homeController.currentFeature[0].properties!.photos!, ), errorBuilder: (BuildContext context, Object exception, StackTrace? stackTrace) { return Image.asset("assets/images/empty_image.png"); @@ -56,64 +59,31 @@ class BottomSheetNew extends GetView { ); } } - } - else{ - GeoJsonFeature gf = indexController.currentFeature[0]; - if(gf!.properties!["photos"] == null || gf.properties!["photos"] == ""){ - return Image(image: AssetImage('assets/images/empty_image.png')); - } - else{ - String _photo = gf!.properties!["photos"]; - if(_photo.contains('http')){ - return Image(image: NetworkImage( - gf.properties!["photos"], - ), - errorBuilder: (BuildContext context, Object exception, StackTrace? stackTrace) { - return Image.asset("assets/images/empty_image.png"); - }, - ); - } - else { - return Image(image: NetworkImage( - '${server_url}/media/compressed/' + gf.properties!["photos"], - ), - errorBuilder: (BuildContext context, Object exception, StackTrace? stackTrace) { - return Image.asset("assets/images/empty_image.png"); - }, - ); - } - } - } - - } void _launchURL(url) async { if (!await launch(url)) throw 'Could not launch $url'; } - bool isInDestination(String locationid){ - int lid = int.parse(locationid); - if(destinationController.destinations.where((element) => element.location_id == lid).length > 0){ - return true; - } - else{ - return false; - } - } - + // bool isInDestination(String locationid){ + // int lid = int.parse(locationid); + // if(destinationController.destinations.where((element) => element.location_id == lid).length > 0){ + // return true; + // } + // else{ + // return false; + // } + // } @override Widget build(BuildContext context) { - destinationController.skip_gps = true; - print('---- rog_mode ----- ${indexController.rog_mode} -----'); - return indexController.rog_mode == 0 ? detailsSheet(context) : destinationSheet(context); + locationController.skip_gps = true; + return destinationSheet(context); } // Show destination detais SingleChildScrollView destinationSheet(BuildContext context) { - print('---- currentDestinationFeature ----- ${indexController.currentDestinationFeature[0].name} -----'); return SingleChildScrollView( child: Column( @@ -141,14 +111,14 @@ class BottomSheetNew extends GetView { child: Container( alignment: Alignment.center, child: Obx(() => - indexController.currentUser.length > 0 ? - Text("${TextUtils.getDisplayText(indexController.currentDestinationFeature[0])} : ${TextUtils.getDisplayText(indexController.currentDestinationFeature[0])} : ${indexController.currentDestinationFeature[0].name!}", style: TextStyle( + authController.authList.isNotEmpty ? + Text("${TextUtils.getDisplayText(homeController.currentFeature[0])} : ${TextUtils.getDisplayText(homeController.currentFeature[0])} : ${homeController.currentFeature[0].properties!.location_name}", style: TextStyle( fontSize: 15.0, fontWeight: FontWeight.bold, ), ) : - Text("${indexController.currentDestinationFeature[0].name!}", style: TextStyle( + Text("${homeController.currentFeature[0].properties!.location_name}", style: TextStyle( fontSize: 15.0, fontWeight: FontWeight.bold, ), @@ -174,38 +144,48 @@ class BottomSheetNew extends GetView { mainAxisAlignment: MainAxisAlignment.spaceAround, children: [ Obx(() => - indexController.currentDestinationFeature.isNotEmpty && destinationController.is_in_checkin.value == true && destinationController.is_at_start.value == false ? + homeController.currentBound.isNotEmpty && locationController.is_in_checkin.value == true && locationController.is_at_start.value == false ? Row( children: [ ElevatedButton( - onPressed: (){ - if(indexController.currentDestinationFeature[0].checkedin == null || indexController.currentDestinationFeature[0].checkedin == false){ - if(indexController.currentDestinationFeature[0].hidden_location == 0){ - destinationController.skip_gps = false; - destinationController.is_photo_shoot.value = true; + onPressed: () async { + final _locId = homeController.currentFeature[0].location_id; + final _exist = await checkinDBHelper.exists(_locId!); + if(_exist){ + if(homeController.currentFeature[0].properties!.hidden_location == 0){ + locationController.skip_gps = false; + locationController.is_photo_shoot.value = true; Get.back(); } else{ - destinationController.makeCheckin(indexController.currentDestinationFeature[0], true, ""); - if(indexController.currentDestinationFeature[0].cp != -1){ - destinationController.rogaining_counted.value =true; + locationController.makeCheckin(homeController.currentFeature[0], true, ""); + if(homeController.currentFeature[0].properties!.cp != -1){ + locationController.rogaining_counted.value =true; } } } else{ - destinationController.makeCheckin(indexController.currentDestinationFeature[0], false, ""); + locationController.makeCheckin(homeController.currentFeature[0], false, ""); } //Get.back(); }, - child: Text( - //Checkin - indexController.currentDestinationFeature[0].checkedin == null || indexController.currentDestinationFeature[0].checkedin == false ? - "チェックイン" - : - "チェックアウト" - ) + child: FutureBuilder( + future: checkinDBHelper.exists(homeController.currentFeature[0].location_id!), + builder: (BuildContext context, AsyncSnapshot snapshot){ + if (snapshot.connectionState == ConnectionState.waiting) { + return CircularProgressIndicator(); // return a circular progress indicator while waiting + } else { + if (snapshot.hasError) + return Text('Error: ${snapshot.error}'); // return error text if something went wrong + else + return snapshot.data! ? + const Text("チェックイン") : // Widget to show if locationId exists + const Text("チェックアウト"); + } + }, + ), ), ], ) @@ -213,19 +193,28 @@ class BottomSheetNew extends GetView { Container(), ), Obx(() => - destinationController.is_at_start.value == true ? + locationController.is_at_start.value == true ? ElevatedButton( onPressed: (){ - destinationController.is_in_rog.value = true; - destinationController.addToRogaining(destinationController.current_lat, destinationController.current_lon, indexController.currentDestinationFeature[0].location_id!); + locationController.is_in_rog.value = true; + locationController.addToRogaining(locationController.current_lat, locationController.current_lon, homeController.currentFeature[0].location_id!); ExternalService().StartRogaining().then((value) => Get.back()); }, - child: Text( - // start - indexController.currentDestinationFeature[0].checkedin != null || indexController.currentDestinationFeature[0].checkedin == true ? - "ロゲイニングを開始" - : - "間違った目的地..." + child: + FutureBuilder( + future: checkinDBHelper.exists(homeController.currentFeature[0].location_id!), + builder: (context, snapshot){ + if (snapshot.connectionState == ConnectionState.waiting) { + return CircularProgressIndicator(); // return a circular progress indicator while waiting + } else { + if (snapshot.hasError) + return Text('Error: ${snapshot.error}'); // return error text if something went wrong + else + return snapshot.data! ? + const Text("ロゲイニングを開始") : // Widget to show if locationId exists + const Text("間違った目的地..."); + } + }, ) ) : @@ -233,18 +222,27 @@ class BottomSheetNew extends GetView { ), Obx(() => - destinationController.is_at_goal.value == true && destinationController.rogaining_counted ==true ? + locationController.is_at_goal.value == true && locationController.rogaining_counted ==true ? ElevatedButton( onPressed: (){ Get.toNamed(AppPages.CAMERA_PAGE); Get.back(); }, - child: Text( - //goal - indexController.currentDestinationFeature[0].checkedin != null || indexController.currentDestinationFeature[0].checkedin == true ? - "ロゲイニングを終える" - : - "間違った目的地 ..." + child: + FutureBuilder( + future: checkinDBHelper.exists(homeController.currentFeature[0].location_id!), + builder: (context, snapshot){ + if (snapshot.connectionState == ConnectionState.waiting) { + return CircularProgressIndicator(); // return a circular progress indicator while waiting + } else { + if (snapshot.hasError) + return Text('Error: ${snapshot.error}'); // return error text if something went wrong + else + return snapshot.data! ? + const Text("ロゲイニングを終える") : // Widget to show if locationId exists + const Text("間違った目的地 ..."); + } + }, ) ) : @@ -254,32 +252,32 @@ class BottomSheetNew extends GetView { ], ), Obx(() => - indexController.currentDestinationFeature[0].address != null && indexController.currentDestinationFeature[0].address!.isNotEmpty ? - getDetails(context, "address".tr, indexController.currentDestinationFeature[0].address! ?? '') + homeController.currentFeature[0].properties!.address != null ? + getDetails(context, "address".tr, homeController.currentFeature[0].properties!.address! ?? '') : Container(width: 0.0, height: 0,), ), Obx(() => - indexController.currentDestinationFeature[0].phone != null && indexController.currentDestinationFeature[0].phone!.isNotEmpty ? - getDetails(context, "telephone".tr, indexController.currentDestinationFeature[0].phone! ?? '') + homeController.currentFeature[0].properties!.phone != null ? + getDetails(context, "telephone".tr, homeController.currentFeature[0].properties!.phone! ?? '') : Container(width: 0.0, height: 0,), ), Obx(() => - indexController.currentDestinationFeature[0].email != null && indexController.currentDestinationFeature[0].email!.isNotEmpty ? - getDetails(context, "email".tr, indexController.currentDestinationFeature[0].email! ?? '') + homeController.currentFeature[0].properties!.email != null ? + getDetails(context, "email".tr, homeController.currentFeature[0].properties!.email! ?? '') : Container(width: 0.0, height: 0,), ), Obx(() => - indexController.currentDestinationFeature[0].webcontents != null && indexController.currentDestinationFeature[0].webcontents!.isNotEmpty ? - getDetails(context, "web".tr, indexController.currentDestinationFeature[0].webcontents! ?? '', isurl: true) + homeController.currentFeature[0].properties!.webcontents != null ? + getDetails(context, "web".tr, homeController.currentFeature[0].properties!.webcontents! ?? '', isurl: true) : Container(width: 0.0, height: 0,), ), Obx(() => - indexController.currentDestinationFeature[0].videos != null && indexController.currentDestinationFeature[0].videos!.isNotEmpty ? - getDetails(context, "video".tr, indexController.currentDestinationFeature[0].videos! ?? '', isurl: true) + homeController.currentFeature[0].properties!.videos != null ? + getDetails(context, "video".tr, homeController.currentFeature[0].properties!.videos! ?? '', isurl: true) : Container(width: 0.0, height: 0,), ), @@ -333,7 +331,7 @@ class BottomSheetNew extends GetView { child: Container( alignment: Alignment.center, child: Obx(() => - Text(indexController.currentFeature[0].properties!["location_name"], style: TextStyle( + Text(homeController.currentFeature[0].properties!.location_name!, style: TextStyle( fontSize: 15.0, fontWeight: FontWeight.bold, ), @@ -364,38 +362,60 @@ class BottomSheetNew extends GetView { mainAxisAlignment: MainAxisAlignment.spaceAround, children: [ Obx(() => - indexController.currentDestinationFeature.isNotEmpty && indexController.currentDestinationFeature[0].cp == -1 && indexController.currentDestinationFeature[0].checkedin == false && destinationController.is_at_start.value == true ? - ElevatedButton( - onPressed: (){ - destinationController.is_in_rog.value = true; - destinationController.addToRogaining(destinationController.current_lat, destinationController.current_lon, indexController.currentDestinationFeature[0].location_id!); - ExternalService().StartRogaining().then((value) => Get.back()); - }, - child: Text( - // start - indexController.currentDestinationFeature[0].checkedin != null || indexController.currentDestinationFeature[0].checkedin == true ? - "ロゲイニングを開始" - : - "間違った目的地..." - ) - ) - : - Container(), - + FutureBuilder( + future: checkinDBHelper.exists(homeController.currentFeature[0].location_id!), + builder: (context, snapshot){ + if (snapshot.connectionState == ConnectionState.waiting) { + return CircularProgressIndicator(); // return a circular progress indicator while waiting + } else { + if (snapshot.hasError) + return Text('Error: ${snapshot.error}'); // return error text if something went wrong + else + if(homeController.currentFeature[0].properties!.cp == -1 && locationController.is_at_start.value ==true){ + return ElevatedButton( + onPressed: (){ + locationController.is_in_rog.value = true; + locationController.addToRogaining(locationController.current_lat, locationController.current_lon, homeController.currentFeature[0].location_id!); + ExternalService().StartRogaining().then((value) => Get.back()); + }, + child: Text( + // start + snapshot.data! == true ? + "ロゲイニングを開始" + : + "間違った目的地..." + ) + ); + } + else { + return Container(); + } + } + }, + ) ), Obx(() => - destinationController.is_at_goal.value == true && destinationController.rogaining_counted ==true ? + locationController.is_at_goal.value == true && locationController.rogaining_counted ==true ? ElevatedButton( onPressed: (){ Get.toNamed(AppPages.CAMERA_PAGE); Get.back(); }, - child: Text( - //goal - indexController.currentDestinationFeature[0].checkedin != null || indexController.currentDestinationFeature[0].checkedin == true ? - "ロゲイニングを終える" - : - "間違った目的地 ..." + child: + FutureBuilder( + future: checkinDBHelper.exists(homeController.currentFeature[0].location_id!), + builder: (context, snapshot){ + if (snapshot.connectionState == ConnectionState.waiting) { + return CircularProgressIndicator(); // return a circular progress indicator while waiting + } else { + if (snapshot.hasError) + return Text('Error: ${snapshot.error}'); // return error text if something went wrong + else + return snapshot.data! ? + const Text("ロゲイニングを終える") : // Widget to show if locationId exists + const Text("間違った目的地 ..."); + } + }, ) ) : @@ -409,41 +429,56 @@ class BottomSheetNew extends GetView { child: Row( mainAxisAlignment: MainAxisAlignment.start, children: [ - indexController.currentDestinationFeature.isNotEmpty && destinationController.is_in_checkin.value == true ? - Container() - : - FutureBuilder( - future: wantToGo(context), - builder: (context, snapshot) { - return Container( - child: snapshot.data, - ); - }, - ), - indexController.currentFeature[0].properties!["location_name"] != null && (indexController.currentFeature[0].properties!["location_name"] as String).isNotEmpty ? - Flexible(child: Text(indexController.currentFeature[0].properties!["location_name"])) - : - Container(width: 0.0, height: 0,), + FutureBuilder( + future: checkinDBHelper.exists(homeController.currentFeature[0].location_id!), + builder: (context, snapshot){ + if (snapshot.connectionState == ConnectionState.waiting) { + return CircularProgressIndicator(); // return a circular progress indicator while waiting + } else { + if (snapshot.hasError) + return Text('Error: ${snapshot.error}'); // return error text if something went wrong + else{ + if(snapshot.data == true){ + return Container(); + } + else{ + return FutureBuilder( + future: wantToGo(context), + builder: (context, snapshot) { + return Container( + child: snapshot.data, + ); + }, + ); + } + } + } + }, + ) + // indexController.currentFeature[0].properties!["location_name"] != null && (indexController.currentFeature[0].properties!["location_name"] as String).isNotEmpty ? + // Flexible(child: Text(indexController.currentFeature[0].properties!["location_name"])) + // : + // Container(width: 0.0, height: 0,), ], ), ), ElevatedButton( onPressed:() async { - GeoJsonFeature mp = indexController.currentFeature[0] as GeoJsonFeature; + Feature mp = homeController.currentFeature[0]; Position position = await Geolocator.getCurrentPosition(desiredAccuracy: LocationAccuracy.high); - Destination ds = Destination( - lat: position.latitude, - lon: position.longitude + Feature ds = Feature( + latitude: position.latitude, + longitude: position.longitude ); - Destination tp = Destination( - lat: mp.geometry!.geoSerie!.geoPoints[0].latitude, - lon: mp.geometry!.geoSerie!.geoPoints[0].longitude + Feature tp = Feature( + latitude: mp.latitude, + longitude: mp.longitude ); Get.back(); - destinationController.destinationMatrixFromCurrentPoint([ds, tp]); + locationController.destinationMatrixFromCurrentPoint([ds, tp]); }, child:Text("ここへ行く")), ], @@ -455,8 +490,8 @@ class BottomSheetNew extends GetView { children: [ Icon(Icons.roundabout_left), SizedBox(width: 8.0,), - indexController.currentFeature[0].properties!["address"] != null && (indexController.currentFeature[0].properties!["address"] as String).isNotEmpty ? - getDetails(context, "address".tr, indexController.currentFeature[0].properties!["address"] ?? '') + homeController.currentFeature[0].properties!.address != null && homeController.currentFeature[0].properties!.address!.isNotEmpty ? + getDetails(context, "address".tr, homeController.currentFeature[0].properties!.address ?? '') : Container(width: 0.0, height: 0,), ], @@ -468,8 +503,8 @@ class BottomSheetNew extends GetView { children: [ Icon(Icons.phone), SizedBox(width: 8.0,), - indexController.currentFeature[0].properties!["phone"] != null && (indexController.currentFeature[0].properties!["phone"] as String).isNotEmpty ? - getDetails(context, "telephone".tr, indexController.currentFeature[0].properties!["phone"] ?? '') + homeController.currentFeature[0].properties!.phone != null && homeController.currentFeature[0].properties!.phone!.isNotEmpty ? + getDetails(context, "telephone".tr, homeController.currentFeature[0].properties!.phone ?? '') : Container(width: 0.0, height: 0,), ], @@ -481,8 +516,8 @@ class BottomSheetNew extends GetView { children: [ Icon(Icons.email), SizedBox(width: 8.0,), - indexController.currentFeature[0].properties!["email"] != null && (indexController.currentFeature[0].properties!["email"] as String).isNotEmpty ? - getDetails(context, "email".tr, indexController.currentFeature[0].properties!["email"] ?? '') + homeController.currentFeature[0].properties!.email != null && homeController.currentFeature[0].properties!.email!.isNotEmpty ? + getDetails(context, "email".tr, homeController.currentFeature[0].properties!.email ?? '') : Container(width: 0.0, height: 0,), ], @@ -494,8 +529,8 @@ class BottomSheetNew extends GetView { children: [ Icon(Icons.language), SizedBox(width: 8.0,), - indexController.currentFeature[0].properties!["webcontents"] != null && (indexController.currentFeature[0].properties!["webcontents"] as String).isNotEmpty ? - getDetails(context, "web".tr, indexController.currentFeature[0].properties!["webcontents"] ?? '', isurl: true) + homeController.currentFeature[0].properties!.webcontents != null && homeController.currentFeature[0].properties!.webcontents!.isNotEmpty ? + getDetails(context, "web".tr, homeController.currentFeature[0].properties!.webcontents ?? '', isurl: true) : Container(width: 0.0, height: 0,), ], @@ -506,8 +541,8 @@ class BottomSheetNew extends GetView { child: Row( children: [ SizedBox(width: 8.0,), - indexController.currentFeature[0].properties!["remark"] != null && (indexController.currentFeature[0].properties!["remark"] as String).isNotEmpty ? - getDetails(context, "remarks".tr, indexController.currentFeature[0].properties!["remark"] ?? '', isurl: false) + homeController.currentFeature[0].properties!.remark != null && homeController.currentFeature[0].properties!.remark!.isNotEmpty ? + getDetails(context, "remarks".tr, homeController.currentFeature[0].properties!.remark ?? '', isurl: false) : Container(width: 0.0, height: 0,), ], @@ -528,16 +563,10 @@ class BottomSheetNew extends GetView { Future wantToGo(BuildContext context)async { + - bool _selected = false; - print('---target-- ${indexController.currentFeature[0].properties!["location_id"]}----'); - for(Destination d in destinationController.destinations){ - print('---- ${d.location_id.toString()} ----'); - if(d.location_id == indexController.currentFeature[0].properties!["location_id"]){ - _selected = true; - break; - } - } + bool _selected = await checkinDBHelper.exists(homeController.currentFeature[0].location_id!); + DatabaseHelper db = DatabaseHelper.instance; return @@ -547,196 +576,108 @@ class BottomSheetNew extends GetView { Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ - indexController.rog_mode == 0 ? - IconButton( - icon: Icon(Icons.pin_drop_sharp, size: 32, color: _selected == true ? Colors.amber : Colors.blue,), - onPressed: (){ - if(_selected){ - // show remove from destination - Get.defaultDialog( - title: "本当にこのポイントを通過順から外しますか?", - middleText: "場所は目的地リストから削除されます", - backgroundColor: Colors.blue.shade300, - titleStyle: TextStyle(color: Colors.white), - middleTextStyle: TextStyle(color: Colors.white), - textConfirm: "はい", - textCancel: "いいえ", - cancelTextColor: Colors.white, - confirmTextColor: Colors.blue, - buttonColor: Colors.white, - barrierDismissible: false, - radius: 10, - content: Column( - children: [ - ], - ), - onConfirm: (){ - int _id = indexController.currentFeature[0].properties!["location_id"]; - Destination? d = destinationController.destinationById(_id); - print('--- des id is : ${d} -----'); - if(d != null) { - //print('--- des id is : ${d.location_id} -----'); - destinationController.deleteDestination(d); - Get.back(); - Get.back(); - Get.snackbar("追加した", "場所が削除されました"); - } - } - ); - return; - } - // show add to destination - Get.defaultDialog( - title: "この場所を登録してもよろしいですか", - middleText: "ロケーションがロガニング リストに追加されます", - backgroundColor: Colors.blue.shade300, - titleStyle: TextStyle(color: Colors.white), - middleTextStyle: TextStyle(color: Colors.white), - textConfirm: "はい", - textCancel: "いいえ", - cancelTextColor: Colors.white, - confirmTextColor: Colors.blue, - buttonColor: Colors.white, - barrierDismissible: false, - radius: 10, - content: Column( - children: [ - ], - ), - onConfirm: (){ - GeoJsonMultiPoint mp = indexController.currentFeature[0].geometry as GeoJsonMultiPoint; - LatLng pt = LatLng(mp.geoSerie!.geoPoints[0].latitude, mp.geoSerie!.geoPoints[0].longitude); - - print("----- want to go sub location is ---- ${indexController.currentFeature[0].properties!["sub_loc_id"]} -----"); - - Destination dest = Destination( - name: indexController.currentFeature[0].properties!["location_name"], - address: indexController.currentFeature[0].properties!["address"], - phone: indexController.currentFeature[0].properties!["phone"], - email: indexController.currentFeature[0].properties!["email"], - webcontents: indexController.currentFeature[0].properties!["webcontents"], - videos: indexController.currentFeature[0].properties!["videos"], - category: indexController.currentFeature[0].properties!["category"], - series: 1, - lat: pt.latitude, - lon: pt.longitude, - sub_loc_id: indexController.currentFeature[0].properties!["sub_loc_id"], - location_id: indexController.currentFeature[0].properties!["location_id"], - list_order: 1, - photos: indexController.currentFeature[0].properties!["photos"], - checkin_radious: indexController.currentFeature[0].properties!["checkin_radius"], - auto_checkin: indexController.currentFeature[0].properties!["auto_checkin"] == true ? 1 : 0, - cp: indexController.currentFeature[0].properties!["cp"], - checkin_point: indexController.currentFeature[0].properties!["checkin_point"], - buy_point: indexController.currentFeature[0].properties!["buy_point"], - selected: false, - checkedin: false, - hidden_location: indexController.currentFeature[0].properties!["hidden_location"] == true ?1 : 0 - ); - destinationController.addDestinations(dest); - Get.back(); - Get.back(); - Get.snackbar("追加した", "場所が追加されました"); - } - ); - - }, - ): - Container(), - SizedBox(width: 8.0,) , - Obx((() => - - indexController.rog_mode == 1 ? - ElevatedButton( + ElevatedButton( onPressed: () async { - Destination dest = indexController.currentDestinationFeature[0]!; + Feature dest = homeController.currentFeature[0]; //print("------ curent destination is ${dest!.checkedIn}-------"); if(dest != null){ //print("------ curent destination is ${dest!.checkedin}-------::::::::::"); - destinationController.makeCheckin(dest, !dest.checkedin!, ""); + bool checkin = await checkinDBHelper.exists(homeController.currentFeature[0].location_id!); + locationController.makeCheckin(dest, checkin, ""); } }, - child: indexController.currentDestinationFeature[0].checkedin == false ? - Text("チェックイン") - : - Text("チェックアウト") - ): - Container() - - ) - ), + child: + FutureBuilder( + future: checkinDBHelper.exists(homeController.currentFeature[0].location_id!), + builder: (context, snapshot){ + if (snapshot.connectionState == ConnectionState.waiting) { + return CircularProgressIndicator(); + + }else { + if (snapshot.hasError) + return Text('Error: ${snapshot.error}'); // return error text if something went wrong + else + return snapshot.data! ? + const Text("チェックイン") : // Widget to show if locationId exists + const Text("チェックアウト"); + } + }, + ) + ) ], ), ], ); } - Widget getCheckin(BuildContext context){ + // Widget getCheckin(BuildContext context){ - //print("------ currentAction ----- ${indexController.currentAction}-----"); + // //print("------ currentAction ----- ${indexController.currentAction}-----"); - return Row( - mainAxisAlignment: MainAxisAlignment.center, - children: [ - Row( - mainAxisAlignment: MainAxisAlignment.center, - children: [ - indexController.currentAction[0][0]["checkin"] == false ? - Column( - children: [ - Row( - mainAxisSize: MainAxisSize.max, - children: [ - ElevatedButton( - child: Text("Image"), onPressed: (){ - final ImagePicker _picker = ImagePicker(); - _picker.pickImage(source: ImageSource.camera).then((value){ - //print("----- image---- ${value!.path}"); - }); - }, - ) - ], - ), - ElevatedButton( - onPressed: (){ - if(indexController.currentAction.isNotEmpty){ - //print(indexController.currentAction[0]); - indexController.currentAction[0][0]["checkin"] = true; - Map temp = Map.from(indexController.currentAction[0][0]); - indexController.currentAction.clear(); - //print("---temp---${temp}"); - indexController.currentAction.add([temp]); - } - indexController.makeAction(context); - }, - child: Text("checkin".tr) - ) - ], - ) - : - ElevatedButton( - onPressed: (){ - if(indexController.currentAction.isNotEmpty){ - //print(indexController.currentAction[0]); - indexController.currentAction[0][0]["checkin"] = false; - Map temp = Map.from(indexController.currentAction[0][0]); - indexController.currentAction.clear(); - //print("---temp---${temp}"); - indexController.currentAction.add([temp]); - } - indexController.makeAction(context); - }, + // return Row( + // mainAxisAlignment: MainAxisAlignment.center, + // children: [ + // Row( + // mainAxisAlignment: MainAxisAlignment.center, + // children: [ + // indexController.currentAction[0][0]["checkin"] == false ? + // Column( + // children: [ + // Row( + // mainAxisSize: MainAxisSize.max, + // children: [ + // ElevatedButton( + // child: Text("Image"), onPressed: (){ + // final ImagePicker _picker = ImagePicker(); + // _picker.pickImage(source: ImageSource.camera).then((value){ + // //print("----- image---- ${value!.path}"); + // }); + // }, + // ) + // ], + // ), + // ElevatedButton( + // onPressed: (){}, + // //onPressed: (){ + // // if(indexController.currentAction.isNotEmpty){ + // // //print(indexController.currentAction[0]); + // // indexController.currentAction[0][0]["checkin"] = true; + // // Map temp = Map.from(indexController.currentAction[0][0]); + // // indexController.currentAction.clear(); + // // //print("---temp---${temp}"); + // // indexController.currentAction.add([temp]); + // // } + // // indexController.makeAction(context); + // // }, + // child: Text("checkin".tr) + // ) + // ], + // ) + // : + // ElevatedButton( + // onPressed: (){}, + // // onPressed: (){ + // // if(indexController.currentAction.isNotEmpty){ + // // //print(indexController.currentAction[0]); + // // indexController.currentAction[0][0]["checkin"] = false; + // // Map temp = Map.from(indexController.currentAction[0][0]); + // // indexController.currentAction.clear(); + // // //print("---temp---${temp}"); + // // indexController.currentAction.add([temp]); + // // } + // // indexController.makeAction(context); + // // }, - child: Icon( - Icons.favorite, color: Colors.red) + // child: Icon( + // Icons.favorite, color: Colors.red) - , - ) - ], - ) - ], - ); - } + // , + // ) + // ], + // ) + // ], + // ); + // } @@ -749,13 +690,7 @@ class BottomSheetNew extends GetView { InkWell( onTap: (){ if(isurl){ - if(indexController.rog_mode == 0){ - _launchURL(indexController.currentFeature[0].properties!["webcontents"]); - } - else { - indexController.currentDestinationFeature[0].webcontents; - } - + _launchURL(homeController.currentFeature[0].properties!.webcontents); } }, child: Container( diff --git a/pubspec.lock b/pubspec.lock index 16ea261..fda703e 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -652,10 +652,10 @@ packages: dependency: transitive description: name: json_annotation - sha256: cb314f00b2488de7bc575207e54402cd2f92363f333a7933fd1b0631af226baa + sha256: b10a7b2ff83d83c777edba3c6a0f97045ddadd56c944e1a23a3fdf43a1bf4467 url: "https://pub.dev" source: hosted - version: "4.6.0" + version: "4.8.1" latlong2: dependency: "direct main" description: @@ -1182,7 +1182,7 @@ packages: source: hosted version: "1.3.1" unicode: - dependency: transitive + dependency: "direct main" description: name: unicode sha256: "0f69e46593d65245774d4f17125c6084d2c20b4e473a983f6e21b7d7762218f1" @@ -1318,5 +1318,5 @@ packages: source: hosted version: "3.1.1" sdks: - dart: ">=2.18.0 <3.0.0" + dart: ">=2.19.0 <3.0.0" flutter: ">=3.7.0" diff --git a/pubspec.yaml b/pubspec.yaml index ed14e02..3c4d55b 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -75,6 +75,7 @@ dependencies: connectivity_plus: ^3.0.2 flutter_map_tile_caching: ^6.2.0 shared_preferences: ^2.0.15 + unicode: ^0.3.0 flutter_icons: android: true