Compare commits
2 Commits
b9c641954d
...
aada6262fe
| Author | SHA1 | Date | |
|---|---|---|---|
| aada6262fe | |||
| 72267f29bb |
@ -7,6 +7,8 @@ import 'package:get/get.dart';
|
||||
//import 'package:vm_service/vm_service.dart';
|
||||
//import 'package:dart_vm_info/dart_vm_info.dart';
|
||||
|
||||
import 'package:rogapp/pages/settings/settings_controller.dart';
|
||||
|
||||
import 'package:rogapp/pages/destination/destination_controller.dart';
|
||||
import 'package:rogapp/pages/index/index_binding.dart';
|
||||
import 'package:rogapp/routes/app_pages.dart';
|
||||
@ -78,6 +80,7 @@ void main() async {
|
||||
//Get.put(LocationController());
|
||||
|
||||
// startMemoryMonitoring(); // 2024-4-8 Akira: メモリ使用量のチェックを開始 See #2810
|
||||
Get.put(SettingsController()); // これを追加
|
||||
|
||||
runZonedGuarded(() {
|
||||
runApp(const ProviderScope(child: MyApp()));
|
||||
|
||||
@ -243,7 +243,10 @@ class CameraPage extends StatelessWidget {
|
||||
destinationController.skipGps = false;
|
||||
destinationController.isPhotoShoot.value = false;
|
||||
Get.snackbar("チェックインしました。",
|
||||
"${destination.sub_loc_id} : ${destination.name}");
|
||||
"${destination.sub_loc_id} : ${destination.name}",
|
||||
backgroundColor: Colors.green,
|
||||
colorText: Colors.white
|
||||
);
|
||||
},
|
||||
child: const Text("チェックイン"))
|
||||
: Container())
|
||||
@ -307,12 +310,18 @@ class CameraPage extends StatelessWidget {
|
||||
if (value['status'] == 'OK') {
|
||||
Get.back();
|
||||
destinationController.skipGps = false;
|
||||
Get.snackbar("目標が保存されました", "目標が正常に追加されました");
|
||||
Get.snackbar("目標が保存されました", "目標が正常に追加されました",
|
||||
backgroundColor: Colors.green,
|
||||
colorText: Colors.white
|
||||
);
|
||||
destinationController.resetRogaining(
|
||||
isgoal: true);
|
||||
} else {
|
||||
//print("---- status ${value['status']} ---- ");
|
||||
Get.snackbar("目標が追加されていません", "please_try_again");
|
||||
Get.snackbar("目標が追加されていません", "please_try_again",
|
||||
backgroundColor: Colors.green,
|
||||
colorText: Colors.white
|
||||
);
|
||||
}
|
||||
});
|
||||
} on Exception catch (_) {
|
||||
@ -358,7 +367,10 @@ class CameraPage extends StatelessWidget {
|
||||
destinationController.skipGps = false;
|
||||
destinationController.isPhotoShoot.value = false;
|
||||
Get.snackbar("お買い物加点を行いました。",
|
||||
"${destination.sub_loc_id} : ${destination.name}");
|
||||
"${destination.sub_loc_id} : ${destination.name}",
|
||||
backgroundColor: Colors.green,
|
||||
colorText: Colors.white
|
||||
);
|
||||
},
|
||||
child: const Text("レシートの写真を撮ってください"))
|
||||
: Container())
|
||||
@ -395,7 +407,10 @@ class CameraPage extends StatelessWidget {
|
||||
destinationController.skipGps = false;
|
||||
destinationController.isPhotoShoot.value = false;
|
||||
Get.snackbar("お買い物加点を行いました。",
|
||||
"${destination.sub_loc_id} : ${destination.name}");
|
||||
"${destination.sub_loc_id} : ${destination.name}",
|
||||
backgroundColor: Colors.green,
|
||||
colorText: Colors.white
|
||||
);
|
||||
},
|
||||
child: const Text("QRコードを読み取ってください"))
|
||||
: Container())
|
||||
@ -430,7 +445,10 @@ class CameraPage extends StatelessWidget {
|
||||
Get.snackbar(
|
||||
"チェックインしました",
|
||||
indexController.currentDestinationFeature[0].name ??
|
||||
"");
|
||||
"",
|
||||
backgroundColor: Colors.green,
|
||||
colorText: Colors.white
|
||||
);
|
||||
},
|
||||
child: const Text("チェックイン"))
|
||||
: Container())
|
||||
@ -677,7 +695,10 @@ class BuyPointCamera extends StatelessWidget {
|
||||
destinationController.skipGps = false;
|
||||
destinationController.isPhotoShoot.value = false;
|
||||
Get.snackbar("お買い物加点を行いました",
|
||||
"${destination.sub_loc_id} : ${destination.name}");
|
||||
"${destination.sub_loc_id} : ${destination.name}",
|
||||
backgroundColor: Colors.green,
|
||||
colorText: Colors.white
|
||||
);
|
||||
},
|
||||
child: const Text("完了"))
|
||||
],
|
||||
|
||||
@ -92,14 +92,16 @@ class ChangePasswordPage extends StatelessWidget {
|
||||
Get.snackbar(
|
||||
"no_values".tr,
|
||||
"values_required".tr,
|
||||
icon: const Icon(
|
||||
backgroundColor: Colors.red,
|
||||
colorText: Colors.white,
|
||||
icon: const Icon(
|
||||
Icons.assistant_photo_outlined,
|
||||
size: 40.0,
|
||||
color: Colors.blue),
|
||||
snackPosition: SnackPosition.TOP,
|
||||
duration: const Duration(
|
||||
milliseconds: 800),
|
||||
backgroundColor: Colors.yellow,
|
||||
//backgroundColor: Colors.yellow,
|
||||
//icon:Image(image:AssetImage("assets/images/dora.png"))
|
||||
);
|
||||
return;
|
||||
|
||||
@ -33,6 +33,7 @@ import 'package:shared_preferences/shared_preferences.dart';
|
||||
|
||||
import 'package:image_gallery_saver/image_gallery_saver.dart';
|
||||
import 'package:rogapp/utils/const.dart';
|
||||
import 'package:logger/logger.dart';
|
||||
|
||||
// 目的地に関連する状態管理とロジックを担当するクラスです。
|
||||
//
|
||||
@ -325,6 +326,16 @@ class DestinationController extends GetxController {
|
||||
ds.isNotEmpty && ds[0].checkedin == true ? true : false;
|
||||
bool isuserLoggedIn = indexController.currentUser.isNotEmpty ? true : false; // ログイン済みか
|
||||
|
||||
/*
|
||||
// スタートとゴールは除外
|
||||
debugPrint("startTimer CP=${d.cp}");
|
||||
if (d.cp == -1 || d.cp == 0 || d.cp == -2) {
|
||||
skipGps = false;
|
||||
return;
|
||||
}
|
||||
|
||||
*/
|
||||
|
||||
// 初期化。GPS信号が強くても弱くても
|
||||
if (checkinRadious >= distance || checkinRadious == -1) {
|
||||
//currentSelectedDestinations.add(d);
|
||||
@ -835,11 +846,13 @@ class DestinationController extends GetxController {
|
||||
Get.snackbar(
|
||||
"ロゲが始まっていません",
|
||||
"ロゲ開始ボタンをタップして、ロゲイニングを始める必要があります",
|
||||
icon: const Icon(
|
||||
backgroundColor: Colors.yellow,
|
||||
colorText: Colors.white,
|
||||
icon: const Icon(
|
||||
Icons.assistant_photo_outlined, size: 40.0, color: Colors.blue),
|
||||
snackPosition: SnackPosition.TOP,
|
||||
duration: const Duration(seconds: 3),
|
||||
backgroundColor: Colors.yellow,
|
||||
duration: const Duration(seconds: 3)
|
||||
// backgroundColor: Colors.yellow,
|
||||
);
|
||||
}
|
||||
}
|
||||
@ -940,6 +953,8 @@ class DestinationController extends GetxController {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
// ロゲイニングにデータを追加する関数です。
|
||||
//
|
||||
void addToRogaining(double lat, double lon, int destinationId) async {
|
||||
@ -966,13 +981,18 @@ class DestinationController extends GetxController {
|
||||
// 指定されたパスの画像をギャラリーに保存する関数です。
|
||||
//
|
||||
_saveImageFromPath(String imagePath) async {
|
||||
// Read the image file from the given path
|
||||
File imageFile = File(imagePath);
|
||||
Uint8List imageBytes = await imageFile.readAsBytes();
|
||||
try {
|
||||
// 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}");
|
||||
// Save the image to the gallery
|
||||
final result = await ImageGallerySaver.saveImage(imageBytes);
|
||||
//print("--- save result --- ${result}");
|
||||
} catch(e, stackTrace){
|
||||
print('エラーが発生しました: $e');
|
||||
print('スタックトレース: $stackTrace');
|
||||
}
|
||||
}
|
||||
|
||||
// 買い物ポイントを作成する関数です。 指定された目的地に対して買い物ポイントの処理を行います。
|
||||
@ -1009,64 +1029,82 @@ class DestinationController extends GetxController {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// チェックインを行う関数です。 指定された目的地に対してチェックインの処理を行います。
|
||||
//
|
||||
// 要検討:チェックインのリクエストが失敗した場合のエラーハンドリングを追加することをお勧めします。
|
||||
//
|
||||
Future<void> makeCheckin(
|
||||
Destination destination, bool action, String imageurl) async {
|
||||
// print("~~~~ calling checkin function ~~~~");
|
||||
// print(
|
||||
// "@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ ressssss ${destination.sub_loc_id}@@@@@@@@@@@");
|
||||
DatabaseHelper db = DatabaseHelper.instance;
|
||||
List<Destination> ddd =
|
||||
await db.getDestinationByLatLon(destination.lat!, destination.lon!);
|
||||
|
||||
if (ddd.isEmpty) {
|
||||
destination.checkedin = true;
|
||||
destination.checkin_image = imageurl;
|
||||
await db.insertDestination(destination);
|
||||
// print("~~~~ inserted into db ~~~~");
|
||||
}
|
||||
try {
|
||||
// print("~~~~ calling checkin function ~~~~");
|
||||
// print(
|
||||
// "@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ ressssss ${destination.sub_loc_id}@@@@@@@@@@@");
|
||||
DatabaseHelper db = DatabaseHelper.instance;
|
||||
List<Destination> ddd =
|
||||
await db.getDestinationByLatLon(destination.lat!, destination.lon!);
|
||||
|
||||
if (imageurl == null || imageurl.isEmpty) {
|
||||
if (photos.isNotEmpty) {
|
||||
// imageurlが空の場合は、destinationのcheckin_imageプロパティを使用する
|
||||
debugPrint("photos = ${photos}");
|
||||
imageurl = photos[0].path;
|
||||
if (ddd.isEmpty) {
|
||||
destination.checkedin = true;
|
||||
destination.checkin_image = imageurl;
|
||||
await db.insertDestination(destination);
|
||||
// print("~~~~ inserted into db ~~~~");
|
||||
}
|
||||
debugPrint("imageurl = ${imageurl}");
|
||||
await _saveImageFromPath(imageurl!);
|
||||
|
||||
if (imageurl == null || imageurl.isEmpty) {
|
||||
if (photos.isNotEmpty) {
|
||||
// imageurlが空の場合は、destinationのcheckin_imageプロパティを使用する
|
||||
debugPrint("photos = ${photos}");
|
||||
imageurl = photos[0].path;
|
||||
}
|
||||
debugPrint("imageurl = ${imageurl}");
|
||||
await _saveImageFromPath(imageurl!);
|
||||
}
|
||||
|
||||
populateDestinations();
|
||||
|
||||
/// post to NATNAT
|
||||
if (indexController.currentUser.isNotEmpty) {
|
||||
double cpNum = destination.cp!;
|
||||
|
||||
int userId = indexController.currentUser[0]["user"]["id"];
|
||||
//print("--- Pressed -----");
|
||||
String team = indexController.currentUser[0]["user"]['team_name'];
|
||||
//print("--- _team : ${_team}-----");
|
||||
String eventCode = indexController.currentUser[0]["user"]["event_code"];
|
||||
//print("--- _event_code : ${_event_code}-----");
|
||||
String token = indexController.currentUser[0]["token"];
|
||||
//print("--- _token : ${_token}-----");
|
||||
DateTime now = DateTime.now();
|
||||
String formattedDate = DateFormat('yyyy-MM-dd HH:mm:ss').format(now);
|
||||
|
||||
await addGPStoDB(currentLat, currentLon, isCheckin: 1);
|
||||
|
||||
// print("------ checkin event $eventCode ------");
|
||||
ExternalService()
|
||||
.makeCheckpoint(
|
||||
userId,
|
||||
token,
|
||||
formattedDate,
|
||||
team,
|
||||
cpNum.round(),
|
||||
eventCode,
|
||||
imageurl)
|
||||
.then((value) {
|
||||
// print("------Ext service check point $value ------");
|
||||
});
|
||||
}
|
||||
// dbService.updateDatabase();
|
||||
|
||||
}catch(e, stacktrace){
|
||||
print("エラー:${e}");
|
||||
//print("stack : ${stacktrace}");
|
||||
}finally{
|
||||
dbService.updateDatabase();
|
||||
}
|
||||
|
||||
populateDestinations();
|
||||
|
||||
/// post to NATNAT
|
||||
if (indexController.currentUser.isNotEmpty) {
|
||||
double cpNum = destination.cp!;
|
||||
|
||||
int userId = indexController.currentUser[0]["user"]["id"];
|
||||
//print("--- Pressed -----");
|
||||
String team = indexController.currentUser[0]["user"]['team_name'];
|
||||
//print("--- _team : ${_team}-----");
|
||||
String eventCode = indexController.currentUser[0]["user"]["event_code"];
|
||||
//print("--- _event_code : ${_event_code}-----");
|
||||
String token = indexController.currentUser[0]["token"];
|
||||
//print("--- _token : ${_token}-----");
|
||||
DateTime now = DateTime.now();
|
||||
String formattedDate = DateFormat('yyyy-MM-dd HH:mm:ss').format(now);
|
||||
|
||||
await addGPStoDB(currentLat, currentLon, isCheckin: 1);
|
||||
|
||||
// print("------ checkin event $eventCode ------");
|
||||
ExternalService()
|
||||
.makeCheckpoint(userId, token, formattedDate, team, cpNum.round(),
|
||||
eventCode, imageurl)
|
||||
.then((value) {
|
||||
// print("------Ext service check point $value ------");
|
||||
});
|
||||
}
|
||||
dbService.updateDatabase();
|
||||
}
|
||||
|
||||
// チェックインを削除する関数です。
|
||||
@ -1580,11 +1618,13 @@ class DestinationController extends GetxController {
|
||||
Get.snackbar(
|
||||
"画面切り替えでエラー",
|
||||
"画面の切り替えができませんでした",
|
||||
icon: const Icon(
|
||||
backgroundColor: Colors.red,
|
||||
colorText: Colors.white,
|
||||
icon: const Icon(
|
||||
Icons.assistant_photo_outlined, size: 40.0, color: Colors.blue),
|
||||
snackPosition: SnackPosition.TOP,
|
||||
duration: const Duration(seconds: 3),
|
||||
backgroundColor: Colors.yellow,
|
||||
//backgroundColor: Colors.yellow,
|
||||
);
|
||||
|
||||
}
|
||||
|
||||
@ -4,6 +4,7 @@ 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/auth_service.dart';
|
||||
import 'package:rogapp/utils/database_helper.dart';
|
||||
import 'package:url_launcher/url_launcher.dart';
|
||||
|
||||
// SafeAreaウィジェットを使用して、画面の安全領域内にメニューを表示しています。
|
||||
@ -127,12 +128,26 @@ class DrawerPage extends StatelessWidget {
|
||||
textConfirm: "確認する",
|
||||
textCancel: "キャンセルする",
|
||||
onCancel: () => Get.back(),
|
||||
onConfirm: () {
|
||||
onConfirm: () async {
|
||||
DestinationController destinationController =
|
||||
Get.find<DestinationController>();
|
||||
DatabaseHelper databaseHelper = DatabaseHelper.instance;
|
||||
|
||||
// ゲーム中のデータを削除
|
||||
await databaseHelper.deleteAllRogaining();
|
||||
await databaseHelper.deleteAllDestinations();
|
||||
destinationController.resetRogaining();
|
||||
destinationController.deleteDBDestinations();
|
||||
|
||||
//destinationController.resetRogaining();
|
||||
//destinationController.deleteDBDestinations();
|
||||
Get.back();
|
||||
Get.snackbar(
|
||||
"リセット完了",
|
||||
"すべてリセットされました。ロゲ開始から再開して下さい。",
|
||||
backgroundColor: Colors.green,
|
||||
colorText: Colors.white,
|
||||
duration: const Duration(seconds: 3),
|
||||
);
|
||||
},
|
||||
);
|
||||
},
|
||||
@ -161,7 +176,10 @@ class DrawerPage extends StatelessWidget {
|
||||
indexController.logout();
|
||||
Get.toNamed(AppPages.TRAVEL);
|
||||
Get.snackbar("accounted_deleted".tr,
|
||||
"account_deleted_message".tr);
|
||||
"account_deleted_message".tr,
|
||||
backgroundColor: Colors.green,
|
||||
colorText: Colors.white
|
||||
);
|
||||
}
|
||||
});
|
||||
},
|
||||
@ -172,6 +190,7 @@ class DrawerPage extends StatelessWidget {
|
||||
width: 0,
|
||||
height: 0,
|
||||
),
|
||||
/*
|
||||
// ユーザーデータ削除のアイテムは、ユーザーがログインしている場合にのみ表示されます。
|
||||
// タップすると、AuthService.deleteUser()を呼び出してユーザーデータを削除します。
|
||||
indexController.currentUser.isNotEmpty
|
||||
@ -215,7 +234,7 @@ class DrawerPage extends StatelessWidget {
|
||||
// title: Text("point_rank".tr),
|
||||
// onTap: (){},
|
||||
// ),
|
||||
|
||||
*/
|
||||
// "rog_web".trというテキストのアイテムは、ユーザーがログインしている場合にのみ表示されます。
|
||||
// タップすると、_launchURL()メソッドを呼び出して外部のウェブサイトを開きます。
|
||||
indexController.currentUser.isNotEmpty
|
||||
@ -238,6 +257,15 @@ class DrawerPage extends StatelessWidget {
|
||||
onTap: () {
|
||||
_launchURL("https://rogaining.sumasen.net/api/privacy/");
|
||||
},
|
||||
),
|
||||
ListTile(
|
||||
leading: const Icon(Icons.settings),
|
||||
title: const Text('設定'),
|
||||
onTap: () {
|
||||
Get.back(); // ドロワーを閉じる
|
||||
Get.toNamed(Routes.SETTINGS);
|
||||
},
|
||||
|
||||
)
|
||||
// ListTile(
|
||||
// leading: const Icon(Icons.router),
|
||||
|
||||
@ -101,7 +101,7 @@ class _GpsPageState extends State<GpsPage> {
|
||||
Widget build(BuildContext context) {
|
||||
return Scaffold(
|
||||
appBar: AppBar(
|
||||
title: Text("GPS way points"),
|
||||
title: Text("移動履歴"),
|
||||
),
|
||||
body: Container(
|
||||
child: Obx(
|
||||
|
||||
@ -205,10 +205,12 @@ class IndexController extends GetxController {
|
||||
Get.snackbar(
|
||||
"ログイン失敗",
|
||||
"ログインIDかパスワードを確認して下さい。",
|
||||
icon: const Icon(Icons.error, size: 40.0, color: Colors.blue),
|
||||
backgroundColor: Colors.red,
|
||||
colorText: Colors.white,
|
||||
icon: const Icon(Icons.error, size: 40.0, color: Colors.blue),
|
||||
snackPosition: SnackPosition.TOP,
|
||||
duration: const Duration(seconds: 3),
|
||||
backgroundColor: Colors.yellow,
|
||||
//backgroundColor: Colors.yellow,
|
||||
//icon:Image(image:AssetImage("assets/images/dora.png"))
|
||||
);
|
||||
}
|
||||
@ -235,10 +237,12 @@ class IndexController extends GetxController {
|
||||
Get.snackbar(
|
||||
'failed'.tr,
|
||||
'password_change_failed_please_try_again'.tr,
|
||||
icon: const Icon(Icons.error, size: 40.0, color: Colors.blue),
|
||||
backgroundColor: Colors.red,
|
||||
colorText: Colors.white,
|
||||
icon: const Icon(Icons.error, size: 40.0, color: Colors.blue),
|
||||
snackPosition: SnackPosition.TOP,
|
||||
duration: const Duration(milliseconds: 800),
|
||||
backgroundColor: Colors.yellow,
|
||||
//backgroundColor: Colors.yellow,
|
||||
//icon:Image(image:AssetImage("assets/images/dora.png"))
|
||||
);
|
||||
}
|
||||
@ -277,10 +281,12 @@ class IndexController extends GetxController {
|
||||
Get.snackbar(
|
||||
'failed'.tr,
|
||||
'user_registration_failed_please_try_again'.tr,
|
||||
icon: const Icon(Icons.error, size: 40.0, color: Colors.blue),
|
||||
backgroundColor: Colors.red,
|
||||
colorText: Colors.white,
|
||||
icon: const Icon(Icons.error, size: 40.0, color: Colors.blue),
|
||||
snackPosition: SnackPosition.TOP,
|
||||
duration: const Duration(milliseconds: 800),
|
||||
backgroundColor: Colors.yellow,
|
||||
//backgroundColor: Colors.yellow,
|
||||
//icon:Image(image:AssetImage("assets/images/dora.png"))
|
||||
);
|
||||
}
|
||||
@ -455,11 +461,13 @@ class IndexController extends GetxController {
|
||||
Get.snackbar(
|
||||
"Too many Points",
|
||||
"please zoom in",
|
||||
icon: const Icon(
|
||||
backgroundColor: Colors.yellow,
|
||||
colorText: Colors.white,
|
||||
icon: const Icon(
|
||||
Icons.assistant_photo_outlined, size: 40.0, color: Colors.blue),
|
||||
snackPosition: SnackPosition.TOP,
|
||||
duration: const Duration(seconds: 3),
|
||||
backgroundColor: Colors.yellow,
|
||||
//backgroundColor: Colors.yellow,
|
||||
);
|
||||
showPopup = false;
|
||||
}
|
||||
|
||||
@ -107,7 +107,9 @@ class LoginPage extends StatelessWidget {
|
||||
"no_values".tr,
|
||||
"email_and_password_required"
|
||||
.tr,
|
||||
icon: const Icon(
|
||||
backgroundColor: Colors.red,
|
||||
colorText: Colors.white,
|
||||
icon: const Icon(
|
||||
Icons
|
||||
.assistant_photo_outlined,
|
||||
size: 40.0,
|
||||
@ -116,7 +118,7 @@ class LoginPage extends StatelessWidget {
|
||||
SnackPosition.TOP,
|
||||
duration: const Duration(
|
||||
seconds: 3),
|
||||
backgroundColor: Colors.yellow,
|
||||
// backgroundColor: Colors.yellow,
|
||||
//icon:Image(image:AssetImage("assets/images/dora.png"))
|
||||
);
|
||||
return;
|
||||
@ -262,10 +264,11 @@ class LoginPage extends StatelessWidget {
|
||||
child: Padding(
|
||||
padding: EdgeInsets.all(8.0),
|
||||
child: Text(
|
||||
"※第8回と第9回は、岐阜県からの「清流の国ぎふ」SDGs推進ネットワーク連携促進補助金を受けています",
|
||||
"※第8回と第9回は、岐阜県の令和5年度「清流の国ぎふ」SDGs推進ネットワーク連携促進補助金を受けています",
|
||||
style: TextStyle(
|
||||
//overflow: TextOverflow.ellipsis,
|
||||
fontSize:
|
||||
12, // Consider adjusting the font size if the text is too small.
|
||||
10.0, // Consider adjusting the font size if the text is too small.
|
||||
// Removed overflow: TextOverflow.ellipsis to allow text wrapping.
|
||||
),
|
||||
),
|
||||
|
||||
@ -100,6 +100,8 @@ class LoginPopupPage extends StatelessWidget {
|
||||
"no_values".tr,
|
||||
"email_and_password_required"
|
||||
.tr,
|
||||
backgroundColor: Colors.red,
|
||||
colorText: Colors.white,
|
||||
icon: const Icon(
|
||||
Icons
|
||||
.assistant_photo_outlined,
|
||||
@ -109,7 +111,7 @@ class LoginPopupPage extends StatelessWidget {
|
||||
SnackPosition.TOP,
|
||||
duration: const Duration(
|
||||
milliseconds: 800),
|
||||
backgroundColor: Colors.yellow,
|
||||
//backgroundColor: Colors.yellow,
|
||||
//icon:Image(image:AssetImage("assets/images/dora.png"))
|
||||
);
|
||||
return;
|
||||
|
||||
@ -101,11 +101,13 @@ class RegisterPage extends StatelessWidget {
|
||||
Get.snackbar(
|
||||
"No match",
|
||||
"Passwords does not match",
|
||||
icon: const Icon(Icons.assistant_photo_outlined,
|
||||
backgroundColor: Colors.red,
|
||||
colorText: Colors.white,
|
||||
icon: const Icon(Icons.assistant_photo_outlined,
|
||||
size: 40.0, color: Colors.blue),
|
||||
snackPosition: SnackPosition.TOP,
|
||||
duration: const Duration(milliseconds: 800),
|
||||
backgroundColor: Colors.yellow,
|
||||
// backgroundColor: Colors.yellow,
|
||||
//icon:Image(image:AssetImage("assets/images/dora.png"))
|
||||
);
|
||||
}
|
||||
@ -114,11 +116,13 @@ class RegisterPage extends StatelessWidget {
|
||||
Get.snackbar(
|
||||
"no_values".tr,
|
||||
"email_and_password_required".tr,
|
||||
icon: const Icon(Icons.assistant_photo_outlined,
|
||||
backgroundColor: Colors.red,
|
||||
colorText: Colors.white,
|
||||
icon: const Icon(Icons.assistant_photo_outlined,
|
||||
size: 40.0, color: Colors.blue),
|
||||
snackPosition: SnackPosition.TOP,
|
||||
duration: const Duration(milliseconds: 800),
|
||||
backgroundColor: Colors.yellow,
|
||||
//backgroundColor: Colors.yellow,
|
||||
//icon:Image(image:AssetImage("assets/images/dora.png"))
|
||||
);
|
||||
return;
|
||||
|
||||
12
lib/pages/settings/settings_binding.dart
Normal file
12
lib/pages/settings/settings_binding.dart
Normal file
@ -0,0 +1,12 @@
|
||||
// lib/pages/settings/settings_binding.dart
|
||||
|
||||
import 'package:get/get.dart';
|
||||
import 'package:rogapp/pages/settings/settings_controller.dart';
|
||||
|
||||
class SettingsBinding extends Bindings {
|
||||
@override
|
||||
void dependencies() {
|
||||
Get.put<SettingsController>(SettingsController()); // これを修正
|
||||
//Get.lazyPut<SettingsController>(() => SettingsController());
|
||||
}
|
||||
}
|
||||
26
lib/pages/settings/settings_controller.dart
Normal file
26
lib/pages/settings/settings_controller.dart
Normal file
@ -0,0 +1,26 @@
|
||||
// lib/pages/settings/settings_controller.dart
|
||||
|
||||
import 'package:get/get.dart';
|
||||
import 'package:rogapp/widgets/map_widget.dart';
|
||||
|
||||
|
||||
class SettingsController extends GetxController {
|
||||
var timerDuration = Duration(seconds: 10).obs;
|
||||
var autoReturnDisabled = false.obs;
|
||||
final MapResetController mapResetController = Get.put(MapResetController());
|
||||
|
||||
void updateTimerDuration(int seconds) {
|
||||
timerDuration.value = Duration(seconds: seconds);
|
||||
}
|
||||
|
||||
void setAutoReturnDisabled(bool value) {
|
||||
autoReturnDisabled.value = value;
|
||||
if (!value) {
|
||||
resetIdleTimer();
|
||||
}
|
||||
}
|
||||
|
||||
void resetIdleTimer() {
|
||||
mapResetController.resetIdleTimer!();
|
||||
}
|
||||
}
|
||||
63
lib/pages/settings/settings_page.dart
Normal file
63
lib/pages/settings/settings_page.dart
Normal file
@ -0,0 +1,63 @@
|
||||
// lib/pages/settings/settings_page.dart
|
||||
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:get/get.dart';
|
||||
import 'package:rogapp/pages/settings/settings_controller.dart';
|
||||
|
||||
class SettingsPage extends GetView<SettingsController> {
|
||||
const SettingsPage({Key? key}) : super(key: key);
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Scaffold(
|
||||
appBar: AppBar(
|
||||
title: const Text('設定'),
|
||||
),
|
||||
body: Padding(
|
||||
padding: const EdgeInsets.all(16.0),
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
const Text(
|
||||
'タイマーの長さ',
|
||||
style: TextStyle(
|
||||
fontSize: 18,
|
||||
fontWeight: FontWeight.bold,
|
||||
),
|
||||
),
|
||||
const SizedBox(height: 8),
|
||||
Obx(
|
||||
() => controller.autoReturnDisabled.value
|
||||
? Container()
|
||||
: Slider(
|
||||
value: controller.timerDuration.value.inSeconds.toDouble(),
|
||||
min: 5,
|
||||
max: 30,
|
||||
divisions: 5,
|
||||
label: '${controller.timerDuration.value.inSeconds}秒',
|
||||
onChanged: (value) {
|
||||
controller.updateTimerDuration(value.toInt());
|
||||
},
|
||||
),
|
||||
),
|
||||
const SizedBox(height: 8),
|
||||
const Text(
|
||||
'マップ操作がなければ自動的に現在地に復帰します。そのタイマー秒数を入れて下さい。チェックボックスをチェックすると、自動復帰は行われなくなります。',
|
||||
style: TextStyle(fontSize: 14),
|
||||
),
|
||||
const SizedBox(height: 16),
|
||||
Obx(
|
||||
() => CheckboxListTile(
|
||||
title: const Text('自動復帰なし'),
|
||||
value: controller.autoReturnDisabled.value,
|
||||
onChanged: (value) {
|
||||
controller.setAutoReturnDisabled(value!);
|
||||
},
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
@ -19,6 +19,8 @@ import 'package:rogapp/pages/progress/progress.dart';
|
||||
import 'package:rogapp/pages/register/register_page.dart';
|
||||
import 'package:rogapp/pages/search/search_binding.dart';
|
||||
import 'package:rogapp/pages/search/search_page.dart';
|
||||
import 'package:rogapp/pages/settings/settings_page.dart';
|
||||
import 'package:rogapp/pages/settings/settings_binding.dart';
|
||||
import 'package:rogapp/pages/subperf/subperf_page.dart';
|
||||
import 'package:rogapp/spa/spa_binding.dart';
|
||||
import 'package:rogapp/spa/spa_page.dart';
|
||||
@ -48,6 +50,7 @@ class AppPages {
|
||||
static const PROGRESS = Routes.PROGRESS;
|
||||
static const HISTORY = Routes.HISTORY;
|
||||
static const GPS = Routes.GPS;
|
||||
static const SETTINGS = Routes.SETTINGS;
|
||||
|
||||
static final routes = [
|
||||
GetPage(
|
||||
@ -108,6 +111,11 @@ class AppPages {
|
||||
GetPage(
|
||||
name: Routes.GPS,
|
||||
page: () => const GpsPage(),
|
||||
),
|
||||
GetPage(
|
||||
name: Routes.SETTINGS,
|
||||
page: () => const SettingsPage(),
|
||||
binding: SettingsBinding(),
|
||||
)
|
||||
];
|
||||
}
|
||||
|
||||
@ -26,4 +26,5 @@ abstract class Routes {
|
||||
static const PROGRESS = '/progress';
|
||||
static const HISTORY = '/history';
|
||||
static const GPS = '/gp';
|
||||
static const SETTINGS = '/settings';
|
||||
}
|
||||
|
||||
@ -110,15 +110,19 @@ class AuthService {
|
||||
}
|
||||
} catch( e ){
|
||||
print('Error in login: $e');
|
||||
Get.snackbar("通信エラーがおきました", "サーバーと通信できませんでした");
|
||||
Get.snackbar("通信エラーがおきました", "サーバーと通信できませんでした",
|
||||
backgroundColor: Colors.red,
|
||||
colorText: Colors.white);
|
||||
Get.snackbar(
|
||||
"通信エラーがおきました",
|
||||
"サーバーと通信できませんでした",
|
||||
backgroundColor: Colors.red,
|
||||
colorText: Colors.white,
|
||||
icon: const Icon(
|
||||
Icons.assistant_photo_outlined, size: 40.0, color: Colors.blue),
|
||||
snackPosition: SnackPosition.TOP,
|
||||
duration: const Duration(seconds: 3),
|
||||
backgroundColor: Colors.yellow,
|
||||
//backgroundColor: Colors.yellow,
|
||||
);
|
||||
cats = {};
|
||||
}
|
||||
|
||||
@ -1,4 +1,5 @@
|
||||
import 'dart:io';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:get/get.dart';
|
||||
import 'package:http/http.dart' as http;
|
||||
import 'package:intl/intl.dart';
|
||||
@ -32,6 +33,8 @@ class ExternalService {
|
||||
Future<Map<String, dynamic>> startRogaining() async {
|
||||
final IndexController indexController = Get.find<IndexController>();
|
||||
|
||||
debugPrint("== startRogaining ==");
|
||||
|
||||
Map<String, dynamic> res = {};
|
||||
|
||||
int userId = indexController.currentUser[0]["user"]["id"];
|
||||
@ -42,6 +45,7 @@ class ExternalService {
|
||||
|
||||
if (indexController.connectionStatusName.value != "wifi" &&
|
||||
indexController.connectionStatusName.value != "mobile") {
|
||||
debugPrint("== No network ==");
|
||||
DatabaseHelper db = DatabaseHelper.instance;
|
||||
Rog rog = Rog(
|
||||
id: 1,
|
||||
@ -54,6 +58,8 @@ class ExternalService {
|
||||
rog_action_type: 0);
|
||||
db.insertRogaining(rog);
|
||||
} else {
|
||||
debugPrint("== startRogaining processing==");
|
||||
|
||||
String url = 'https://rogaining.sumasen.net/gifuroge/start_from_rogapp';
|
||||
//print('++++++++$url');
|
||||
final http.Response response = await http.post(
|
||||
@ -94,6 +100,8 @@ class ExternalService {
|
||||
if (imageurl != null) {
|
||||
if (indexController.connectionStatusName.value != "wifi" &&
|
||||
indexController.connectionStatusName.value != "mobile") {
|
||||
debugPrint("== checkin without network ==");
|
||||
|
||||
DatabaseHelper db = DatabaseHelper.instance;
|
||||
Rog rog = Rog(
|
||||
id: 1,
|
||||
@ -107,6 +115,7 @@ class ExternalService {
|
||||
);
|
||||
db.insertRogaining(rog);
|
||||
} else {
|
||||
debugPrint("== Normal Check in ===");
|
||||
String serverUrl = ConstValues.currentServer();
|
||||
String url1 = "$serverUrl/api/checkinimage/";
|
||||
final im1Bytes = File(imageurl).readAsBytesSync();
|
||||
@ -167,16 +176,26 @@ class ExternalService {
|
||||
if (response2.statusCode == 200) {
|
||||
res = json.decode(utf8.decode(response2.bodyBytes));
|
||||
//print('----checkin res _res : $res ----');
|
||||
if (res["status"] == "ERROR") {
|
||||
Get.snackbar("エラーがおきました", res["detail"]);
|
||||
if (res["status"] == "ERROR" && cp>0 ) {
|
||||
// スタート・ゴールはエラー除外。
|
||||
Get.snackbar("エラーがおきました", res["detail"],
|
||||
backgroundColor: Colors.red,
|
||||
colorText: Colors.white
|
||||
);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
Get.snackbar("サーバーエラーがおきました", "サーバーと通信できませんでした");
|
||||
Get.snackbar("サーバーエラーがおきました", "サーバーと通信できませんでした",
|
||||
backgroundColor: Colors.red,
|
||||
colorText: Colors.white
|
||||
);
|
||||
}
|
||||
} catch( e ) {
|
||||
print('Error in makeCheckpoint: $e');
|
||||
Get.snackbar("通信エラーがおきました", "サーバーと通信できませんでした");
|
||||
Get.snackbar("通信エラーがおきました", "サーバーと通信できませんでした",
|
||||
backgroundColor: Colors.red,
|
||||
colorText: Colors.white
|
||||
);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
@ -234,6 +253,8 @@ class ExternalService {
|
||||
final DestinationController destinationController =
|
||||
Get.find<DestinationController>();
|
||||
|
||||
debugPrint("== goal Rogaining ==");
|
||||
|
||||
//if(indexController.connectionStatusName != "wifi" && indexController.connectionStatusName != "mobile"){
|
||||
DatabaseHelper db = DatabaseHelper.instance;
|
||||
Rog rog = Rog(
|
||||
|
||||
@ -79,7 +79,7 @@ class StringValues extends Translations{
|
||||
'drawer_title':'ロゲイニング参加者はログイン するとチェックポイントが参照 できます',
|
||||
'app_title': '旅行工程表',
|
||||
'address':'住所',
|
||||
'email':'Eメール',
|
||||
'email':'ゼッケン番号',
|
||||
'password':'パスワード',
|
||||
'web':'ウェブ',
|
||||
'wikipedia':'ウィキペディア',
|
||||
@ -147,7 +147,7 @@ class StringValues extends Translations{
|
||||
"accounted_deleted": "アカウントが削除されました",
|
||||
"account_deleted_message": "あなたのアカウントは正常に削除されました",
|
||||
"privacy": "プライバシーポリシー",
|
||||
"app_developed_by_gifu_dx": "このアプリは岐阜県DX補助金事業で開発されました。"
|
||||
"app_developed_by_gifu_dx": "※このアプリは令和4年度岐阜県DX補助金事業で開発されました。"
|
||||
},
|
||||
};
|
||||
}
|
||||
@ -15,7 +15,7 @@ class GameStatusIndicator extends StatelessWidget {
|
||||
IconData iconData =
|
||||
gameStarted ? Icons.stop_circle : Icons.play_circle_filled;
|
||||
// Text to show based on the game status
|
||||
String text = gameStarted ? 'ゲーム開始' : 'ゲーム未開始';
|
||||
String text = gameStarted ? 'ゲーム中' : 'ゲーム前';
|
||||
|
||||
// Layout for minimized view
|
||||
if (minimized) {
|
||||
|
||||
@ -198,6 +198,7 @@ class BottomSheetNew extends GetView<BottomSheetController> {
|
||||
// Clear data and start game logic here
|
||||
destinationController.isInRog.value = true;
|
||||
destinationController.resetRogaining();
|
||||
|
||||
destinationController.addToRogaining(
|
||||
destinationController.currentLat,
|
||||
destinationController.currentLon,
|
||||
@ -480,16 +481,37 @@ class BottomSheetNew extends GetView<BottomSheetController> {
|
||||
// Finish or Goal
|
||||
getActionButton(context, destination),
|
||||
//remove checkin
|
||||
isAlreadyCheckedIn == true && destination.cp != -1
|
||||
isAlreadyCheckedIn == true && destination.cp != 0 && destination.cp != -1 && destination.cp != -2
|
||||
? ElevatedButton(
|
||||
style: ElevatedButton.styleFrom(
|
||||
backgroundColor: Colors.blueAccent),
|
||||
onPressed: () async {
|
||||
await destinationController
|
||||
.removeCheckin(destination.cp!.toInt());
|
||||
destinationController
|
||||
.deleteDestination(destination);
|
||||
Get.back();
|
||||
try {
|
||||
await destinationController
|
||||
.removeCheckin(destination.cp!.toInt());
|
||||
destinationController
|
||||
.deleteDestination(destination);
|
||||
Get.back();
|
||||
Get.snackbar(
|
||||
'チェックイン取り消し',
|
||||
'${destination
|
||||
.name}のチェックインは取り消されました',
|
||||
backgroundColor: Colors.green,
|
||||
colorText: Colors.white,
|
||||
duration: Duration(seconds: 3),
|
||||
);
|
||||
} catch (e ) {
|
||||
// エラーハンドリング
|
||||
Get.snackbar(
|
||||
'Error',
|
||||
'An error occurred while canceling check-in.',
|
||||
backgroundColor: Colors.red,
|
||||
colorText: Colors.white,
|
||||
duration: Duration(seconds: 3),
|
||||
);
|
||||
// 必要に応じてエラーログを記録
|
||||
print('Error canceling check-in: $e');
|
||||
}
|
||||
},
|
||||
child: const Text(
|
||||
"チェックイン取消",
|
||||
|
||||
@ -1,325 +0,0 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:get/get.dart';
|
||||
import 'package:geolocator/geolocator.dart';
|
||||
import 'package:rogapp/model/destination.dart';
|
||||
import 'package:rogapp/pages/index/index_controller.dart';
|
||||
import 'package:rogapp/utils/const.dart';
|
||||
import 'package:url_launcher/url_launcher.dart';
|
||||
import 'package:rogapp/pages/destination/destination_controller.dart';
|
||||
|
||||
|
||||
class BottomSheetBase extends StatelessWidget {
|
||||
|
||||
BottomSheetBase({super.key, required this.destination,this.isAlreadyCheckedIn = false});
|
||||
|
||||
final IndexController indexController = Get.find<IndexController>();
|
||||
final DestinationController destinationController = Get.find<DestinationController>();
|
||||
|
||||
final bool isAlreadyCheckedIn; // すでにチェックイン済みかどうかのフラグ
|
||||
final Destination destination; // 目的地オブジェクト
|
||||
|
||||
|
||||
// そのポイントの写真を取得するメソッド
|
||||
//
|
||||
Image getImage() {
|
||||
String serverUrl = ConstValues.currentServer();
|
||||
|
||||
// currentDestinationFeature(destinationそのもの)のphotoデータのチェック
|
||||
// Nouffer のコードでは、indexController.rogMode によって、destination(currentDestinationFeature) かGeoJSONFeature(currentFeature)の違いで処理が分かれていた。
|
||||
// しかし、現在のコードでは GeoJSONFeature gf = indexController.currentFeature[0]; は使われていない。
|
||||
//
|
||||
if (indexController.currentDestinationFeature[0].photos! == "") {
|
||||
// 定義されていなければ、empty_image.png を選択
|
||||
return const Image(image: AssetImage('assets/images/empty_image.png'));
|
||||
} else {
|
||||
String photo = indexController.currentDestinationFeature[0].photos!;
|
||||
if (photo.contains('http')) {
|
||||
// photo にhttpの文字が含まれていれば、ネットから拾ってくる。エラーならempty_image.pngを表示。
|
||||
return Image(
|
||||
image: NetworkImage(
|
||||
indexController.currentDestinationFeature[0].photos!,
|
||||
),
|
||||
errorBuilder:
|
||||
(BuildContext context, Object exception, StackTrace? stackTrace) {
|
||||
return Image.asset("assets/images/empty_image.png");
|
||||
},
|
||||
);
|
||||
} else {
|
||||
// photo にhttpの文字が含まれていなければ、指定サーバー($serverUrl/media/compressed/*)から拾ってくる。エラーならempty_image.pngを表示。
|
||||
return Image(
|
||||
image: NetworkImage(
|
||||
'$serverUrl/media/compressed/${indexController.currentDestinationFeature[0].photos!}',
|
||||
),
|
||||
errorBuilder:
|
||||
(BuildContext context, Object exception, StackTrace? stackTrace) {
|
||||
return Image.asset("assets/images/empty_image.png");
|
||||
},
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// URLを開くためのメソッドです。
|
||||
// url_launcherパッケージを使用して、指定されたURLを開きます。
|
||||
//
|
||||
void _launchURL(url) async {
|
||||
if (!await launchUrl(url)) throw 'Could not launch $url';
|
||||
}
|
||||
|
||||
// 指定されたlocationidが目的地リストに含まれているかどうかを確認するメソッドです。
|
||||
// destinationController.destinationsリストを走査し、locationidが一致する目的地があるかどうかを返します。
|
||||
//
|
||||
bool isInDestination(String locationid) {
|
||||
int lid = int.parse(locationid);
|
||||
if (destinationController.destinations
|
||||
.where((element) => element.location_id == lid)
|
||||
.isNotEmpty) {
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return SingleChildScrollView(
|
||||
child: Column(
|
||||
children: buildWidgets(context),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
// このメソッドはList<Widget>を返します。
|
||||
List<Widget> buildWidgets(BuildContext context) {
|
||||
return [
|
||||
Padding(
|
||||
padding: const EdgeInsets.all(8.0),
|
||||
child: Row(
|
||||
children: [
|
||||
MaterialButton(
|
||||
onPressed: () {
|
||||
Get.back();
|
||||
},
|
||||
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(() => Text("${destination.sub_loc_id} : ${destination.name}",
|
||||
style: const TextStyle(fontSize: 15.0, fontWeight: FontWeight.bold))),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
Row(
|
||||
children: [Expanded(child: SizedBox(height: 260.0, child: Obx(() => getImage())))],
|
||||
),
|
||||
Obx(() => Padding(
|
||||
padding: const EdgeInsets.all(8.0),
|
||||
child: getDetails(context),
|
||||
)),
|
||||
const SizedBox(height: 60.0),
|
||||
];
|
||||
}
|
||||
|
||||
Widget getDetails(BuildContext context) {
|
||||
return Column(
|
||||
children: [
|
||||
Padding(
|
||||
padding: const EdgeInsets.all(8.0),
|
||||
child: Row(
|
||||
children: [
|
||||
const Icon(Icons.roundabout_left),
|
||||
const SizedBox(
|
||||
width: 8.0,
|
||||
),
|
||||
destination.address != null && destination.address!.isNotEmpty
|
||||
? getDetailsItem(
|
||||
context,
|
||||
"address".tr,
|
||||
destination.address ?? '',
|
||||
)
|
||||
: const SizedBox(
|
||||
width: 0.0,
|
||||
height: 0,
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
Padding(
|
||||
padding: const EdgeInsets.all(8.0),
|
||||
child: Row(
|
||||
children: [
|
||||
const Icon(Icons.phone),
|
||||
const SizedBox(
|
||||
width: 8.0,
|
||||
),
|
||||
destination.phone != null && destination.phone!.isNotEmpty
|
||||
? getDetailsItem(
|
||||
context,
|
||||
"telephone".tr,
|
||||
destination.phone ?? '',
|
||||
)
|
||||
: const SizedBox(
|
||||
width: 0.0,
|
||||
height: 0,
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
Padding(
|
||||
padding: const EdgeInsets.all(8.0),
|
||||
child: Row(
|
||||
children: [
|
||||
const Icon(Icons.email),
|
||||
const SizedBox(
|
||||
width: 8.0,
|
||||
),
|
||||
destination.email != null && destination.email!.isNotEmpty
|
||||
? getDetailsItem(
|
||||
context,
|
||||
"email".tr,
|
||||
destination.email ?? '',
|
||||
)
|
||||
: const SizedBox(
|
||||
width: 0.0,
|
||||
height: 0,
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
Padding(
|
||||
padding: const EdgeInsets.all(8.0),
|
||||
child: Row(
|
||||
children: [
|
||||
const Icon(Icons.language),
|
||||
const SizedBox(
|
||||
width: 8.0,
|
||||
),
|
||||
destination.webcontents != null &&
|
||||
destination.webcontents!.isNotEmpty
|
||||
? getDetailsItem(
|
||||
context,
|
||||
"web".tr,
|
||||
destination.webcontents ?? '',
|
||||
isUrl: true,
|
||||
)
|
||||
: const SizedBox(
|
||||
width: 0.0,
|
||||
height: 0,
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
Padding(
|
||||
padding: const EdgeInsets.all(8.0),
|
||||
child: Row(
|
||||
children: [
|
||||
const SizedBox(
|
||||
width: 8.0,
|
||||
),
|
||||
indexController.currentFeature[0]
|
||||
.properties!["remark"] !=
|
||||
null &&
|
||||
(indexController.currentFeature[0]
|
||||
.properties!["remark"] as String)
|
||||
.isNotEmpty
|
||||
? getDetailsItem(
|
||||
context,
|
||||
"remarks".tr,
|
||||
indexController.currentFeature[0]
|
||||
.properties!["remark"] ??
|
||||
'',
|
||||
isUrl: false)
|
||||
: const SizedBox(
|
||||
width: 0.0,
|
||||
height: 0,
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
Row(
|
||||
mainAxisAlignment: MainAxisAlignment.end,
|
||||
children: [
|
||||
ElevatedButton(
|
||||
style: ElevatedButton.styleFrom(
|
||||
backgroundColor: Theme.of(context).colorScheme.onPrimaryContainer),
|
||||
onPressed: () async {
|
||||
// print(
|
||||
// "dist to start ${destinationController.distanceToStart()}");
|
||||
Get.back();
|
||||
//print("---- go to ----");
|
||||
// GeoJSONMultiPoint mp = indexController
|
||||
// .currentFeature[0] as GeoJSONMultiPoint;
|
||||
Position position =
|
||||
await Geolocator.getCurrentPosition(
|
||||
desiredAccuracy:
|
||||
LocationAccuracy.bestForNavigation,
|
||||
forceAndroidLocationManager: true);
|
||||
//print("------- position -------- $position");
|
||||
Destination ds = Destination(
|
||||
lat: position.latitude,
|
||||
lon: position.longitude);
|
||||
|
||||
Destination tp = Destination(
|
||||
lat: destination.lat, lon: destination.lon);
|
||||
|
||||
destinationController
|
||||
.destinationMatrixFromCurrentPoint([ds, tp]);
|
||||
|
||||
// TODO: Implement "ここへ行く" functionality
|
||||
},
|
||||
child: Text(
|
||||
"ルート",
|
||||
style: TextStyle(
|
||||
color: Theme.of(context).colorScheme.onPrimary,
|
||||
),
|
||||
),
|
||||
),
|
||||
const SizedBox(
|
||||
width: 10,
|
||||
),
|
||||
],
|
||||
),
|
||||
],
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
|
||||
Widget getDetailsItem(BuildContext context, String label, String text,
|
||||
{bool isUrl = false}) {
|
||||
return Row(
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
children: [
|
||||
Text(label),
|
||||
const SizedBox(
|
||||
width: 10.0,
|
||||
),
|
||||
InkWell(
|
||||
onTap: () {
|
||||
if (isUrl) {
|
||||
_launchURL(destination.webcontents);
|
||||
}
|
||||
},
|
||||
child: SizedBox(
|
||||
width: MediaQuery.of(context).size.width -
|
||||
(MediaQuery.of(context).size.width * 0.35),
|
||||
child: Text(
|
||||
text,
|
||||
textAlign: TextAlign.justify,
|
||||
style: TextStyle(
|
||||
color: isUrl ? Colors.blue : Colors.black,
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
);
|
||||
}
|
||||
}
|
||||
@ -1,34 +0,0 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:get/get.dart';
|
||||
import 'package:rogapp/pages/destination/destination_controller.dart';
|
||||
import 'package:rogapp/widgets/bottom_sheets/bottom_sheet_normal_point.dart';
|
||||
|
||||
class BottomSheetBuyPoint extends BottomSheetNormalPoint {
|
||||
BottomSheetBuyPoint({super.key, required super.destination});
|
||||
|
||||
final DestinationController destinationController = Get.find<DestinationController>();
|
||||
|
||||
@override
|
||||
List<Widget> buildWidgets(BuildContext context) {
|
||||
// super.buildWidgets(context) を継承して、追加のウィジェットをリストに組み込む
|
||||
return [
|
||||
...super.buildWidgets(context),
|
||||
ElevatedButton(
|
||||
onPressed: () async {
|
||||
// 「買い物チェックイン」ボタンがタップされた際の処理
|
||||
// TODO: Implement QR code scanning and buy point processing logic
|
||||
},
|
||||
child: const Text('買い物チェックイン'),
|
||||
),
|
||||
];
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return SingleChildScrollView(
|
||||
child: Column(
|
||||
children: buildWidgets(context),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
@ -1,69 +0,0 @@
|
||||
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/widgets/bottom_sheets/bottom_sheet_base.dart';
|
||||
import 'package:latlong2/latlong.dart';
|
||||
import 'package:rogapp/pages/camera/camera_page.dart';
|
||||
import 'dart:ui' as ui;
|
||||
|
||||
class BottomSheetGoal extends BottomSheetBase {
|
||||
BottomSheetGoal({super.key, required super.destination});
|
||||
|
||||
final DestinationController destinationController = Get.find<DestinationController>();
|
||||
|
||||
@override
|
||||
List<Widget> buildWidgets(BuildContext context) {
|
||||
// super.buildWidgets(context) を継承して、追加のウィジェットをリストに組み込む
|
||||
return [
|
||||
...super.buildWidgets(context),
|
||||
ElevatedButton(
|
||||
onPressed: destinationController.distanceToStart() <= 100
|
||||
? () async {
|
||||
// 「ゴール時間撮影」ボタンがタップされた際の処理
|
||||
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 && ... GPS信号が弱い時でもOKとする。
|
||||
(destinationController.distanceToStart() <= 500 || destinationController.isGpsSignalWeak() ) &&
|
||||
destination.cp == -1 &&
|
||||
DestinationController.ready_for_goal == true) {
|
||||
|
||||
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('ゴール時間撮影'),
|
||||
),
|
||||
];
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return SingleChildScrollView(
|
||||
child: Column(
|
||||
children: buildWidgets(context),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
@ -1,64 +0,0 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:get/get.dart';
|
||||
import 'package:rogapp/pages/destination/destination_controller.dart';
|
||||
import 'package:rogapp/widgets/bottom_sheets/bottom_sheet_base.dart';
|
||||
|
||||
class BottomSheetNormalPoint extends BottomSheetBase {
|
||||
BottomSheetNormalPoint({super.key, required super.destination});
|
||||
|
||||
final DestinationController destinationController = Get.find<DestinationController>();
|
||||
|
||||
@override
|
||||
List<Widget> buildWidgets(BuildContext context) {
|
||||
// super.buildWidgets(context) を継承して、追加のウィジェットをリストに組み込む
|
||||
return [
|
||||
...super.buildWidgets(context),
|
||||
ElevatedButton(
|
||||
onPressed: destinationController.distanceToStart() <= 100
|
||||
? () async {
|
||||
if (destinationController.rogainingCounted.value == true &&
|
||||
(destinationController.distanceToStart() <= 500 ||
|
||||
destinationController.isGpsSignalWeak()) &&
|
||||
destination.cp! > 0) {
|
||||
// isAlreadyCheckedIn == true
|
||||
// 「チェックイン撮影」ボタンがタップされた際の処理
|
||||
try {
|
||||
Get.back();
|
||||
await destinationController.callforCheckin(destination);
|
||||
// ここで、CameraPageへの遷移が行われる。
|
||||
|
||||
} catch (e) {
|
||||
// エラーハンドリング
|
||||
Get.snackbar(
|
||||
'Error',
|
||||
'An error occurred while processing check-in.',
|
||||
backgroundColor: Colors.red,
|
||||
colorText: Colors.white,
|
||||
duration: Duration(seconds: 3),
|
||||
);
|
||||
// 必要に応じてエラーログを記録
|
||||
print('Error processing check-in: $e');
|
||||
}
|
||||
} else if (destination.checkedin == true) { // 取り消しの場合?
|
||||
;
|
||||
}
|
||||
}
|
||||
: null,
|
||||
|
||||
child: Obx( () => Text(
|
||||
destinationController.isInRog.value ? 'チェックイン取消' : 'チェックイン',
|
||||
),
|
||||
),
|
||||
),
|
||||
];
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return SingleChildScrollView(
|
||||
child: Column(
|
||||
children: buildWidgets(context),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
@ -1,102 +0,0 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:get/get.dart';
|
||||
import 'package:rogapp/pages/destination/destination_controller.dart';
|
||||
import 'package:rogapp/widgets/bottom_sheets/bottom_sheet_base.dart';
|
||||
import 'package:rogapp/main.dart';
|
||||
import 'package:rogapp/services/external_service.dart';
|
||||
|
||||
class BottomSheetStart extends BottomSheetBase {
|
||||
|
||||
BottomSheetStart({super.key, required super.destination});
|
||||
|
||||
final DestinationController destinationController = Get.find<DestinationController>();
|
||||
|
||||
@override
|
||||
List<Widget> buildWidgets(BuildContext context) {
|
||||
// super.buildWidgets(context) を継承して、追加のウィジェットをリストに組み込む
|
||||
return [
|
||||
...super.buildWidgets(context),
|
||||
ElevatedButton(
|
||||
onPressed: destinationController.distanceToStart() <= 100
|
||||
? () async {
|
||||
// ボタンがタップされた際の処理
|
||||
// Check conditions to show confirmation dialog
|
||||
if (destinationController.isInRog.value == false &&
|
||||
(destinationController.distanceToStart() <= 500 || destinationController.isGpsSignalWeak() ) && //追加 Akira 2024-4-5
|
||||
(destination.cp == -1 || destination.cp == 0 ) &&
|
||||
destinationController.rogainingCounted.value == false) {
|
||||
// ロゲがまだ開始されていない: destinationController.isInRog.value == false
|
||||
// かつ (開始ポイントまでの距離が 500m 以内 destinationController.distanceToStart() <= 500
|
||||
// または GPS信号強度が弱い場合: destinationController.isGpsSignalWeak()
|
||||
// ) かつ
|
||||
// そのポイントのCP番号が -1 または 0 の場合:
|
||||
// かつ ポイントがカウントされていない場合: 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(); // main.dart 参照 // ゲームの状態を保存する。
|
||||
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 && destination.cp != 0 ) {
|
||||
//print("counted ${destinationController.rogainingCounted.value}");
|
||||
// Existing logic for other conditions
|
||||
|
||||
Get.back();
|
||||
await destinationController.callforCheckin(destination);
|
||||
} else {
|
||||
return;
|
||||
}
|
||||
|
||||
}
|
||||
: null,
|
||||
child: Obx(
|
||||
() => Text(
|
||||
destinationController.isInRog.value ? '競技中' : 'ロゲ開始',
|
||||
),
|
||||
),
|
||||
),
|
||||
];
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return SingleChildScrollView(
|
||||
child: Column(
|
||||
children: buildWidgets(context),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
@ -1,43 +0,0 @@
|
||||
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/widgets/bottom_sheets/bottom_sheet_base.dart';
|
||||
|
||||
class BottomSheetStartGoal extends BottomSheetBase {
|
||||
BottomSheetStartGoal({Key? key, required Destination destination})
|
||||
: super(key: key, destination: destination);
|
||||
|
||||
final DestinationController destinationController =
|
||||
Get.find<DestinationController>();
|
||||
|
||||
@override
|
||||
List<Widget> buildWidgets(BuildContext context) {
|
||||
// super.buildWidgets(context) を継承して、追加のウィジェットをリストに組み込む
|
||||
return [
|
||||
...super.buildWidgets(context),
|
||||
ElevatedButton(
|
||||
onPressed: destinationController.distanceToStart() <= 100
|
||||
? () async {
|
||||
// 「ロゲ開始」または「ゴール時間撮影」ボタンがタップされた際の処理
|
||||
// TODO: Implement start game or goal time capture logic based on game state
|
||||
}
|
||||
: null,
|
||||
child: Obx(
|
||||
() => Text(
|
||||
destinationController.isInRog.value ? 'ゴール時間撮影' : 'ロゲ開始',
|
||||
),
|
||||
),
|
||||
),
|
||||
];
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return SingleChildScrollView(
|
||||
child: Column(
|
||||
children: buildWidgets(context),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
@ -1,6 +1,7 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:get/get.dart';
|
||||
import 'package:rogapp/pages/destination/destination_controller.dart';
|
||||
import 'package:rogapp/routes/app_pages.dart'; // これを追加
|
||||
|
||||
class CurrentPosition extends StatefulWidget {
|
||||
const CurrentPosition({super.key});
|
||||
@ -13,20 +14,28 @@ class _CurrentPositionState extends State<CurrentPosition> {
|
||||
final DestinationController destinationController =
|
||||
Get.find<DestinationController>();
|
||||
|
||||
void _onLongPress() {
|
||||
Get.toNamed(AppPages.SETTINGS); // これを追加
|
||||
}
|
||||
|
||||
@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,
|
||||
return GestureDetector( // GestureDetectorを追加
|
||||
onLongPress: _onLongPress, // 長押しイベントを追加
|
||||
child: Container (
|
||||
// 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,
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
|
||||
@ -127,7 +127,9 @@ class DestinationWidget extends StatelessWidget {
|
||||
destinationController.deleteAllDestinations();
|
||||
Get.back();
|
||||
Get.snackbar(
|
||||
"deleted".tr, "all_destinations_are_deleted_successfully".tr);
|
||||
"deleted".tr, "all_destinations_are_deleted_successfully".tr,
|
||||
backgroundColor: Colors.green,
|
||||
colorText: Colors.white);
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
@ -6,6 +6,7 @@ import 'package:flutter_polyline_points/flutter_polyline_points.dart';
|
||||
import 'package:geojson_vi/geojson_vi.dart';
|
||||
import 'package:get/get.dart';
|
||||
import 'package:latlong2/latlong.dart';
|
||||
import 'package:rogapp/pages/settings/settings_binding.dart';
|
||||
import 'package:rogapp/model/destination.dart';
|
||||
import 'package:rogapp/pages/destination/destination_controller.dart';
|
||||
import 'package:rogapp/pages/index/index_controller.dart';
|
||||
@ -16,8 +17,13 @@ import 'package:rogapp/widgets/base_layer_widget.dart';
|
||||
import 'package:rogapp/widgets/bottom_sheet_new.dart';
|
||||
import 'package:rogapp/widgets/current_position_widget.dart';
|
||||
import 'package:rogapp/widgets/game_state_view.dart';
|
||||
import 'package:rogapp/pages/settings/settings_controller.dart';
|
||||
import 'package:flutter_map_tile_caching/flutter_map_tile_caching.dart';
|
||||
|
||||
class MapResetController {
|
||||
void Function()? resetIdleTimer;
|
||||
}
|
||||
|
||||
class MapWidget extends StatefulWidget {
|
||||
const MapWidget({Key? key}) : super(key: key);
|
||||
|
||||
@ -31,6 +37,7 @@ class _MapWidgetState extends State<MapWidget> with WidgetsBindingObserver {
|
||||
final DestinationController destinationController =
|
||||
Get.find<DestinationController>();
|
||||
final LocationController locationController = Get.find<LocationController>();
|
||||
final SettingsController settingsController = Get.find<SettingsController>();
|
||||
|
||||
late MapController mapController;
|
||||
final Completer<MapController> mapControllerCompleter = Completer<MapController>();
|
||||
@ -45,6 +52,7 @@ class _MapWidgetState extends State<MapWidget> with WidgetsBindingObserver {
|
||||
@override
|
||||
void initState() {
|
||||
super.initState();
|
||||
SettingsBinding().dependencies(); // これを追加
|
||||
_startIdleTimer();
|
||||
mapController = MapController();
|
||||
indexController.mapController = mapController;
|
||||
@ -67,10 +75,19 @@ class _MapWidgetState extends State<MapWidget> with WidgetsBindingObserver {
|
||||
});
|
||||
});
|
||||
|
||||
late MapResetController mapResetController = MapResetController();
|
||||
mapResetController.resetIdleTimer = _resetIdleTimer;
|
||||
Get.put(mapResetController);
|
||||
|
||||
// indexController.mapController = MapController(initCompleter: mapControllerCompleter);
|
||||
|
||||
}
|
||||
|
||||
void _resetIdleTimer() {
|
||||
_timer?.cancel();
|
||||
_startIdleTimer();
|
||||
}
|
||||
|
||||
@override
|
||||
void dispose() {
|
||||
WidgetsBinding.instance.removeObserver(this); // added
|
||||
@ -90,7 +107,10 @@ class _MapWidgetState extends State<MapWidget> with WidgetsBindingObserver {
|
||||
|
||||
// _centerMapOnUser を10秒間でコール
|
||||
void _startIdleTimer() {
|
||||
_timer = Timer(const Duration(milliseconds: (1000 * 10)), _centerMapOnUser);
|
||||
final settingsController = Get.find<SettingsController>();
|
||||
if (!settingsController.autoReturnDisabled.value) {
|
||||
_timer = Timer(settingsController.timerDuration.value, _centerMapOnUser);
|
||||
}
|
||||
}
|
||||
|
||||
// タイマーをリセットして_startIdleTimer をコール
|
||||
@ -174,6 +194,7 @@ class _MapWidgetState extends State<MapWidget> with WidgetsBindingObserver {
|
||||
|
||||
// Widget getMarkerShape(GeoJSONFeature i, BuildContext context) {
|
||||
Widget getMarkerShape(GeoJSONFeature i) {
|
||||
/*
|
||||
String labelText = TextUtils.getDisplayTextFeture(i);
|
||||
if( i.properties!['cp'] == 0 ){
|
||||
labelText="Start/Goal";
|
||||
@ -184,10 +205,11 @@ class _MapWidgetState extends State<MapWidget> with WidgetsBindingObserver {
|
||||
//}else{
|
||||
// labelText=i.properties!['cp'];
|
||||
}
|
||||
*/
|
||||
//if( i.properties!['cp'] <= 0 ) {
|
||||
// debugPrint("Text=${labelText}");
|
||||
//}
|
||||
final double maxWidth = labelText.length * 16.0; //16.0;
|
||||
//final double maxWidth = labelText.length * 16.0; //16.0;
|
||||
GeoJSONMultiPoint p = i.geometry as GeoJSONMultiPoint;
|
||||
return InkWell(
|
||||
onTap: () {
|
||||
@ -238,21 +260,20 @@ class _MapWidgetState extends State<MapWidget> with WidgetsBindingObserver {
|
||||
Icons.circle,
|
||||
size: 6.0,
|
||||
),
|
||||
i.properties!['cp'] <= 0
|
||||
? Transform.translate
|
||||
i.properties!['cp'] <= 0 ? Transform.translate
|
||||
(
|
||||
offset: const Offset(-3, 0),
|
||||
offset: const Offset(-3, 0), //-3
|
||||
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,
|
||||
),
|
||||
),
|
||||
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,
|
||||
),
|
||||
@ -262,42 +283,42 @@ class _MapWidgetState extends State<MapWidget> with WidgetsBindingObserver {
|
||||
Transform.translate(
|
||||
offset: const Offset(30, 0), // 30,0
|
||||
child: Align(
|
||||
alignment: Alignment.centerLeft,
|
||||
alignment: Alignment.center,
|
||||
child: Container (
|
||||
//width: 200, // 幅を指定
|
||||
//height: 60, // 40
|
||||
color: Colors.transparent,
|
||||
//child: Text(' ').
|
||||
//constraints: const BoxConstraints(maxWidth: 1000.0), // 最大幅を設定
|
||||
constraints: BoxConstraints(maxWidth: maxWidth), // 最大幅を設定
|
||||
//constraints: BoxConstraints(maxWidth: maxWidth), // 最大幅を設定
|
||||
//color: Colors.purple.withOpacity(0.2),
|
||||
child: Stack(
|
||||
children: <Widget>[
|
||||
Text( // アウトライン
|
||||
labelText,
|
||||
TextUtils.getDisplayTextFeture(i),
|
||||
style: TextStyle(
|
||||
fontSize: 14, // 16
|
||||
fontSize: 16, // 16
|
||||
fontWeight: FontWeight.w700,
|
||||
height: 1.2,
|
||||
//height: 1.2,
|
||||
foreground: Paint()
|
||||
..style = PaintingStyle.stroke
|
||||
..strokeWidth = 2
|
||||
..color = Colors.white,
|
||||
),
|
||||
maxLines: 1, // テキストを1行に制限
|
||||
softWrap: false, // テキストの折り返しを無効化
|
||||
//maxLines: 1, // テキストを1行に制限
|
||||
//softWrap: false, // テキストの折り返しを無効化
|
||||
),
|
||||
Text( // テキスト
|
||||
labelText,
|
||||
TextUtils.getDisplayTextFeture(i),
|
||||
style: const TextStyle(
|
||||
fontSize: 14,
|
||||
fontSize: 16,
|
||||
fontWeight: FontWeight.w700,
|
||||
//fontWeight: FontWeight.bold,
|
||||
height: 1.2,
|
||||
//height: 1.2,
|
||||
color: Colors.black,
|
||||
),
|
||||
maxLines: 1, // テキストを1行に制限
|
||||
softWrap: false, // テキストの折り返しを無効化
|
||||
//maxLines: 1, // テキストを1行に制限
|
||||
//softWrap: false, // テキストの折り返しを無効化
|
||||
),
|
||||
],
|
||||
),
|
||||
@ -321,6 +342,7 @@ class _MapWidgetState extends State<MapWidget> with WidgetsBindingObserver {
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final settingsController = Get.find<SettingsController>(); // これを追加
|
||||
//final PopupController popupController = PopupController();
|
||||
return Stack(
|
||||
children: [
|
||||
|
||||
Reference in New Issue
Block a user