Compare commits
33 Commits
static_sta
...
mapseven
| Author | SHA1 | Date | |
|---|---|---|---|
| accd0cad43 | |||
| 7e6b5f887a | |||
| dd36ab8399 | |||
| b37a33bc2f | |||
| e35608651b | |||
| c6eb97bbb2 | |||
| cb3a843566 | |||
| f5922d9034 | |||
| 1414d370f4 | |||
| e30c5f255c | |||
| e6a7d37519 | |||
| 2f329669e9 | |||
| 773650be82 | |||
| cd258744fc | |||
| eaee1ce820 | |||
| d7ff309c09 | |||
| d55ba7cfdb | |||
| 992f9f3414 | |||
| c3cb6d758c | |||
| cfa9e055f5 | |||
| 494b27bf9e | |||
| eda5f77e2d | |||
| b9e4df069f | |||
| 2fb095bd50 | |||
| 591b6f7aed | |||
| 8e050267e1 | |||
| c95cb75934 | |||
| 0b5ce75d6c | |||
| c67914f286 | |||
| 9145e0e27d | |||
| 445c53d21b | |||
| 56c07852f9 | |||
| fa0587178f |
@ -21,6 +21,6 @@
|
||||
<key>CFBundleVersion</key>
|
||||
<string>1.0</string>
|
||||
<key>MinimumOSVersion</key>
|
||||
<string>11.0</string>
|
||||
<string>12.0</string>
|
||||
</dict>
|
||||
</plist>
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
# Uncomment this line to define a global platform for your project
|
||||
# platform :ios, '11.0'
|
||||
platform :ios, '12.0'
|
||||
|
||||
# CocoaPods analytics sends network stats synchronously affecting flutter build latency.
|
||||
ENV['COCOAPODS_DISABLE_STATS'] = 'true'
|
||||
|
||||
@ -12,10 +12,10 @@ PODS:
|
||||
- FMDB (2.7.5):
|
||||
- FMDB/standard (= 2.7.5)
|
||||
- FMDB/standard (2.7.5)
|
||||
- gallery_saver (0.0.1):
|
||||
- Flutter
|
||||
- geolocator_apple (1.2.0):
|
||||
- Flutter
|
||||
- image_gallery_saver (2.0.2):
|
||||
- Flutter
|
||||
- image_picker_ios (0.0.1):
|
||||
- Flutter
|
||||
- isar_flutter_libs (1.0.0):
|
||||
@ -23,7 +23,9 @@ PODS:
|
||||
- path_provider_foundation (0.0.1):
|
||||
- Flutter
|
||||
- FlutterMacOS
|
||||
- permission_handler_apple (9.1.1):
|
||||
- permission_handler_apple (9.3.0):
|
||||
- Flutter
|
||||
- pointer_interceptor_ios (0.0.1):
|
||||
- Flutter
|
||||
- ReachabilitySwift (5.0.0)
|
||||
- shared_preferences_foundation (0.0.1):
|
||||
@ -41,12 +43,13 @@ DEPENDENCIES:
|
||||
- Flutter (from `Flutter`)
|
||||
- flutter_compass (from `.symlinks/plugins/flutter_compass/ios`)
|
||||
- flutter_keyboard_visibility (from `.symlinks/plugins/flutter_keyboard_visibility/ios`)
|
||||
- gallery_saver (from `.symlinks/plugins/gallery_saver/ios`)
|
||||
- geolocator_apple (from `.symlinks/plugins/geolocator_apple/ios`)
|
||||
- image_gallery_saver (from `.symlinks/plugins/image_gallery_saver/ios`)
|
||||
- image_picker_ios (from `.symlinks/plugins/image_picker_ios/ios`)
|
||||
- isar_flutter_libs (from `.symlinks/plugins/isar_flutter_libs/ios`)
|
||||
- path_provider_foundation (from `.symlinks/plugins/path_provider_foundation/darwin`)
|
||||
- permission_handler_apple (from `.symlinks/plugins/permission_handler_apple/ios`)
|
||||
- pointer_interceptor_ios (from `.symlinks/plugins/pointer_interceptor_ios/ios`)
|
||||
- shared_preferences_foundation (from `.symlinks/plugins/shared_preferences_foundation/darwin`)
|
||||
- sqflite (from `.symlinks/plugins/sqflite/ios`)
|
||||
- url_launcher_ios (from `.symlinks/plugins/url_launcher_ios/ios`)
|
||||
@ -67,10 +70,10 @@ EXTERNAL SOURCES:
|
||||
:path: ".symlinks/plugins/flutter_compass/ios"
|
||||
flutter_keyboard_visibility:
|
||||
:path: ".symlinks/plugins/flutter_keyboard_visibility/ios"
|
||||
gallery_saver:
|
||||
:path: ".symlinks/plugins/gallery_saver/ios"
|
||||
geolocator_apple:
|
||||
:path: ".symlinks/plugins/geolocator_apple/ios"
|
||||
image_gallery_saver:
|
||||
:path: ".symlinks/plugins/image_gallery_saver/ios"
|
||||
image_picker_ios:
|
||||
:path: ".symlinks/plugins/image_picker_ios/ios"
|
||||
isar_flutter_libs:
|
||||
@ -79,6 +82,8 @@ EXTERNAL SOURCES:
|
||||
:path: ".symlinks/plugins/path_provider_foundation/darwin"
|
||||
permission_handler_apple:
|
||||
:path: ".symlinks/plugins/permission_handler_apple/ios"
|
||||
pointer_interceptor_ios:
|
||||
:path: ".symlinks/plugins/pointer_interceptor_ios/ios"
|
||||
shared_preferences_foundation:
|
||||
:path: ".symlinks/plugins/shared_preferences_foundation/darwin"
|
||||
sqflite:
|
||||
@ -87,23 +92,24 @@ EXTERNAL SOURCES:
|
||||
:path: ".symlinks/plugins/url_launcher_ios/ios"
|
||||
|
||||
SPEC CHECKSUMS:
|
||||
camera_avfoundation: 3125e8cd1a4387f6f31c6c63abb8a55892a9eeeb
|
||||
connectivity_plus: 07c49e96d7fc92bc9920617b83238c4d178b446a
|
||||
Flutter: f04841e97a9d0b0a8025694d0796dd46242b2854
|
||||
camera_avfoundation: 759172d1a77ae7be0de08fc104cfb79738b8a59e
|
||||
connectivity_plus: bf0076dd84a130856aa636df1c71ccaff908fa1d
|
||||
Flutter: e0871f40cf51350855a761d2e70bf5af5b9b5de7
|
||||
flutter_compass: cbbd285cea1584c7ac9c4e0c3e1f17cbea55e855
|
||||
flutter_keyboard_visibility: 0339d06371254c3eb25eeb90ba8d17dca8f9c069
|
||||
FMDB: 2ce00b547f966261cd18927a3ddb07cb6f3db82a
|
||||
gallery_saver: 9fc173c9f4fcc48af53b2a9ebea1b643255be542
|
||||
geolocator_apple: cc556e6844d508c95df1e87e3ea6fa4e58c50401
|
||||
image_picker_ios: 4a8aadfbb6dc30ad5141a2ce3832af9214a705b5
|
||||
geolocator_apple: 9157311f654584b9bb72686c55fc02a97b73f461
|
||||
image_gallery_saver: cb43cc43141711190510e92c460eb1655cd343cb
|
||||
image_picker_ios: 99dfe1854b4fa34d0364e74a78448a0151025425
|
||||
isar_flutter_libs: b69f437aeab9c521821c3f376198c4371fa21073
|
||||
path_provider_foundation: 29f094ae23ebbca9d3d0cec13889cd9060c0e943
|
||||
permission_handler_apple: e76247795d700c14ea09e3a2d8855d41ee80a2e6
|
||||
path_provider_foundation: 3784922295ac71e43754bd15e0653ccfd36a147c
|
||||
permission_handler_apple: 9878588469a2b0d0fc1e048d9f43605f92e6cec2
|
||||
pointer_interceptor_ios: 9280618c0b2eeb80081a343924aa8ad756c21375
|
||||
ReachabilitySwift: 985039c6f7b23a1da463388634119492ff86c825
|
||||
shared_preferences_foundation: 5b919d13b803cadd15ed2dc053125c68730e5126
|
||||
sqflite: 31f7eba61e3074736dff8807a9b41581e4f7f15a
|
||||
url_launcher_ios: 08a3dfac5fb39e8759aeb0abbd5d9480f30fc8b4
|
||||
shared_preferences_foundation: b4c3b4cddf1c21f02770737f147a3f5da9d39695
|
||||
sqflite: 50a33e1d72bd59ee092a519a35d107502757ebed
|
||||
url_launcher_ios: bbd758c6e7f9fd7b5b1d4cde34d2b95fcce5e812
|
||||
|
||||
PODFILE CHECKSUM: a1c2f8dde3796ecc1697a15e7c75eb5205d8a740
|
||||
PODFILE CHECKSUM: 7a34d5e980f9e05ecf4e24c79da64ca020615638
|
||||
|
||||
COCOAPODS: 1.12.1
|
||||
COCOAPODS: 1.15.2
|
||||
|
||||
@ -139,6 +139,7 @@
|
||||
9705A1C41CF9048500538489 /* Embed Frameworks */,
|
||||
3B06AD1E1E4923F5004D2608 /* Thin Binary */,
|
||||
CD1CB185AC38B6B245F9A672 /* [CP] Embed Pods Frameworks */,
|
||||
4D62FB08D65E9D3D4D84B418 /* [CP] Copy Pods Resources */,
|
||||
);
|
||||
buildRules = (
|
||||
);
|
||||
@ -213,6 +214,23 @@
|
||||
shellPath = /bin/sh;
|
||||
shellScript = "/bin/sh \"$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh\" embed_and_thin";
|
||||
};
|
||||
4D62FB08D65E9D3D4D84B418 /* [CP] Copy Pods Resources */ = {
|
||||
isa = PBXShellScriptBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
);
|
||||
inputFileListPaths = (
|
||||
"${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-resources-${CONFIGURATION}-input-files.xcfilelist",
|
||||
);
|
||||
name = "[CP] Copy Pods Resources";
|
||||
outputFileListPaths = (
|
||||
"${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-resources-${CONFIGURATION}-output-files.xcfilelist",
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
shellPath = /bin/sh;
|
||||
shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-resources.sh\"\n";
|
||||
showEnvVarsInLog = 0;
|
||||
};
|
||||
9740EEB61CF901F6004384FC /* Run Script */ = {
|
||||
isa = PBXShellScriptBuildPhase;
|
||||
alwaysOutOfDate = 1;
|
||||
@ -342,7 +360,7 @@
|
||||
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
|
||||
GCC_WARN_UNUSED_FUNCTION = YES;
|
||||
GCC_WARN_UNUSED_VARIABLE = YES;
|
||||
IPHONEOS_DEPLOYMENT_TARGET = 11.0;
|
||||
IPHONEOS_DEPLOYMENT_TARGET = 12.0;
|
||||
MTL_ENABLE_DEBUG_INFO = NO;
|
||||
ONLY_ACTIVE_ARCH = YES;
|
||||
SDKROOT = iphoneos;
|
||||
@ -358,17 +376,25 @@
|
||||
buildSettings = {
|
||||
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
|
||||
CLANG_ENABLE_MODULES = YES;
|
||||
CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)";
|
||||
DEVELOPMENT_TEAM = ECMVJVB7LV;
|
||||
CODE_SIGN_IDENTITY = "Apple Development";
|
||||
CODE_SIGN_STYLE = Automatic;
|
||||
CURRENT_PROJECT_VERSION = 453;
|
||||
DEVELOPMENT_TEAM = UMNEWT25JR;
|
||||
ENABLE_BITCODE = NO;
|
||||
FLUTTER_BUILD_NAME = 4.5.0;
|
||||
FLUTTER_BUILD_NUMBER = 453;
|
||||
INFOPLIST_FILE = Runner/Info.plist;
|
||||
INFOPLIST_KEY_CFBundleDisplayName = "岐阜ナビ";
|
||||
INFOPLIST_KEY_LSApplicationCategoryType = "public.app-category.healthcare-fitness";
|
||||
IPHONEOS_DEPLOYMENT_TARGET = 12.0;
|
||||
LD_RUNPATH_SEARCH_PATHS = (
|
||||
"$(inherited)",
|
||||
"@executable_path/Frameworks",
|
||||
);
|
||||
MARKETING_VERSION = 4.5.0;
|
||||
PRODUCT_BUNDLE_IDENTIFIER = com.dvox.gifunavi;
|
||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||
PROVISIONING_PROFILE_SPECIFIER = "";
|
||||
SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h";
|
||||
SWIFT_VERSION = 5.0;
|
||||
VERSIONING_SYSTEM = "apple-generic";
|
||||
@ -422,7 +448,7 @@
|
||||
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
|
||||
GCC_WARN_UNUSED_FUNCTION = YES;
|
||||
GCC_WARN_UNUSED_VARIABLE = YES;
|
||||
IPHONEOS_DEPLOYMENT_TARGET = 11.0;
|
||||
IPHONEOS_DEPLOYMENT_TARGET = 12.0;
|
||||
MTL_ENABLE_DEBUG_INFO = YES;
|
||||
ONLY_ACTIVE_ARCH = YES;
|
||||
SDKROOT = iphoneos;
|
||||
@ -471,7 +497,7 @@
|
||||
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
|
||||
GCC_WARN_UNUSED_FUNCTION = YES;
|
||||
GCC_WARN_UNUSED_VARIABLE = YES;
|
||||
IPHONEOS_DEPLOYMENT_TARGET = 11.0;
|
||||
IPHONEOS_DEPLOYMENT_TARGET = 12.0;
|
||||
MTL_ENABLE_DEBUG_INFO = NO;
|
||||
ONLY_ACTIVE_ARCH = YES;
|
||||
SDKROOT = iphoneos;
|
||||
@ -489,17 +515,25 @@
|
||||
buildSettings = {
|
||||
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
|
||||
CLANG_ENABLE_MODULES = YES;
|
||||
CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)";
|
||||
DEVELOPMENT_TEAM = ECMVJVB7LV;
|
||||
CODE_SIGN_IDENTITY = "Apple Development";
|
||||
CODE_SIGN_STYLE = Automatic;
|
||||
CURRENT_PROJECT_VERSION = 453;
|
||||
DEVELOPMENT_TEAM = UMNEWT25JR;
|
||||
ENABLE_BITCODE = NO;
|
||||
FLUTTER_BUILD_NAME = 4.5.0;
|
||||
FLUTTER_BUILD_NUMBER = 453;
|
||||
INFOPLIST_FILE = Runner/Info.plist;
|
||||
INFOPLIST_KEY_CFBundleDisplayName = "岐阜ナビ";
|
||||
INFOPLIST_KEY_LSApplicationCategoryType = "public.app-category.healthcare-fitness";
|
||||
IPHONEOS_DEPLOYMENT_TARGET = 12.0;
|
||||
LD_RUNPATH_SEARCH_PATHS = (
|
||||
"$(inherited)",
|
||||
"@executable_path/Frameworks",
|
||||
);
|
||||
MARKETING_VERSION = 4.5.0;
|
||||
PRODUCT_BUNDLE_IDENTIFIER = com.dvox.gifunavi;
|
||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||
PROVISIONING_PROFILE_SPECIFIER = "";
|
||||
SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h";
|
||||
SWIFT_OPTIMIZATION_LEVEL = "-Onone";
|
||||
SWIFT_VERSION = 5.0;
|
||||
@ -513,17 +547,25 @@
|
||||
buildSettings = {
|
||||
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
|
||||
CLANG_ENABLE_MODULES = YES;
|
||||
CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)";
|
||||
DEVELOPMENT_TEAM = ECMVJVB7LV;
|
||||
CODE_SIGN_IDENTITY = "Apple Development";
|
||||
CODE_SIGN_STYLE = Automatic;
|
||||
CURRENT_PROJECT_VERSION = 453;
|
||||
DEVELOPMENT_TEAM = UMNEWT25JR;
|
||||
ENABLE_BITCODE = NO;
|
||||
FLUTTER_BUILD_NAME = 4.5.0;
|
||||
FLUTTER_BUILD_NUMBER = 453;
|
||||
INFOPLIST_FILE = Runner/Info.plist;
|
||||
INFOPLIST_KEY_CFBundleDisplayName = "岐阜ナビ";
|
||||
INFOPLIST_KEY_LSApplicationCategoryType = "public.app-category.healthcare-fitness";
|
||||
IPHONEOS_DEPLOYMENT_TARGET = 12.0;
|
||||
LD_RUNPATH_SEARCH_PATHS = (
|
||||
"$(inherited)",
|
||||
"@executable_path/Frameworks",
|
||||
);
|
||||
MARKETING_VERSION = 4.5.0;
|
||||
PRODUCT_BUNDLE_IDENTIFIER = com.dvox.gifunavi;
|
||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||
PROVISIONING_PROFILE_SPECIFIER = "";
|
||||
SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h";
|
||||
SWIFT_VERSION = 5.0;
|
||||
VERSIONING_SYSTEM = "apple-generic";
|
||||
|
||||
@ -65,5 +65,7 @@
|
||||
<true/>
|
||||
<key>UIApplicationSupportsIndirectInputEvents</key>
|
||||
<true/>
|
||||
<key>FLTEnableImpeller</key>
|
||||
<false/>
|
||||
</dict>
|
||||
</plist>
|
||||
|
||||
@ -4,6 +4,7 @@ import 'package:get/get.dart';
|
||||
import 'package:rogapp/pages/destination/destination_controller.dart';
|
||||
import 'package:rogapp/pages/index/index_binding.dart';
|
||||
import 'package:rogapp/routes/app_pages.dart';
|
||||
import 'package:rogapp/utils/location_controller.dart';
|
||||
import 'package:rogapp/utils/string_values.dart';
|
||||
import 'package:shared_preferences/shared_preferences.dart';
|
||||
// import 'package:is_lock_screen/is_lock_screen.dart';
|
||||
@ -15,6 +16,7 @@ void saveGameState() async {
|
||||
pref.setBool("is_in_rog", destinationController.isInRog.value);
|
||||
pref.setBool(
|
||||
"rogaining_counted", destinationController.rogainingCounted.value);
|
||||
pref.setBool("ready_for_goal", DestinationController.ready_for_goal);
|
||||
}
|
||||
|
||||
void restoreGame() async {
|
||||
@ -25,6 +27,8 @@ void restoreGame() async {
|
||||
destinationController.isInRog.value = pref.getBool("is_in_rog") ?? false;
|
||||
destinationController.rogainingCounted.value =
|
||||
pref.getBool("rogaining_counted") ?? false;
|
||||
DestinationController.ready_for_goal =
|
||||
pref.getBool("ready_for_goal") ?? false;
|
||||
//print(
|
||||
// "--restored -- destinationController.isInRog.value ${pref.getBool("is_in_rog")} -- ${pref.getBool("rogaining_counted")}");
|
||||
}
|
||||
@ -84,25 +88,32 @@ class _MyAppState extends State<MyApp> with WidgetsBindingObserver {
|
||||
|
||||
@override
|
||||
void didChangeAppLifecycleState(AppLifecycleState state) {
|
||||
LocationController locationController = Get.find<LocationController>();
|
||||
|
||||
DestinationController destinationController =
|
||||
Get.find<DestinationController>();
|
||||
switch (state) {
|
||||
case AppLifecycleState.resumed:
|
||||
locationController.resumePositionStream();
|
||||
//print("RESUMED");
|
||||
restoreGame();
|
||||
break;
|
||||
case AppLifecycleState.inactive:
|
||||
locationController.resumePositionStream();
|
||||
//print("INACTIVE");
|
||||
break;
|
||||
case AppLifecycleState.paused:
|
||||
locationController.resumePositionStream();
|
||||
//print("PAUSED");
|
||||
saveGameState();
|
||||
break;
|
||||
case AppLifecycleState.detached:
|
||||
locationController.resumePositionStream();
|
||||
//print("DETACHED");
|
||||
saveGameState();
|
||||
break;
|
||||
case AppLifecycleState.hidden:
|
||||
locationController.resumePositionStream();
|
||||
//print("DETACHED");
|
||||
saveGameState();
|
||||
break;
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
import 'dart:async';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_map/plugin_api.dart';
|
||||
import 'package:flutter_map/flutter_map.dart';
|
||||
import 'package:flutter_map_location_marker/flutter_map_location_marker.dart';
|
||||
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
||||
import 'package:latlong2/latlong.dart';
|
||||
|
||||
@ -136,7 +136,9 @@ class CameraPage extends StatelessWidget {
|
||||
}
|
||||
|
||||
if (destinationController.isAtGoal.value &&
|
||||
destinationController.isInRog.value) {
|
||||
destinationController.isInRog.value &&
|
||||
destination.cp == -1) {
|
||||
//goal
|
||||
return Row(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceAround,
|
||||
children: [
|
||||
@ -189,7 +191,8 @@ class CameraPage extends StatelessWidget {
|
||||
Get.back();
|
||||
destinationController.skipGps = false;
|
||||
Get.snackbar("目標が保存されました", "目標が正常に追加されました");
|
||||
destinationController.resetRogaining();
|
||||
destinationController.resetRogaining(
|
||||
isgoal: true);
|
||||
} else {
|
||||
//print("---- status ${value['status']} ---- ");
|
||||
Get.snackbar("目標が追加されていません", "please_try_again");
|
||||
@ -210,6 +213,7 @@ class CameraPage extends StatelessWidget {
|
||||
);
|
||||
} else if (destinationController.isInRog.value &&
|
||||
dbDest?.checkedin != null &&
|
||||
destination.cp != -1 &&
|
||||
dbDest?.checkedin == true) {
|
||||
//make buypoint image
|
||||
return Row(
|
||||
@ -396,45 +400,6 @@ class StartRogaining extends StatelessWidget {
|
||||
}
|
||||
}
|
||||
|
||||
// class NotAtGoal extends StatelessWidget {
|
||||
// NotAtGoal({Key? key}) : super(key: key);
|
||||
|
||||
// DestinationController destinationController =
|
||||
// Get.find<DestinationController>();
|
||||
|
||||
// @override
|
||||
// Widget build(BuildContext context) {
|
||||
// return Scaffold(
|
||||
// appBar: AppBar(
|
||||
// title: Text(
|
||||
// "Not reached the goal yet".tr,
|
||||
// ),
|
||||
// ),
|
||||
// body: Container(
|
||||
// child: Center(
|
||||
// child: Column(
|
||||
// mainAxisAlignment: MainAxisAlignment.center,
|
||||
// children: [
|
||||
// Text("You have not reached the goal yet.".tr,
|
||||
// style: const TextStyle(fontSize: 24)),
|
||||
// const SizedBox(
|
||||
// height: 40.0,
|
||||
// ),
|
||||
// ElevatedButton(
|
||||
// onPressed: () {
|
||||
// Get.back();
|
||||
// destinationController.skip_gps = false;
|
||||
// },
|
||||
// child: const Text("Back"),
|
||||
// ),
|
||||
// ],
|
||||
// ),
|
||||
// ),
|
||||
// ),
|
||||
// );
|
||||
// }
|
||||
// }
|
||||
|
||||
class BuyPointCamera extends StatelessWidget {
|
||||
BuyPointCamera({Key? key, required this.destination}) : super(key: key);
|
||||
|
||||
@ -445,6 +410,8 @@ class BuyPointCamera extends StatelessWidget {
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
//print("in camera purchase 1 ${destinationController.isInRog.value}");
|
||||
|
||||
return Scaffold(
|
||||
appBar: AppBar(
|
||||
automaticallyImplyLeading: false,
|
||||
@ -482,6 +449,8 @@ class BuyPointCamera extends StatelessWidget {
|
||||
children: [
|
||||
ElevatedButton(
|
||||
onPressed: () {
|
||||
// print(
|
||||
// "in camera purchase 2 ${destinationController.isInRog.value}");
|
||||
destinationController.openCamera(
|
||||
context, destination);
|
||||
},
|
||||
@ -495,7 +464,8 @@ class BuyPointCamera extends StatelessWidget {
|
||||
onPressed: () async {
|
||||
await destinationController
|
||||
.cancelBuyPoint(destination);
|
||||
Get.back();
|
||||
Navigator.of(Get.context!).pop();
|
||||
//Get.back();
|
||||
destinationController.rogainingCounted.value = true;
|
||||
destinationController.skipGps = false;
|
||||
destinationController.isPhotoShoot.value = false;
|
||||
@ -519,10 +489,14 @@ class BuyPointCamera extends StatelessWidget {
|
||||
style: ElevatedButton.styleFrom(
|
||||
backgroundColor: Colors.red),
|
||||
onPressed: () async {
|
||||
// print(
|
||||
// "in camera purchase 3 ${destinationController.isInRog.value}");
|
||||
await destinationController.makeBuyPoint(
|
||||
destination,
|
||||
destinationController.photos[0].path);
|
||||
Get.back();
|
||||
// print(
|
||||
// "in camera purchase 4 ${destinationController.isInRog.value}");
|
||||
destinationController.rogainingCounted.value =
|
||||
true;
|
||||
destinationController.skipGps = false;
|
||||
|
||||
@ -1,8 +1,10 @@
|
||||
import 'dart:io';
|
||||
import 'dart:typed_data';
|
||||
import 'package:camera_camera/camera_camera.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_map/flutter_map.dart';
|
||||
import 'package:geojson/geojson.dart';
|
||||
import 'package:flutter_map_location_marker/flutter_map_location_marker.dart';
|
||||
import 'package:geojson_vi/geojson_vi.dart';
|
||||
import 'package:geolocator/geolocator.dart';
|
||||
import 'package:get/get.dart';
|
||||
import 'package:intl/intl.dart';
|
||||
@ -13,6 +15,7 @@ import 'package:rogapp/model/gps_data.dart';
|
||||
import 'package:rogapp/pages/camera/camera_page.dart';
|
||||
import 'package:rogapp/pages/index/index_controller.dart';
|
||||
import 'package:rogapp/routes/app_pages.dart';
|
||||
import 'package:rogapp/services/DatabaseService.dart';
|
||||
import 'package:rogapp/services/destination_service.dart';
|
||||
import 'package:rogapp/services/external_service.dart';
|
||||
import 'package:rogapp/services/location_service.dart';
|
||||
@ -20,13 +23,15 @@ import 'package:rogapp/services/maxtrix_service.dart';
|
||||
import 'package:rogapp/services/perfecture_service.dart';
|
||||
import 'package:rogapp/utils/database_gps.dart';
|
||||
import 'package:rogapp/utils/database_helper.dart';
|
||||
import 'package:rogapp/utils/location_controller.dart';
|
||||
import 'package:rogapp/widgets/bottom_sheet_new.dart';
|
||||
import 'dart:async';
|
||||
|
||||
import 'package:modal_bottom_sheet/modal_bottom_sheet.dart';
|
||||
import 'package:rogapp/widgets/debug_widget.dart';
|
||||
import 'package:shared_preferences/shared_preferences.dart';
|
||||
import 'package:gallery_saver/gallery_saver.dart';
|
||||
|
||||
import 'package:image_gallery_saver/image_gallery_saver.dart';
|
||||
|
||||
class DestinationController extends GetxController {
|
||||
late LocationSettings locationSettings;
|
||||
@ -39,8 +44,11 @@ class DestinationController extends GetxController {
|
||||
double currentLon = 0.0;
|
||||
DateTime lastGPSCollectedTime = DateTime.now();
|
||||
|
||||
bool shouldShowBottomSheet = true;
|
||||
|
||||
static bool gps_push_started = false;
|
||||
static bool game_started = false;
|
||||
static bool ready_for_goal = false;
|
||||
|
||||
bool skip_10s = false;
|
||||
|
||||
@ -70,6 +78,8 @@ class DestinationController extends GetxController {
|
||||
final photos = <File>[].obs;
|
||||
|
||||
final IndexController indexController = Get.find<IndexController>();
|
||||
final LocationController locationController = Get.put(LocationController());
|
||||
final DatabaseService dbService = DatabaseService();
|
||||
|
||||
int _start = 0;
|
||||
int chekcs = 0;
|
||||
@ -79,10 +89,9 @@ class DestinationController extends GetxController {
|
||||
return DateFormat('yyyy-MM-dd HH:mm:ss').format(datetime);
|
||||
}
|
||||
|
||||
Destination festuretoDestination(GeoJsonFeature fs) {
|
||||
GeoJsonMultiPoint mp = fs.geometry as GeoJsonMultiPoint;
|
||||
LatLng pt = LatLng(mp.geoSerie!.geoPoints[0].latitude,
|
||||
mp.geoSerie!.geoPoints[0].longitude);
|
||||
Destination festuretoDestination(GeoJSONFeature fs) {
|
||||
GeoJSONMultiPoint mp = fs.geometry as GeoJSONMultiPoint;
|
||||
LatLng pt = LatLng(mp.coordinates[0][1], mp.coordinates[0][0]);
|
||||
|
||||
//print("----- ${indexController.currentFeature[0].properties} -----");
|
||||
|
||||
@ -112,7 +121,7 @@ class DestinationController extends GetxController {
|
||||
tags: fs.properties!["tags"]);
|
||||
}
|
||||
|
||||
Future<void> startTimerLocation(GeoJsonFeature fs, double distance) async {
|
||||
Future<void> startTimerLocation(GeoJSONFeature fs, double distance) async {
|
||||
//print("---- in startTimer ----");
|
||||
// print("---- is in rog is $is_in_rog ----");
|
||||
double checkinRadious = fs.properties!['checkin_radius'] ?? double.infinity;
|
||||
@ -156,7 +165,7 @@ class DestinationController extends GetxController {
|
||||
//make current destination
|
||||
// print("---- checkin_radious $checkinRadious ----");
|
||||
// print("---- distance $distance ----");
|
||||
if (checkinRadious >= distance) {
|
||||
if (checkinRadious >= distance || checkinRadious == -1) {
|
||||
//currentSelectedDestinations.add(d);
|
||||
indexController.currentDestinationFeature.clear();
|
||||
indexController.currentDestinationFeature.add(d);
|
||||
@ -170,15 +179,22 @@ class DestinationController extends GetxController {
|
||||
|
||||
if (isPhotoShoot.value == true) {
|
||||
photos.clear();
|
||||
await showModalBottomSheet(
|
||||
constraints: BoxConstraints.loose(Size(Get.width, Get.height * 0.75)),
|
||||
context: Get.context!,
|
||||
isScrollControlled: true,
|
||||
builder: ((context) => CameraPage(destination: d))).whenComplete(() {
|
||||
skipGps = false;
|
||||
chekcs = 0;
|
||||
isInCheckin.value = false;
|
||||
});
|
||||
if (shouldShowBottomSheet) {
|
||||
shouldShowBottomSheet = false;
|
||||
if (d.cp == -1) return;
|
||||
await showModalBottomSheet(
|
||||
constraints:
|
||||
BoxConstraints.loose(Size(Get.width, Get.height * 0.75)),
|
||||
context: Get.context!,
|
||||
isScrollControlled: true,
|
||||
builder: ((context) => CameraPage(destination: d)))
|
||||
.whenComplete(() {
|
||||
shouldShowBottomSheet = true;
|
||||
skipGps = false;
|
||||
chekcs = 0;
|
||||
isInCheckin.value = false;
|
||||
});
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
@ -192,43 +208,55 @@ class DestinationController extends GetxController {
|
||||
chekcs = 1;
|
||||
isInCheckin.value = true;
|
||||
isAtStart.value = true;
|
||||
await showModalBottomSheet(
|
||||
constraints:
|
||||
BoxConstraints.loose(Size(Get.width, Get.height * 0.85)),
|
||||
context: Get.context!,
|
||||
isScrollControlled: true,
|
||||
builder: ((context) => BottomSheetNew(
|
||||
destination: d,
|
||||
))).whenComplete(() {
|
||||
skipGps = false;
|
||||
chekcs = 0;
|
||||
isAtStart.value = false;
|
||||
isInCheckin.value = false;
|
||||
});
|
||||
if (shouldShowBottomSheet) {
|
||||
shouldShowBottomSheet = false;
|
||||
if (d.cp == -1) return;
|
||||
await showModalBottomSheet(
|
||||
constraints:
|
||||
BoxConstraints.loose(Size(Get.width, Get.height * 0.85)),
|
||||
context: Get.context!,
|
||||
isScrollControlled: true,
|
||||
builder: ((context) => BottomSheetNew(
|
||||
destination: d,
|
||||
))).whenComplete(() {
|
||||
shouldShowBottomSheet = true;
|
||||
skipGps = false;
|
||||
chekcs = 0;
|
||||
isAtStart.value = false;
|
||||
isInCheckin.value = false;
|
||||
});
|
||||
}
|
||||
return;
|
||||
} else if (isInRog.value == true && indexController.rogMode.value == 1) {
|
||||
} else if (isInRog.value == true &&
|
||||
indexController.rogMode.value == 1 &&
|
||||
d.cp != -1) {
|
||||
// print("----- in location popup checkin cp - ${d.cp}----");
|
||||
chekcs = 2;
|
||||
isInCheckin.value = true;
|
||||
await showModalBottomSheet(
|
||||
constraints:
|
||||
BoxConstraints.loose(Size(Get.width, Get.height * 0.75)),
|
||||
context: Get.context!,
|
||||
isScrollControlled: true,
|
||||
builder: ((context) => BottomSheetNew(
|
||||
destination: d,
|
||||
))).whenComplete(() {
|
||||
skipGps = false;
|
||||
chekcs = 0;
|
||||
isInCheckin.value = false;
|
||||
});
|
||||
if (shouldShowBottomSheet) {
|
||||
shouldShowBottomSheet = false;
|
||||
if (d.cp == -1) return;
|
||||
await showModalBottomSheet(
|
||||
constraints:
|
||||
BoxConstraints.loose(Size(Get.width, Get.height * 0.75)),
|
||||
context: Get.context!,
|
||||
isScrollControlled: true,
|
||||
builder: ((context) => BottomSheetNew(
|
||||
destination: d,
|
||||
))).whenComplete(() {
|
||||
shouldShowBottomSheet = true;
|
||||
skipGps = false;
|
||||
chekcs = 0;
|
||||
isInCheckin.value = false;
|
||||
});
|
||||
}
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// print("---- location checkin radious ${d.checkin_radious} ----");
|
||||
// print("---- already checked in $locationAlreadyCheckedIn ----");
|
||||
if (checkinRadious >= distance &&
|
||||
if ((checkinRadious >= distance || checkinRadious == -1) &&
|
||||
locationAlreadyCheckedIn == false &&
|
||||
isInRog.value == true) {
|
||||
if (autoCheckin) {
|
||||
@ -253,38 +281,48 @@ class DestinationController extends GetxController {
|
||||
isInCheckin.value = true;
|
||||
photos.clear();
|
||||
// print("--- calling checkin ---");
|
||||
await showModalBottomSheet(
|
||||
constraints:
|
||||
BoxConstraints.loose(Size(Get.width, Get.height * 0.75)),
|
||||
context: Get.context!,
|
||||
isScrollControlled: true,
|
||||
builder: ((context) => CameraPage(
|
||||
destination: d,
|
||||
))).whenComplete(() {
|
||||
skipGps = false;
|
||||
rogainingCounted.value = true;
|
||||
chekcs = 0;
|
||||
isInCheckin.value = false;
|
||||
});
|
||||
if (shouldShowBottomSheet) {
|
||||
shouldShowBottomSheet = false;
|
||||
if (d.cp == -1) return;
|
||||
await showModalBottomSheet(
|
||||
constraints:
|
||||
BoxConstraints.loose(Size(Get.width, Get.height * 0.75)),
|
||||
context: Get.context!,
|
||||
isScrollControlled: true,
|
||||
builder: ((context) => CameraPage(
|
||||
destination: d,
|
||||
))).whenComplete(() {
|
||||
shouldShowBottomSheet = true;
|
||||
skipGps = false;
|
||||
rogainingCounted.value = true;
|
||||
chekcs = 0;
|
||||
isInCheckin.value = false;
|
||||
});
|
||||
}
|
||||
return;
|
||||
} else if (isInRog.value == true && d.cp != -1) {
|
||||
chekcs = 4;
|
||||
isInCheckin.value = true;
|
||||
await showMaterialModalBottomSheet(
|
||||
expand: true,
|
||||
context: Get.context!,
|
||||
backgroundColor: Colors.transparent,
|
||||
builder: (context) => BottomSheetNew(
|
||||
destination: d,
|
||||
)).whenComplete(() {
|
||||
skipGps = false;
|
||||
chekcs = 0;
|
||||
isInCheckin.value = false;
|
||||
});
|
||||
if (shouldShowBottomSheet) {
|
||||
shouldShowBottomSheet = false;
|
||||
if (d.cp == -1) return;
|
||||
await showMaterialModalBottomSheet(
|
||||
expand: true,
|
||||
context: Get.context!,
|
||||
backgroundColor: Colors.transparent,
|
||||
builder: (context) => BottomSheetNew(
|
||||
destination: d,
|
||||
)).whenComplete(() {
|
||||
shouldShowBottomSheet = true;
|
||||
skipGps = false;
|
||||
chekcs = 0;
|
||||
isInCheckin.value = false;
|
||||
});
|
||||
}
|
||||
return;
|
||||
}
|
||||
}
|
||||
} else if (checkinRadious >= distance &&
|
||||
} else if ((checkinRadious >= distance || checkinRadious == -1) &&
|
||||
locationAlreadyCheckedIn == true &&
|
||||
buyPointImageAdded == false &&
|
||||
ds.isNotEmpty &&
|
||||
@ -295,20 +333,26 @@ class DestinationController extends GetxController {
|
||||
isInCheckin.value = true;
|
||||
photos.clear();
|
||||
//print("--- open buy point $buyPointImageAdded ${d.buypoint_image} ----");
|
||||
await showModalBottomSheet(
|
||||
constraints: BoxConstraints.loose(Size(Get.width, Get.height * 0.75)),
|
||||
context: Get.context!,
|
||||
isScrollControlled: true,
|
||||
builder: ((context) => CameraPage(
|
||||
buyPointPhoto: true,
|
||||
destination: d,
|
||||
dbDest: ds.first,
|
||||
))).whenComplete(() {
|
||||
skipGps = false;
|
||||
rogainingCounted.value = true;
|
||||
chekcs = 0;
|
||||
isInCheckin.value = false;
|
||||
});
|
||||
if (shouldShowBottomSheet) {
|
||||
shouldShowBottomSheet = false;
|
||||
if (d.cp == -1) return;
|
||||
await showModalBottomSheet(
|
||||
constraints:
|
||||
BoxConstraints.loose(Size(Get.width, Get.height * 0.75)),
|
||||
context: Get.context!,
|
||||
isScrollControlled: true,
|
||||
builder: ((context) => CameraPage(
|
||||
buyPointPhoto: true,
|
||||
destination: d,
|
||||
dbDest: ds.first,
|
||||
))).whenComplete(() {
|
||||
shouldShowBottomSheet = true;
|
||||
skipGps = false;
|
||||
rogainingCounted.value = true;
|
||||
chekcs = 0;
|
||||
isInCheckin.value = false;
|
||||
});
|
||||
}
|
||||
return;
|
||||
}
|
||||
// print("---- cp --- ${d.cp} -----");
|
||||
@ -328,18 +372,23 @@ class DestinationController extends GetxController {
|
||||
chekcs = 5;
|
||||
isAtGoal.value = true;
|
||||
photos.clear();
|
||||
await showModalBottomSheet(
|
||||
constraints:
|
||||
BoxConstraints.loose(Size(Get.width, Get.height * 0.75)),
|
||||
context: Get.context!,
|
||||
isScrollControlled: true,
|
||||
builder: ((context) => CameraPage(
|
||||
destination: d,
|
||||
))).whenComplete(() {
|
||||
skipGps = false;
|
||||
chekcs = 0;
|
||||
isAtGoal.value = false;
|
||||
});
|
||||
if (shouldShowBottomSheet) {
|
||||
shouldShowBottomSheet = false;
|
||||
if (d.cp == -1) return;
|
||||
await showModalBottomSheet(
|
||||
constraints:
|
||||
BoxConstraints.loose(Size(Get.width, Get.height * 0.75)),
|
||||
context: Get.context!,
|
||||
isScrollControlled: true,
|
||||
builder: ((context) => CameraPage(
|
||||
destination: d,
|
||||
))).whenComplete(() {
|
||||
shouldShowBottomSheet = true;
|
||||
skipGps = false;
|
||||
chekcs = 0;
|
||||
isAtGoal.value = false;
|
||||
});
|
||||
}
|
||||
return;
|
||||
} else if (isInRog.value == false &&
|
||||
indexController.rogMode.value == 1 &&
|
||||
@ -348,19 +397,24 @@ class DestinationController extends GetxController {
|
||||
//print("---- in start -----");
|
||||
chekcs = 6;
|
||||
isAtStart.value = true;
|
||||
await showModalBottomSheet(
|
||||
constraints:
|
||||
BoxConstraints.loose(Size(Get.width, Get.height * 0.75)),
|
||||
context: Get.context!,
|
||||
isScrollControlled: true,
|
||||
builder: ((context) => BottomSheetNew(
|
||||
destination: d,
|
||||
))).whenComplete(() {
|
||||
//print("----- finished start -------");
|
||||
skipGps = false;
|
||||
chekcs = 0;
|
||||
isAtStart.value = false;
|
||||
});
|
||||
if (shouldShowBottomSheet) {
|
||||
shouldShowBottomSheet = false;
|
||||
if (d.cp == -1) return;
|
||||
await showModalBottomSheet(
|
||||
constraints:
|
||||
BoxConstraints.loose(Size(Get.width, Get.height * 0.75)),
|
||||
context: Get.context!,
|
||||
isScrollControlled: true,
|
||||
builder: ((context) => BottomSheetNew(
|
||||
destination: d,
|
||||
))).whenComplete(() {
|
||||
shouldShowBottomSheet = true;
|
||||
//print("----- finished start -------");
|
||||
skipGps = false;
|
||||
chekcs = 0;
|
||||
isAtStart.value = false;
|
||||
});
|
||||
}
|
||||
return;
|
||||
}
|
||||
}
|
||||
@ -371,7 +425,7 @@ class DestinationController extends GetxController {
|
||||
return;
|
||||
}
|
||||
|
||||
Future<void> resetRogaining() async {
|
||||
Future<void> resetRogaining({bool isgoal = false}) async {
|
||||
//print("----- resetting --------");
|
||||
|
||||
isInCheckin.value = false;
|
||||
@ -380,17 +434,25 @@ class DestinationController extends GetxController {
|
||||
isAtGoal.value = false;
|
||||
isGpsSelected.value = true;
|
||||
skipGps = false;
|
||||
ready_for_goal = false;
|
||||
|
||||
_start = 0;
|
||||
chekcs = 0;
|
||||
rogainingCounted.value = false;
|
||||
|
||||
DatabaseHelper db = DatabaseHelper.instance;
|
||||
|
||||
if (isgoal == false) {
|
||||
await db.deleteAllDestinations();
|
||||
await db.deleteAllRogaining();
|
||||
}
|
||||
|
||||
int? latgoal = await db.latestGoal();
|
||||
if (latgoal != null) {
|
||||
lastGoalAt = DateTime.fromMicrosecondsSinceEpoch(latgoal);
|
||||
//print("===== last goal : $last_goal_at =====");
|
||||
}
|
||||
dbService.updateDatabase();
|
||||
}
|
||||
|
||||
void deleteAllDestinations() {
|
||||
@ -499,103 +561,63 @@ class DestinationController extends GetxController {
|
||||
}
|
||||
});
|
||||
} else {
|
||||
Get.snackbar("始まっていない", "ロゲイニングを始める必要があります");
|
||||
Get.snackbar(
|
||||
"始まっていません",
|
||||
"ロゲ開始ボタンをタップして、ロゲイニングを始める必要があります",
|
||||
icon: const Icon(Icons.assistant_photo_outlined, size: 40.0, color: Colors.blue),
|
||||
snackPosition: SnackPosition.TOP,
|
||||
duration: const Duration(seconds: 3),
|
||||
backgroundColor: Colors.yellow,
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Future<void> addGPStoDB(double la, double ln, {isCheckin = 0}) async {
|
||||
GpsDatabaseHelper db = GpsDatabaseHelper.instance;
|
||||
final team_name = indexController.currentUser[0]["user"]['team_name'];
|
||||
final event_code = indexController.currentUser[0]["user"]["event_code"];
|
||||
GpsData gps_data = GpsData(
|
||||
id: 0,
|
||||
team_name: team_name,
|
||||
event_code: event_code,
|
||||
lat: la,
|
||||
lon: ln,
|
||||
is_checkin: isCheckin,
|
||||
created_at: DateTime.now().millisecondsSinceEpoch);
|
||||
var res = await db.insertGps(gps_data);
|
||||
//print("==gps res == ${res}");
|
||||
//print("in addGPStoDB ${indexController.currentUser}");
|
||||
try {
|
||||
GpsDatabaseHelper db = GpsDatabaseHelper.instance;
|
||||
final team_name = indexController.currentUser[0]["user"]['team_name'];
|
||||
final event_code = indexController.currentUser[0]["user"]["event_code"];
|
||||
GpsData gps_data = GpsData(
|
||||
id: 0,
|
||||
team_name: team_name,
|
||||
event_code: event_code,
|
||||
lat: la,
|
||||
lon: ln,
|
||||
is_checkin: isCheckin,
|
||||
created_at: DateTime.now().millisecondsSinceEpoch);
|
||||
var res = await db.insertGps(gps_data);
|
||||
} catch (err) {
|
||||
print("errr ready gps ${err}");
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
Future<void> checkForCheckin() async {
|
||||
//print("--- Start of checkForCheckin function ---");
|
||||
dbService.updateDatabase();
|
||||
await Future.delayed(const Duration(milliseconds: 3000));
|
||||
game_started = true;
|
||||
|
||||
try {
|
||||
//print("--- 000 ---- $skip_gps----");
|
||||
await Future.delayed(const Duration(milliseconds: 3000));
|
||||
Position position = await Geolocator.getCurrentPosition(
|
||||
desiredAccuracy: LocationAccuracy.bestForNavigation);
|
||||
|
||||
currentLat = position.latitude;
|
||||
currentLon = position.longitude;
|
||||
final la = position.latitude;
|
||||
final ln = position.longitude;
|
||||
|
||||
LogManager().addLog(
|
||||
"GPS : $currentLat, $currentLon - ${DateTime.now().hour}:${DateTime.now().minute}:${DateTime.now().second}:${DateTime.now().microsecond}");
|
||||
|
||||
//print("--- gps is ${la}, ${ln}");
|
||||
|
||||
//add gps to database
|
||||
//check distance to previous point
|
||||
var distance = const Distance();
|
||||
double distanceToDest = distance.as(
|
||||
LengthUnit.Meter,
|
||||
LatLng(position.latitude, position.longitude),
|
||||
LatLng(currentLat, currentLon));
|
||||
Duration difference =
|
||||
lastGPSCollectedTime.difference(DateTime.now()).abs();
|
||||
if (difference.inSeconds >= 10 || distanceToDest >= 10) {
|
||||
print(
|
||||
"^^^^^^^^ GPS data collected ${DateFormat('kk:mm:ss \n EEE d MMM').format(DateTime.now())}, ^^^ ${position.latitude}, ${position.longitude}");
|
||||
|
||||
await addGPStoDB(la, ln);
|
||||
lastGPSCollectedTime = DateTime.now();
|
||||
}
|
||||
|
||||
// GpsDatabaseHelper db = GpsDatabaseHelper.instance;
|
||||
// final team_name = indexController.currentUser[0]["user"]['team_name'];
|
||||
// final event_code = indexController.currentUser[0]["user"]["event_code"];
|
||||
// print("--- curr gps is ${la}, ${ln}");
|
||||
// GpsData gps_data = GpsData(
|
||||
// id: 0,
|
||||
// team_name: team_name,
|
||||
// event_code: event_code,
|
||||
// lat: la,
|
||||
// lon: ln,
|
||||
// created_at: DateTime.now().microsecondsSinceEpoch);
|
||||
// await db.insertGps(gps_data);
|
||||
|
||||
for (GeoJsonFeature fs in indexController.locations[0].collection) {
|
||||
GeoJsonMultiPoint mp = fs.geometry as GeoJsonMultiPoint;
|
||||
LatLng pt = LatLng(mp.geoSerie!.geoPoints[0].latitude,
|
||||
mp.geoSerie!.geoPoints[0].longitude);
|
||||
indexController.locations[0].features.forEach((fs) async {
|
||||
GeoJSONMultiPoint mp = fs!.geometry as GeoJSONMultiPoint;
|
||||
LatLng pt = LatLng(mp.coordinates[0][1], mp.coordinates[0][0]);
|
||||
|
||||
double latFs = pt.latitude;
|
||||
double lonFs = pt.longitude;
|
||||
var distanceFs = const Distance();
|
||||
//print("--- points : ${pt.latitude}, ${pt.longitude} ----");
|
||||
//print("--- points : ${pt.latitude}, ${pt.longitude} ----");
|
||||
double distFs = distanceFs.as(
|
||||
LengthUnit.Meter, LatLng(latFs, lonFs), LatLng(la, ln));
|
||||
double distFs = distanceFs.as(LengthUnit.Meter, LatLng(latFs, lonFs),
|
||||
LatLng(currentLat, currentLon));
|
||||
Destination des = festuretoDestination(fs);
|
||||
|
||||
//print(
|
||||
// "--- position is ---- ${position.longitude}, --- ${position.longitude}----");
|
||||
|
||||
//print("--- distFs ---- $distFs, --- ${des.checkin_radious}----");
|
||||
if (distFs <= des.checkin_radious! && skipGps == false) {
|
||||
//print("--- 789 ---- $skip_gps----");
|
||||
//near a location
|
||||
//print("---- before call startTimerLocation ----");
|
||||
await startTimerLocation(fs, distFs);
|
||||
break;
|
||||
// Note: You cannot break out of forEach. If you need to stop processing, you might have to reconsider using forEach.
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
if (gps_push_started == false) {
|
||||
pushGPStoServer();
|
||||
}
|
||||
@ -644,11 +666,21 @@ class DestinationController extends GetxController {
|
||||
populateDestinations();
|
||||
}
|
||||
|
||||
_saveImageFromPath(String imagePath) async {
|
||||
// Read the image file from the given path
|
||||
File imageFile = File(imagePath);
|
||||
Uint8List imageBytes = await imageFile.readAsBytes();
|
||||
|
||||
// Save the image to the gallery
|
||||
final result = await ImageGallerySaver.saveImage(imageBytes);
|
||||
//print("--- save result --- ${result}");
|
||||
}
|
||||
|
||||
Future<void> makeBuyPoint(Destination destination, String imageurl) async {
|
||||
DatabaseHelper db = DatabaseHelper.instance;
|
||||
await db.updateBuyPoint(destination, imageurl);
|
||||
populateDestinations();
|
||||
await GallerySaver.saveImage(imageurl);
|
||||
await _saveImageFromPath(imageurl);
|
||||
|
||||
if (indexController.currentUser.isNotEmpty) {
|
||||
double cpNum = destination.cp!;
|
||||
@ -690,7 +722,7 @@ class DestinationController extends GetxController {
|
||||
// print("~~~~ inserted into db ~~~~");
|
||||
}
|
||||
|
||||
await GallerySaver.saveImage(imageurl);
|
||||
await _saveImageFromPath(imageurl);
|
||||
|
||||
populateDestinations();
|
||||
|
||||
@ -719,9 +751,11 @@ class DestinationController extends GetxController {
|
||||
// print("------Ext service check point $value ------");
|
||||
});
|
||||
}
|
||||
dbService.updateDatabase();
|
||||
}
|
||||
|
||||
Future<void> removeCheckin(int cp) {
|
||||
dbService.updateDatabase();
|
||||
return ExternalService().removeCheckin(cp);
|
||||
}
|
||||
|
||||
@ -734,20 +768,84 @@ class DestinationController extends GetxController {
|
||||
|
||||
@override
|
||||
void onInit() async {
|
||||
startGame();
|
||||
super.onInit();
|
||||
locationController.locationMarkerPositionStream.listen(
|
||||
(locationMarkerPosition) {
|
||||
if (locationMarkerPosition != null) {
|
||||
handleLocationUpdate(locationMarkerPosition);
|
||||
}
|
||||
}, onError: (err) {
|
||||
print("Error: $err");
|
||||
});
|
||||
|
||||
startGame();
|
||||
}
|
||||
|
||||
@override
|
||||
void onClose() {
|
||||
locationController.stopPositionStream();
|
||||
}
|
||||
|
||||
void handleLocationUpdate(LocationMarkerPosition? position) async {
|
||||
try {
|
||||
if (position != null) {
|
||||
if (distanceToStart() >= 150) {
|
||||
ready_for_goal = true;
|
||||
}
|
||||
|
||||
var distance = const Distance();
|
||||
double distanceToDest = distance.as(
|
||||
LengthUnit.Meter,
|
||||
LatLng(position.latitude, position.longitude),
|
||||
LatLng(currentLat, currentLon));
|
||||
|
||||
Duration difference =
|
||||
lastGPSCollectedTime.difference(DateTime.now()).abs();
|
||||
if (difference.inSeconds >= 10 || distanceToDest >= 10) {
|
||||
// print(
|
||||
// "^^^^^^^^ GPS data collected ${DateFormat('kk:mm:ss \n EEE d MMM').format(DateTime.now())}, ^^^ ${position.latitude}, ${position.longitude}");
|
||||
|
||||
LogManager().addLog(
|
||||
"GPS : $currentLat, $currentLon - ${DateTime.now().hour}:${DateTime.now().minute}:${DateTime.now().second}:${DateTime.now().microsecond}");
|
||||
if (isInRog.value) {
|
||||
await addGPStoDB(position.latitude, position.longitude);
|
||||
lastGPSCollectedTime = DateTime.now();
|
||||
}
|
||||
}
|
||||
}
|
||||
} finally {
|
||||
if (position != null &&
|
||||
(position.latitude != 0 && position.longitude != 0)) {
|
||||
currentLat = position.latitude;
|
||||
currentLon = position.longitude;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
double distanceToStart() {
|
||||
if (indexController.locations.isEmpty) {
|
||||
return 1000000000;
|
||||
}
|
||||
//print("=== gfs len == ${indexController.locations[0].collection.length}");
|
||||
GeoJsonFeature gfs = indexController.locations[0].collection
|
||||
.firstWhere((element) => festuretoDestination(element).cp == -1);
|
||||
double distanceToDest = double.infinity;
|
||||
if (indexController.locations[0].features.isEmpty) {
|
||||
return distanceToDest;
|
||||
}
|
||||
GeoJSONFeature? gfs = indexController.locations[0].features.firstWhere(
|
||||
(element) => festuretoDestination(element!).cp == -1,
|
||||
orElse: () => null, // Provide a null value if no element is found
|
||||
);
|
||||
|
||||
//print("gfs : ${gfs}");
|
||||
|
||||
if (gfs == null) {
|
||||
return distanceToDest;
|
||||
}
|
||||
|
||||
Destination des = festuretoDestination(gfs);
|
||||
|
||||
//print("=== gfs == ${des.toMap()}");
|
||||
|
||||
double distanceToDest = double.infinity;
|
||||
var distance = const Distance();
|
||||
distanceToDest = distance.as(LengthUnit.Meter,
|
||||
LatLng(currentLat, currentLon), LatLng(des.lat!, des.lon!));
|
||||
@ -756,13 +854,23 @@ class DestinationController extends GetxController {
|
||||
}
|
||||
|
||||
int getForcedChckinDistance(Destination dest) {
|
||||
if (dest.checkin_radious == -1) {
|
||||
return 10000000000000000;
|
||||
}
|
||||
|
||||
int _retValue = 100;
|
||||
if (dest.cp == -1) {
|
||||
return 500;
|
||||
}
|
||||
Destination? ds;
|
||||
GeoJsonFeature gfs = indexController.locations[0].collection
|
||||
.firstWhere((element) => festuretoDestination(element).cp == -1);
|
||||
GeoJSONFeature? gfs = indexController.locations[0].features.firstWhere(
|
||||
(element) => festuretoDestination(element!).cp == -1,
|
||||
orElse: () => null, // Provide a null value if no element is found
|
||||
);
|
||||
|
||||
if (gfs == null) {
|
||||
return _retValue;
|
||||
}
|
||||
|
||||
ds = festuretoDestination(gfs);
|
||||
var distance = const Distance();
|
||||
@ -824,10 +932,22 @@ class DestinationController extends GetxController {
|
||||
indexController.currentBound.clear();
|
||||
indexController.currentBound.add(bnds);
|
||||
indexController.loadLocationsBound();
|
||||
centerMapToCurrentLocation();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
void centerMapToCurrentLocation() {
|
||||
assert(() {
|
||||
print("center is ${currentLon}, ${currentLon}");
|
||||
return true;
|
||||
}());
|
||||
// Akira
|
||||
if (currentLat != 0 || currentLon != 0) {
|
||||
indexController.mapController.move(LatLng(currentLat, currentLon), 17.0);
|
||||
}
|
||||
}
|
||||
|
||||
void connectionChanged(String val) {
|
||||
//print('----- %%%%%%%%%%%%%%%%%%%%% ----- $val');
|
||||
Map<String, dynamic> res = {};
|
||||
@ -903,6 +1023,7 @@ class DestinationController extends GetxController {
|
||||
db.deleteDestination(d.location_id!).then((value) {
|
||||
populateDestinations();
|
||||
});
|
||||
dbService.updateDatabase();
|
||||
}
|
||||
|
||||
void deleteDBDestinations() {
|
||||
@ -910,6 +1031,7 @@ class DestinationController extends GetxController {
|
||||
db.deleteAllDestinations().then((value) {
|
||||
populateDestinations();
|
||||
});
|
||||
dbService.updateDatabase();
|
||||
}
|
||||
|
||||
// ---------- database ------------------///
|
||||
@ -932,6 +1054,7 @@ class DestinationController extends GetxController {
|
||||
});
|
||||
}
|
||||
});
|
||||
dbService.updateDatabase();
|
||||
}
|
||||
|
||||
void toggleSelection(Destination dest) async {
|
||||
@ -965,7 +1088,7 @@ class DestinationController extends GetxController {
|
||||
}
|
||||
|
||||
void destinationMatrixFromCurrentPoint(List<Destination> points) {
|
||||
buildShowDialog(Get.context!);
|
||||
//buildShowDialog(Get.context!);
|
||||
MatrixService.getDestinations(points).then((mat) {
|
||||
//print(" matrix is ------- $mat");
|
||||
matrix = mat;
|
||||
@ -984,7 +1107,7 @@ class DestinationController extends GetxController {
|
||||
skipGps = false;
|
||||
return;
|
||||
} finally {
|
||||
Get.back();
|
||||
//Get.back();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
import 'dart:async';
|
||||
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_map/plugin_api.dart';
|
||||
import 'package:flutter_map/flutter_map.dart';
|
||||
import 'package:flutter_map_location_marker/flutter_map_location_marker.dart';
|
||||
import 'package:flutter_map_marker_popup/flutter_map_marker_popup.dart';
|
||||
import 'package:flutter_polyline_points/flutter_polyline_points.dart';
|
||||
@ -42,64 +42,61 @@ class DestinationMapPage extends StatelessWidget {
|
||||
//print("^^^^ $d ^^^^");
|
||||
Marker m = Marker(
|
||||
point: LatLng(d.lat!, d.lon!),
|
||||
anchorPos: AnchorPos.align(AnchorAlign.center),
|
||||
builder: (cts) {
|
||||
return InkWell(
|
||||
onTap: () {
|
||||
//print("-- Destination is --- ${d.name} ------");
|
||||
if (indexController.currentDestinationFeature.isNotEmpty) {
|
||||
indexController.currentDestinationFeature.clear();
|
||||
}
|
||||
indexController.currentDestinationFeature.add(d);
|
||||
//indexController.getAction();
|
||||
alignment: Alignment.center,
|
||||
child: InkWell(
|
||||
onTap: () {
|
||||
//print("-- Destination is --- ${d.name} ------");
|
||||
if (indexController.currentDestinationFeature.isNotEmpty) {
|
||||
indexController.currentDestinationFeature.clear();
|
||||
}
|
||||
indexController.currentDestinationFeature.add(d);
|
||||
//indexController.getAction();
|
||||
|
||||
showModalBottomSheet(
|
||||
context: Get.context!,
|
||||
isScrollControlled: true,
|
||||
constraints: BoxConstraints.loose(
|
||||
Size(Get.width, Get.height * 0.85)),
|
||||
builder: ((context) => BottomSheetNew(
|
||||
destination: d,
|
||||
))).whenComplete(() {
|
||||
//print("---- set skip gps to false -----");
|
||||
destinationController.skipGps = false;
|
||||
});
|
||||
},
|
||||
child: Row(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
children: [
|
||||
Container(
|
||||
width: 20,
|
||||
height: 20,
|
||||
decoration: BoxDecoration(
|
||||
color: Colors.red,
|
||||
shape: BoxShape.circle,
|
||||
border: Border.all(
|
||||
color: Colors.white,
|
||||
width:
|
||||
d.checkin_radious != null ? d.checkin_radious! : 1,
|
||||
),
|
||||
),
|
||||
child: Center(
|
||||
child: Text(
|
||||
(i + 1).toString(),
|
||||
style: const TextStyle(color: Colors.white),
|
||||
),
|
||||
showModalBottomSheet(
|
||||
context: Get.context!,
|
||||
isScrollControlled: true,
|
||||
constraints:
|
||||
BoxConstraints.loose(Size(Get.width, Get.height * 0.85)),
|
||||
builder: ((context) => BottomSheetNew(
|
||||
destination: d,
|
||||
))).whenComplete(() {
|
||||
//print("---- set skip gps to false -----");
|
||||
destinationController.skipGps = false;
|
||||
});
|
||||
},
|
||||
child: Row(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
children: [
|
||||
Container(
|
||||
width: 20,
|
||||
height: 20,
|
||||
decoration: BoxDecoration(
|
||||
color: Colors.red,
|
||||
shape: BoxShape.circle,
|
||||
border: Border.all(
|
||||
color: Colors.white,
|
||||
width: d.checkin_radious != null ? d.checkin_radious! : 1,
|
||||
),
|
||||
),
|
||||
Container(
|
||||
color: Colors.yellow,
|
||||
child: Text(
|
||||
TextUtils.getDisplayText(d),
|
||||
style: const TextStyle(
|
||||
fontSize: 15.0,
|
||||
fontWeight: FontWeight.bold,
|
||||
overflow: TextOverflow.visible),
|
||||
)),
|
||||
],
|
||||
),
|
||||
);
|
||||
});
|
||||
child: Center(
|
||||
child: Text(
|
||||
(i + 1).toString(),
|
||||
style: const TextStyle(color: Colors.white),
|
||||
),
|
||||
),
|
||||
),
|
||||
Container(
|
||||
color: Colors.yellow,
|
||||
child: Text(
|
||||
TextUtils.getDisplayText(d),
|
||||
style: const TextStyle(
|
||||
fontSize: 15.0,
|
||||
fontWeight: FontWeight.bold,
|
||||
overflow: TextOverflow.visible),
|
||||
)),
|
||||
],
|
||||
),
|
||||
));
|
||||
|
||||
pts.add(m);
|
||||
}
|
||||
|
||||
@ -115,9 +115,10 @@ class _GpsPageState extends State<GpsPage> {
|
||||
]),
|
||||
zoom: 1,
|
||||
interactiveFlags: InteractiveFlag.pinchZoom | InteractiveFlag.drag,
|
||||
|
||||
onPositionChanged: (MapPosition pos, isvalue) {
|
||||
indexController.currentBound = [pos.bounds!];
|
||||
onPositionChanged: (MapPosition pos, bool hasGesture) {
|
||||
if (hasGesture) {
|
||||
indexController.currentBound = [pos.bounds!];
|
||||
}
|
||||
},
|
||||
onTap: (tapPos, cord) {}, // Hide popup when the map is tapped.
|
||||
),
|
||||
@ -126,21 +127,23 @@ class _GpsPageState extends State<GpsPage> {
|
||||
MarkerLayer(
|
||||
markers: gpsData.map((i) {
|
||||
return Marker(
|
||||
anchorPos: AnchorPos.exactly(Anchor(108.0, 18.0)),
|
||||
height: 32.0,
|
||||
width: 120.0,
|
||||
point: LatLng(i.lat, i.lon),
|
||||
builder: (ctx) {
|
||||
return getMarkerShape(i);
|
||||
// return Container(
|
||||
// width: 40,
|
||||
// height: 40,
|
||||
// color: Colors.orange,
|
||||
// );
|
||||
},
|
||||
);
|
||||
width: 30.0, // Fixed width
|
||||
height: 30.0, // Fixed height
|
||||
point: LatLng(i.lat, i.lon),
|
||||
child: getMarkerShape(i),
|
||||
alignment: Alignment.center);
|
||||
}).toList(),
|
||||
)
|
||||
),
|
||||
// MarkerLayer(
|
||||
// markers: gpsData.map((i) {
|
||||
// return Marker(
|
||||
// alignment: Alignment.center,
|
||||
// height: 32.0,
|
||||
// width: 120.0,
|
||||
// point: LatLng(i.lat, i.lon),
|
||||
// child: getMarkerShape(i));
|
||||
// }).toList(),
|
||||
// )
|
||||
],
|
||||
),
|
||||
)),
|
||||
|
||||
@ -1,11 +1,13 @@
|
||||
import 'package:get/get.dart';
|
||||
import 'package:rogapp/pages/destination/destination_controller.dart';
|
||||
import 'package:rogapp/pages/index/index_controller.dart';
|
||||
import 'package:rogapp/utils/location_controller.dart';
|
||||
|
||||
class IndexBinding extends Bindings {
|
||||
@override
|
||||
void dependencies() {
|
||||
Get.put<IndexController>(IndexController());
|
||||
Get.put<LocationController>(LocationController());
|
||||
Get.put<DestinationController>(DestinationController());
|
||||
}
|
||||
}
|
||||
|
||||
@ -4,9 +4,8 @@ import 'package:connectivity_plus/connectivity_plus.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter/services.dart';
|
||||
import 'package:flutter_map/flutter_map.dart';
|
||||
import 'package:flutter_map/plugin_api.dart';
|
||||
import 'package:flutter_polyline_points/flutter_polyline_points.dart';
|
||||
import 'package:geojson/geojson.dart';
|
||||
import 'package:geojson_vi/geojson_vi.dart';
|
||||
import 'package:get/get.dart';
|
||||
import 'package:latlong2/latlong.dart';
|
||||
import 'package:rogapp/model/destination.dart';
|
||||
@ -18,8 +17,8 @@ import 'package:rogapp/utils/database_helper.dart';
|
||||
import 'package:shared_preferences/shared_preferences.dart';
|
||||
|
||||
class IndexController extends GetxController {
|
||||
List<GeoJsonFeatureCollection> locations = <GeoJsonFeatureCollection>[].obs;
|
||||
List<GeoJsonFeature> currentFeature = <GeoJsonFeature>[].obs;
|
||||
List<GeoJSONFeatureCollection> locations = <GeoJSONFeatureCollection>[].obs;
|
||||
List<GeoJSONFeature> currentFeature = <GeoJSONFeature>[].obs;
|
||||
List<Destination> currentDestinationFeature = <Destination>[].obs;
|
||||
List<dynamic> perfectures = <dynamic>[].obs;
|
||||
List<LatLngBounds> currentBound = <LatLngBounds>[].obs;
|
||||
@ -173,11 +172,11 @@ class IndexController extends GetxController {
|
||||
} else {
|
||||
isLoading.value = false;
|
||||
Get.snackbar(
|
||||
"Failed",
|
||||
"User login failed, please try again.",
|
||||
"ログイン失敗",
|
||||
"ログインIDかパスワードを確認して下さい。",
|
||||
icon: const Icon(Icons.error, size: 40.0, color: Colors.blue),
|
||||
snackPosition: SnackPosition.TOP,
|
||||
duration: const Duration(milliseconds: 800),
|
||||
duration: const Duration(seconds: 3),
|
||||
backgroundColor: Colors.yellow,
|
||||
//icon:Image(image:AssetImage("assets/images/dora.png"))
|
||||
);
|
||||
@ -283,6 +282,7 @@ class IndexController extends GetxController {
|
||||
});
|
||||
}
|
||||
|
||||
/*
|
||||
void loadLocationsBound() {
|
||||
if (isCustomAreaSelected.value == true) {
|
||||
return;
|
||||
@ -311,7 +311,7 @@ class IndexController extends GetxController {
|
||||
if (value == null) {
|
||||
return;
|
||||
}
|
||||
if (value.collection.isEmpty) {
|
||||
if (value.features.isEmpty) {
|
||||
if (showPopup == false) {
|
||||
return;
|
||||
}
|
||||
@ -321,34 +321,104 @@ class IndexController extends GetxController {
|
||||
icon: const Icon(Icons.assistant_photo_outlined,
|
||||
size: 40.0, color: Colors.blue),
|
||||
snackPosition: SnackPosition.TOP,
|
||||
duration: const Duration(milliseconds: 800),
|
||||
duration: const Duration(seconds: 2),
|
||||
backgroundColor: Colors.yellow,
|
||||
//icon:Image(image:AssetImage("assets/images/dora.png"))
|
||||
);
|
||||
showPopup = false;
|
||||
//Get.showSnackbar(GetSnackBar(message: "Too many points, please zoom in",));
|
||||
}
|
||||
if (value.collection.isNotEmpty) {
|
||||
if (value.features.isNotEmpty) {
|
||||
////print("---- added---");
|
||||
locations.add(value);
|
||||
}
|
||||
});
|
||||
}
|
||||
*/
|
||||
|
||||
// 2024-04-03 Akira .. Update the code . See ticket 2800.
|
||||
//
|
||||
void loadLocationsBound() {
|
||||
if (isCustomAreaSelected.value == true) {
|
||||
return;
|
||||
}
|
||||
locations.clear();
|
||||
String cat = currentCat.isNotEmpty ? currentCat[0] : "";
|
||||
if (currentCat.isNotEmpty && currentCat[0] == "-all-") {
|
||||
cat = "";
|
||||
}
|
||||
LatLngBounds bounds = mapController.bounds!;
|
||||
currentBound.clear();
|
||||
currentBound.add(bounds);
|
||||
|
||||
isLoading.value = true; // ローディング状態をtrueに設定
|
||||
|
||||
LocationService.loadLocationsBound(
|
||||
bounds.southWest.latitude,
|
||||
bounds.southWest.longitude,
|
||||
bounds.northWest.latitude,
|
||||
bounds.northWest.longitude,
|
||||
bounds.northEast.latitude,
|
||||
bounds.northEast.longitude,
|
||||
bounds.southEast.latitude,
|
||||
bounds.southEast.longitude,
|
||||
cat
|
||||
).then((value) {
|
||||
isLoading.value = false; // ローディング状態をfalseに設定
|
||||
|
||||
if (value == null) {
|
||||
// APIからのレスポンスがnullの場合は処理を中断
|
||||
return;
|
||||
}
|
||||
if (value.features.isEmpty) {
|
||||
if (showPopup == false) {
|
||||
return;
|
||||
}
|
||||
Get.snackbar(
|
||||
"Too many Points",
|
||||
"please zoom in",
|
||||
icon: const Icon(Icons.assistant_photo_outlined, size: 40.0, color: Colors.blue),
|
||||
snackPosition: SnackPosition.TOP,
|
||||
duration: const Duration(seconds: 3),
|
||||
backgroundColor: Colors.yellow,
|
||||
);
|
||||
showPopup = false;
|
||||
}
|
||||
if (value.features.isNotEmpty) {
|
||||
locations.add(value);
|
||||
}
|
||||
}).catchError((error) {
|
||||
isLoading.value = false; // ローディング状態をfalseに設定
|
||||
|
||||
// エラーハンドリング: APIリクエストが失敗した場合
|
||||
Get.snackbar(
|
||||
"Error",
|
||||
"Failed to load locations. Please check your internet connection and try again.",
|
||||
icon: const Icon(Icons.error, size: 40.0, color: Colors.red),
|
||||
snackPosition: SnackPosition.TOP,
|
||||
duration: const Duration(milliseconds: 800),
|
||||
backgroundColor: Colors.yellow,
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
void setBound(LatLngBounds bounds) {
|
||||
currentBound.clear();
|
||||
currentBound.add(bounds);
|
||||
}
|
||||
|
||||
GeoJsonFeature? getFeatureForLatLong(double lat, double long) {
|
||||
GeoJSONFeature? getFeatureForLatLong(double lat, double long) {
|
||||
if (locations.isNotEmpty) {
|
||||
for (GeoJsonFeature i in locations[0].collection) {
|
||||
GeoJsonMultiPoint p = i.geometry as GeoJsonMultiPoint;
|
||||
if (p.geoSerie!.geoPoints[0].latitude == lat &&
|
||||
p.geoSerie!.geoPoints[0].longitude == long) {
|
||||
return i;
|
||||
GeoJSONFeature? foundFeature;
|
||||
|
||||
locations[0].features.forEach((i) {
|
||||
GeoJSONMultiPoint p = i!.geometry as GeoJSONMultiPoint;
|
||||
if (p.coordinates[0][1] == lat && p.coordinates[0][0] == long) {
|
||||
foundFeature = i;
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
return foundFeature;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@ -1,11 +1,14 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:get/get.dart';
|
||||
import 'package:rogapp/model/destination.dart';
|
||||
import 'package:rogapp/model/gps_data.dart';
|
||||
import 'package:rogapp/pages/destination/destination_controller.dart';
|
||||
import 'package:rogapp/pages/drawer/drawer_page.dart';
|
||||
import 'package:rogapp/pages/index/index_controller.dart';
|
||||
import 'package:rogapp/routes/app_pages.dart';
|
||||
import 'package:rogapp/services/DatabaseService.dart';
|
||||
import 'package:rogapp/utils/database_gps.dart';
|
||||
import 'package:rogapp/utils/database_helper.dart';
|
||||
import 'package:rogapp/widgets/list_widget.dart';
|
||||
import 'package:rogapp/widgets/map_widget.dart';
|
||||
|
||||
@ -25,6 +28,13 @@ class IndexPage extends GetView<IndexController> {
|
||||
appBar: AppBar(
|
||||
title: Text("add_location".tr),
|
||||
actions: [
|
||||
// IconButton(
|
||||
// onPressed: () {
|
||||
// DatabaseService ds = DatabaseService();
|
||||
// ds.updateDatabase();
|
||||
// },
|
||||
// icon: const Icon(Icons.ten_k_sharp)),
|
||||
|
||||
IconButton(
|
||||
onPressed: () async {
|
||||
// GpsDatabaseHelper db = GpsDatabaseHelper.instance;
|
||||
|
||||
@ -1,16 +1,15 @@
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
class LoadingPage extends StatelessWidget {
|
||||
const LoadingPage({ Key? key }) : super(key: key);
|
||||
const LoadingPage({Key? key}) : super(key: key);
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Container(
|
||||
alignment: Alignment.topCenter,
|
||||
margin: const EdgeInsets.only(top: 20),
|
||||
child: const CircularProgressIndicator(
|
||||
value: 0.8,
|
||||
)
|
||||
);
|
||||
alignment: Alignment.center,
|
||||
margin: const EdgeInsets.only(top: 20),
|
||||
child: const CircularProgressIndicator(
|
||||
value: 0.8,
|
||||
));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -16,6 +16,12 @@ class LoginPage extends StatelessWidget {
|
||||
return Scaffold(
|
||||
resizeToAvoidBottomInset: false,
|
||||
backgroundColor: Colors.white,
|
||||
appBar: AppBar(
|
||||
elevation: 0,
|
||||
backgroundColor: Colors.white,
|
||||
automaticallyImplyLeading: false,
|
||||
),
|
||||
/* 2024-04-03 Updated by Akira . See https://wiki.sumasen.net/issues/2796?issue_count=1&issue_position=1
|
||||
appBar: AppBar(
|
||||
elevation: 0,
|
||||
backgroundColor: Colors.white,
|
||||
@ -29,6 +35,7 @@ class LoginPage extends StatelessWidget {
|
||||
color: Colors.black,
|
||||
)),
|
||||
),
|
||||
*/
|
||||
body: indexController.currentUser.isEmpty
|
||||
? SizedBox(
|
||||
width: double.infinity,
|
||||
@ -88,7 +95,7 @@ class LoginPage extends StatelessWidget {
|
||||
MaterialButton(
|
||||
minWidth: double.infinity,
|
||||
height: 40,
|
||||
onPressed: () {
|
||||
onPressed: () async {
|
||||
if (emailController.text.isEmpty ||
|
||||
passwordController
|
||||
.text.isEmpty) {
|
||||
@ -104,7 +111,7 @@ class LoginPage extends StatelessWidget {
|
||||
snackPosition:
|
||||
SnackPosition.TOP,
|
||||
duration: const Duration(
|
||||
milliseconds: 800),
|
||||
seconds: 3),
|
||||
backgroundColor: Colors.yellow,
|
||||
//icon:Image(image:AssetImage("assets/images/dora.png"))
|
||||
);
|
||||
@ -116,6 +123,30 @@ class LoginPage extends StatelessWidget {
|
||||
emailController.text,
|
||||
passwordController.text,
|
||||
context);
|
||||
/*
|
||||
try {
|
||||
bool isLoggedIn = await indexController.login(emailController.text, passwordController.text,context);
|
||||
if (isLoggedIn) {
|
||||
Get.offAllNamed(AppPages.INDEX);
|
||||
} else {
|
||||
Get.snackbar(
|
||||
"Login Failed",
|
||||
"Invalid email or password",
|
||||
icon: const Icon(Icons.error, color: Colors.red),
|
||||
snackPosition: SnackPosition.BOTTOM,
|
||||
);
|
||||
}
|
||||
} catch (e) {
|
||||
Get.snackbar(
|
||||
"Error",
|
||||
"An error occurred during login",
|
||||
icon: const Icon(Icons.error, color: Colors.red),
|
||||
snackPosition: SnackPosition.BOTTOM,
|
||||
);
|
||||
} finally {
|
||||
indexController.isLoading.value = false;
|
||||
}
|
||||
*/ // ここまで
|
||||
},
|
||||
color: Colors.indigoAccent[400],
|
||||
shape: RoundedRectangleBorder(
|
||||
@ -128,6 +159,16 @@ class LoginPage extends StatelessWidget {
|
||||
fontSize: 16,
|
||||
color: Colors.white70),
|
||||
),
|
||||
/*
|
||||
child: Obx(
|
||||
() => indexController.isLoading.value
|
||||
? const CircularProgressIndicator(color: Colors.white)
|
||||
: const Text(
|
||||
"ログイン",
|
||||
style: TextStyle(fontWeight: FontWeight.w600, fontSize: 16, color: Colors.white70),
|
||||
),
|
||||
),
|
||||
*/ // ここまで
|
||||
),
|
||||
const SizedBox(
|
||||
height: 5.0,
|
||||
@ -209,7 +250,25 @@ class LoginPage extends StatelessWidget {
|
||||
),
|
||||
),
|
||||
],
|
||||
)
|
||||
),
|
||||
const Row(
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
children: [
|
||||
Flexible(
|
||||
child: Padding(
|
||||
padding: EdgeInsets.all(8.0),
|
||||
child: Text(
|
||||
"※第8回と第9回は、岐阜県からの「清流の国ぎふ」SDGs推進ネットワーク連携促進補助金を受けています",
|
||||
style: TextStyle(
|
||||
fontSize:
|
||||
12, // Consider adjusting the font size if the text is too small.
|
||||
// Removed overflow: TextOverflow.ellipsis to allow text wrapping.
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
],
|
||||
),
|
||||
],
|
||||
|
||||
@ -1,23 +1,21 @@
|
||||
import 'package:geojson/geojson.dart';
|
||||
import 'package:geojson_vi/geojson_vi.dart';
|
||||
import 'package:get/get.dart';
|
||||
import 'package:rogapp/pages/index/index_controller.dart';
|
||||
|
||||
class SearchBarController extends GetxController {
|
||||
List<GeoJSONFeature> searchResults = <GeoJSONFeature>[].obs;
|
||||
|
||||
List<GeoJsonFeature> searchResults = <GeoJsonFeature>[].obs;
|
||||
|
||||
|
||||
@override
|
||||
@override
|
||||
void onInit() {
|
||||
IndexController indexController = Get.find<IndexController>();
|
||||
if(indexController.locations.isNotEmpty){
|
||||
for(int i=0; i<= indexController.locations[0].collection.length - 1; i++){
|
||||
GeoJsonFeature p = indexController.locations[0].collection[i];
|
||||
if (indexController.locations.isNotEmpty) {
|
||||
for (int i = 0;
|
||||
i <= indexController.locations[0].features.length - 1;
|
||||
i++) {
|
||||
GeoJSONFeature p = indexController.locations[0].features[i]!;
|
||||
searchResults.add(p);
|
||||
}
|
||||
}
|
||||
super.onInit();
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_typeahead/flutter_typeahead.dart';
|
||||
import 'package:geojson/geojson.dart';
|
||||
import 'package:geojson_vi/geojson_vi.dart';
|
||||
import 'package:get/get.dart';
|
||||
import 'package:rogapp/model/destination.dart';
|
||||
import 'package:rogapp/pages/destination/destination_controller.dart';
|
||||
@ -48,46 +48,32 @@ class SearchPage extends StatelessWidget {
|
||||
//title: const CupertinoSearchTextField(),
|
||||
),
|
||||
body: SingleChildScrollView(
|
||||
child: TypeAheadField(
|
||||
textFieldConfiguration: TextFieldConfiguration(
|
||||
autofocus: true,
|
||||
style: DefaultTextStyle.of(context).style.copyWith(
|
||||
fontStyle: FontStyle.normal,
|
||||
fontSize: 15.0,
|
||||
),
|
||||
decoration: InputDecoration(
|
||||
border: const OutlineInputBorder(),
|
||||
hintText: "検索",
|
||||
prefixIcon: const Icon(Icons.search),
|
||||
suffixIcon: IconButton(
|
||||
icon: const Icon(Icons.clear),
|
||||
onPressed: () {
|
||||
// clear the text field
|
||||
},
|
||||
),
|
||||
),
|
||||
),
|
||||
suggestionsCallback: (pattern) async {
|
||||
return searchController.searchResults.where(
|
||||
(GeoJsonFeature element) => element.properties!["location_name"]
|
||||
.toString()
|
||||
.contains(pattern));
|
||||
//return await
|
||||
},
|
||||
itemBuilder: (context, GeoJsonFeature suggestion) {
|
||||
return ListTile(
|
||||
title: Text(suggestion.properties!["location_name"]),
|
||||
subtitle: suggestion.properties!["category"] != null
|
||||
? Text(suggestion.properties!["category"])
|
||||
: const Text(""),
|
||||
//leading: getImage(index),
|
||||
);
|
||||
},
|
||||
onSuggestionSelected: (GeoJsonFeature suggestion) {
|
||||
child: TypeAheadField<GeoJSONFeature>(
|
||||
// textFieldConfiguration: TextFieldConfiguration(
|
||||
// autofocus: true,
|
||||
// style: DefaultTextStyle.of(context).style.copyWith(
|
||||
// fontStyle: FontStyle.normal,
|
||||
// fontSize: 15.0,
|
||||
// ),
|
||||
// decoration: InputDecoration(
|
||||
// border: const OutlineInputBorder(),
|
||||
// hintText: "検索",
|
||||
// prefixIcon: const Icon(Icons.search),
|
||||
// suffixIcon: IconButton(
|
||||
// icon: const Icon(Icons.clear),
|
||||
// onPressed: () {
|
||||
// // clear the text field
|
||||
// },
|
||||
// ),
|
||||
// ),
|
||||
// ),
|
||||
onSelected: (GeoJSONFeature suggestion) {
|
||||
indexController.currentFeature.clear();
|
||||
indexController.currentFeature.add(suggestion);
|
||||
DestinationController destinationController = Get.find<DestinationController>();
|
||||
Destination des = destinationController.festuretoDestination(suggestion);
|
||||
DestinationController destinationController =
|
||||
Get.find<DestinationController>();
|
||||
Destination des =
|
||||
destinationController.festuretoDestination(suggestion);
|
||||
Get.back();
|
||||
showModalBottomSheet(
|
||||
constraints:
|
||||
@ -95,7 +81,28 @@ class SearchPage extends StatelessWidget {
|
||||
isScrollControlled: true,
|
||||
context: context,
|
||||
//builder: (context) => BottomSheetWidget(),
|
||||
builder: ((context) => BottomSheetNew(destination: des,)));
|
||||
builder: ((context) => BottomSheetNew(
|
||||
destination: des,
|
||||
)));
|
||||
},
|
||||
|
||||
suggestionsCallback: (pattern) async {
|
||||
return searchController.searchResults
|
||||
.where((GeoJSONFeature element) => element
|
||||
.properties!["location_name"]
|
||||
.toString()
|
||||
.contains(pattern))
|
||||
.toList();
|
||||
//return await
|
||||
},
|
||||
itemBuilder: (context, GeoJSONFeature suggestion) {
|
||||
return ListTile(
|
||||
title: Text(suggestion.properties!["location_name"]),
|
||||
subtitle: suggestion.properties!["category"] != null
|
||||
? Text(suggestion.properties!["category"])
|
||||
: const Text(""),
|
||||
//leading: getImage(index),
|
||||
);
|
||||
},
|
||||
),
|
||||
),
|
||||
|
||||
55
lib/services/DatabaseService.dart
Normal file
55
lib/services/DatabaseService.dart
Normal file
@ -0,0 +1,55 @@
|
||||
import 'dart:async';
|
||||
|
||||
import 'package:rogapp/model/destination.dart';
|
||||
import 'package:rogapp/utils/database_helper.dart';
|
||||
|
||||
class DatabaseService {
|
||||
// Private constructor
|
||||
DatabaseService._privateConstructor();
|
||||
|
||||
// Static instance
|
||||
static final DatabaseService _instance =
|
||||
DatabaseService._privateConstructor();
|
||||
|
||||
// Factory constructor to return the instance
|
||||
factory DatabaseService() {
|
||||
return _instance;
|
||||
}
|
||||
|
||||
// StreamController for updates
|
||||
final StreamController<List<Destination>> _dbUpdateController =
|
||||
StreamController<List<Destination>>.broadcast();
|
||||
|
||||
// Getter for the stream
|
||||
Stream<List<Destination>> get destinationUpdatesStream =>
|
||||
_dbUpdateController.stream;
|
||||
|
||||
// Method to fetch destinations
|
||||
Future<List<Destination>> fetchDestinations() async {
|
||||
// Your database fetch logic here
|
||||
List<Destination> destinations = await _fetchFromDb();
|
||||
_dbUpdateController.add(destinations);
|
||||
return destinations;
|
||||
}
|
||||
|
||||
// Method to update the database and emit an update through the stream
|
||||
Future<void> updateDatabase() async {
|
||||
// Your update logic here
|
||||
|
||||
// After updating, fetch the updated list and add it to the stream
|
||||
fetchDestinations();
|
||||
}
|
||||
|
||||
// Method to fetch data from the database (placeholder)
|
||||
Future<List<Destination>> _fetchFromDb() async {
|
||||
// Simulate fetching data with a delay
|
||||
DatabaseHelper db = DatabaseHelper.instance;
|
||||
List<Destination> destinations = await db.getDestinations();
|
||||
return destinations; // Replace with your actual fetch operation
|
||||
}
|
||||
|
||||
// Dispose method to close the stream controller
|
||||
void dispose() {
|
||||
_dbUpdateController.close();
|
||||
}
|
||||
}
|
||||
@ -202,13 +202,13 @@ class ExternalService {
|
||||
'image': ""
|
||||
}),
|
||||
);
|
||||
var vvv = jsonEncode(<String, String>{
|
||||
'team_name': teamname,
|
||||
'cp_number': cp.toString(),
|
||||
'event_code': eventcode,
|
||||
'image': res["checkinimage"].toString().replaceAll(
|
||||
'http://localhost:8100', 'http://rogaining.sumasen.net')
|
||||
});
|
||||
// var vvv = jsonEncode(<String, String>{
|
||||
// 'team_name': teamname,
|
||||
// 'cp_number': cp.toString(),
|
||||
// 'event_code': eventcode,
|
||||
// 'image': res["checkinimage"].toString().replaceAll(
|
||||
// 'http://localhost:8100', 'http://rogaining.sumasen.net')
|
||||
// });
|
||||
// print("--json-- $vvv");
|
||||
// print("--- checnin response ${response3.statusCode}----");
|
||||
if (response3.statusCode == 200) {
|
||||
@ -293,14 +293,14 @@ class ExternalService {
|
||||
.toString()
|
||||
.replaceAll('http://localhost:8100', 'http://rogaining.sumasen.net')
|
||||
});
|
||||
// print("-- json -- $rec");
|
||||
// print('----- response2 is $response2 --------');
|
||||
//print("-- json -- $rec");
|
||||
//print('----- response2 is $response2 --------');
|
||||
if (response2.statusCode == 200) {
|
||||
res2 = json.decode(utf8.decode(response2.bodyBytes));
|
||||
}
|
||||
}
|
||||
//}
|
||||
destinationController.resetRogaining();
|
||||
destinationController.resetRogaining(isgoal: true);
|
||||
return res2;
|
||||
}
|
||||
|
||||
|
||||
@ -1,32 +1,32 @@
|
||||
import 'package:geojson/geojson.dart';
|
||||
import 'package:http/http.dart' as http;
|
||||
// import 'package:geojson/geojson.dart';
|
||||
// import 'package:http/http.dart' as http;
|
||||
|
||||
import '../utils/const.dart';
|
||||
// import '../utils/const.dart';
|
||||
|
||||
class LocationLineService {
|
||||
static Future<GeoJsonFeature?> loadLocationLines() async {
|
||||
final geo = GeoJson();
|
||||
GeoJsonFeature? fs;
|
||||
String serverUrl = ConstValues.currentServer();
|
||||
String url = '$serverUrl/api/location_line/';
|
||||
//print('++++++++$url');
|
||||
final response = await http.get(
|
||||
Uri.parse(url),
|
||||
headers: <String, String>{
|
||||
'Content-Type': 'application/json; charset=UTF-8',
|
||||
},
|
||||
);
|
||||
// class LocationLineService {
|
||||
// static Future<GeoJsonFeature?> loadLocationLines() async {
|
||||
// final geo = GeoJson();
|
||||
// GeoJsonFeature? fs;
|
||||
// String serverUrl = ConstValues.currentServer();
|
||||
// String url = '$serverUrl/api/location_line/';
|
||||
// //print('++++++++$url');
|
||||
// final response = await http.get(
|
||||
// Uri.parse(url),
|
||||
// headers: <String, String>{
|
||||
// 'Content-Type': 'application/json; charset=UTF-8',
|
||||
// },
|
||||
// );
|
||||
|
||||
if (response.statusCode == 200) {
|
||||
geo.processedFeatures.listen((fst) {
|
||||
fs = fst;
|
||||
});
|
||||
// if (response.statusCode == 200) {
|
||||
// geo.processedFeatures.listen((fst) {
|
||||
// fs = fst;
|
||||
// });
|
||||
|
||||
await geo.parse(response.body, verbose: true);
|
||||
// await geo.parse(response.body, verbose: true);
|
||||
|
||||
return fs;
|
||||
} else {
|
||||
throw Exception('Failed to create album.');
|
||||
}
|
||||
}
|
||||
}
|
||||
// return fs;
|
||||
// } else {
|
||||
// throw Exception('Failed to create album.');
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
|
||||
@ -1,33 +1,33 @@
|
||||
import 'package:geojson/geojson.dart';
|
||||
import 'package:http/http.dart' as http;
|
||||
// import 'package:geojson/geojson.dart';
|
||||
// import 'package:http/http.dart' as http;
|
||||
|
||||
import '../utils/const.dart';
|
||||
// import '../utils/const.dart';
|
||||
|
||||
class LocationPolygonervice {
|
||||
static Future<GeoJsonFeature?> loadLocationLines() async {
|
||||
final geo = GeoJson();
|
||||
GeoJsonFeature? fs;
|
||||
// class LocationPolygonervice {
|
||||
// static Future<GeoJsonFeature?> loadLocationLines() async {
|
||||
// final geo = GeoJson();
|
||||
// GeoJsonFeature? fs;
|
||||
|
||||
String serverUrl = ConstValues.currentServer();
|
||||
String url = '$serverUrl/api/location_polygon/';
|
||||
//print('++++++++$url');
|
||||
final response = await http.get(
|
||||
Uri.parse(url),
|
||||
headers: <String, String>{
|
||||
'Content-Type': 'application/json; charset=UTF-8',
|
||||
},
|
||||
);
|
||||
// String serverUrl = ConstValues.currentServer();
|
||||
// String url = '$serverUrl/api/location_polygon/';
|
||||
// //print('++++++++$url');
|
||||
// final response = await http.get(
|
||||
// Uri.parse(url),
|
||||
// headers: <String, String>{
|
||||
// 'Content-Type': 'application/json; charset=UTF-8',
|
||||
// },
|
||||
// );
|
||||
|
||||
if (response.statusCode == 200) {
|
||||
geo.processedFeatures.listen((fst) {
|
||||
fs = fst;
|
||||
});
|
||||
// if (response.statusCode == 200) {
|
||||
// geo.processedFeatures.listen((fst) {
|
||||
// fs = fst;
|
||||
// });
|
||||
|
||||
await geo.parse(response.body, verbose: true);
|
||||
// await geo.parse(response.body, verbose: true);
|
||||
|
||||
return fs;
|
||||
} else {
|
||||
throw Exception('Failed to create album.');
|
||||
}
|
||||
}
|
||||
}
|
||||
// return fs;
|
||||
// } else {
|
||||
// throw Exception('Failed to create album.');
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
|
||||
@ -1,39 +1,13 @@
|
||||
import 'dart:convert';
|
||||
|
||||
import 'package:geojson/geojson.dart';
|
||||
import 'package:geojson_vi/geojson_vi.dart';
|
||||
import 'package:get/get.dart';
|
||||
import 'package:http/http.dart' as http;
|
||||
import 'package:rogapp/pages/destination/destination_controller.dart';
|
||||
import 'package:rogapp/pages/index/index_controller.dart';
|
||||
import 'package:rogapp/utils/const.dart';
|
||||
|
||||
class LocationService {
|
||||
// static Future<GeoJsonFeatureCollection?> loadLocations() async {
|
||||
|
||||
// final IndexController indexController = Get.find<IndexController>();
|
||||
|
||||
// String server_url = ConstValues.currentServer();
|
||||
// String url = "";
|
||||
// if(indexController.currentUser.length > 0){
|
||||
// url = '${server_url}/api/location/?is_rog=True';
|
||||
// }
|
||||
// else {
|
||||
// url = '${server_url}/api/location/';
|
||||
// }
|
||||
// //String url = 'http://localhost:8100/api/location/';
|
||||
// final response = await http.get(Uri.parse(url),
|
||||
// headers: <String, String>{
|
||||
// 'Content-Type': 'application/json; charset=UTF-8',
|
||||
// },
|
||||
// );
|
||||
|
||||
// if (response.statusCode == 200) {
|
||||
|
||||
// return featuresFromGeoJson(utf8.decode(response.bodyBytes));
|
||||
// }
|
||||
// return null;
|
||||
// }
|
||||
|
||||
static Future<GeoJsonFeatureCollection?> loadLocationsFor(
|
||||
static Future<GeoJSONFeatureCollection?> loadLocationsFor(
|
||||
String perfecture, String cat) async {
|
||||
final IndexController indexController = Get.find<IndexController>();
|
||||
String url = "";
|
||||
@ -67,8 +41,8 @@ class LocationService {
|
||||
);
|
||||
|
||||
if (response.statusCode == 200) {
|
||||
GeoJsonFeatureCollection cc =
|
||||
await featuresFromGeoJson(utf8.decode(response.bodyBytes));
|
||||
GeoJSONFeatureCollection cc =
|
||||
GeoJSONFeatureCollection.fromJSON(utf8.decode(response.bodyBytes));
|
||||
//print(cc);
|
||||
return cc; //featuresFromGeoJson(utf8.decode(response.bodyBytes));
|
||||
}
|
||||
@ -95,48 +69,7 @@ class LocationService {
|
||||
return ext;
|
||||
}
|
||||
|
||||
static Future<GeoJsonFeatureCollection?> loadLocationsSubFor(
|
||||
String subperfecture, String cat) async {
|
||||
final IndexController indexController = Get.find<IndexController>();
|
||||
String url = "";
|
||||
String serverUrl = ConstValues.currentServer();
|
||||
if (cat.isNotEmpty) {
|
||||
if (indexController.currentUser.isNotEmpty) {
|
||||
bool rog = indexController.currentUser[0]['user']['is_rogaining'];
|
||||
String r = rog == true ? 'True' : 'False';
|
||||
var grp = indexController.currentUser[0]['user']['event_code'];
|
||||
url = '$serverUrl/api/insubperf?rog=$r&subperf=$subperfecture&cat=$cat';
|
||||
} else {
|
||||
url = '$serverUrl/api/insubperf?subperf=$subperfecture&cat=$cat';
|
||||
}
|
||||
} else {
|
||||
if (indexController.currentUser.isNotEmpty) {
|
||||
bool rog = indexController.currentUser[0]['user']['is_rogaining'];
|
||||
String r = rog == true ? 'True' : 'False';
|
||||
var grp = indexController.currentUser[0]['user']['event_code'];
|
||||
url = '$serverUrl/api/insubperf?rog=$r&subperf=$subperfecture';
|
||||
} else {
|
||||
url = '$serverUrl/api/insubperf?subperf=$subperfecture';
|
||||
}
|
||||
}
|
||||
//print('++++++++$url');
|
||||
final response = await http.get(
|
||||
Uri.parse(url),
|
||||
headers: <String, String>{
|
||||
'Content-Type': 'application/json; charset=UTF-8',
|
||||
},
|
||||
);
|
||||
|
||||
if (response.statusCode == 200) {
|
||||
GeoJsonFeatureCollection cc =
|
||||
await featuresFromGeoJson(utf8.decode(response.bodyBytes));
|
||||
//print(cc);
|
||||
return cc; //featuresFromGeoJson(utf8.decode(response.bodyBytes));
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
static Future<GeoJsonFeatureCollection?> loadLocationsBound(
|
||||
static Future<GeoJSONFeatureCollection?> loadLocationsBound(
|
||||
double lat1,
|
||||
double lon1,
|
||||
double lat2,
|
||||
@ -183,13 +116,15 @@ class LocationService {
|
||||
);
|
||||
|
||||
if (response.statusCode == 500) {
|
||||
return GeoJsonFeatureCollection(); //featuresFromGeoJson(utf8.decode(response.bodyBytes));
|
||||
return null; //featuresFromGeoJson(utf8.decode(response.bodyBytes));
|
||||
}
|
||||
|
||||
if (response.statusCode == 200) {
|
||||
GeoJsonFeatureCollection cc =
|
||||
await featuresFromGeoJson(utf8.decode(response.bodyBytes));
|
||||
if (cc.collection.isEmpty) {
|
||||
DestinationController destinationController =
|
||||
Get.find<DestinationController>();
|
||||
GeoJSONFeatureCollection cc =
|
||||
GeoJSONFeatureCollection.fromJSON(utf8.decode(response.bodyBytes));
|
||||
if (cc.features.isEmpty) {
|
||||
return null;
|
||||
} else {
|
||||
//print("---- feature got from server is ${cc.collection[0].properties} ------");
|
||||
@ -199,7 +134,7 @@ class LocationService {
|
||||
return null;
|
||||
}
|
||||
|
||||
static Future<GeoJsonFeatureCollection?> loadCustomLocations(
|
||||
static Future<GeoJSONFeatureCollection?> loadCustomLocations(
|
||||
String name, String cat) async {
|
||||
final IndexController indexController = Get.find<IndexController>();
|
||||
String url = "";
|
||||
@ -236,13 +171,13 @@ class LocationService {
|
||||
);
|
||||
|
||||
if (response.statusCode == 500) {
|
||||
return GeoJsonFeatureCollection(); //featuresFromGeoJson(utf8.decode(response.bodyBytes));
|
||||
return null; //featuresFromGeoJson(utf8.decode(response.bodyBytes));
|
||||
}
|
||||
|
||||
if (response.statusCode == 200) {
|
||||
GeoJsonFeatureCollection cc =
|
||||
await featuresFromGeoJson(utf8.decode(response.bodyBytes));
|
||||
if (cc.collection.isEmpty) {
|
||||
GeoJSONFeatureCollection cc =
|
||||
GeoJSONFeatureCollection.fromJSON(utf8.decode(response.bodyBytes));
|
||||
if (cc.features.isEmpty) {
|
||||
return null;
|
||||
} else {
|
||||
return cc;
|
||||
|
||||
@ -51,7 +51,7 @@ class MatrixService {
|
||||
|
||||
Map<String, dynamic> cats = {};
|
||||
String url =
|
||||
"https://maps.googleapis.com/maps/api/directions/json?destination=$destination&mode=$mode&waypoints=$locs&origin=$origin&key=AIzaSyAUBI1ablMKuJwGj2-kSuEhvYxvB1A-mOE";
|
||||
"https://maps.googleapis.com/maps/api/directions/json?destination=$destination&mode=$mode&waypoints=$locs&origin=$origin&key=AIzaSyCN2xFsqFyadWwpjiFxymrxzS6G1tNzraI";
|
||||
//print('++++++++$url');
|
||||
final http.Response response =
|
||||
await http.get(Uri.parse(url), headers: <String, String>{
|
||||
|
||||
@ -44,20 +44,26 @@ class GpsDatabaseHelper {
|
||||
}
|
||||
|
||||
Future<int> insertGps(GpsData gps) async {
|
||||
Database db = await instance.database;
|
||||
int? nextOrder =
|
||||
Sqflite.firstIntValue(await db.rawQuery('SELECT MAX(id) FROM gps'));
|
||||
nextOrder = nextOrder ?? 0;
|
||||
nextOrder = nextOrder + 1;
|
||||
gps.id = nextOrder;
|
||||
//print("---- insering ${gps.toMap()}");
|
||||
int res = await db.insert(
|
||||
'gps',
|
||||
gps.toMap(),
|
||||
conflictAlgorithm: ConflictAlgorithm.replace,
|
||||
);
|
||||
//print("------ database helper insert $res-----------::::::::");
|
||||
return res;
|
||||
try {
|
||||
print("---- try insering ${gps.toMap()}");
|
||||
Database db = await instance.database;
|
||||
int? nextOrder =
|
||||
Sqflite.firstIntValue(await db.rawQuery('SELECT MAX(id) FROM gps'));
|
||||
nextOrder = nextOrder ?? 0;
|
||||
nextOrder = nextOrder + 1;
|
||||
gps.id = nextOrder;
|
||||
print("---- insering ${gps.toMap()}");
|
||||
int res = await db.insert(
|
||||
'gps',
|
||||
gps.toMap(),
|
||||
conflictAlgorithm: ConflictAlgorithm.replace,
|
||||
);
|
||||
print("------ database helper insert $res-----------::::::::");
|
||||
return res;
|
||||
} catch (err) {
|
||||
print("------ error $err-----------::::::::");
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
Future<List<GpsData>> getGPSData(String team_name, String event_code) async {
|
||||
|
||||
162
lib/utils/location_controller.dart
Normal file
162
lib/utils/location_controller.dart
Normal file
@ -0,0 +1,162 @@
|
||||
import 'dart:async';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:get/get.dart';
|
||||
import 'package:geolocator/geolocator.dart';
|
||||
import 'package:rogapp/widgets/debug_widget.dart';
|
||||
import 'package:flutter_map_location_marker/flutter_map_location_marker.dart';
|
||||
|
||||
class LocationController extends GetxController {
|
||||
// Reactive variable to hold the current position
|
||||
Rx<Position?> currentPosition = Rx<Position?>(null);
|
||||
|
||||
// Subscription to the position stream
|
||||
StreamSubscription<Position>? positionStream;
|
||||
|
||||
final locationMarkerPositionStreamController =
|
||||
StreamController<LocationMarkerPosition?>.broadcast();
|
||||
|
||||
bool isStreamPaused = false;
|
||||
|
||||
Stream<LocationMarkerPosition?> get locationMarkerPositionStream =>
|
||||
locationMarkerPositionStreamController.stream;
|
||||
|
||||
@override
|
||||
void onInit() {
|
||||
super.onInit();
|
||||
// Start listening to location updates when the controller is initialized
|
||||
startPositionStream();
|
||||
}
|
||||
|
||||
void startPositionStream() async {
|
||||
// Check for location service and permissions before starting the stream
|
||||
bool serviceEnabled = await Geolocator.isLocationServiceEnabled();
|
||||
if (!serviceEnabled) {
|
||||
// Use GetX's context to show a dialog
|
||||
Get.dialog(
|
||||
AlertDialog(
|
||||
title: const Text('Location Services Disabled'),
|
||||
content: const Text(
|
||||
'Please enable location services to continue using the app.'),
|
||||
actions: <Widget>[
|
||||
TextButton(
|
||||
child: const Text('OK'),
|
||||
onPressed: () {
|
||||
// Close the dialog
|
||||
Get.back();
|
||||
// Optionally, you can direct the user to the settings page
|
||||
// Geolocator.openLocationSettings();
|
||||
},
|
||||
),
|
||||
],
|
||||
),
|
||||
barrierDismissible: false, // User must tap button to close dialog
|
||||
);
|
||||
return;
|
||||
}
|
||||
|
||||
LocationPermission permission = await Geolocator.checkPermission();
|
||||
if (permission == LocationPermission.denied) {
|
||||
permission = await Geolocator.requestPermission();
|
||||
if (permission == LocationPermission.denied) {
|
||||
// Show a dialog if permissions are still denied
|
||||
Get.dialog(
|
||||
AlertDialog(
|
||||
title: const Text('Location Permission Denied'),
|
||||
content: const Text(
|
||||
'This app requires location permissions to function properly. Please enable location permissions in your device settings.'),
|
||||
actions: <Widget>[
|
||||
TextButton(
|
||||
child: const Text('OK'),
|
||||
onPressed: () {
|
||||
// Close the dialog
|
||||
Get.back();
|
||||
// Optionally, direct the user to the app settings
|
||||
// Geolocator.openAppSettings();
|
||||
},
|
||||
),
|
||||
],
|
||||
),
|
||||
barrierDismissible: false,
|
||||
);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (permission == LocationPermission.deniedForever) {
|
||||
// Show a dialog if permissions are permanently denied
|
||||
Get.dialog(
|
||||
AlertDialog(
|
||||
title: const Text('Location Permission Needed'),
|
||||
content: const Text(
|
||||
'Location permissions have been permanently denied. Please open app settings to enable location permissions.'),
|
||||
actions: <Widget>[
|
||||
TextButton(
|
||||
child: const Text('Open Settings'),
|
||||
onPressed: () {
|
||||
// Close the dialog and open app settings
|
||||
Get.back();
|
||||
Geolocator.openAppSettings();
|
||||
},
|
||||
),
|
||||
],
|
||||
),
|
||||
barrierDismissible: false,
|
||||
);
|
||||
return;
|
||||
}
|
||||
|
||||
// Set up the location options
|
||||
const locationOptions =
|
||||
LocationSettings(accuracy: LocationAccuracy.high, distanceFilter: 0);
|
||||
|
||||
await positionStream?.cancel();
|
||||
|
||||
positionStream =
|
||||
Geolocator.getPositionStream(locationSettings: locationOptions).listen(
|
||||
(Position? position) {
|
||||
if (position != null) {
|
||||
final LocationMarkerPosition locationMarkerPosition =
|
||||
LocationMarkerPosition(
|
||||
latitude: position.latitude,
|
||||
longitude: position.longitude,
|
||||
accuracy: position.accuracy);
|
||||
locationMarkerPositionStreamController.add(locationMarkerPosition);
|
||||
} else {
|
||||
locationMarkerPositionStreamController.add(null);
|
||||
}
|
||||
},
|
||||
onError: (e) {
|
||||
locationMarkerPositionStreamController.addError(e);
|
||||
},
|
||||
);
|
||||
|
||||
// Resume stream if it was paused previously
|
||||
if (isStreamPaused) {
|
||||
isStreamPaused = false;
|
||||
positionStream!.resume();
|
||||
}
|
||||
}
|
||||
|
||||
// Method to stop the position stream
|
||||
void stopPositionStream() {
|
||||
if (positionStream != null) {
|
||||
positionStream!.pause();
|
||||
isStreamPaused = true;
|
||||
}
|
||||
}
|
||||
|
||||
// Method to resume the position stream
|
||||
void resumePositionStream() {
|
||||
if (positionStream != null && isStreamPaused) {
|
||||
positionStream!.resume();
|
||||
isStreamPaused = false;
|
||||
}
|
||||
}
|
||||
|
||||
@override
|
||||
void onClose() {
|
||||
// Cancel the position stream subscription when the controller is closed
|
||||
positionStream?.cancel();
|
||||
super.onClose();
|
||||
}
|
||||
}
|
||||
@ -129,7 +129,7 @@ class StringValues extends Translations{
|
||||
'finishing_rogaining' : 'ロゲイニングを終えて',
|
||||
'cp_pls_take_photo' : "CPです。撮影してください。",
|
||||
'take_photo of the clock' : '時計の写真を撮る',
|
||||
'finish_goal': 'フィニッシュゴール',
|
||||
'finish_goal': 'ゴール完了',
|
||||
'goal_saved': "目標を保存しました",
|
||||
'goal_added_successfuly' : '目標が正常に追加されました',
|
||||
'goal_not_added' : '目標が追加されていません',
|
||||
|
||||
@ -1,8 +1,8 @@
|
||||
import 'package:geojson/geojson.dart';
|
||||
import 'package:geojson_vi/geojson_vi.dart';
|
||||
import 'package:rogapp/model/destination.dart';
|
||||
|
||||
class TextUtils {
|
||||
static String getDisplayTextFeture(GeoJsonFeature f) {
|
||||
static String getDisplayTextFeture(GeoJSONFeature f) {
|
||||
RegExp regex = RegExp(r'([.]*0)(?!.*\d)');
|
||||
String txt = "";
|
||||
// if(f.properties!["cp"] > 0){
|
||||
|
||||
57
lib/widgets/GameState/CheckinState.dart
Normal file
57
lib/widgets/GameState/CheckinState.dart
Normal file
@ -0,0 +1,57 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:rogapp/widgets/GameState/Colors.dart';
|
||||
|
||||
class LocationVisitedWidget extends StatelessWidget {
|
||||
final int count;
|
||||
final bool minimized;
|
||||
|
||||
const LocationVisitedWidget(
|
||||
{Key? key, required this.count, this.minimized = false})
|
||||
: super(key: key);
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
if (minimized) {
|
||||
return Container(
|
||||
height: 40,
|
||||
width: 40,
|
||||
decoration: BoxDecoration(
|
||||
color: JapaneseColors.mizu,
|
||||
shape: BoxShape.circle,
|
||||
),
|
||||
child: Center(
|
||||
child: Text(
|
||||
'$count',
|
||||
style: TextStyle(
|
||||
color: Colors.white,
|
||||
fontWeight: FontWeight.bold,
|
||||
fontSize: 14,
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
} else {
|
||||
return Container(
|
||||
padding: EdgeInsets.symmetric(vertical: 8, horizontal: 8),
|
||||
decoration: BoxDecoration(
|
||||
color: JapaneseColors.matcha,
|
||||
borderRadius: BorderRadius.circular(10),
|
||||
),
|
||||
child: Row(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: [
|
||||
Icon(Icons.check_circle_outline, color: Colors.white, size: 24),
|
||||
SizedBox(width: 8),
|
||||
Text(
|
||||
'$count チェックイン', // "X Check-ins" in Japanese
|
||||
style: TextStyle(
|
||||
color: Colors.white,
|
||||
fontWeight: FontWeight.bold,
|
||||
fontSize: 16),
|
||||
),
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
12
lib/widgets/GameState/Colors.dart
Normal file
12
lib/widgets/GameState/Colors.dart
Normal file
@ -0,0 +1,12 @@
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
class JapaneseColors {
|
||||
static const Color mizu = Color(0xFFA4DDED); // Mizu (light blue)
|
||||
static const Color matcha = Color(0xFFC5E1A5);
|
||||
static const Color ume = Color(0xFFE1A8A8); // Ume (plum)
|
||||
static const Color take = Color(0xFF7B8D42); // Take (bamboo)
|
||||
static const Color sora = Color(0xFFA1CAF1);
|
||||
static const Color indigo = Color(0xFF264653); // Aizome
|
||||
static const Color sakuraPink = Color(0xFFFAD2E1); // Sakura-iro
|
||||
/// Matcha (green tea)
|
||||
}
|
||||
72
lib/widgets/GameState/ConnectionStatus.dart
Normal file
72
lib/widgets/GameState/ConnectionStatus.dart
Normal file
@ -0,0 +1,72 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:rogapp/widgets/GameState/Colors.dart';
|
||||
|
||||
enum ConnectionStatus { none, mobile, wifi }
|
||||
|
||||
class ConnectionStatusIndicator extends StatelessWidget {
|
||||
final ConnectionStatus connectionStatus;
|
||||
final bool minimized;
|
||||
|
||||
const ConnectionStatusIndicator({
|
||||
Key? key,
|
||||
required this.connectionStatus,
|
||||
this.minimized = false,
|
||||
}) : super(key: key);
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
Color backgroundColor;
|
||||
IconData iconData;
|
||||
String text;
|
||||
|
||||
switch (connectionStatus) {
|
||||
case ConnectionStatus.none:
|
||||
backgroundColor = JapaneseColors.ume;
|
||||
iconData = Icons.signal_cellular_off;
|
||||
text = 'No Connection';
|
||||
break;
|
||||
case ConnectionStatus.mobile:
|
||||
backgroundColor = JapaneseColors.take;
|
||||
iconData = Icons.signal_cellular_alt;
|
||||
text = 'Mobile Data';
|
||||
break;
|
||||
case ConnectionStatus.wifi:
|
||||
backgroundColor = JapaneseColors.sora;
|
||||
iconData = Icons.wifi;
|
||||
text = 'Wi-Fi';
|
||||
break;
|
||||
default:
|
||||
backgroundColor = Colors.grey; // Fallback color
|
||||
iconData = Icons.device_unknown;
|
||||
text = 'Unknown';
|
||||
}
|
||||
|
||||
return Container(
|
||||
height: minimized ? 40 : null,
|
||||
width: minimized ? 40 : null,
|
||||
padding:
|
||||
minimized ? null : EdgeInsets.symmetric(vertical: 8, horizontal: 16),
|
||||
decoration: BoxDecoration(
|
||||
color: backgroundColor,
|
||||
shape: minimized ? BoxShape.circle : BoxShape.rectangle,
|
||||
borderRadius: minimized ? null : BorderRadius.circular(10),
|
||||
),
|
||||
child: minimized
|
||||
? Center(
|
||||
child: Icon(iconData, color: Colors.white, size: 24),
|
||||
)
|
||||
: Row(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: [
|
||||
Icon(iconData, color: Colors.white),
|
||||
SizedBox(width: 8),
|
||||
Text(
|
||||
text,
|
||||
style: TextStyle(
|
||||
color: Colors.white, fontWeight: FontWeight.bold),
|
||||
),
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
51
lib/widgets/GameState/DashboardWidget.dart
Normal file
51
lib/widgets/GameState/DashboardWidget.dart
Normal file
@ -0,0 +1,51 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:rogapp/widgets/GameState/CheckinState.dart';
|
||||
import 'package:rogapp/widgets/GameState/game_on_off.dart';
|
||||
|
||||
class DashboardWidget extends StatelessWidget {
|
||||
final bool gameStarted;
|
||||
final int locationsVisited;
|
||||
final bool isMinimized;
|
||||
|
||||
const DashboardWidget({
|
||||
Key? key,
|
||||
required this.gameStarted,
|
||||
required this.locationsVisited,
|
||||
this.isMinimized = false,
|
||||
}) : super(key: key);
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
List<Widget> widgets = [
|
||||
GameStatusIndicator(gameStarted: gameStarted, minimized: isMinimized),
|
||||
SizedBox(
|
||||
height: isMinimized ? 0 : 8, width: isMinimized ? 8 : 0), // Spacing
|
||||
LocationVisitedWidget(count: locationsVisited, minimized: isMinimized),
|
||||
];
|
||||
|
||||
return Container(
|
||||
padding: EdgeInsets.all(isMinimized ? 8 : 16),
|
||||
decoration: BoxDecoration(
|
||||
color: Colors.white,
|
||||
boxShadow: [
|
||||
BoxShadow(
|
||||
color: Colors.grey.withOpacity(0.5),
|
||||
spreadRadius: 5,
|
||||
blurRadius: 7,
|
||||
offset: Offset(0, 3),
|
||||
),
|
||||
],
|
||||
borderRadius: BorderRadius.circular(10),
|
||||
),
|
||||
child: isMinimized
|
||||
? Row(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: widgets,
|
||||
)
|
||||
: Column(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: widgets,
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
55
lib/widgets/GameState/game_on_off.dart
Normal file
55
lib/widgets/GameState/game_on_off.dart
Normal file
@ -0,0 +1,55 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:rogapp/widgets/GameState/Colors.dart';
|
||||
|
||||
class GameStatusIndicator extends StatelessWidget {
|
||||
final bool gameStarted;
|
||||
final bool minimized;
|
||||
|
||||
const GameStatusIndicator(
|
||||
{Key? key, required this.gameStarted, this.minimized = true})
|
||||
: super(key: key);
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
// Icons to show based on the game status
|
||||
IconData iconData =
|
||||
gameStarted ? Icons.stop_circle : Icons.play_circle_filled;
|
||||
// Text to show based on the game status
|
||||
String text = gameStarted ? 'ゲーム開始' : 'ゲーム未開始';
|
||||
|
||||
// Layout for minimized view
|
||||
if (minimized) {
|
||||
return Container(
|
||||
height: 40, // Square size
|
||||
width: 40, // Square size
|
||||
decoration: BoxDecoration(
|
||||
color:
|
||||
gameStarted ? JapaneseColors.indigo : JapaneseColors.sakuraPink,
|
||||
shape: BoxShape
|
||||
.circle, // Making it circle when minimized for a more distinct look
|
||||
),
|
||||
child: Icon(iconData, color: Colors.white),
|
||||
);
|
||||
}
|
||||
|
||||
// Layout for expanded view
|
||||
return Container(
|
||||
padding: EdgeInsets.all(12),
|
||||
decoration: BoxDecoration(
|
||||
color: gameStarted ? JapaneseColors.indigo : JapaneseColors.sakuraPink,
|
||||
borderRadius: BorderRadius.circular(10),
|
||||
),
|
||||
child: Row(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: [
|
||||
Icon(iconData, color: Colors.white),
|
||||
SizedBox(width: 8),
|
||||
Text(
|
||||
text,
|
||||
style: TextStyle(color: Colors.white, fontWeight: FontWeight.bold),
|
||||
),
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
@ -8,17 +8,14 @@ class BaseLayer extends StatelessWidget {
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return TileLayer(
|
||||
urlTemplate: "https://cyberjapandata.gsi.go.jp/xyz/std/{z}/{x}/{y}.png",
|
||||
tileProvider: FMTC.instance('OpenStreetMap (A)').getTileProvider(
|
||||
FMTCTileProviderSettings(
|
||||
behavior: CacheBehavior.values
|
||||
.byName('cacheFirst'),
|
||||
cachedValidDuration: const Duration(
|
||||
days: 14
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
urlTemplate: "https://cyberjapandata.gsi.go.jp/xyz/std/{z}/{x}/{y}.png",
|
||||
tileProvider: FMTC.instance('OpenStreetMap (A)').getTileProvider(
|
||||
settings: FMTCTileProviderSettings(
|
||||
behavior: CacheBehavior.values.byName('cacheFirst'),
|
||||
cachedValidDuration: const Duration(days: 14),
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -1,11 +1,8 @@
|
||||
|
||||
|
||||
import 'package:geojson/geojson.dart';
|
||||
import 'package:geojson_vi/geojson_vi.dart';
|
||||
import 'package:get/get_state_manager/get_state_manager.dart';
|
||||
|
||||
class BottomSheetController extends GetxController{
|
||||
|
||||
List<GeoJsonFeature>? currentFeature = <GeoJsonFeature>[];
|
||||
class BottomSheetController extends GetxController {
|
||||
List<GeoJSONFeature>? currentFeature = <GeoJSONFeature>[];
|
||||
|
||||
BottomSheetController({this.currentFeature});
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,7 +1,6 @@
|
||||
import 'dart:ffi';
|
||||
import 'dart:ui' as ui;
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:geojson/geojson.dart';
|
||||
import 'package:geojson_vi/geojson_vi.dart';
|
||||
import 'package:geolocator/geolocator.dart';
|
||||
import 'package:get/get.dart';
|
||||
import 'package:image_picker/image_picker.dart';
|
||||
@ -11,14 +10,12 @@ 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/routes/app_pages.dart';
|
||||
import 'package:rogapp/services/external_service.dart';
|
||||
import 'package:rogapp/utils/const.dart';
|
||||
import 'package:rogapp/utils/database_helper.dart';
|
||||
import 'package:rogapp/utils/text_util.dart';
|
||||
import 'package:rogapp/widgets/bottom_sheet_controller.dart';
|
||||
import 'package:rogapp/widgets/debug_widget.dart';
|
||||
import 'package:sqflite/sqflite.dart';
|
||||
import 'package:url_launcher/url_launcher.dart';
|
||||
|
||||
class BottomSheetNew extends GetView<BottomSheetController> {
|
||||
@ -34,8 +31,8 @@ class BottomSheetNew extends GetView<BottomSheetController> {
|
||||
|
||||
Image getImage() {
|
||||
String serverUrl = ConstValues.currentServer();
|
||||
|
||||
if (indexController.rogMode == 1) {
|
||||
//print("----- rogaining mode 1");
|
||||
if (indexController.currentDestinationFeature.isEmpty ||
|
||||
indexController.currentDestinationFeature[0].photos! == "") {
|
||||
return const Image(image: AssetImage('assets/images/empty_image.png'));
|
||||
@ -65,8 +62,8 @@ class BottomSheetNew extends GetView<BottomSheetController> {
|
||||
}
|
||||
}
|
||||
} else {
|
||||
GeoJsonFeature<dynamic> gf = indexController.currentFeature[0];
|
||||
//print("=== photo sss ${gf.properties!["photos"]}");
|
||||
GeoJSONFeature gf = indexController.currentFeature[0];
|
||||
print("=== photo sss ${gf.properties!["photos"]}");
|
||||
if (gf.properties!["photos"] == null || gf.properties!["photos"] == "") {
|
||||
return const Image(image: AssetImage('assets/images/empty_image.png'));
|
||||
} else {
|
||||
@ -113,8 +110,140 @@ class BottomSheetNew extends GetView<BottomSheetController> {
|
||||
}
|
||||
}
|
||||
|
||||
Widget getActionButton(BuildContext context, Destination destination) {
|
||||
assert(() {
|
||||
print("getActionButton ${destinationController.rogainingCounted.value}");
|
||||
print("getActionButton ${destinationController.distanceToStart()}");
|
||||
print("getActionButton ${destination.cp}");
|
||||
print("getActionButton ${DestinationController.ready_for_goal}");
|
||||
return true;
|
||||
}());
|
||||
// ...2024-04-03 Akira デバッグモードのみ出力するようにした。
|
||||
|
||||
Destination cdest = destinationController
|
||||
.festuretoDestination(indexController.currentFeature[0]);
|
||||
var distance = const Distance();
|
||||
double distanceToDest = distance.as(
|
||||
LengthUnit.Meter,
|
||||
LatLng(
|
||||
destinationController.currentLat, destinationController.currentLon),
|
||||
LatLng(cdest.lat!, cdest.lon!));
|
||||
|
||||
if (destinationController.rogainingCounted.value == true &&
|
||||
destinationController.distanceToStart() <= 500 &&
|
||||
destination.cp == -1 &&
|
||||
DestinationController.ready_for_goal == true) {
|
||||
//goal
|
||||
return ElevatedButton(
|
||||
style: ElevatedButton.styleFrom(backgroundColor: Colors.red),
|
||||
onPressed: destinationController.rogainingCounted.value == true &&
|
||||
destinationController.distanceToStart() <= 500 &&
|
||||
destination.cp == -1 &&
|
||||
DestinationController.ready_for_goal == true
|
||||
? () async {
|
||||
destinationController.isAtGoal.value = true;
|
||||
destinationController.photos.clear();
|
||||
await showModalBottomSheet(
|
||||
constraints: BoxConstraints.loose(
|
||||
ui.Size(Get.width, Get.height * 0.75)),
|
||||
context: Get.context!,
|
||||
isScrollControlled: true,
|
||||
builder: ((context) => CameraPage(
|
||||
destination: destination,
|
||||
))).whenComplete(() {
|
||||
destinationController.skipGps = false;
|
||||
destinationController.chekcs = 0;
|
||||
destinationController.isAtGoal.value = false;
|
||||
});
|
||||
}
|
||||
: null,
|
||||
child: const Text(
|
||||
"ロゲイニングを終える",
|
||||
style: TextStyle(color: Colors.white),
|
||||
));
|
||||
} else if (distanceToDest <=
|
||||
destinationController.getForcedChckinDistance(destination)) {
|
||||
//start
|
||||
return ElevatedButton(
|
||||
style: ElevatedButton.styleFrom(
|
||||
backgroundColor: Theme.of(context).colorScheme.secondary,
|
||||
),
|
||||
onPressed: () async {
|
||||
// Check conditions to show confirmation dialog
|
||||
if (destinationController.isInRog.value == false &&
|
||||
destination.cp == -1 &&
|
||||
destinationController.rogainingCounted.value == false) {
|
||||
print("counted ${destinationController.rogainingCounted.value}");
|
||||
|
||||
// Show confirmation dialog
|
||||
Get.dialog(
|
||||
AlertDialog(
|
||||
title: const Text("確認"), //confirm
|
||||
content: const Text(
|
||||
"ロゲを開始すると、今までのロゲデータが全てクリアされます。本当に開始しますか?"), //are you sure
|
||||
actions: <Widget>[
|
||||
TextButton(
|
||||
child: const Text("いいえ"), //no
|
||||
onPressed: () {
|
||||
Get.back(); // Close the dialog
|
||||
},
|
||||
),
|
||||
TextButton(
|
||||
child: const Text("はい"), //yes
|
||||
onPressed: () async {
|
||||
// Clear data and start game logic here
|
||||
destinationController.isInRog.value = true;
|
||||
destinationController.resetRogaining();
|
||||
destinationController.addToRogaining(
|
||||
destinationController.currentLat,
|
||||
destinationController.currentLon,
|
||||
destination.location_id!,
|
||||
);
|
||||
saveGameState();
|
||||
await ExternalService().startRogaining();
|
||||
Get.back(); // Close the dialog and potentially navigate away
|
||||
},
|
||||
),
|
||||
],
|
||||
),
|
||||
barrierDismissible:
|
||||
false, // User must tap a button to close the dialog
|
||||
);
|
||||
} else if (destinationController.isInRog.value == true &&
|
||||
destination.cp != -1) {
|
||||
//print("counted ${destinationController.rogainingCounted.value}");
|
||||
// Existing logic for other conditions
|
||||
|
||||
Get.back();
|
||||
await destinationController.callforCheckin(destination);
|
||||
} else {
|
||||
return;
|
||||
}
|
||||
},
|
||||
child: Text(
|
||||
destination.cp == -1 &&
|
||||
destinationController.isInRog.value == false &&
|
||||
destinationController.rogainingCounted.value == false
|
||||
? "ロゲ開始"
|
||||
: destinationController.isInRog.value == true &&
|
||||
destination.cp == -1
|
||||
? "ゲーム中"
|
||||
: isAlreadyCheckedIn == true
|
||||
? "ゲーム中"
|
||||
: destinationController.isInRog.value == true
|
||||
? "チェックイン"
|
||||
: "始まっていない",
|
||||
style: TextStyle(color: Theme.of(context).colorScheme.onSecondary),
|
||||
),
|
||||
);
|
||||
}
|
||||
return Container();
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
//print("to start ${destinationController.distanceToStart()}");
|
||||
|
||||
destinationController.skipGps = true;
|
||||
// print('--- c use --- ${indexController.currentUser[0].values}');
|
||||
// print('---- rog_mode ----- ${indexController.rogMode.value} -----');
|
||||
@ -124,261 +253,6 @@ class BottomSheetNew extends GetView<BottomSheetController> {
|
||||
return detailsSheet(context);
|
||||
}
|
||||
|
||||
// Show destination detais
|
||||
// SingleChildScrollView destinationSheet(BuildContext context) {
|
||||
// // print(
|
||||
// // '---- currentDestinationFeature ----- ${indexController.currentDestinationFeature[0].name} -----');
|
||||
|
||||
// return SingleChildScrollView(
|
||||
// child: Column(
|
||||
// children: [
|
||||
// Padding(
|
||||
// padding: const EdgeInsets.all(8.0),
|
||||
// child: Row(
|
||||
// children: [
|
||||
// MaterialButton(
|
||||
// onPressed: () {
|
||||
// Get.back();
|
||||
// //destinationController.makePrevious(indexController.currentDestinationFeature[0]);
|
||||
// },
|
||||
// color: Colors.blue,
|
||||
// textColor: Colors.white,
|
||||
// padding: const EdgeInsets.all(16),
|
||||
// shape: const CircleBorder(),
|
||||
// child: const Icon(
|
||||
// Icons.arrow_back_ios,
|
||||
// size: 14,
|
||||
// ),
|
||||
// ),
|
||||
// Expanded(
|
||||
// child: Container(
|
||||
// alignment: Alignment.center,
|
||||
// child: Obx(() => indexController.currentUser.isNotEmpty
|
||||
// ? Text(
|
||||
// "${TextUtils.getDisplayText(indexController.currentDestinationFeature[0])} : ${TextUtils.getDisplayText(indexController.currentDestinationFeature[0])} : ${indexController.currentDestinationFeature[0].name!}",
|
||||
// style: const TextStyle(
|
||||
// fontSize: 15.0,
|
||||
// fontWeight: FontWeight.bold,
|
||||
// ),
|
||||
// )
|
||||
// : Text(
|
||||
// indexController.currentDestinationFeature[0].name!,
|
||||
// style: const TextStyle(
|
||||
// fontSize: 15.0,
|
||||
// fontWeight: FontWeight.bold,
|
||||
// ),
|
||||
// )),
|
||||
// ),
|
||||
// ),
|
||||
// ],
|
||||
// ),
|
||||
// ),
|
||||
// Row(
|
||||
// children: [
|
||||
// Expanded(
|
||||
// child: SizedBox(
|
||||
// height: 260.0,
|
||||
// child: Obx(() => getImage()),
|
||||
// )),
|
||||
// ],
|
||||
// ),
|
||||
// Row(
|
||||
// mainAxisAlignment: MainAxisAlignment.spaceAround,
|
||||
// children: [
|
||||
// Obx(
|
||||
// () => indexController.currentDestinationFeature.isNotEmpty &&
|
||||
// destinationController.isInCheckin.value == true &&
|
||||
// destinationController.isAtStart.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.skipGps = false;
|
||||
// destinationController.isPhotoShoot.value =
|
||||
// true;
|
||||
// Get.back();
|
||||
// } else {
|
||||
// destinationController.makeCheckin(
|
||||
// indexController
|
||||
// .currentDestinationFeature[0],
|
||||
// true,
|
||||
// "");
|
||||
// if (indexController
|
||||
// .currentDestinationFeature[0].cp !=
|
||||
// -1) {
|
||||
// destinationController
|
||||
// .rogainingCounted.value = true;
|
||||
// }
|
||||
// }
|
||||
// } else {
|
||||
// destinationController.makeCheckin(
|
||||
// indexController
|
||||
// .currentDestinationFeature[0],
|
||||
// false,
|
||||
// "");
|
||||
// }
|
||||
// //Get.back();
|
||||
// },
|
||||
// child: Text(
|
||||
// //Checkin
|
||||
// indexController.currentDestinationFeature[0]
|
||||
// .checkedin ==
|
||||
// null ||
|
||||
// indexController
|
||||
// .currentDestinationFeature[0]
|
||||
// .checkedin ==
|
||||
// false
|
||||
// ? "チェックイン"
|
||||
// : "チェックアウト")),
|
||||
// ],
|
||||
// )
|
||||
// : Container(),
|
||||
// ),
|
||||
// Obx(
|
||||
// () => destinationController.isAtStart.value == true
|
||||
// ? ElevatedButton(
|
||||
// onPressed: () {
|
||||
// destinationController.isInRog.value = true;
|
||||
// destinationController.addToRogaining(
|
||||
// destinationController.currentLat,
|
||||
// destinationController.currentLon,
|
||||
// indexController
|
||||
// .currentDestinationFeature[0].location_id!);
|
||||
// saveGameState();
|
||||
// ExternalService()
|
||||
// .startRogaining()
|
||||
// .then((value) => Get.back());
|
||||
// },
|
||||
// child: Text(
|
||||
// // start
|
||||
// indexController.currentDestinationFeature[0]
|
||||
// .checkedin !=
|
||||
// null ||
|
||||
// indexController.currentDestinationFeature[0]
|
||||
// .checkedin ==
|
||||
// true
|
||||
// ? "ロゲイニングを開始"
|
||||
// : "間違った目的地..."))
|
||||
// : Container(),
|
||||
// ),
|
||||
// Obx(
|
||||
// () => destinationController.isAtGoal.value == true &&
|
||||
// destinationController.rogainingCounted.value == true
|
||||
// ? ElevatedButton(
|
||||
// onPressed: () {
|
||||
// Get.toNamed(AppPages.CAMERA_PAGE);
|
||||
// Get.back();
|
||||
// },
|
||||
// child: Text(
|
||||
// //goal
|
||||
// indexController.currentDestinationFeature[0]
|
||||
// .checkedin !=
|
||||
// null ||
|
||||
// indexController.currentDestinationFeature[0]
|
||||
// .checkedin ==
|
||||
// true
|
||||
// ? "ロゲイニングを終える"
|
||||
// : "間違った目的地 ..."))
|
||||
// : Container(),
|
||||
// ),
|
||||
// ],
|
||||
// ),
|
||||
// Obx(
|
||||
// () => indexController.currentDestinationFeature[0].address !=
|
||||
// null &&
|
||||
// indexController
|
||||
// .currentDestinationFeature[0].address!.isNotEmpty
|
||||
// ? getDetails(context, "address".tr,
|
||||
// indexController.currentDestinationFeature[0].address! ?? '')
|
||||
// : const SizedBox(
|
||||
// width: 0.0,
|
||||
// height: 0,
|
||||
// ),
|
||||
// ),
|
||||
// Obx(
|
||||
// () => indexController.currentDestinationFeature[0].phone != null &&
|
||||
// indexController
|
||||
// .currentDestinationFeature[0].phone!.isNotEmpty
|
||||
// ? getDetails(context, "telephone".tr,
|
||||
// indexController.currentDestinationFeature[0].phone! ?? '')
|
||||
// : const SizedBox(
|
||||
// width: 0.0,
|
||||
// height: 0,
|
||||
// ),
|
||||
// ),
|
||||
// Obx(
|
||||
// () => indexController.currentDestinationFeature[0].email != null &&
|
||||
// indexController
|
||||
// .currentDestinationFeature[0].email!.isNotEmpty
|
||||
// ? getDetails(context, "email".tr,
|
||||
// indexController.currentDestinationFeature[0].email! ?? '')
|
||||
// : const SizedBox(
|
||||
// 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)
|
||||
// : const SizedBox(
|
||||
// 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)
|
||||
// : const SizedBox(
|
||||
// width: 0.0,
|
||||
// height: 0,
|
||||
// ),
|
||||
// ),
|
||||
// const SizedBox(
|
||||
// height: 20.0,
|
||||
// ),
|
||||
// // Obx(() =>
|
||||
// // //wantToGo(context),
|
||||
|
||||
// // FutureBuilder<Widget>(
|
||||
// // future: wantToGo(context),
|
||||
// // builder: (context, snapshot) {
|
||||
// // return Container(
|
||||
// // child: snapshot.data,
|
||||
// // );
|
||||
// // },
|
||||
// // ),
|
||||
|
||||
// // ),
|
||||
// const SizedBox(
|
||||
// height: 60.0,
|
||||
// )
|
||||
// ],
|
||||
// ),
|
||||
// );
|
||||
// }
|
||||
|
||||
Future<bool> isDestinationCheckedIn(Destination d) async {
|
||||
DatabaseHelper db = DatabaseHelper.instance;
|
||||
List<Destination> ds = await db.getDestinationByLatLon(d.lat!, d.lon!);
|
||||
@ -462,79 +336,13 @@ class BottomSheetNew extends GetView<BottomSheetController> {
|
||||
Row(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceAround,
|
||||
children: [
|
||||
// Obx(
|
||||
// () => indexController
|
||||
// .currentDestinationFeature.isNotEmpty &&
|
||||
// indexController
|
||||
// .currentDestinationFeature[0].cp ==
|
||||
// -1 &&
|
||||
// indexController.currentDestinationFeature[0]
|
||||
// .checkedin ==
|
||||
// false &&
|
||||
// destinationController.isAtStart.value == true
|
||||
// ? ElevatedButton(
|
||||
// onPressed: () async {
|
||||
// await destinationController
|
||||
// .resetRogaining();
|
||||
// //print("~~~~ start button ~~~~");
|
||||
// destinationController.isInRog.value = true;
|
||||
// destinationController.addToRogaining(
|
||||
// destinationController.currentLat,
|
||||
// destinationController.currentLon,
|
||||
// indexController
|
||||
// .currentDestinationFeature[0]
|
||||
// .location_id!);
|
||||
// saveGameState();
|
||||
// ExternalService()
|
||||
// .startRogaining()
|
||||
// .then((value) {
|
||||
// Get.back();
|
||||
// });
|
||||
// },
|
||||
// child: Text(
|
||||
// // start
|
||||
// indexController
|
||||
// .currentDestinationFeature[
|
||||
// 0]
|
||||
// .checkedin !=
|
||||
// null ||
|
||||
// indexController
|
||||
// .currentDestinationFeature[
|
||||
// 0]
|
||||
// .checkedin ==
|
||||
// true
|
||||
// ? "ロゲイニングを開始"
|
||||
// : "間違った目的地..."))
|
||||
// : Container(),
|
||||
// ),
|
||||
|
||||
destinationController.rogainingCounted.value == true &&
|
||||
destinationController.distanceToStart() <=
|
||||
500 &&
|
||||
destination.cp == -1
|
||||
? ElevatedButton(
|
||||
onPressed: () async {
|
||||
destinationController.isAtGoal.value = true;
|
||||
destinationController.photos.clear();
|
||||
await showModalBottomSheet(
|
||||
constraints: BoxConstraints.loose(ui.Size(
|
||||
Get.width, Get.height * 0.75)),
|
||||
context: Get.context!,
|
||||
isScrollControlled: true,
|
||||
builder: ((context) => CameraPage(
|
||||
destination: destination,
|
||||
))).whenComplete(() {
|
||||
destinationController.skipGps = false;
|
||||
destinationController.chekcs = 0;
|
||||
destinationController.isAtGoal.value =
|
||||
false;
|
||||
});
|
||||
},
|
||||
child: Text("ロゲイニングを終える"))
|
||||
: Container(),
|
||||
// Finish or Goal
|
||||
getActionButton(context, destination),
|
||||
//remove checkin
|
||||
isAlreadyCheckedIn == true && destination.cp != -1
|
||||
? ElevatedButton(
|
||||
style: ElevatedButton.styleFrom(
|
||||
backgroundColor: Colors.blueAccent),
|
||||
onPressed: () async {
|
||||
await destinationController
|
||||
.removeCheckin(destination.cp!.toInt());
|
||||
@ -542,35 +350,11 @@ class BottomSheetNew extends GetView<BottomSheetController> {
|
||||
.deleteDestination(destination);
|
||||
Get.back();
|
||||
},
|
||||
child: const Text("チェックイン取消"))
|
||||
child: const Text(
|
||||
"チェックイン取消",
|
||||
style: TextStyle(color: Colors.white),
|
||||
)) //remove checkin
|
||||
: Container(),
|
||||
|
||||
// Obx(
|
||||
// () => destinationController.rogainingCounted.value ==
|
||||
// false &&
|
||||
// destination.cp == -1 &&
|
||||
// destinationController.distanceToStart() <= 500
|
||||
// ? ElevatedButton(
|
||||
// onPressed: () {
|
||||
// Get.toNamed(AppPages.CAMERA_PAGE);
|
||||
// Get.back();
|
||||
// },
|
||||
// child: Text(
|
||||
// //goal
|
||||
// indexController
|
||||
// .currentDestinationFeature[
|
||||
// 0]
|
||||
// .checkedin !=
|
||||
// null ||
|
||||
// indexController
|
||||
// .currentDestinationFeature[
|
||||
// 0]
|
||||
// .checkedin ==
|
||||
// true
|
||||
// ? "ロゲイニングを終える"
|
||||
// : "間違った目的地 ..."))
|
||||
// : Container(),
|
||||
// ),
|
||||
],
|
||||
),
|
||||
Row(
|
||||
@ -582,11 +366,12 @@ class BottomSheetNew extends GetView<BottomSheetController> {
|
||||
.colorScheme
|
||||
.onPrimaryContainer),
|
||||
onPressed: () async {
|
||||
// print(
|
||||
// "dist to start ${destinationController.distanceToStart()}");
|
||||
Get.back();
|
||||
//print("---- go to ----");
|
||||
GeoJsonFeature<GeoJsonMultiPoint> mp =
|
||||
indexController.currentFeature[0]
|
||||
as GeoJsonFeature<GeoJsonMultiPoint>;
|
||||
// GeoJSONMultiPoint mp = indexController
|
||||
// .currentFeature[0] as GeoJSONMultiPoint;
|
||||
Position position =
|
||||
await Geolocator.getCurrentPosition(
|
||||
desiredAccuracy:
|
||||
@ -598,14 +383,12 @@ class BottomSheetNew extends GetView<BottomSheetController> {
|
||||
lon: position.longitude);
|
||||
|
||||
Destination tp = Destination(
|
||||
lat: mp.geometry!.geoSerie!.geoPoints[0]
|
||||
.latitude,
|
||||
lon: mp.geometry!.geoSerie!.geoPoints[0]
|
||||
.longitude);
|
||||
lat: destination.lat, lon: destination.lon);
|
||||
|
||||
destinationController
|
||||
.destinationMatrixFromCurrentPoint([ds, tp]);
|
||||
},
|
||||
//go here
|
||||
child: Text(
|
||||
"ここへ行く",
|
||||
style: TextStyle(
|
||||
@ -617,61 +400,6 @@ class BottomSheetNew extends GetView<BottomSheetController> {
|
||||
),
|
||||
|
||||
// forced start / checkin
|
||||
distanceToDest <=
|
||||
destinationController
|
||||
.getForcedChckinDistance(destination)
|
||||
? Obx(() => ElevatedButton(
|
||||
style: ElevatedButton.styleFrom(
|
||||
backgroundColor: Theme.of(context)
|
||||
.colorScheme
|
||||
.secondary),
|
||||
onPressed: () async {
|
||||
//print("~~~~ manual checkin button ~~~~");
|
||||
if (destination.cp == -1 &&
|
||||
destinationController.isInRog.value ==
|
||||
false &&
|
||||
destinationController
|
||||
.rogainingCounted.value ==
|
||||
false) {
|
||||
destinationController.isInRog.value = true;
|
||||
destinationController.addToRogaining(
|
||||
destinationController.currentLat,
|
||||
destinationController.currentLon,
|
||||
destination.location_id!);
|
||||
saveGameState();
|
||||
ExternalService()
|
||||
.startRogaining()
|
||||
.then((value) => Get.back());
|
||||
} else {
|
||||
if (destination.cp == -1) {
|
||||
return;
|
||||
}
|
||||
Get.back();
|
||||
await destinationController
|
||||
.callforCheckin(destination);
|
||||
}
|
||||
},
|
||||
child: Text(
|
||||
destination.cp == -1 &&
|
||||
destinationController
|
||||
.isInRog.value ==
|
||||
false &&
|
||||
destinationController
|
||||
.rogainingCounted.value ==
|
||||
false
|
||||
? "ロゲ開始"
|
||||
: destinationController.isInRog.value ==
|
||||
true &&
|
||||
destination.cp == -1
|
||||
? "ゲーム中"
|
||||
: isAlreadyCheckedIn == true
|
||||
? "ゲーム中"
|
||||
: "チェックイン",
|
||||
style: TextStyle(
|
||||
color: Theme.of(context)
|
||||
.colorScheme
|
||||
.onSecondary))))
|
||||
: Container(),
|
||||
],
|
||||
),
|
||||
Row(
|
||||
|
||||
34
lib/widgets/current_position_widget.dart
Normal file
34
lib/widgets/current_position_widget.dart
Normal file
@ -0,0 +1,34 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:get/get.dart';
|
||||
import 'package:rogapp/pages/destination/destination_controller.dart';
|
||||
|
||||
class CurrentPosition extends StatefulWidget {
|
||||
const CurrentPosition({super.key});
|
||||
|
||||
@override
|
||||
State<CurrentPosition> createState() => _CurrentPositionState();
|
||||
}
|
||||
|
||||
class _CurrentPositionState extends State<CurrentPosition> {
|
||||
final DestinationController destinationController =
|
||||
Get.find<DestinationController>();
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Container(
|
||||
width: 40,
|
||||
height: 40,
|
||||
decoration: BoxDecoration(
|
||||
color: Colors.grey, borderRadius: BorderRadius.circular(20.0)),
|
||||
child: IconButton(
|
||||
onPressed: () {
|
||||
destinationController.centerMapToCurrentLocation();
|
||||
},
|
||||
icon: const Icon(
|
||||
Icons.location_searching,
|
||||
color: Colors.white,
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
210
lib/widgets/game_state_view.dart
Normal file
210
lib/widgets/game_state_view.dart
Normal file
@ -0,0 +1,210 @@
|
||||
import 'dart:ffi';
|
||||
import 'dart:math';
|
||||
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:get/get.dart';
|
||||
import 'package:rogapp/model/destination.dart';
|
||||
import 'package:rogapp/pages/destination/destination_controller.dart';
|
||||
import 'package:rogapp/pages/index/index_controller.dart';
|
||||
import 'package:rogapp/services/DatabaseService.dart';
|
||||
import 'package:rogapp/utils/database_helper.dart';
|
||||
import 'package:rogapp/widgets/GameState/CheckinState.dart';
|
||||
import 'package:rogapp/widgets/GameState/ConnectionStatus.dart';
|
||||
import 'package:rogapp/widgets/GameState/DashboardWidget.dart';
|
||||
import 'package:rogapp/widgets/GameState/game_on_off.dart';
|
||||
|
||||
class GameStateManager {
|
||||
static final GameStateManager _instance = GameStateManager._internal();
|
||||
|
||||
factory GameStateManager() {
|
||||
return _instance;
|
||||
}
|
||||
|
||||
GameStateManager._internal();
|
||||
|
||||
List<String> _logs = [];
|
||||
List<VoidCallback> _listeners = [];
|
||||
|
||||
List<String> get logs => _logs;
|
||||
|
||||
void addLog(String log) {
|
||||
_logs.add(log);
|
||||
_notifyListeners(); // Notify all listeners
|
||||
}
|
||||
|
||||
void clearLogs() {
|
||||
_logs.clear();
|
||||
_notifyListeners(); // Notify all listeners
|
||||
}
|
||||
|
||||
void addListener(VoidCallback listener) {
|
||||
_listeners.add(listener);
|
||||
}
|
||||
|
||||
void removeListener(VoidCallback listener) {
|
||||
_listeners.remove(listener);
|
||||
}
|
||||
|
||||
void _notifyListeners() {
|
||||
for (var listener in _listeners) {
|
||||
listener();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class GameStateWidget extends StatefulWidget {
|
||||
const GameStateWidget({super.key});
|
||||
|
||||
@override
|
||||
State<GameStateWidget> createState() => _GameStateWidgetState();
|
||||
}
|
||||
|
||||
class _GameStateWidgetState extends State<GameStateWidget> {
|
||||
final GameStateManager gameStateManager = GameStateManager();
|
||||
|
||||
final IndexController indexController = Get.find<IndexController>();
|
||||
final DestinationController destinationController =
|
||||
Get.find<DestinationController>();
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
super.initState();
|
||||
gameStateManager.addListener(_updateLogs);
|
||||
}
|
||||
|
||||
@override
|
||||
void dispose() {
|
||||
gameStateManager.removeListener(_updateLogs);
|
||||
super.dispose();
|
||||
}
|
||||
|
||||
void _updateLogs() {
|
||||
Future.delayed(Duration.zero, () {
|
||||
if (mounted) {
|
||||
setState(() {});
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
void toggleExpanded() {
|
||||
setState(() {
|
||||
isExpanded = !isExpanded;
|
||||
});
|
||||
}
|
||||
|
||||
void clearLogs() {
|
||||
gameStateManager.clearLogs();
|
||||
}
|
||||
|
||||
bool isExpanded = false;
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final DatabaseService dbService = DatabaseService();
|
||||
return Container(
|
||||
width: MediaQuery.of(context).size.width,
|
||||
decoration: BoxDecoration(color: Colors.black12),
|
||||
child: GestureDetector(
|
||||
onTap: toggleExpanded,
|
||||
child: AnimatedContainer(
|
||||
duration: const Duration(milliseconds: 200),
|
||||
color: isExpanded ? Colors.black54 : Colors.black12,
|
||||
height: isExpanded ? 160.0 : 48.0, // Adjust sizes as needed
|
||||
child: Column(
|
||||
children: [
|
||||
// Top bar with clear button
|
||||
if (isExpanded)
|
||||
Container(
|
||||
padding: EdgeInsets.symmetric(horizontal: 10.0),
|
||||
color: Colors.blueGrey, // Adjust color as needed
|
||||
child: Row(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
crossAxisAlignment: CrossAxisAlignment.center,
|
||||
children: [
|
||||
Text('ゲームステータス', style: TextStyle(color: Colors.white)),
|
||||
IconButton(
|
||||
icon: Icon(Icons.clear, color: Colors.white),
|
||||
onPressed: toggleExpanded,
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
|
||||
// Log messages
|
||||
Expanded(
|
||||
child: SingleChildScrollView(
|
||||
child: Wrap(
|
||||
alignment: WrapAlignment.spaceEvenly,
|
||||
children: [
|
||||
Obx(() => Padding(
|
||||
padding: const EdgeInsets.all(4.0),
|
||||
child: GameStatusIndicator(
|
||||
gameStarted: destinationController.isInRog.value,
|
||||
minimized: !isExpanded,
|
||||
),
|
||||
)),
|
||||
Padding(
|
||||
padding: const EdgeInsets.all(4.0),
|
||||
child: StreamBuilder<List<Destination>>(
|
||||
stream: dbService.destinationUpdatesStream,
|
||||
builder: (context, snapshot) {
|
||||
if (snapshot.connectionState ==
|
||||
ConnectionState.waiting) {
|
||||
return const CircularProgressIndicator();
|
||||
} else if (snapshot.hasError) {
|
||||
return LocationVisitedWidget(
|
||||
count: 0,
|
||||
minimized: !isExpanded,
|
||||
);
|
||||
} else if (snapshot.hasData) {
|
||||
return LocationVisitedWidget(
|
||||
count: snapshot.data!.length,
|
||||
minimized: !isExpanded,
|
||||
);
|
||||
} else {
|
||||
return LocationVisitedWidget(
|
||||
count: 0,
|
||||
minimized: !isExpanded,
|
||||
);
|
||||
}
|
||||
},
|
||||
),
|
||||
|
||||
// child: LocationVisitedWidget(
|
||||
// count:
|
||||
// minimized: !isExpanded,
|
||||
// ),
|
||||
),
|
||||
Padding(
|
||||
padding: const EdgeInsets.all(4.0),
|
||||
child: Obx(() => ConnectionStatusIndicator(
|
||||
connectionStatus: (indexController
|
||||
.connectionStatusName.value ==
|
||||
"wifi" ||
|
||||
indexController
|
||||
.connectionStatusName.value ==
|
||||
"mobile")
|
||||
? indexController.connectionStatusName.value ==
|
||||
"wifi"
|
||||
? ConnectionStatus.wifi
|
||||
: ConnectionStatus.mobile
|
||||
: ConnectionStatus.none,
|
||||
minimized: !isExpanded)),
|
||||
) // Expanded view
|
||||
],
|
||||
),
|
||||
// child: Obx(
|
||||
// () => DashboardWidget(
|
||||
// gameStarted: destinationController.isInRog.value,
|
||||
// locationsVisited: 3,
|
||||
// isMinimized: false,
|
||||
// ),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
@ -1,5 +1,5 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:geojson/geojson.dart';
|
||||
import 'package:geojson_vi/geojson_vi.dart';
|
||||
import 'package:get/get.dart';
|
||||
import 'package:rogapp/model/destination.dart';
|
||||
import 'package:rogapp/pages/destination/destination_controller.dart';
|
||||
@ -22,16 +22,15 @@ class _ListWidgetState extends State<ListWidget> {
|
||||
Get.find<DestinationController>();
|
||||
|
||||
Image getImage(int index) {
|
||||
if (indexController.locations[0].collection[index].properties!["photos"] ==
|
||||
if (indexController.locations[0].features[index]!.properties!["photos"] ==
|
||||
null ||
|
||||
indexController.locations[0].collection[index].properties!["photos"] ==
|
||||
indexController.locations[0].features[index]!.properties!["photos"] ==
|
||||
"") {
|
||||
return const Image(image: AssetImage('assets/images/empty_image.png'));
|
||||
} else {
|
||||
//print("==== photo index is $index ===");
|
||||
String serverUrl = ConstValues.currentServer();
|
||||
GeoJsonFeature<dynamic> gf =
|
||||
indexController.locations[0].collection[index];
|
||||
GeoJSONFeature gf = indexController.locations[0].features[index]!;
|
||||
String photo = gf.properties!["photos"];
|
||||
return Image(
|
||||
image: NetworkImage('$serverUrl/media/compressed/$photo'),
|
||||
@ -43,7 +42,7 @@ class _ListWidgetState extends State<ListWidget> {
|
||||
}
|
||||
}
|
||||
|
||||
void changeCurrentFeature(GeoJsonFeature fs) {
|
||||
void changeCurrentFeature(GeoJSONFeature fs) {
|
||||
if (indexController.currentFeature.isNotEmpty) {
|
||||
indexController.currentFeature.clear();
|
||||
}
|
||||
@ -55,14 +54,14 @@ class _ListWidgetState extends State<ListWidget> {
|
||||
super.initState();
|
||||
}
|
||||
|
||||
Destination createDestination(GeoJsonFeature feature) {
|
||||
Destination createDestination(GeoJSONFeature feature) {
|
||||
final props = feature.properties;
|
||||
GeoJsonMultiPoint pt = feature.geometry;
|
||||
GeoJSONMultiPoint pt = feature.geometry as GeoJSONMultiPoint;
|
||||
|
||||
return Destination(
|
||||
cp: props!['cp'],
|
||||
lat: pt.geoSerie!.geoPoints.first.latitude,
|
||||
lon: pt.geoSerie!.geoPoints.first.longitude,
|
||||
lat: pt.coordinates[0][1],
|
||||
lon: pt.coordinates[0][0],
|
||||
);
|
||||
}
|
||||
|
||||
@ -72,7 +71,7 @@ class _ListWidgetState extends State<ListWidget> {
|
||||
lat: indexController.currentLat, lon: indexController.currentLon);
|
||||
//Destination dest1 = createDestination(indexController.locations[0].collection[0]);
|
||||
Destination dest2 =
|
||||
createDestination(indexController.locations[0].collection[i]);
|
||||
createDestination(indexController.locations[0].features[i]!);
|
||||
|
||||
// Get the distance between these two destinations
|
||||
final res = await MatrixService.getDestinations([desCurr, dest2]);
|
||||
@ -83,9 +82,9 @@ class _ListWidgetState extends State<ListWidget> {
|
||||
|
||||
Future<void> _pullRefresh() async {
|
||||
//print("pull to refesh");
|
||||
indexController.locations[0].collection.sort((a, b) =>
|
||||
(a.properties!['cp'] as Comparable)
|
||||
.compareTo(b.properties!['cp'] as Comparable));
|
||||
indexController.locations[0].features.sort((a, b) =>
|
||||
(a!.properties!['cp'] as Comparable)
|
||||
.compareTo(b!.properties!['cp'] as Comparable));
|
||||
setState(() {});
|
||||
}
|
||||
|
||||
@ -96,12 +95,12 @@ class _ListWidgetState extends State<ListWidget> {
|
||||
? RefreshIndicator(
|
||||
onRefresh: _pullRefresh,
|
||||
child: ListView.builder(
|
||||
itemCount: indexController.locations[0].collection.length,
|
||||
itemCount: indexController.locations[0].features.length,
|
||||
shrinkWrap: true,
|
||||
itemBuilder: (_, index) {
|
||||
bool isFound = false;
|
||||
for (Destination d in destinationController.destinations) {
|
||||
if (indexController.locations[0].collection[index]
|
||||
if (indexController.locations[0].features[index]!
|
||||
.properties!['location_id'] ==
|
||||
d.location_id) {
|
||||
isFound = true;
|
||||
@ -113,8 +112,8 @@ class _ListWidgetState extends State<ListWidget> {
|
||||
selected: isFound,
|
||||
selectedTileColor: Colors.yellow.shade200,
|
||||
onTap: () {
|
||||
GeoJsonFeature gf =
|
||||
indexController.locations[0].collection[index];
|
||||
GeoJSONFeature gf =
|
||||
indexController.locations[0].features[index]!;
|
||||
Destination des =
|
||||
destinationController.festuretoDestination(gf);
|
||||
changeCurrentFeature(gf);
|
||||
@ -129,29 +128,27 @@ class _ListWidgetState extends State<ListWidget> {
|
||||
)));
|
||||
},
|
||||
leading: getImage(index),
|
||||
title: indexController.locations[0].collection[index]
|
||||
title: indexController.locations[0].features[index]!
|
||||
.properties!['location_name'] !=
|
||||
null
|
||||
? Text(indexController.locations[0]
|
||||
.collection[index].properties!['location_name']
|
||||
? Text(indexController.locations[0].features[index]!
|
||||
.properties!['location_name']
|
||||
.toString())
|
||||
: const Text(""),
|
||||
subtitle: indexController.locations[0].collection[index]
|
||||
subtitle: indexController.locations[0].features[index]!
|
||||
.properties!['category'] !=
|
||||
null
|
||||
? Text(indexController.locations[0]
|
||||
.collection[index].properties!['category'])
|
||||
? Text(indexController.locations[0].features[index]!
|
||||
.properties!['category'])
|
||||
: const Text(""),
|
||||
trailing: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.end,
|
||||
children: [
|
||||
indexController.locations[0].collection[index]
|
||||
indexController.locations[0].features[index]!
|
||||
.properties!['sub_loc_id'] !=
|
||||
null
|
||||
? Text(indexController
|
||||
.locations[0]
|
||||
.collection[index]
|
||||
.properties!['sub_loc_id'])
|
||||
? Text(indexController.locations[0]
|
||||
.features[index]!.properties!['sub_loc_id'])
|
||||
: const Text(""),
|
||||
SizedBox(
|
||||
width: 100,
|
||||
|
||||
@ -1,68 +1,80 @@
|
||||
import 'dart:async';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_map/plugin_api.dart';
|
||||
import 'package:flutter_map/flutter_map.dart';
|
||||
import 'package:flutter_map_location_marker/flutter_map_location_marker.dart';
|
||||
import 'package:flutter_map_marker_cluster/flutter_map_marker_cluster.dart';
|
||||
import 'package:flutter_polyline_points/flutter_polyline_points.dart';
|
||||
import 'package:geojson/geojson.dart';
|
||||
import 'package:geojson_vi/geojson_vi.dart';
|
||||
import 'package:get/get.dart';
|
||||
import 'package:latlong2/latlong.dart';
|
||||
import 'package:rogapp/model/destination.dart';
|
||||
import 'package:rogapp/pages/destination/destination_controller.dart';
|
||||
import 'package:rogapp/pages/index/index_controller.dart';
|
||||
import 'package:rogapp/utils/database_helper.dart';
|
||||
import 'package:rogapp/utils/location_controller.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:rogapp/widgets/debug_widget.dart';
|
||||
|
||||
class MapWidget extends StatelessWidget {
|
||||
final IndexController indexController = Get.find<IndexController>();
|
||||
final DestinationController destinationController =
|
||||
Get.find<DestinationController>();
|
||||
import 'package:rogapp/widgets/current_position_widget.dart';
|
||||
import 'package:rogapp/widgets/game_state_view.dart';
|
||||
|
||||
class MapWidget extends StatefulWidget {
|
||||
MapWidget({Key? key}) : super(key: key);
|
||||
|
||||
StreamSubscription? subscription;
|
||||
@override
|
||||
State<MapWidget> createState() => _MapWidgetState();
|
||||
}
|
||||
|
||||
Widget getMarkerShape(GeoJsonFeature i, BuildContext context) {
|
||||
GeoJsonMultiPoint p = i.geometry as GeoJsonMultiPoint;
|
||||
class _MapWidgetState extends State<MapWidget> {
|
||||
final IndexController indexController = Get.find<IndexController>();
|
||||
|
||||
final DestinationController destinationController =
|
||||
Get.find<DestinationController>();
|
||||
final LocationController locationController = Get.find<LocationController>();
|
||||
|
||||
StreamSubscription? subscription;
|
||||
Timer? _timer;
|
||||
|
||||
Widget getMarkerShape(GeoJSONFeature i, BuildContext context) {
|
||||
GeoJSONMultiPoint p = i.geometry as GeoJSONMultiPoint;
|
||||
//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: () {
|
||||
GeoJsonFeature? fs = indexController.getFeatureForLatLong(
|
||||
p.geoSerie!.geoPoints[0].latitude,
|
||||
p.geoSerie!.geoPoints[0].longitude);
|
||||
//print("------- fs $fs------");
|
||||
if (fs != null) {
|
||||
indexController.currentFeature.clear();
|
||||
indexController.currentFeature.add(fs);
|
||||
//print("----- fs is ${fs.properties!['photos']}");
|
||||
return InkWell(
|
||||
onTap: () {
|
||||
GeoJSONFeature? fs = indexController.getFeatureForLatLong(
|
||||
p.coordinates[0][1], p.coordinates[0][0]);
|
||||
//print("------- fs $fs------");
|
||||
if (fs != null) {
|
||||
indexController.currentFeature.clear();
|
||||
indexController.currentFeature.add(fs);
|
||||
//print("----- fs is ${fs.properties!['photos']}");
|
||||
|
||||
Destination des = destinationController.festuretoDestination(fs);
|
||||
Destination des = destinationController.festuretoDestination(fs);
|
||||
|
||||
DatabaseHelper db = DatabaseHelper.instance;
|
||||
db.getDestinationByLatLon(des.lat!, des.lon!).then((value) {
|
||||
showModalBottomSheet(
|
||||
constraints: BoxConstraints.loose(
|
||||
Size(Get.width, Get.height * 0.85)),
|
||||
context: context,
|
||||
isScrollControlled: true,
|
||||
isDismissible: true,
|
||||
builder: ((context) => BottomSheetNew(
|
||||
destination: des, isAlreadyCheckedIn: value.isNotEmpty))
|
||||
//builder:((context) => BottomSheetWidget())
|
||||
).whenComplete(() {
|
||||
destinationController.skipGps = false;
|
||||
});
|
||||
});
|
||||
}
|
||||
},
|
||||
child: Container(
|
||||
DatabaseHelper db = DatabaseHelper.instance;
|
||||
db.getDestinationByLatLon(des.lat!, des.lon!).then((value) {
|
||||
destinationController.shouldShowBottomSheet = false;
|
||||
showModalBottomSheet(
|
||||
constraints:
|
||||
BoxConstraints.loose(Size(Get.width, Get.height * 0.85)),
|
||||
context: context,
|
||||
isScrollControlled: true,
|
||||
isDismissible: true,
|
||||
builder: ((context) => BottomSheetNew(
|
||||
destination: des, isAlreadyCheckedIn: value.isNotEmpty))
|
||||
//builder:((context) => BottomSheetWidget())
|
||||
).whenComplete(() {
|
||||
destinationController.shouldShowBottomSheet = true;
|
||||
destinationController.skipGps = false;
|
||||
});
|
||||
});
|
||||
}
|
||||
},
|
||||
child: Stack(
|
||||
fit: StackFit.expand,
|
||||
//mainAxisAlignment: MainAxisAlignment.center,
|
||||
children: [
|
||||
Container(
|
||||
height: 32,
|
||||
width: 32,
|
||||
decoration: BoxDecoration(
|
||||
@ -82,42 +94,64 @@ class MapWidget extends StatelessWidget {
|
||||
size: 6.0,
|
||||
),
|
||||
i.properties!['cp'] == -1
|
||||
? Transform.rotate(
|
||||
alignment: Alignment.centerLeft,
|
||||
origin: Offset.fromDirection(1, 26),
|
||||
angle: 270 * pi / 180,
|
||||
child: const Icon(
|
||||
Icons.play_arrow_outlined,
|
||||
color: Colors.red,
|
||||
size: 70,
|
||||
))
|
||||
? Transform.translate(
|
||||
offset: Offset(18, 0),
|
||||
child: Transform.rotate(
|
||||
alignment: Alignment.centerLeft,
|
||||
origin: Offset.fromDirection(1, 26),
|
||||
angle: 270 * pi / 180,
|
||||
child: const Icon(
|
||||
Icons.play_arrow_outlined,
|
||||
color: Colors.red,
|
||||
size: 70,
|
||||
)),
|
||||
)
|
||||
: Container(
|
||||
color: Colors.transparent,
|
||||
),
|
||||
],
|
||||
)),
|
||||
),
|
||||
Container(
|
||||
color: Colors.purple.withOpacity(0.4),
|
||||
// child: Text(TextUtils.getDisplayTextFeture(i),
|
||||
// style: const TextStyle(
|
||||
// fontSize: 16,
|
||||
// fontWeight: FontWeight.bold,
|
||||
// color: Colors.red,
|
||||
// ))),
|
||||
child: Text(
|
||||
TextUtils.getDisplayTextFeture(i),
|
||||
style: TextStyle(
|
||||
fontSize: 16,
|
||||
fontWeight: FontWeight.w700,
|
||||
// アウトラインの色と幅を設定
|
||||
foreground: Paint()
|
||||
..style = PaintingStyle.stroke
|
||||
..strokeWidth = 1
|
||||
..color = Colors.white,
|
||||
),
|
||||
))
|
||||
],
|
||||
Transform.translate(
|
||||
offset: Offset(45, 0),
|
||||
child: Align(
|
||||
alignment: Alignment.center,
|
||||
child: Container(
|
||||
color: Colors.purple.withOpacity(0.2),
|
||||
// child: Text(TextUtils.getDisplayTextFeture(i),
|
||||
// style: const TextStyle(
|
||||
// fontSize: 16,
|
||||
// fontWeight: FontWeight.bold,
|
||||
// color: Colors.red,
|
||||
// ))),
|
||||
child: Stack(
|
||||
children: <Widget>[
|
||||
// Text with white outline
|
||||
Text(
|
||||
TextUtils.getDisplayTextFeture(i),
|
||||
style: TextStyle(
|
||||
fontSize: 16,
|
||||
fontWeight: FontWeight.w700,
|
||||
foreground: Paint()
|
||||
..style = PaintingStyle.stroke
|
||||
..strokeWidth = 1
|
||||
..color = Colors.white,
|
||||
),
|
||||
),
|
||||
// Text with black fill
|
||||
Text(
|
||||
TextUtils.getDisplayTextFeture(i),
|
||||
style: TextStyle(
|
||||
fontSize: 16,
|
||||
fontWeight: FontWeight.w700,
|
||||
color: Colors.black,
|
||||
),
|
||||
),
|
||||
],
|
||||
)),
|
||||
),
|
||||
)
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
@ -131,6 +165,33 @@ class MapWidget extends StatelessWidget {
|
||||
return pts;
|
||||
}
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
super.initState();
|
||||
_startIdleTimer();
|
||||
}
|
||||
|
||||
void _startIdleTimer() {
|
||||
_timer = Timer(const Duration(milliseconds: (1000 * 10)), _centerMapOnUser);
|
||||
}
|
||||
|
||||
void _resetTimer() {
|
||||
_timer?.cancel();
|
||||
_startIdleTimer();
|
||||
}
|
||||
|
||||
void _centerMapOnUser() {
|
||||
assert(() {
|
||||
print("showBottomSheet ${destinationController.shouldShowBottomSheet}");
|
||||
return true;
|
||||
}());
|
||||
// 2024-04-03 Akira Log enabled only debug mode..
|
||||
//
|
||||
//if (destinationController.shouldShowBottomSheet) {
|
||||
destinationController.centerMapToCurrentLocation();
|
||||
//}
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
// print(
|
||||
@ -152,7 +213,8 @@ class MapWidget extends StatelessWidget {
|
||||
subscription = indexController.mapController.mapEventStream
|
||||
.listen((MapEvent mapEvent) {
|
||||
if (mapEvent is MapEventMoveStart) {
|
||||
//print(DateTime.now().toString() + ' [MapEventMoveStart] START');
|
||||
// print(DateTime.now().toString() +
|
||||
// ' [MapEventMoveStart] START');
|
||||
// do something
|
||||
}
|
||||
if (mapEvent is MapEventMoveEnd) {}
|
||||
@ -169,7 +231,11 @@ class MapWidget extends StatelessWidget {
|
||||
interactiveFlags:
|
||||
InteractiveFlag.pinchZoom | InteractiveFlag.drag,
|
||||
|
||||
onPositionChanged: (MapPosition pos, isvalue) {
|
||||
onPositionChanged: (MapPosition pos, hasGesture) {
|
||||
//print("map position changed ${pos.center!.latitude}");
|
||||
if (hasGesture) {
|
||||
_resetTimer();
|
||||
}
|
||||
indexController.currentBound = [pos.bounds!];
|
||||
},
|
||||
onTap: (_, __) => popupController
|
||||
@ -190,7 +256,9 @@ class MapWidget extends StatelessWidget {
|
||||
: Container(),
|
||||
),
|
||||
CurrentLocationLayer(
|
||||
followOnLocationUpdate: FollowOnLocationUpdate.never,
|
||||
positionStream: locationController
|
||||
.locationMarkerPositionStreamController.stream,
|
||||
alignDirectionOnUpdate: AlignOnUpdate.never,
|
||||
turnOnHeadingUpdate: TurnOnHeadingUpdate.never,
|
||||
style: const LocationMarkerStyle(
|
||||
marker: DefaultLocationMarker(
|
||||
@ -204,37 +272,36 @@ class MapWidget extends StatelessWidget {
|
||||
),
|
||||
),
|
||||
indexController.locations.isNotEmpty &&
|
||||
indexController.locations[0].collection.isNotEmpty
|
||||
indexController.locations[0].features.isNotEmpty
|
||||
? MarkerLayer(
|
||||
markers:
|
||||
indexController.locations[0].collection.map((i) {
|
||||
indexController.locations[0].features.map((i) {
|
||||
//print("i si ${i.properties!['location_id']}");
|
||||
|
||||
RegExp regex = RegExp(r'([.]*0)(?!.*\d)');
|
||||
GeoJsonMultiPoint p =
|
||||
i.geometry as GeoJsonMultiPoint;
|
||||
GeoJSONMultiPoint p =
|
||||
i!.geometry as GeoJSONMultiPoint;
|
||||
//print(
|
||||
// "lat is ${p.geoSerie!.geoPoints[0].latitude} and lon is ${p.geoSerie!.geoPoints[0].longitude}");
|
||||
return Marker(
|
||||
anchorPos: AnchorPos.exactly(Anchor(108.0, 18.0)),
|
||||
height: 32.0,
|
||||
width: 120.0,
|
||||
point: LatLng(p.geoSerie!.geoPoints[0].latitude,
|
||||
p.geoSerie!.geoPoints[0].longitude),
|
||||
builder: (ctx) {
|
||||
return getMarkerShape(i, context);
|
||||
},
|
||||
);
|
||||
alignment: Alignment.center,
|
||||
height: 27.0,
|
||||
width: 127.0,
|
||||
point: LatLng(
|
||||
p.coordinates[0][1], p.coordinates[0][0]),
|
||||
child: getMarkerShape(i, context));
|
||||
}).toList(),
|
||||
)
|
||||
: const Center(child: CircularProgressIndicator()),
|
||||
],
|
||||
)),
|
||||
const Positioned(
|
||||
bottom: 10,
|
||||
left: 0,
|
||||
child: DebugWidget(),
|
||||
)
|
||||
const Positioned(top: 0, left: 0, child: GameStateWidget()),
|
||||
const Positioned(bottom: 10, right: 10, child: CurrentPosition())
|
||||
// const Positioned(
|
||||
// bottom: 10,
|
||||
// left: 0,
|
||||
// child: DebugWidget(),
|
||||
// )
|
||||
],
|
||||
);
|
||||
}
|
||||
|
||||
@ -5,9 +5,9 @@ PODS:
|
||||
- file_selector_macos (0.0.1):
|
||||
- FlutterMacOS
|
||||
- FlutterMacOS (1.0.0)
|
||||
- FMDB (2.7.5):
|
||||
- FMDB/standard (= 2.7.5)
|
||||
- FMDB/standard (2.7.5)
|
||||
- FMDB (2.7.10):
|
||||
- FMDB/standard (= 2.7.10)
|
||||
- FMDB/standard (2.7.10)
|
||||
- geolocator_apple (1.2.0):
|
||||
- FlutterMacOS
|
||||
- isar_flutter_libs (1.0.0):
|
||||
@ -15,7 +15,7 @@ PODS:
|
||||
- path_provider_foundation (0.0.1):
|
||||
- Flutter
|
||||
- FlutterMacOS
|
||||
- ReachabilitySwift (5.0.0)
|
||||
- ReachabilitySwift (5.2.1)
|
||||
- shared_preferences_foundation (0.0.1):
|
||||
- Flutter
|
||||
- FlutterMacOS
|
||||
@ -65,15 +65,15 @@ SPEC CHECKSUMS:
|
||||
connectivity_plus: 18d3c32514c886e046de60e9c13895109866c747
|
||||
file_selector_macos: 468fb6b81fac7c0e88d71317f3eec34c3b008ff9
|
||||
FlutterMacOS: 8f6f14fa908a6fb3fba0cd85dbd81ec4b251fb24
|
||||
FMDB: 2ce00b547f966261cd18927a3ddb07cb6f3db82a
|
||||
FMDB: eae540775bf7d0c87a5af926ae37af69effe5a19
|
||||
geolocator_apple: 72a78ae3f3e4ec0db62117bd93e34523f5011d58
|
||||
isar_flutter_libs: 43385c99864c168fadba7c9adeddc5d38838ca6a
|
||||
path_provider_foundation: 29f094ae23ebbca9d3d0cec13889cd9060c0e943
|
||||
ReachabilitySwift: 985039c6f7b23a1da463388634119492ff86c825
|
||||
shared_preferences_foundation: 5b919d13b803cadd15ed2dc053125c68730e5126
|
||||
sqflite: a5789cceda41d54d23f31d6de539d65bb14100ea
|
||||
path_provider_foundation: 3784922295ac71e43754bd15e0653ccfd36a147c
|
||||
ReachabilitySwift: 5ae15e16814b5f9ef568963fb2c87aeb49158c66
|
||||
shared_preferences_foundation: b4c3b4cddf1c21f02770737f147a3f5da9d39695
|
||||
sqflite: d0307f984e859ce2bd39b230d672a448ea3f47b4
|
||||
url_launcher_macos: d2691c7dd33ed713bf3544850a623080ec693d95
|
||||
|
||||
PODFILE CHECKSUM: 236401fc2c932af29a9fcf0e97baeeb2d750d367
|
||||
|
||||
COCOAPODS: 1.12.1
|
||||
COCOAPODS: 1.15.2
|
||||
|
||||
@ -195,7 +195,6 @@
|
||||
DB3AD6E65B5CC8A5A9E2767E /* Pods-RunnerTests.release.xcconfig */,
|
||||
6114E0F2A0E1D978BBC23F48 /* Pods-RunnerTests.profile.xcconfig */,
|
||||
);
|
||||
name = Pods;
|
||||
path = Pods;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
@ -259,7 +258,7 @@
|
||||
isa = PBXProject;
|
||||
attributes = {
|
||||
LastSwiftUpdateCheck = 0920;
|
||||
LastUpgradeCheck = 1430;
|
||||
LastUpgradeCheck = 1510;
|
||||
ORGANIZATIONNAME = "";
|
||||
TargetAttributes = {
|
||||
331C80D4294CF70F00263BE5 = {
|
||||
@ -342,6 +341,7 @@
|
||||
};
|
||||
33CC111E2044C6BF0003C045 /* ShellScript */ = {
|
||||
isa = PBXShellScriptBuildPhase;
|
||||
alwaysOutOfDate = 1;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
);
|
||||
@ -358,7 +358,7 @@
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
shellPath = /bin/sh;
|
||||
shellScript = "\"$FLUTTER_ROOT\"/packages/flutter_tools/bin/macos_assemble.sh && touch Flutter/ephemeral/tripwire";
|
||||
shellScript = "\"$FLUTTER_ROOT\"/packages/flutter_tools/bin/macos_assemble.sh && touch Flutter/ephemeral/tripwire\n";
|
||||
};
|
||||
427A05FAB0ED774C4EAAB828 /* [CP] Check Pods Manifest.lock */ = {
|
||||
isa = PBXShellScriptBuildPhase;
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<Scheme
|
||||
LastUpgradeVersion = "1430"
|
||||
LastUpgradeVersion = "1510"
|
||||
version = "1.3">
|
||||
<BuildAction
|
||||
parallelizeBuildables = "YES"
|
||||
|
||||
528
pubspec.lock
528
pubspec.lock
File diff suppressed because it is too large
Load Diff
40
pubspec.yaml
40
pubspec.yaml
@ -15,7 +15,7 @@ publish_to: "none" # Remove this line if you wish to publish to pub.dev
|
||||
# In iOS, build-name is used as CFBundleShortVersionString while build-number used as CFBundleVersion.
|
||||
# Read more about iOS versioning at
|
||||
# https://developer.apple.com/library/archive/documentation/General/Reference/InfoPlistKeyReference/Articles/CoreFoundationKeys.html
|
||||
version: 1.0.26+26
|
||||
version: 1.0.33+33
|
||||
|
||||
environment:
|
||||
sdk: ">=3.1.0 <4.0.0"
|
||||
@ -35,12 +35,17 @@ dependencies:
|
||||
cupertino_icons: ^1.0.2
|
||||
sqflite: ^2.0.1
|
||||
get: ^4.6.6
|
||||
flutter_map: ^4.0.0
|
||||
geolocator: ^9.0.2
|
||||
permission_handler: ^10.0.0
|
||||
flutter_map: ^6.0.1
|
||||
geolocator: ^10.1.0
|
||||
permission_handler: ^11.3.1
|
||||
# permission_handler: ^11.1.0 <== older
|
||||
# permission_handler 11.2.0 (11.3.1 available)
|
||||
# permission_handler_android 12.0.3 (12.0.5 available)
|
||||
# permission_handler_apple 9.3.0 (9.4.4 available)
|
||||
# permission_handler_platform_interface 4.1.0 (4.2.1 available)
|
||||
google_api_availability: ^5.0.0
|
||||
tuple: ^2.0.0
|
||||
latlong2: ^0.8.1
|
||||
latlong2: ^0.9.0
|
||||
positioned_tap_detector_2: ^1.0.4
|
||||
transparent_image: ^2.0.0
|
||||
async: ^2.8.2
|
||||
@ -53,31 +58,32 @@ dependencies:
|
||||
flutter_map_location_marker: any
|
||||
flutter_map_marker_cluster: any
|
||||
material_design_icons_flutter: ^7.0.7296
|
||||
google_fonts: ^4.0.4
|
||||
google_fonts: ^6.1.0
|
||||
keyboard_dismisser: ^3.0.0
|
||||
image_picker: ^1.0.4
|
||||
#geojson_vi: ^2.0.7
|
||||
geojson: ^1.0.0
|
||||
geojson_vi: ^2.2.1
|
||||
#geojson: ^1.0.0
|
||||
url_launcher: ^6.0.20
|
||||
flutter_breadcrumb: ^1.0.1
|
||||
timeline_tile: ^2.0.0
|
||||
# google_maps_flutter: ^2.5.0
|
||||
#flutter_map_marker_popup: any
|
||||
flutter_polyline_points: ^1.0.0
|
||||
google_maps_webservice: ^0.0.19
|
||||
flutter_typeahead: ^4.0.0
|
||||
flutter_polyline_points: ^2.0.0
|
||||
#google_maps_webservice: ^0.0.20-nullsafety.5
|
||||
flutter_typeahead: ^5.0.1
|
||||
flutter_launcher_icons: ^0.13.1
|
||||
rename: ^2.0.1
|
||||
rename: ^3.0.1
|
||||
circular_menu: ^2.0.1
|
||||
camera_camera: ^3.0.0
|
||||
intl: ^0.18.1
|
||||
modal_bottom_sheet: ^3.0.0-pre
|
||||
connectivity_plus: ^4.0.2
|
||||
flutter_map_tile_caching: ^8.0.1
|
||||
connectivity_plus: ^5.0.2
|
||||
flutter_map_tile_caching: ^9.0.0-dev.5
|
||||
shared_preferences: ^2.0.15
|
||||
gallery_saver: ^2.3.2
|
||||
# gallery_saver: ^2.3.2
|
||||
image_gallery_saver: ^2.0.3
|
||||
flutter_riverpod: ^2.4.0
|
||||
http: ^0.13.6
|
||||
http: ^1.1.0
|
||||
|
||||
flutter_icons:
|
||||
android: true
|
||||
@ -93,7 +99,7 @@ dev_dependencies:
|
||||
# activated in the `analysis_options.yaml` file located at the root of your
|
||||
# package. See that file for information about deactivating specific lint
|
||||
# rules and activating additional ones.
|
||||
flutter_lints: ^2.0.3
|
||||
flutter_lints: ^3.0.1
|
||||
|
||||
# For information on the generic Dart part of this file, see the
|
||||
# following page: https://dart.dev/tools/pub/pubspec
|
||||
|
||||
Reference in New Issue
Block a user