377 lines
13 KiB
Dart
377 lines
13 KiB
Dart
import 'package:flutter/material.dart';
|
|
import 'package:get/get.dart';
|
|
import 'package:gsp_app/views/pages/MenstrualCycleTracker/viewModel/StoringDates.dart';
|
|
import 'package:intl/intl.dart';
|
|
import 'package:syncfusion_flutter_datepicker/datepicker.dart';
|
|
|
|
import '../../../../api/base_manager.dart';
|
|
import 'StorageService.dart';
|
|
|
|
class HelperMethods extends GetxController {
|
|
RxString fertility = "May not be fertile".obs;
|
|
Rx<Color> fertilityColor = Color(0xFFFFEB3B).obs;
|
|
RxString observableDateTime = "15 December".obs;
|
|
RxString observableDateTimeOnTrackerHomePage =
|
|
DateFormat('dd MMMM').format(DateTime.now()).obs;
|
|
Rx<DateTime?> updateDateForHomepage = DateTime.now().obs;
|
|
RxBool overviewButtonColorTransparent = false.obs;
|
|
changeObservableDateTimeOnTrackerHomePage(bool front) {
|
|
DateTime currentDate =
|
|
DateFormat('dd MMMM').parse(observableDateTimeOnTrackerHomePage.value);
|
|
// Set the current year to the parsed date
|
|
DateTime updatedDate = DateTime(
|
|
DateTime.now().year,
|
|
currentDate.month,
|
|
currentDate.day,
|
|
);
|
|
// Add one day to the current date
|
|
|
|
if (front) {
|
|
updatedDate = updatedDate.add(Duration(days: 1));
|
|
currentPositionInCycleIndex + 1;
|
|
} else {
|
|
updatedDate = updatedDate.subtract(Duration(days: 1));
|
|
currentPositionInCycleIndex - 1;
|
|
}
|
|
|
|
//For HomePage
|
|
updateDateForHomepage.value = updatedDate;
|
|
// Format the updated date and update the observable
|
|
observableDateTimeOnTrackerHomePage.value =
|
|
DateFormat('dd MMMM').format(updatedDate);
|
|
calculateOutOfDays();
|
|
}
|
|
|
|
updateFertility(String value) {
|
|
fertility.value = value;
|
|
}
|
|
|
|
// Method to format DateTime as "dd MMMM" (e.g., "15 December")
|
|
formatDateTime(DateTime dateTime) {
|
|
observableDateTime.value = DateFormat('dd MMMM').format(dateTime);
|
|
}
|
|
|
|
RxBool showPeriodCycleText = true.obs;
|
|
RxString formattedDay = "".obs;
|
|
|
|
// Method to format DateTime as "dd" for periodCycle 1/22 on overview page
|
|
formatDateTime2(DateTime dateTime) {
|
|
formattedDay.value = DateFormat('dd').format(dateTime);
|
|
if (int.parse(formattedDay.value) > currentPeriodCycle.value) {
|
|
showPeriodCycleText.value = false;
|
|
} else {
|
|
showPeriodCycleText.value = true;
|
|
}
|
|
}
|
|
|
|
//Period calculation
|
|
|
|
Rx<DateTime?> firstPeriodDate = Rx<DateTime?>(null);
|
|
RxInt periodCycleLength = RxInt(0);
|
|
RxInt periodLength = RxInt(0);
|
|
RxList<DateTime?> predictedDate = <DateTime?>[].obs;
|
|
RxList<PickerDateRange> pickerdateRange = <PickerDateRange>[].obs;
|
|
|
|
//---------++++++++++--------------
|
|
//Other days calculation
|
|
|
|
RxList<DateTime?> fertileDates = <DateTime?>[].obs;
|
|
RxList<DateTime?> ovulatingDate = <DateTime?>[].obs;
|
|
//RxList<DateTime?> notfertilityDates = <DateTime?>[].obs;
|
|
List<int> periodCycleLengthList = [];
|
|
RxBool isLoading = true.obs;
|
|
// -----------+++++++++++++-----------
|
|
calculateFirstTime() async {
|
|
predictedDate.add(
|
|
firstPeriodDate.value!.add(Duration(days: periodCycleLength.value)));
|
|
|
|
pickerdateRange.add(PickerDateRange(firstPeriodDate.value,
|
|
firstPeriodDate.value!.add(Duration(days: periodLength.value - 1))));
|
|
periodCycleLengthList.add(periodCycleLength.value);
|
|
if (periodCycleLength.value > 21) {
|
|
ovulatingDate.add(firstPeriodDate.value!.add(const Duration(days: 14)));
|
|
}
|
|
List<Map<String, DateTime>> dateMaps = [];
|
|
// Iterate through selectedRanges and add each PickerDateRange to the list of maps
|
|
for (PickerDateRange range in pickerdateRange.value) {
|
|
Map<String, DateTime> dateMap = {
|
|
"start": range.startDate ?? DateTime.now(),
|
|
"end": range.endDate ?? DateTime.now(),
|
|
};
|
|
dateMaps.add(dateMap);
|
|
}
|
|
var updata = {
|
|
"predicted_dates": predictedDate.value.toString(),
|
|
"fertile_dates": fertileDates.value.toString(),
|
|
"ovulating_dates": ovulatingDate.value.toString(),
|
|
"pickerdateRange": dateMaps.toString(),
|
|
"period_cycle_length": periodCycleLengthList.first
|
|
};
|
|
final resp = await StoringDates().storeAllList(updata);
|
|
if (resp.status == ResponseStatus.SUCCESS) {
|
|
Future.delayed(const Duration(seconds: 2), () {
|
|
isLoading.value = false;
|
|
});
|
|
StorageService().storeinitialSetup();
|
|
}
|
|
}
|
|
|
|
// reCalculateFromApi() {
|
|
// predictedDate.add(
|
|
// firstPeriodDate.value!.add(Duration(days: periodCycleLength.value)));
|
|
|
|
// pickerdateRange.add(PickerDateRange(firstPeriodDate.value,
|
|
// firstPeriodDate.value!.add(Duration(days: periodLength.value - 1))));
|
|
// periodCycleLengthList.add(periodCycleLength.value);
|
|
// if (periodCycleLength.value > 21) {
|
|
// ovulatingDate.add(firstPeriodDate.value!.add(const Duration(days: 14)));
|
|
// }
|
|
// }
|
|
|
|
recalculate() async {
|
|
List<int> data = calculatePeriodCycleLength();
|
|
predictedDate.clear();
|
|
ovulatingDate.clear();
|
|
for (var i = 0; i < pickerdateRange.length; i++) {
|
|
predictedDate
|
|
.add(pickerdateRange[i].startDate!.add(Duration(days: data[i])));
|
|
if (periodCycleLength.value > 21) {
|
|
ovulatingDate
|
|
.add(pickerdateRange[i].startDate!.add(const Duration(days: 14)));
|
|
}
|
|
}
|
|
List<Map<String, DateTime>> dateMaps = [];
|
|
// Iterate through selectedRanges and add each PickerDateRange to the list of maps
|
|
for (PickerDateRange range in pickerdateRange.value) {
|
|
Map<String, DateTime> dateMap = {
|
|
"start": range.startDate ?? DateTime.now(),
|
|
"end": range.endDate ?? DateTime.now(),
|
|
};
|
|
dateMaps.add(dateMap);
|
|
}
|
|
var updata = {
|
|
"predicted_dates": predictedDate.value.toString(),
|
|
"fertile_dates": fertileDates.value.toString(),
|
|
"ovulating_dates": ovulatingDate.value.toString(),
|
|
"pickerdateRange": dateMaps.toString(),
|
|
"period_cycle_length": periodCycleLengthList.first
|
|
};
|
|
|
|
//await StoringDates().storeAllList(updata);
|
|
isLoading.value = true;
|
|
final resp = await StoringDates().storeAllList(updata);
|
|
if (resp.status == ResponseStatus.SUCCESS) {
|
|
Future.delayed(const Duration(seconds: 1), () {
|
|
isLoading.value = false;
|
|
});
|
|
StorageService().storeinitialSetup();
|
|
}
|
|
getLast5PeriodDates();
|
|
}
|
|
|
|
List<int> calculatePeriodCycleLength() {
|
|
if (pickerdateRange.length >= 2) {
|
|
// int totalPeriodCycleLength = 0;
|
|
// // Clear all elements except the first one
|
|
if (periodCycleLengthList.length > 1) {
|
|
periodCycleLengthList.removeRange(1, periodCycleLengthList.length);
|
|
}
|
|
pickerdateRange.sort((a, b) => a.startDate!.compareTo(b.startDate!));
|
|
// Calculate the sum of period cycle lengths
|
|
for (int i = 0; i < pickerdateRange.length - 1; i++) {
|
|
DateTime? currentStartDate = pickerdateRange[i].startDate;
|
|
DateTime? nextStartDate = pickerdateRange[i + 1].startDate;
|
|
|
|
// Calculate the difference in days and add it to the list
|
|
int periodCycleLength =
|
|
nextStartDate!.difference(currentStartDate!).inDays;
|
|
periodCycleLengthList.add(periodCycleLength);
|
|
}
|
|
|
|
// // Calculate the average period cycle length
|
|
// int averagePeriodCycleLength =
|
|
// totalPeriodCycleLength ~/ (pickerdateRange.length - 1);
|
|
}
|
|
return periodCycleLengthList;
|
|
|
|
// avg end ++++++++--------+++++
|
|
// if (pickerdateRange.length >= 2) {
|
|
// pickerdateRange.sort((a, b) => a.startDate!.compareTo(b.startDate!));
|
|
// DateTime? secondLastStartDate =
|
|
// pickerdateRange[pickerdateRange.length - 2].startDate;
|
|
// DateTime? lastStartDate = pickerdateRange.last.startDate;
|
|
|
|
// // Calculate the period cycle length in days
|
|
// int periodCycleLength =
|
|
// lastStartDate!.difference(secondLastStartDate!).inDays;
|
|
|
|
// print("calculated period cycle length is $periodCycleLength");
|
|
// // Clear all elements except the first one
|
|
// if (periodCycleLengthList.length > 1) {
|
|
// periodCycleLengthList.removeRange(1, periodCycleLengthList.length);
|
|
// }
|
|
// periodCycleLengthList.add(periodCycleLength);
|
|
// }
|
|
// return periodCycleLengthList;
|
|
}
|
|
|
|
Rx<DateTime?> predictedPeriodCycleForHomePage = Rx<DateTime?>(null);
|
|
// RxInt indexOfCurrentPeriodCycle = 0.obs;
|
|
int calculatePeriodCycle() {
|
|
DateTime currentDate = DateTime.now();
|
|
List<int> data = calculatePeriodCycleLength();
|
|
|
|
int index = predictedDate
|
|
.indexWhere((date) => date != null && date.isAfter(currentDate));
|
|
if (index >= 0) {
|
|
predictedPeriodCycleForHomePage.value = predictedDate[index];
|
|
//indexOfCurrentPeriodCycle.value = index;
|
|
return data[index];
|
|
} else {
|
|
return 99999;
|
|
}
|
|
}
|
|
|
|
RxInt currentPeriodCycle = 0.obs;
|
|
RxInt outOfDays = 0.obs;
|
|
|
|
calculateOutOfDays() {
|
|
int result = calculatePeriodCycle();
|
|
if (result != 99999) {
|
|
currentPeriodCycle.value = result;
|
|
triggerManipulation();
|
|
disabledNext = false.obs;
|
|
// showNext = true.obs;
|
|
// showPrev = true.obs;
|
|
} else {
|
|
showNext = false.obs;
|
|
showPrev = false.obs;
|
|
disabledNext = true.obs;
|
|
}
|
|
update();
|
|
}
|
|
|
|
RxBool showNext = true.obs;
|
|
RxBool showPrev = true.obs;
|
|
RxBool endOfCycle = true.obs;
|
|
RxBool disabledNext = false.obs;
|
|
|
|
triggerManipulation() {
|
|
if (currentPositionInCycleIndex.value == currentPeriodCycle.value) {
|
|
showNext.value = false;
|
|
endOfCycle.value = false;
|
|
} else if (currentPositionInCycleIndex.value == 0) {
|
|
showPrev.value = false;
|
|
} else {
|
|
showNext.value = true;
|
|
showPrev.value = true;
|
|
endOfCycle.value = true;
|
|
}
|
|
}
|
|
|
|
//for changing color of centre calendar icon
|
|
RxList<DateTime?> allDatesList = <DateTime?>[].obs;
|
|
|
|
calculatePeriodDateForCalender() {
|
|
allDatesList = generateAllDates(pickerdateRange);
|
|
}
|
|
|
|
RxList<DateTime?> generateAllDates(RxList<PickerDateRange> ranges) {
|
|
RxList<DateTime?> allDates = <DateTime?>[].obs;
|
|
|
|
for (var range in ranges) {
|
|
DateTime currentDate = range.startDate!;
|
|
while (currentDate.isBefore(range.endDate!) ||
|
|
currentDate.isAtSameMomentAs(range.endDate!)) {
|
|
allDates.add(currentDate);
|
|
currentDate = currentDate.add(const Duration(days: 1));
|
|
}
|
|
}
|
|
|
|
return allDates;
|
|
}
|
|
|
|
storePredictedDateFromApi(List<String> dateStrings) {
|
|
List<DateTime?> predictedDates =
|
|
dateStrings.map((dateString) => DateTime.parse(dateString)).toList();
|
|
|
|
predictedDate.assignAll(predictedDates);
|
|
|
|
print("Predicted Dates: ${helperController.predictedDate.value}");
|
|
}
|
|
|
|
storeOvulatingDateFromApi(List<String> dateStrings) {
|
|
// Convert the List of strings into a List<DateTime>
|
|
List<DateTime> ovulatingDate1 =
|
|
dateStrings.map((dateString) => DateTime.parse(dateString)).toList();
|
|
ovulatingDate.value = ovulatingDate1;
|
|
}
|
|
|
|
storeFirstPeriodDate() {
|
|
helperController.firstPeriodDate.value = pickerdateRange.first.startDate;
|
|
}
|
|
|
|
storePeriodCycles(response) {
|
|
periodCycleLengthList.add(response);
|
|
|
|
periodCycleLength.value = response;
|
|
}
|
|
|
|
List<DateTime> last5startDates = [];
|
|
|
|
getLast5PeriodDates() {
|
|
// Calculate the number of elements to consider (minimum between 5 and the list length)
|
|
int elementsToConsider =
|
|
pickerdateRange.length < 5 ? pickerdateRange.length : 5;
|
|
last5startDates.clear();
|
|
// Extract start dates from the last elementsToConsider ranges
|
|
for (int i = pickerdateRange.length - elementsToConsider;
|
|
i < pickerdateRange.length;
|
|
i++) {
|
|
last5startDates.add(pickerdateRange[i].startDate!);
|
|
}
|
|
|
|
// Now, startDates contains the last elementsToConsider start dates
|
|
print("Start Dates: $last5startDates");
|
|
}
|
|
|
|
RxInt currentPositionInCycleIndex = 0.obs;
|
|
|
|
calculateCurrentPositionInCycle(DateTime valueFromOverview) {
|
|
List<DateTime> dateList = generateDateList(
|
|
pickerdateRange.last.startDate!,
|
|
helperController.predictedPeriodCycleForHomePage.value ??
|
|
DateTime.now());
|
|
// Search date which was visible on Homepage Inside circle
|
|
// DateTime currentDate1 =
|
|
// DateFormat('dd MMMM').parse(observableDateTimeOnTrackerHomePage.value);
|
|
|
|
// //Search date which is in overview page -> Period cycle:
|
|
// DateTime currentDate1 =
|
|
// DateFormat('dd MMMM').parse(observableDateTimeOnTrackerHomePage.value);
|
|
// // Set the current year to the parsed date
|
|
// DateTime updatedDate = DateTime(
|
|
// DateTime.now().year,
|
|
// currentDate1.month,
|
|
// currentDate1.day,
|
|
// );
|
|
currentPositionInCycleIndex.value = dateList.indexOf(valueFromOverview);
|
|
|
|
if (currentPositionInCycleIndex.value == -1) {
|
|
showPeriodCycleText.value = false;
|
|
}
|
|
}
|
|
|
|
List<DateTime> generateDateList(DateTime startDate, DateTime endDate) {
|
|
List<DateTime> dateList = [];
|
|
dateList.add(startDate);
|
|
|
|
while (startDate.isBefore(endDate)) {
|
|
startDate = startDate.add(Duration(days: 1));
|
|
dateList.add(startDate);
|
|
}
|
|
|
|
return dateList;
|
|
}
|
|
}
|