2024-09-02 ほぼOK

This commit is contained in:
2024-09-02 21:25:19 +09:00
parent dc58dc0584
commit fe46d46ab6
59 changed files with 2006 additions and 677 deletions

View File

@ -3,12 +3,18 @@ import 'package:gifunavi/pages/destination/destination_controller.dart';
import 'package:gifunavi/pages/index/index_controller.dart';
import 'package:gifunavi/utils/location_controller.dart';
import '../../services/api_service.dart';
class IndexBinding extends Bindings {
@override
void dependencies() {
Get.lazyPut<IndexController>(() => IndexController());
//Get.put<IndexController>(IndexController());
Get.put<LocationController>(LocationController());
Get.put<DestinationController>(DestinationController());
//Get.lazyPut<IndexController>(() => IndexController());
////Get.put<IndexController>(IndexController());
//Get.put<LocationController>(LocationController());
//Get.put<DestinationController>(DestinationController());
Get.put(IndexController(apiService: Get.find<ApiService>()), permanent: true);
Get.put(LocationController(), permanent: true);
Get.put(DestinationController(), permanent: true);
}
}

View File

@ -1,4 +1,5 @@
import 'dart:async';
import 'dart:io';
import 'package:connectivity_plus/connectivity_plus.dart';
import 'package:flutter/material.dart';
@ -31,6 +32,8 @@ import 'package:gifunavi/widgets/helper_dialog.dart';
import 'package:timezone/timezone.dart' as tz;
import 'package:timezone/data/latest.dart' as tz;
import '../permission/permission.dart';
class IndexController extends GetxController with WidgetsBindingObserver {
List<GeoJSONFeatureCollection> locations = <GeoJSONFeatureCollection>[].obs;
List<GeoJSONFeature> currentFeature = <GeoJSONFeature>[].obs;
@ -68,9 +71,14 @@ class IndexController extends GetxController with WidgetsBindingObserver {
String? userToken;
//late final ApiService _apiService;
final ApiService _apiService = Get.find<ApiService>();
final ApiService _apiService; // = Get.find<ApiService>();
final DatabaseHelper _dbHelper = DatabaseHelper.instance;
IndexController({
required ApiService apiService,
}) : _apiService = apiService;
// mode = 0 is map mode, mode = 1 list mode
var mode = 0.obs;
@ -235,6 +243,10 @@ class IndexController extends GetxController with WidgetsBindingObserver {
initConnectivity();
_connectivitySubscription = _connectivity.onConnectivityChanged.listen(_updateConnectionStatus);
WidgetsBinding.instance.addPostFrameCallback((_) async {
await PermissionController.checkAndRequestPermissions();
});
WidgetsBinding.instance.addObserver(this);
_startLocationService(); // アプリ起動時にLocationServiceを開始する
@ -263,10 +275,10 @@ class IndexController extends GetxController with WidgetsBindingObserver {
connectionStatusName.value = "WiFi";
break;
case ConnectivityResult.mobile:
connectionStatusName.value = "モバイルデータ";
connectionStatusName.value = "mobile";
break;
case ConnectivityResult.none:
connectionStatusName.value = "オフライン";
connectionStatusName.value = "offline";
break;
default:
connectionStatusName.value = "不明";
@ -352,22 +364,53 @@ class IndexController extends GetxController with WidgetsBindingObserver {
}
void _startLocationService() async {
const platform = MethodChannel('location');
try {
logManager.addOperationLog("Called start location service.");
await platform.invokeMethod('startLocationService');
} on PlatformException catch (e) {
print("Failed to start location service: '${e.message}'.");
if (Platform.isAndroid) {
const platform = MethodChannel('location');
try {
logManager.addOperationLog("Called start location service.");
await platform.invokeMethod('startLocationService');
} on PlatformException catch (e) {
print("Failed to start location service: '${e.message}'.");
}
}else if (Platform.isIOS) {
// iOSの位置情報サービス開始ロジック
// 例: geolocatorプラグインを使用する場合
try {
bool serviceEnabled = await Geolocator.isLocationServiceEnabled();
if (!serviceEnabled) {
// 位置情報サービスが無効の場合の処理
return;
}
// 位置情報の権限確認と取得開始
LocationPermission permission = await Geolocator.checkPermission();
if (permission == LocationPermission.denied) {
permission = await Geolocator.requestPermission();
if (permission == LocationPermission.denied) {
// 権限が拒否された場合の処理
return;
}
}
// 位置情報の取得開始
Geolocator.getPositionStream().listen((Position position) {
// 位置情報を使用した処理
});
} catch (e) {
print('Error starting iOS location service: $e');
}
}
}
void _stopLocationService() async {
const platform = MethodChannel('location');
try {
logManager.addOperationLog("Called stop location service.");
await platform.invokeMethod('stopLocationService');
} on PlatformException catch (e) {
print("Failed to stop location service: '${e.message}'.");
if (Platform.isAndroid) {
const platform = MethodChannel('location');
try {
logManager.addOperationLog("Called stop location service.");
await platform.invokeMethod('stopLocationService');
} on PlatformException catch (e) {
print("Failed to stop location service: '${e.message}'.");
}
}else{
debugPrint("stopLocation for iOS");
}
}
@ -433,51 +476,75 @@ class IndexController extends GetxController with WidgetsBindingObserver {
// 要検討:エラーハンドリングが行われていますが、エラーメッセージをローカライズすることを検討してください。
//
void login(String email, String password, BuildContext context) async{
AuthService.login(email, password).then((value) async {
print("------- logged in user details ######## $value ###### --------");
if (value.isNotEmpty) {
logManager.addOperationLog("User logged in : $value.");
// Navigator.pop(context);
print("--------- user details login ----- $value");
changeUser(value);
// ログイン成功後、api_serviceを初期化
await Get.putAsync(() => ApiService().init());
// ユーザー情報の完全性をチェック
if (await checkUserInfoComplete()) {
Get.offAllNamed(AppPages.INDEX);
} else {
Get.offAllNamed(AppPages.USER_DETAILS_EDIT);
}
Future<void> login(String email, String password) async {
try {
final value = await AuthService.login(email, password);
if (value.isNotEmpty && value['token'] != null) {
await changeUser(value);
await _initializeUserData();
Get.offAllNamed(AppPages.INDEX);
} else {
logManager.addOperationLog("User failed login : $email , $password.");
isLoading.value = false;
Get.snackbar(
"login_failed".tr,
"check_login_id_or_password".tr,
Get.snackbar('Login Failed', 'Invalid credentials');
}
} catch (e) {
print('Login error: $e');
Get.snackbar('Login Failed', 'An error occurred. Please try again.');
}
}
Future<void> _initializeUserData() async {
try {
await fetchUserEventInfo();
await fetchTeamData();
// 他の必要なデータ取得処理
} catch (e) {
print('Error initializing user data: $e');
Get.snackbar('Error', 'Failed to load user data. Please try again.');
}
}
Future<void> login_old(String email, String password, BuildContext context) async{
try {
AuthService.login(email, password).then((value) async {
print("------- logged in user details ######## $value ###### --------");
if (value.isNotEmpty && value['token']!=null) {
logManager.addOperationLog("User logged in : $value.");
// Navigator.pop(context);
print("--------- user details login ----- $value");
// ログイン成功後、api_serviceを初期化
await Get.putAsync(() => ApiService().init());
// ユーザー情報の完全性をチェック
if (await checkUserInfoComplete()) {
Get.offAllNamed(AppPages.INDEX);
} else {
Get.offAllNamed(AppPages.USER_DETAILS_EDIT);
}
} else {
logManager.addOperationLog("User failed login : $email , $password.");
isLoading.value = false;
Get.snackbar(
"login_failed".tr,
"check_login_id_or_password".tr,
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,
//icon:Image(image:AssetImage("assets/images/dora.png"))
);
}
});
snackPosition: SnackPosition.TOP,
duration: const Duration(seconds: 3),
//backgroundColor: Colors.yellow,
//icon:Image(image:AssetImage("assets/images/dora.png"))
);
}
});
} catch(e ){
print('Login error: $e');
Get.snackbar('Login Failed', 'An error occurred. Please try again.');
}
}
Future<bool> checkUserInfoComplete() async {
final user = await ApiService.to.getCurrentUser();
return user.firstname.isNotEmpty &&
user.lastname.isNotEmpty &&
user.dateOfBirth != null;
}
// 要検討:エラーハンドリングが行われていますが、エラーメッセージをローカライズすることを検討してください。
//
@ -532,12 +599,12 @@ class IndexController extends GetxController with WidgetsBindingObserver {
}
*/
void logout() async {
Future<void> logout() async {
logManager.addOperationLog("User logout : $currentUser .");
saveGameState();
locations.clear();
DatabaseHelper db = DatabaseHelper.instance;
db.deleteAllDestinations().then((value) {
db.deleteAllDestinationsExceptTodayCheckins().then((value) {
DestinationController destinationController =
Get.find<DestinationController>();
destinationController.populateDestinations();
@ -619,28 +686,48 @@ class IndexController extends GetxController with WidgetsBindingObserver {
}
*/
void changeUser(Map<String, dynamic> value, {bool replace = true}) async{
currentUser.clear();
currentUser.add(value);
if (replace) {
saveToDevice(currentUser[0]["token"]);
Future<void> changeUser(Map<String, dynamic> value, {bool replace = true}) async{
try {
if (value['user'] == null || value['token'] == null) {
throw Exception('Invalid user data');
}
currentUser.clear();
currentUser.add(value);
if (replace) {
saveToDevice(currentUser[0]["token"]);
}
isLoading.value = false;
// ユーザーのイベント情報を取得
await fetchUserEventInfo();
loadLocationsBound(currentUser[0]["user"]["event_code"]);
if (currentUser.isNotEmpty) {
rogMode.value = 0;
restoreGame();
// チームデータを取得
await fetchTeamData();
} else {
rogMode.value = 1;
}
Get.toNamed(AppPages.INDEX);
} catch( e ){
print('Error in changeUser: $e');
Get.snackbar('Error', 'Failed to update user information');
}
isLoading.value = false;
}
// ユーザーのイベント情報を取得
await fetchUserEventInfo();
loadLocationsBound( currentUser[0]["user"]["event_code"]);
if (currentUser.isNotEmpty) {
rogMode.value = 0;
restoreGame();
// チームデータを取得
await fetchTeamData();
} else {
rogMode.value = 1;
Future<bool> checkUserInfoComplete() async {
try {
final user = await ApiService.to.getCurrentUser();
return user.firstname.isNotEmpty &&
user.lastname.isNotEmpty &&
user.dateOfBirth != null;
} catch (e) {
print('Error checking user info: $e');
return false;
}
Get.toNamed(AppPages.INDEX);
}
Future<void> fetchUserEventInfo() async {
@ -697,7 +784,7 @@ class IndexController extends GetxController with WidgetsBindingObserver {
Future<void> fetchTeamData() async {
try {
Get.put(TeamController());
Get.put(TeamController(apiService:Get.find<ApiService>()));
// \"TeamController\" not found. You need to call \"Get.put(TeamController())\" or \"Get.lazyPut(()=>TeamController())\"
final teamController = Get.find<TeamController>();
await teamController.fetchTeams();
@ -945,7 +1032,7 @@ class IndexController extends GetxController with WidgetsBindingObserver {
Future<void> checkEntryData() async {
// エントリーデータの有無をチェックするロジック
final teamController = TeamController();
final teamController = TeamController(apiService:Get.find<ApiService>());
bool hasEntryData = teamController.checkIfUserHasEntryData();
if (!hasEntryData) {
await showHelperDialog(

View File

@ -38,10 +38,21 @@ class _IndexPageState extends State<IndexPage> {
super.initState();
WidgetsBinding.instance.addPostFrameCallback((_) {
//checkLoginAndShowDialog();
//checkEventAndNavigate();
});
}
void checkLoginAndShowDialog() {
void checkEventAndNavigate() async {
if (indexController.currentUser.isNotEmpty &&
indexController.currentUser[0]["user"]["event_code"] == null) {
// イベントコードがない場合、EVENT_ENTRYページに遷移
await Get.toNamed(AppPages.EVENT_ENTRY);
// EVENT_ENTRYページから戻ってきた後に警告を表示
_showEventSelectionWarning();
}
}
void checkLoginAndShowDialog() async {
if (indexController.currentUser.isEmpty) {
showDialog(
context: context,
@ -78,9 +89,30 @@ class _IndexPageState extends State<IndexPage> {
);
},
);
}else{
if(indexController.currentUser[0]["user"]["event_code"] == null) {
// イベントコードがない場合、EVENT_ENTRYページに遷移
await Get.toNamed(AppPages.EVENT_ENTRY);
// EVENT_ENTRYページから戻ってきた後に警告を表示
_showEventSelectionWarning();
}
}
}
void _showEventSelectionWarning() {
Get.dialog(
AlertDialog(
title: Text('警告'),
content: Text('イベントを選択してください。'),
actions: [
TextButton(
child: Text('OK'),
onPressed: () => Get.back(),
),
],
),
);
}
// class IndexPage extends GetView<IndexController> {
// IndexPage({Key? key}) : super(key: key);