Untitled
unknown
plain_text
2 months ago
8.0 kB
5
Indexable
import 'package:flutter/material.dart'; import 'package:dio/dio.dart'; import 'package:get/get.dart'; import 'package:shared_preferences/shared_preferences.dart'; import 'package:family_tree/app/modules/family_tree/controllers/tree_controller.dart'; import 'package:family_tree/app/modules/family_tree/model/family_model.dart'; import 'package:family_tree/app/modules/profile/controllers/profile_controller.dart'; import 'package:family_tree/app/modules/session/controllers/session_controller.dart'; import 'package:family_tree/constant/shared_preference_key.dart'; import 'package:family_tree/constant/url.dart'; import 'package:family_tree/library/dio_client.dart'; import 'package:family_tree/mgwidgets/loading_widget.dart'; class FamilyTreeController extends GetxController with GetTickerProviderStateMixin { // Dependencies final sessionController = Get.put(SessionController()); final dio = DioClient(withLog: false); // UI Controllers late TabController tabController; // Observable State final isOpenFindPerson = false.obs; final family = <FamilyModel>[].obs; final index = 0.obs; final loading = false.obs; final listTreeController = <TreeController>[].obs; // Internal State final scrollKey = GlobalKey(); int activeTreeId = 0; int treeId = 0; bool isRefresh = false; // Find a tree by its ID FamilyModel? getTreeById(int treeId) { for (var data in family) { if (data.tree.treeId == treeId) { return data; } } return null; } @override void onInit() async { // Initialize tab controller with zero length initially tabController = TabController( vsync: this, length: 0, ); // Check if we need to focus on a specific tree if (Get.arguments != null && Get.arguments.containsKey('tree_id')) { activeTreeId = Get.arguments['tree_id']; } // Fetch data to populate the trees await fetchDataTree(refreshTab: true); super.onInit(); } // Pull-to-refresh handler Future<void> onRefresh() async { Get.put(LoadingWidget()).show(); await fetchDataTree(); Get.put(LoadingWidget()).close(); } // Fake refresh for testing purposes Future<void> onRefreshFake() async { Get.put(LoadingWidget()).show(); Get.put(LoadingWidget()).close(); } // Fetch tree data from API Future<void> fetchDataTree({ bool refreshTab = true, bool toLastFamily = false, }) async { try { // If we're refreshing tabs, reset the tab controller if (refreshTab == true) { tabController = TabController(length: 0, vsync: this); } loading(true); // Get authentication token final prefs = await SharedPreferences.getInstance(); var token = prefs.getString(SharedPreferenceKey.token); dio.baseOptions.headers['Authorization'] = 'Bearer $token'; // Clear existing data family.clear(); // Fetch tree data from API var response = await dio.requestGet(getTreePath, {}); var result = response!.data; var json = List<Map<String, dynamic>>.from(result['data']); // Process each family tree List<TreeController> listTreeControllerTemp = []; for (var a in json) { // Create family model FamilyModel temp = FamilyModel.fromJson(a); family.add(temp); // Create and configure a tree controller for this family TreeController tempTreeController = Get.put( TreeController(), tag: temp.treeId.toString(), ); // Initialize controller collections List<ScrollController> listScrollFamily = []; List<List<GlobalKey>> listKeyFamily = []; List<GlobalKey> listKeyGeneration = []; List<List<bool>> listChildBlink = []; List<List<bool>> listSpouseBlink = []; // Process each generation in the family for (var j in temp.generations) { List<GlobalKey> listKeyFamilyGeneration = []; List<bool> childBlink = []; List<bool> spouseBlink = []; // Set up keys and blink states for each child for (int k = 0; k < j.children.length; k++) { listKeyFamilyGeneration.add(GlobalKey()); childBlink.add(false); spouseBlink.add(false); } // Add collections to their respective controllers listChildBlink.add(childBlink); listSpouseBlink.add(spouseBlink); listScrollFamily.add(ScrollController()); listKeyFamily.add(listKeyFamilyGeneration); listKeyGeneration.add(GlobalKey()); } // Assign collections to the tree controller tempTreeController.listChildBlink.value = listChildBlink; tempTreeController.listSpouseBlink.value = listSpouseBlink; tempTreeController.listFamilyKeyGeneration.value = listKeyGeneration; tempTreeController.listFamilyScrollGeneration.value = listScrollFamily; tempTreeController.listFamilyKeyChild.value = listKeyFamily; // Refresh controller state tempTreeController.listFamilyScrollGeneration.refresh(); tempTreeController.listFamilyKeyChild.refresh(); // Add to the main list of tree controllers listTreeControllerTemp.add(tempTreeController); } // Update the main list of tree controllers listTreeController.value = listTreeControllerTemp; listTreeController.refresh(); // Update tab controller if needed if (refreshTab == true) { tabController = TabController( vsync: this, length: family.length, ); } // Set up tab selection listener tabController.addListener(() { index.value = tabController.index; }); // Set active tab based on tree ID if specified for (var i = 0; i < family.length; i++) { if (family[i].treeId == treeId) { tabController.index = i; index.value = i; treeId = 0; } } // Ensure tab index is set tabController.index = index.value; // Update UI state loading(false); family.refresh(); return; } catch (e) { // Handle errors silently print("Error fetching tree data: $e"); } return null; } // Remove tree data (for cleanup) Future<void> removeTree({ bool refreshTab = true, bool toLastFamily = false, }) async { try { family.clear(); family.refresh(); print(family.length); } catch (e) { // Handle errors silently } return null; } // API call to unmerge photos for two persons Future<void> postUnmergePhoto({ required int personId1, required int personId2, }) async { // Prepare request parameters var param = { 'person_id1': personId1, 'person_id2': personId2, }; // Show loading indicator Get.put(LoadingWidget()).show(); try { // Get authentication token final prefs = await SharedPreferences.getInstance(); var token = prefs.getString(SharedPreferenceKey.token); // Make API request var response = await dio.requestPost( unmergePhoto, param, options: Options( headers: { 'authorization': 'Bearer $token', }, ), ); // Handle response if (response == null) { Get.back(); return null; } // Refresh data after successful unmerge await fetchDataTree(refreshTab: false); await Get.put(ProfileController()).loadData(); } catch (e) { print("Error unmerging photos: $e"); } finally { // Close loading indicator Get.put(LoadingWidget()).close(); } } // Set active tree by ID void setActiveTreeId(int treeId) { int activeIndex = family.indexWhere((e) => e.treeId == treeId); if (activeIndex >= 0) { tabController.animateTo(activeIndex); } } }
Editor is loading...
Leave a Comment