Fix Android issues
This commit is contained in:
6
TODO.txt
6
TODO.txt
@ -5,3 +5,9 @@
|
||||
|
||||
ログインした際に、イベントが選択されていなければ、イベントを選択するように促す。
|
||||
事前チェックインした写真が履歴に表示されない。
|
||||
|
||||
ユーザー名間違えたらログインできなくなる。
|
||||
|
||||
起動時に最後の参加イベントが過去日だったら、
|
||||
チェックポイントをクリアする。
|
||||
当日なら、参加処理?をしてタイトルを変える。
|
||||
|
||||
8
android/app/proguard-rules.pro
vendored
Normal file
8
android/app/proguard-rules.pro
vendored
Normal file
@ -0,0 +1,8 @@
|
||||
-assumenosideeffects class android.util.Log {
|
||||
public static boolean isLoggable(java.lang.String, int);
|
||||
public static int v(...);
|
||||
public static int i(...);
|
||||
public static int w(...);
|
||||
public static int d(...);
|
||||
public static int e(...);
|
||||
}
|
||||
@ -19,26 +19,34 @@
|
||||
<rect key="frame" x="0.0" y="0.0" width="393" height="852"/>
|
||||
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
|
||||
<subviews>
|
||||
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" fixedFrame="YES" text="岐阜ナビ" textAlignment="center" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="WPs-nj-CIV">
|
||||
<rect key="frame" x="46" y="123" width="314" height="59"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
|
||||
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="岐阜ナビ" textAlignment="center" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="WPs-nj-CIV">
|
||||
<rect key="frame" x="46" y="122.99999999999999" width="301" height="38.333333333333329"/>
|
||||
<fontDescription key="fontDescription" type="system" pointSize="32"/>
|
||||
<nil key="textColor"/>
|
||||
<nil key="highlightedColor"/>
|
||||
</label>
|
||||
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" fixedFrame="YES" text="NPO 岐阜aiネットワーク" textAlignment="center" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="TM1-SD-6RA">
|
||||
<rect key="frame" x="46" y="722" width="314" height="41"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
|
||||
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" misplaced="YES" text="NPO 岐阜aiネットワーク" textAlignment="center" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="TM1-SD-6RA">
|
||||
<rect key="frame" x="46" y="708" width="301" height="40"/>
|
||||
<fontDescription key="fontDescription" type="system" pointSize="17"/>
|
||||
<nil key="textColor"/>
|
||||
<nil key="highlightedColor"/>
|
||||
</label>
|
||||
<imageView clipsSubviews="YES" userInteractionEnabled="NO" contentMode="scaleAspectFit" horizontalHuggingPriority="251" verticalHuggingPriority="251" fixedFrame="YES" image="LaunchImage" translatesAutoresizingMaskIntoConstraints="NO" id="hCH-Iu-4S2">
|
||||
<rect key="frame" x="83" y="314" width="240" height="224"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
|
||||
<imageView clipsSubviews="YES" userInteractionEnabled="NO" contentMode="scaleAspectFit" horizontalHuggingPriority="251" verticalHuggingPriority="251" image="LaunchImage" translatesAutoresizingMaskIntoConstraints="NO" id="hCH-Iu-4S2">
|
||||
<rect key="frame" x="46" y="241.33333333333334" width="301" height="341.33333333333326"/>
|
||||
</imageView>
|
||||
</subviews>
|
||||
<color key="backgroundColor" red="1" green="1" blue="1" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
|
||||
<constraints>
|
||||
<constraint firstItem="xbc-2k-c8Z" firstAttribute="top" secondItem="TM1-SD-6RA" secondAttribute="bottom" constant="70" id="DbA-tx-JAk"/>
|
||||
<constraint firstAttribute="trailingMargin" secondItem="hCH-Iu-4S2" secondAttribute="trailing" constant="30" id="DsC-fI-z7h"/>
|
||||
<constraint firstAttribute="trailingMargin" secondItem="TM1-SD-6RA" secondAttribute="trailing" constant="30" id="Spt-qL-bHo"/>
|
||||
<constraint firstItem="WPs-nj-CIV" firstAttribute="top" secondItem="Ydg-fD-yQy" secondAttribute="bottom" constant="64" id="Wf4-J5-CP7"/>
|
||||
<constraint firstItem="hCH-Iu-4S2" firstAttribute="top" secondItem="WPs-nj-CIV" secondAttribute="bottom" constant="80" id="eIO-ZH-rp5"/>
|
||||
<constraint firstItem="hCH-Iu-4S2" firstAttribute="leading" secondItem="Ze5-6b-2t3" secondAttribute="leadingMargin" constant="30" id="oZr-ky-01l"/>
|
||||
<constraint firstItem="WPs-nj-CIV" firstAttribute="leading" secondItem="Ze5-6b-2t3" secondAttribute="leadingMargin" constant="30" id="pEC-jM-hHf"/>
|
||||
<constraint firstItem="TM1-SD-6RA" firstAttribute="leading" secondItem="Ze5-6b-2t3" secondAttribute="leadingMargin" constant="30" id="pRM-dy-ucg"/>
|
||||
<constraint firstAttribute="trailingMargin" secondItem="WPs-nj-CIV" secondAttribute="trailing" constant="30" id="ugk-x4-Wgc"/>
|
||||
</constraints>
|
||||
</view>
|
||||
</viewController>
|
||||
<placeholder placeholderIdentifier="IBFirstResponder" id="iYj-Kq-Ea1" userLabel="First Responder" sceneMemberID="firstResponder"/>
|
||||
|
||||
@ -216,10 +216,7 @@ void main() async {
|
||||
};
|
||||
|
||||
try {
|
||||
|
||||
|
||||
await initServices();
|
||||
|
||||
runApp(const ProviderScope(child: MyApp()));
|
||||
}catch(e, stackTrace){
|
||||
print('Error during initialization: $e');
|
||||
@ -244,19 +241,6 @@ Future<void> initServices() async {
|
||||
Get.put(LocationController(), permanent: true);
|
||||
|
||||
debugPrint("2: Controllers initialized");
|
||||
/*
|
||||
// すべてのコントローラーとサービスを非同期で初期化
|
||||
Get.lazyPut(() => IndexController(apiService: Get.find<ApiService>()));
|
||||
debugPrint("2: start IndexController");
|
||||
|
||||
// その他のコントローラーを遅延初期化
|
||||
Get.lazyPut(() => SettingsController());
|
||||
debugPrint("2: start SettingsController");
|
||||
Get.lazyPut(() => DestinationController());
|
||||
debugPrint("3: start DestinationController");
|
||||
Get.lazyPut(() => LocationController());
|
||||
debugPrint("4: start LocationController");
|
||||
*/
|
||||
|
||||
// 非同期処理を並列実行
|
||||
await Future.wait([
|
||||
@ -273,6 +257,7 @@ Future<void> initServices() async {
|
||||
|
||||
}catch(e){
|
||||
print('Error initializing : $e');
|
||||
rethrow;
|
||||
}
|
||||
print('All services started...');
|
||||
|
||||
@ -667,11 +652,14 @@ class _MyAppState extends State<MyApp> with WidgetsBindingObserver {
|
||||
}
|
||||
|
||||
void _checkMemoryUsage() async {
|
||||
/*
|
||||
final memoryInfo = await _getMemoryInfo();
|
||||
//debugPrint('Current memory usage: ${memoryInfo['used']} MB');
|
||||
if (memoryInfo['used']! > 100) { // 100MB以上使用している場合
|
||||
_performMemoryCleanup();
|
||||
}
|
||||
|
||||
*/
|
||||
}
|
||||
|
||||
Future<Map<String, int>> _getMemoryInfo() async {
|
||||
|
||||
@ -44,6 +44,9 @@ import 'package:path_provider/path_provider.dart';
|
||||
// 目的地に関連する状態管理とロジックを担当するクラスです。
|
||||
//
|
||||
class DestinationController extends GetxController {
|
||||
Timer? _checkForCheckinTimer;
|
||||
final int _checkInterval = 3000; // ミリ秒単位でチェック間隔を設定
|
||||
|
||||
late LocationSettings locationSettings; // 位置情報の設定を保持する変数です。
|
||||
|
||||
//late TeamController teamController = TeamController();
|
||||
@ -1019,15 +1022,16 @@ class DestinationController extends GetxController {
|
||||
// 2024-8-24 ... 佐伯呼び出しが必要なのか?
|
||||
//
|
||||
Future<void> checkForCheckin() async {
|
||||
//print("--- Start of checkForCheckin function ---");
|
||||
dbService.updateDatabase();
|
||||
await Future.delayed(const Duration(milliseconds: 3000));
|
||||
game_started = true;
|
||||
if (!game_started) {
|
||||
game_started = true;
|
||||
dbService.updateDatabase();
|
||||
}
|
||||
|
||||
try {
|
||||
// ここで、エラー
|
||||
if( indexController.locations.isNotEmpty ) {
|
||||
indexController.locations[0].features.forEach((fs) async {
|
||||
for (var fs in indexController.locations[0].features) {
|
||||
//indexController.locations[0].features.forEach((fs) async {
|
||||
GeoJSONMultiPoint mp = fs!.geometry as GeoJSONMultiPoint;
|
||||
LatLng pt = LatLng(mp.coordinates[0][1], mp.coordinates[0][0]);
|
||||
|
||||
@ -1045,10 +1049,11 @@ class DestinationController extends GetxController {
|
||||
await startTimerLocation(fs, distFs);
|
||||
// Note: You cannot break out of forEach. If you need to stop processing, you might have to reconsider using forEach.
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
if (gps_push_started == false) {
|
||||
unawaited(pushGPStoServer());
|
||||
pushGPStoServer();
|
||||
//unawaited(pushGPStoServer());
|
||||
}
|
||||
}
|
||||
//print("--- 123 ---- $skip_gps----");
|
||||
@ -1071,14 +1076,19 @@ class DestinationController extends GetxController {
|
||||
// "^^^^^^^^ ${DateFormat('kk:mm:ss \n EEE d MMM').format(DateTime.now())}");
|
||||
try {
|
||||
gps_push_started = true;
|
||||
ExternalService().pushGPS();
|
||||
await ExternalService().pushGPS();
|
||||
} catch (e) {
|
||||
print("An error occurred in pushGPStoServer: $e");
|
||||
//print("An error occurred: $e");
|
||||
//await pushGPStoServer();
|
||||
} finally {
|
||||
//print("--- End of pushGPStoServer function, calling recursively ---");
|
||||
await Future.delayed(const Duration(seconds: 5 * 60));
|
||||
await pushGPStoServer();
|
||||
if (gps_push_started) {
|
||||
Future.delayed(Duration(minutes: 5), pushGPStoServer);
|
||||
}
|
||||
|
||||
//print("--- End of pushGPStoServer function, calling recursively ---");
|
||||
//await Future.delayed(const Duration(seconds: 5 * 60));
|
||||
//await pushGPStoServer();
|
||||
}
|
||||
}
|
||||
|
||||
@ -1332,12 +1342,13 @@ class DestinationController extends GetxController {
|
||||
@override
|
||||
void onInit() async {
|
||||
super.onInit();
|
||||
startCheckForCheckinTimer();
|
||||
|
||||
|
||||
/*
|
||||
WidgetsBinding.instance.addPostFrameCallback((_) async {
|
||||
await PermissionController.checkAndRequestPermissions();
|
||||
});
|
||||
|
||||
*/
|
||||
|
||||
startGPSCheckTimer();
|
||||
|
||||
@ -1415,6 +1426,18 @@ class DestinationController extends GetxController {
|
||||
//checkGPSDataReceived();
|
||||
}
|
||||
|
||||
void startCheckForCheckinTimer() {
|
||||
_checkForCheckinTimer = Timer.periodic(Duration(milliseconds: _checkInterval), (_) {
|
||||
checkForCheckin();
|
||||
});
|
||||
}
|
||||
|
||||
void stopCheckForCheckinTimer() {
|
||||
_checkForCheckinTimer?.cancel();
|
||||
_checkForCheckinTimer = null;
|
||||
}
|
||||
|
||||
|
||||
void restartGPS(){
|
||||
// GPSデータのListenを再開する処理を追加
|
||||
Future.delayed(const Duration(seconds: 5), () {
|
||||
@ -1427,8 +1450,9 @@ class DestinationController extends GetxController {
|
||||
//
|
||||
@override
|
||||
void onClose() {
|
||||
gpsCheckTimer?.cancel();
|
||||
locationController.stopPositionStream();
|
||||
stopCheckForCheckinTimer();
|
||||
//gpsCheckTimer?.cancel();
|
||||
//locationController.stopPositionStream();
|
||||
super.onClose();
|
||||
}
|
||||
|
||||
|
||||
@ -11,6 +11,8 @@ import 'package:gifunavi/services/api_service.dart';
|
||||
import 'package:gifunavi/pages/index/index_controller.dart';
|
||||
import 'package:timezone/timezone.dart' as tz;
|
||||
|
||||
import '../../model/user.dart';
|
||||
|
||||
class EntryController extends GetxController {
|
||||
late ApiService _apiService;
|
||||
|
||||
@ -29,6 +31,8 @@ class EntryController extends GetxController {
|
||||
|
||||
final activeEvents = <Event>[].obs; //有効なイベントリスト
|
||||
|
||||
final teamMembers = <User>[].obs;
|
||||
|
||||
@override
|
||||
void onInit() async {
|
||||
super.onInit();
|
||||
@ -98,12 +102,64 @@ class EntryController extends GetxController {
|
||||
}
|
||||
}
|
||||
|
||||
void updateTeam(Team? value) {
|
||||
Future<void> fetchTeamMembers(int teamId) async {
|
||||
try {
|
||||
final members = await _apiService.getTeamMembers(teamId);
|
||||
teamMembers.assignAll(members);
|
||||
} catch (e) {
|
||||
print('Error fetching team members: $e');
|
||||
Get.snackbar('Error', 'Failed to fetch team members');
|
||||
}
|
||||
}
|
||||
|
||||
List<NewCategory> getFilteredCategories() {
|
||||
if (selectedTeam.value == null) return [];
|
||||
|
||||
if (teamMembers.isEmpty) {
|
||||
// ソロの場合
|
||||
String baseCategory = selectedTeam.value!.members.first.female ? 'ソロ女子' : 'ソロ男子';
|
||||
return categories.where((c) => c.categoryName.startsWith(baseCategory)).toList();
|
||||
} else if (teamMembers.length == 1) {
|
||||
// チームメンバーが1人の場合(ソロ)
|
||||
String baseCategory = teamMembers.first.female ? 'ソロ女子' : 'ソロ男子';
|
||||
return categories.where((c) => c.categoryName.startsWith(baseCategory)).toList();
|
||||
} else {
|
||||
// 複数人の場合
|
||||
bool hasElementaryOrYounger = teamMembers.any(isElementarySchoolOrYounger);
|
||||
String baseCategory = hasElementaryOrYounger ? 'ファミリー' : '一般';
|
||||
return categories.where((c) => c.categoryName.startsWith(baseCategory)).toList();
|
||||
}
|
||||
}
|
||||
|
||||
bool isElementarySchoolOrYounger(User user) {
|
||||
final now = DateTime.now();
|
||||
final age = now.year - user.dateOfBirth!.year;
|
||||
return age <= 12;
|
||||
}
|
||||
|
||||
void updateTeam(Team? value) async {
|
||||
selectedTeam.value = value;
|
||||
if (value != null) {
|
||||
await fetchTeamMembers(value.id);
|
||||
final filteredCategories = getFilteredCategories();
|
||||
if (filteredCategories.isNotEmpty) {
|
||||
selectedCategory.value = filteredCategories.first;
|
||||
} else {
|
||||
selectedCategory.value = null;
|
||||
}
|
||||
} else {
|
||||
teamMembers.clear();
|
||||
selectedCategory.value = null;
|
||||
}
|
||||
}
|
||||
|
||||
void updateTeam_old(Team? value) {
|
||||
selectedTeam.value = value;
|
||||
if (value != null) {
|
||||
selectedCategory.value = value.category;
|
||||
}
|
||||
}
|
||||
|
||||
//void updateTeam(Team? value) => selectedTeam.value = value;
|
||||
void updateCategory(NewCategory? value) => selectedCategory.value = value;
|
||||
//void updateDate(DateTime value) => selectedDate.value = value;
|
||||
|
||||
@ -175,6 +175,20 @@ class EntryDetailPage extends GetView<EntryController> {
|
||||
}
|
||||
|
||||
Widget _buildCategoryDropdown() {
|
||||
final eligibleCategories = controller.getFilteredCategories();
|
||||
|
||||
return DropdownButtonFormField<NewCategory>(
|
||||
decoration: InputDecoration(labelText: 'カテゴリ'),
|
||||
value: controller.selectedCategory.value,
|
||||
items: eligibleCategories.map((category) => DropdownMenuItem<NewCategory>(
|
||||
value: category,
|
||||
child: Text(category.categoryName),
|
||||
)).toList(),
|
||||
onChanged: (value) => controller.updateCategory(value),
|
||||
);
|
||||
}
|
||||
|
||||
Widget _buildCategoryDropdown_old() {
|
||||
final eligibleCategories = controller.categories.where((c) =>
|
||||
c.baseCategory == controller.selectedCategory.value?.baseCategory
|
||||
).toList();
|
||||
|
||||
@ -240,14 +240,14 @@ class IndexController extends GetxController with WidgetsBindingObserver {
|
||||
|
||||
@override
|
||||
void onInit() {
|
||||
super.onInit();
|
||||
try {
|
||||
super.onInit();
|
||||
initConnectivity();
|
||||
_connectivitySubscription = _connectivity.onConnectivityChanged.listen(_updateConnectionStatus);
|
||||
|
||||
WidgetsBinding.instance.addPostFrameCallback((_) async {
|
||||
await PermissionController.checkAndRequestPermissions();
|
||||
});
|
||||
//WidgetsBinding.instance.addPostFrameCallback((_) async {
|
||||
// await PermissionController.checkAndRequestPermissions();
|
||||
//});
|
||||
|
||||
WidgetsBinding.instance.addObserver(this);
|
||||
_startLocationService(); // アプリ起動時にLocationServiceを開始する
|
||||
|
||||
@ -40,7 +40,7 @@ class _IndexPageState extends State<IndexPage> {
|
||||
super.initState();
|
||||
WidgetsBinding.instance.addPostFrameCallback((_) async {
|
||||
await _ensureControllersAreInitialized();
|
||||
await PermissionController.checkAndRequestPermissions();
|
||||
//await PermissionController.checkAndRequestPermissions();
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
@ -167,6 +167,17 @@ class PermissionController {
|
||||
}
|
||||
|
||||
static Future<bool> showLocationDisclosure() async {
|
||||
if (Platform.isIOS) {
|
||||
return await _showLocationDisclosureIOS();
|
||||
} else if (Platform.isAndroid) {
|
||||
return await _showLocationDisclosureAndroid();
|
||||
} else {
|
||||
// その他のプラットフォームの場合はデフォルトの処理を行う
|
||||
return await _showLocationDisclosureIOS();
|
||||
}
|
||||
}
|
||||
|
||||
static Future<bool> _showLocationDisclosureIOS() async {
|
||||
if (Get.context == null) {
|
||||
print('Context is null, cannot show dialog');
|
||||
return false;
|
||||
@ -214,6 +225,41 @@ class PermissionController {
|
||||
}
|
||||
}
|
||||
|
||||
static Future<bool> _showLocationDisclosureAndroid() async {
|
||||
return await showDialog<bool>(
|
||||
context: Get.overlayContext ?? Get.context ?? (throw Exception('No valid context found')),
|
||||
barrierDismissible: false,
|
||||
builder: (BuildContext context) {
|
||||
return AlertDialog(
|
||||
title: const Text('位置情報の使用について'),
|
||||
content: const SingleChildScrollView(
|
||||
child: ListBody(
|
||||
children: <Widget>[
|
||||
Text('このアプリでは、以下の目的で位置情報を使用します:'),
|
||||
Text('• チェックポイントの自動チェックイン(アプリが閉じているときも含む)'),
|
||||
Text('• 移動履歴の記録(バックグラウンドでも継続)'),
|
||||
Text('• 現在地周辺の情報表示'),
|
||||
Text('\nバックグラウンドでも位置情報を継続的に取得します。'),
|
||||
Text('これにより、バッテリーの消費が増加する可能性があります。'),
|
||||
Text('同意しない場合には、アプリは終了します。'),
|
||||
],
|
||||
),
|
||||
),
|
||||
actions: <Widget>[
|
||||
TextButton(
|
||||
child: const Text('同意しない'),
|
||||
onPressed: () => Navigator.of(context).pop(false),
|
||||
),
|
||||
TextButton(
|
||||
child: const Text('同意する'),
|
||||
onPressed: () => Navigator.of(context).pop(true),
|
||||
),
|
||||
],
|
||||
);
|
||||
},
|
||||
) ?? false;
|
||||
}
|
||||
|
||||
static void showPermissionDeniedDialog(String title,String message) {
|
||||
Get.dialog(
|
||||
AlertDialog(
|
||||
|
||||
@ -329,13 +329,6 @@ class TeamController extends GetxController {
|
||||
}
|
||||
|
||||
List<NewCategory> getFilteredCategories_old() {
|
||||
//List<User> teamMembers = getCurrentTeamMembers();
|
||||
return categories.where((category) {
|
||||
return isCategoryValid(category, teamMembers);
|
||||
}).toList();
|
||||
}
|
||||
|
||||
List<NewCategory> getFilteredCategories() {
|
||||
if (teamMembers.isEmpty && currentUser.value != null) {
|
||||
// ソロの場合
|
||||
String baseCategory = currentUser.value!.female ? 'ソロ女子' : 'ソロ男子';
|
||||
@ -347,6 +340,24 @@ class TeamController extends GetxController {
|
||||
}
|
||||
}
|
||||
|
||||
List<NewCategory> getFilteredCategories() {
|
||||
if (teamMembers.isEmpty && currentUser.value != null) {
|
||||
// ソロの場合
|
||||
String baseCategory = currentUser.value!.female ? 'ソロ女子' : 'ソロ男子';
|
||||
return categories.where((c) => c.categoryName.startsWith(baseCategory)).toList();
|
||||
} else if (teamMembers.length == 1) {
|
||||
// チームメンバーが1人の場合(ソロ)
|
||||
String baseCategory = teamMembers.first.female ? 'ソロ女子' : 'ソロ男子';
|
||||
return categories.where((c) => c.categoryName.startsWith(baseCategory)).toList();
|
||||
} else {
|
||||
// 複数人の場合
|
||||
bool hasElementaryOrYounger = teamMembers.any(isElementarySchoolOrYounger);
|
||||
String baseCategory = hasElementaryOrYounger ? 'ファミリー' : '一般';
|
||||
return categories.where((c) => c.categoryName.startsWith(baseCategory)).toList();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
bool isElementarySchoolOrYounger(User user) {
|
||||
final now = DateTime.now();
|
||||
final age = now.year - user.dateOfBirth!.year;
|
||||
@ -379,17 +390,7 @@ class TeamController extends GetxController {
|
||||
// メンバーリストの最新状態を取得
|
||||
await fetchTeamMembers(selectedTeam.value!.id);
|
||||
|
||||
List<NewCategory> eligibleCategories = [];
|
||||
if (teamMembers.isEmpty || teamMembers.length == 1) {
|
||||
if (currentUser.value != null) {
|
||||
String baseCategory = currentUser.value!.female ? 'ソロ女子' : 'ソロ男子';
|
||||
eligibleCategories = categories.where((c) => c.baseCategory == baseCategory).toList();
|
||||
}
|
||||
} else {
|
||||
bool hasElementaryOrYounger = teamMembers.any(isElementarySchoolOrYounger);
|
||||
String baseCategory = hasElementaryOrYounger ? 'ファミリー' : '一般';
|
||||
eligibleCategories = categories.where((c) => c.baseCategory == baseCategory).toList();
|
||||
}
|
||||
List<NewCategory> eligibleCategories = getFilteredCategories();
|
||||
|
||||
// 同じ時間のカテゴリを優先的に選択
|
||||
NewCategory? newCategory = eligibleCategories.firstWhereOrNull((c) => c.time == oldTime);
|
||||
|
||||
@ -120,15 +120,19 @@ class _TeamDetailPageState extends State<TeamDetailPage> {
|
||||
}
|
||||
|
||||
final filteredCategories = controller.getFilteredCategories();
|
||||
final categoriesToDisplay = filteredCategories.isEmpty
|
||||
? controller.categories
|
||||
: filteredCategories;
|
||||
// 選択されているカテゴリが表示リストに含まれていない場合、最初の項目を選択する
|
||||
if (controller.selectedCategory.value == null ||
|
||||
!filteredCategories.contains(controller.selectedCategory.value)) {
|
||||
controller.updateCategory(filteredCategories.isNotEmpty
|
||||
? filteredCategories.first
|
||||
: null);
|
||||
}
|
||||
|
||||
// 選択されているカテゴリが表示リストに含まれていない場合、最初の項目を選択する
|
||||
if (controller.selectedCategory.value == null ||
|
||||
!categoriesToDisplay.contains(controller.selectedCategory.value)) {
|
||||
controller.updateCategory(categoriesToDisplay.isNotEmpty
|
||||
? categoriesToDisplay.first
|
||||
!filteredCategories.contains(controller.selectedCategory.value)) {
|
||||
controller.updateCategory(filteredCategories.isNotEmpty
|
||||
? filteredCategories.first
|
||||
: null);
|
||||
}
|
||||
|
||||
@ -147,7 +151,7 @@ class _TeamDetailPageState extends State<TeamDetailPage> {
|
||||
),
|
||||
),
|
||||
const SizedBox(height: 16),
|
||||
if (categoriesToDisplay.isEmpty)
|
||||
if (filteredCategories.isEmpty)
|
||||
const Text('カテゴリデータを読み込めませんでした。',
|
||||
style: TextStyle(color: Colors.red))
|
||||
else
|
||||
@ -156,7 +160,7 @@ class _TeamDetailPageState extends State<TeamDetailPage> {
|
||||
decoration: const InputDecoration(
|
||||
labelText: 'カテゴリ'),
|
||||
value: controller.selectedCategory.value,
|
||||
items: categoriesToDisplay.map((category) =>
|
||||
items: filteredCategories.map((category) =>
|
||||
DropdownMenuItem(
|
||||
value: category,
|
||||
child: Text(category.categoryName),
|
||||
|
||||
@ -87,7 +87,7 @@ class ApiService extends GetxService{
|
||||
Future<dynamic> _handleRequest(Future<http.Response> Function() request) async {
|
||||
try {
|
||||
final response = await request();
|
||||
if (response.statusCode == 200) {
|
||||
if (response.statusCode == 200 || response.statusCode == 201) {
|
||||
return json.decode(utf8.decode(response.bodyBytes));
|
||||
} else if (response.statusCode == 401) {
|
||||
await _handleUnauthorized();
|
||||
|
||||
@ -370,6 +370,15 @@ class ExternalService {
|
||||
|
||||
//int userId = indexController.currentUser[0]["user"]["id"];
|
||||
//print("--- Pressed -----");
|
||||
if( indexController.currentUser[0]["user"]==null ){
|
||||
return Future.value(false);
|
||||
}
|
||||
if( indexController.currentUser[0]["user"]['team_name']==null ){
|
||||
return Future.value(false);
|
||||
}
|
||||
if( indexController.currentUser[0]["user"]["event_code"]==null ){
|
||||
return Future.value(false);
|
||||
}
|
||||
String team = indexController.currentUser[0]["user"]['team_name'];
|
||||
//print("--- _team : ${_team}-----");
|
||||
String eventCode = indexController.currentUser[0]["user"]["event_code"];
|
||||
|
||||
@ -248,7 +248,7 @@ class LocationController extends GetxController {
|
||||
return;
|
||||
}
|
||||
|
||||
await PermissionController.checkAndRequestPermissions();
|
||||
//await PermissionController.checkAndRequestPermissions();
|
||||
|
||||
// 位置情報の設定を行います。z11
|
||||
// Set up the location options
|
||||
|
||||
@ -54,9 +54,11 @@ class _MapWidgetState extends State<MapWidget> with WidgetsBindingObserver {
|
||||
super.initState();
|
||||
|
||||
// 追加
|
||||
/*
|
||||
WidgetsBinding.instance.addPostFrameCallback((_) {
|
||||
PermissionController.checkAndRequestPermissions();
|
||||
});
|
||||
*/
|
||||
|
||||
debugPrint('MapWidget: initState called');
|
||||
SettingsBinding().dependencies(); // これを追加
|
||||
@ -83,7 +85,7 @@ class _MapWidgetState extends State<MapWidget> with WidgetsBindingObserver {
|
||||
});
|
||||
// MapControllerの初期化が完了したら、IndexControllerのonInitを呼び出す
|
||||
//indexController.checkPermission();
|
||||
PermissionController.checkAndRequestPermissions();
|
||||
//PermissionController.checkAndRequestPermissions();
|
||||
});
|
||||
|
||||
late MapResetController mapResetController = MapResetController();
|
||||
|
||||
@ -16,7 +16,7 @@ publish_to: 'none' # Remove this line if you wish to publish to pub.dev
|
||||
# https://developer.apple.com/library/archive/documentation/General/Reference/InfoPlistKeyReference/Articles/CoreFoundationKeys.html
|
||||
# In Windows, build-name is used as the major, minor, and patch parts
|
||||
# of the product and file versions while build-number is used as the build suffix.
|
||||
version: 4.8.19+499
|
||||
version: 4.8.20+500
|
||||
|
||||
environment:
|
||||
sdk: ^3.5.0
|
||||
|
||||
Reference in New Issue
Block a user