android – Calendar would not work in manufacturing solely flutter

android – Calendar would not work in manufacturing solely flutter


So, i’ve developed a calendar in flutter, it ought to load within the chosen days three informations: drugs, occasions and meals. In debug mode it really works simply high quality, however in manufacturing when i attempt to entry the calendar, if it have any drugs registered, the display freezes and no data is loaded. Each apple and google manufacturing variations make this. Any suggestions?
In debug mode it would not present any errors, it was anticipated to load the objects within the _load features into the display, as a substitute, in manufacturing (app printed in each shops) the display freezes and app maintain caught no different actions will be executed

import 'package deal:app_cuidadoria/no_bloc_components/add_event_item.dart';
import 'package deal:app_cuidadoria/no_bloc_models/occasion.dart';
import 'package deal:app_cuidadoria/no_bloc_models/refeicao.dart';
import 'package deal:app_cuidadoria/shared_components/custom_hour_field.dart';
import 'package deal:app_cuidadoria/side_menu/pages/side_menu_drawer.dart';
import 'package deal:cloud_firestore/cloud_firestore.dart';
import 'package deal:flutter/materials.dart';
import 'package deal:flutter/companies.dart';
import 'package deal:intl/intl.dart';
import 'package deal:shared_preferences/shared_preferences.dart';
import 'package deal:table_calendar/table_calendar.dart';

import 'package deal:app_cuidadoria/no_bloc_components/add_medicine_item.dart';
import 'package deal:app_cuidadoria/no_bloc_components/event_item.dart';
import 'package deal:app_cuidadoria/no_bloc_models/drugs.dart';
import 'package deal:uuid/uuid.dart';

class MedicineCalendarPage extends StatefulWidget {
  const MedicineCalendarPage({
    tremendous.key,
    required this.uid,
  });
  closing String uid;

  @override
  State createState() => _MedicineCalendarPageState();
}

class _MedicineCalendarPageState extends State {
  DateTime _selectedDate =
      DateTime(DateTime.now().12 months, DateTime.now().month, DateTime.now().day);
  Record _eventsForSelectedDay = [];
  Record medicineList = [];
  Record eventList = [];
  Record mealList = [];
  Record _selectedDays = [];
  int userLevel = 0;
  @override
  void initState() {
    init();
    tremendous.initState();
  }

  init() async {
    closing cache = await SharedPreferences.getInstance();
    await _loadEventsForSelectedDate(_selectedDate);
    await _loadEventsNotMedForSelectedDate(_selectedDate);
    await _loadMealsForSelectedDate(_selectedDate);
    setState(() {
      userLevel = cache.getInt('userLevel') ?? 0;
    });
    _eventsForSelectedDay.type((a, b) {
      // Expressão common para capturar HH:mm no closing da string
      RegExp regExp = RegExp(r'(d{2}):(d{2})$');

      Match? matchA = regExp.firstMatch(a);
      Match? matchB = regExp.firstMatch(b);

      if (matchA != null && matchB != null) {
        int hourA = int.parse(matchA.group(1)!);
        int minuteA = int.parse(matchA.group(2)!);
        int hourB = int.parse(matchB.group(1)!);
        int minuteB = int.parse(matchB.group(2)!);

        // Criamos uma representação em minutos do dia para comparar
        int totalMinutesA = hourA * 60 + minuteA;
        int totalMinutesB = hourB * 60 + minuteB;

        return totalMinutesA.compareTo(totalMinutesB);
      }

      return 0; // Caso não tenha horário, não altera a ordem
    });
  }

  Future _loadEventsForSelectedDate(DateTime selectedDate) async {
    selectedDate =
        DateTime(selectedDate.12 months, selectedDate.month, selectedDate.day);
    closing querySnapshot = await FirebaseFirestore.occasion
        .assortment('medicines')
        .the place('uid', isEqualTo: widget.uid)
        .get();
    Record loadedEvents = [];

    for (var doc in querySnapshot.docs) {
      closing information = doc.information();
      DateTime startDate =
          DateTime.fromMillisecondsSinceEpoch(information['startDate'] as int);
      DateTime adjustedStartDate =
          DateTime(startDate.12 months, startDate.month, startDate.day);
      DateTime? endDate = information['endDate'] != null
          ? DateTime.fromMillisecondsSinceEpoch(information['endDate'] as int)
          : null;
      String description = information['medicineName'];
      bool repeatDaily = information['repeatDaily'];
      bool repeatMultipleTimes = information['repeatMultipleTimes'];
      int? hourInterval = information['hourInterval'];
      int? dayInterval = information['dayInterval'];
      int? dosage = (information['dosage'] as double).spherical();
      String? sort = information['type'];
      Record? specificDays = information['specificDays'] != null
          ? Record.from((information['specificDays'] as Record))
          : null;

      if (selectedDate.isBefore(adjustedStartDate) ||
          (endDate != null && selectedDate.isAfter(endDate))) {
        proceed; // Ignora eventos fora do intervalo de datas válidas
      }

      // Verifica se o medicamento deve ser tomado no dia selecionado
      bool shouldGenerateEvent = false;
      Record convertedSpecificDays = [];
      if (specificDays != null && specificDays.isNotEmpty) {
        convertedSpecificDays = specificDays
            .map((e) {
              swap (e.toLowerCase()) {
                case 'seg':
                  return DateTime.monday;
                case 'ter':
                  return DateTime.tuesday;
                case 'qua':
                  return DateTime.wednesday;
                case 'qui':
                  return DateTime.thursday;
                case 'intercourse':
                  return DateTime.friday;
                case 'sab':
                  return DateTime.saturday;
                case 'dom':
                  return DateTime.sunday;
                default:
                  return -1; // Valor inválido
              }
            })
            .the place((day) => day != -1)
            .toList(); // Filtra dias inválidos
      }
      if (repeatDaily) {
        shouldGenerateEvent = true;
      } else if (dayInterval != null &&
          // selectedDate.distinction(adjustedStartDate).inDays % dayInterval == 0
          (selectedDate.day == adjustedStartDate.day ||
              (selectedDate.day - adjustedStartDate.day) % dayInterval == 0)) {
        shouldGenerateEvent = true;
      } else if (convertedSpecificDays.accommodates(selectedDate.weekday)) {
        shouldGenerateEvent = true;
      }

      if (shouldGenerateEvent) {
        // Calcula a primeira dose do dia baseado no horário mais próximo
        DateTime firstDose = DateTime(
          selectedDate.12 months,
          selectedDate.month,
          selectedDate.day,
          startDate.hour,
          startDate.minute,
        );

        loadedEvents.add(
            '$description:n$dosage $sort - ${DateFormat('HH:mm').format(firstDose)}');
        medicineList.add(Drugs.fromDocument(doc));

        // Se houver múltiplas doses no mesmo dia, calcula os próximos horários
        if (repeatMultipleTimes && hourInterval != null) {
          DateTime nextDose = firstDose.add(Period(hours: hourInterval));
          whereas (nextDose.day == selectedDate.day) {
            loadedEvents.add(
                '$description:n$dosage $sort - ${DateFormat('HH:mm').format(nextDose)}');
            nextDose = nextDose.add(Period(hours: hourInterval));
            medicineList.add(Drugs.fromDocument(doc));
          }
        }
      }
    }

    // setState(() {
      _eventsForSelectedDay = loadedEvents;
    // });
  }

Future _loadMealsForSelectedDate(DateTime selectedDate) async {
  closing querySnapshot = await FirebaseFirestore.occasion
      .assortment('meals')
      .the place('idPaciente', isEqualTo: widget.uid)
      .get();

  Set uniqueMealIds = {}; // Para rastrear IDs únicos
  Record loadedMeals = [];

  selectedDate = DateTime(selectedDate.12 months, selectedDate.month, selectedDate.day);

  for (var doc in querySnapshot.docs) {
    closing information = doc.information();
    String description = '${information['titulo']} - ${information['horario']}';
    String id = information['id']; 

    if (uniqueMealIds.accommodates(id)) proceed; // Evita duplicatas

    Record? specificDays =
        information['dia'] != null ? Record.from((information['dia'] as Record)) : null;

    // Verifica se o medicamento deve ser tomado no dia selecionado
    bool shouldGenerateEvent = false;
    Record convertedSpecificDays = [];
    
    if (specificDays != null && specificDays.isNotEmpty) {
      convertedSpecificDays = specificDays
          .map((e) {
            swap (e.toLowerCase()) {
              case 'seg': return DateTime.monday;
              case 'ter': return DateTime.tuesday;
              case 'qua': return DateTime.wednesday;
              case 'qui': return DateTime.thursday;
              case 'intercourse': return DateTime.friday;
              case 'sáb': return DateTime.saturday;
              case 'dom': return DateTime.sunday;
              default: return -1; // Valor inválido
            }
          })
          .the place((day) => day != -1)
          .toList(); // Filtra dias inválidos
    }

    if (convertedSpecificDays.accommodates(selectedDate.weekday)) {
      shouldGenerateEvent = true;
    }

    if (shouldGenerateEvent) {
      uniqueMealIds.add(id); // Marca o ID como adicionado
      loadedMeals.add(description);
      mealList.add(Refeicao.fromDocument(doc));
    }
  }

  // Atualiza o estado apenas uma vez
  // setState(() {
    _eventsForSelectedDay.addAll(loadedMeals);
  // });
}

  Future _loadEventsNotMedForSelectedDate(DateTime selectedDate) async {
    closing querySnapshot = await FirebaseFirestore.occasion
        .assortment('occasions')
        .the place('uid', isEqualTo: widget.uid)
        .get();
    Record loadedEvents = [];
    selectedDate =
        DateTime(selectedDate.12 months, selectedDate.month, selectedDate.day);

    for (var doc in querySnapshot.docs) {
      closing information = doc.information();
      DateTime startDate =
          DateTime.fromMillisecondsSinceEpoch(information['startDate'] as int);
      DateTime adjustedStartDate =
          DateTime(startDate.12 months, startDate.month, startDate.day);
      DateTime? endDate = information['endDate'] != null
          ? DateTime.fromMillisecondsSinceEpoch(information['endDate'] as int)
          : null;
      String description = information['description'];
      bool repeatDaily = information['repeatDaily'];
      bool repeatMultipleTimes = information['repeatMultipleTimes'];
      int? hourInterval = information['hourInterval'];
      int? dayInterval = information['dayInterval'];
      Record? specificDays = information['specificDays'] != null
          ? Record.from((information['specificDays'] as Record))
          : null;

      if (selectedDate.isBefore(adjustedStartDate) ||
          (endDate != null && selectedDate.isAfter(endDate))) {
        proceed; 
      }

      bool shouldGenerateEvent = false;
      Record convertedSpecificDays = [];
      if (specificDays != null && specificDays.isNotEmpty) {
        convertedSpecificDays = specificDays
            .map((e) {
              swap (e.toLowerCase()) {
                case 'seg':
                  return DateTime.monday;
                case 'ter':
                  return DateTime.tuesday;
                case 'qua':
                  return DateTime.wednesday;
                case 'qui':
                  return DateTime.thursday;
                case 'intercourse':
                  return DateTime.friday;
                case 'sáb':
                  return DateTime.saturday;
                case 'dom':
                  return DateTime.sunday;
                default:
                  return -1; 
              }
            })
            .the place((day) => day != -1)
            .toList();
      }
      if (repeatDaily) {
        shouldGenerateEvent = true;
      } else if (dayInterval != null &&
          (selectedDate.day == adjustedStartDate.day ||
              (selectedDate.day - adjustedStartDate.day) % dayInterval == 0)) {
        shouldGenerateEvent = true;
      } else if (convertedSpecificDays.accommodates(selectedDate.weekday)) {
        shouldGenerateEvent = true;
      }

      if (shouldGenerateEvent) {
        DateTime firstDose = DateTime(
          selectedDate.12 months,
          selectedDate.month,
          selectedDate.day,
          startDate.hour,
          startDate.minute,
        );

        loadedEvents
            .add('$description - ${DateFormat('HH:mm').format(firstDose)}');
        eventList.add(Occasion.fromDocument(doc));

        if (repeatMultipleTimes && hourInterval != null) {
          DateTime nextDose = firstDose.add(Period(hours: hourInterval));
          whereas (nextDose.day == selectedDate.day) {
            loadedEvents
                .add('$description - ${DateFormat('HH:mm').format(nextDose)}');
            nextDose = nextDose.add(Period(hours: hourInterval));
            eventList.add(Occasion.fromDocument(doc));
          }
        }
      }
    }

    setState(() {
      _eventsForSelectedDay.addAll(loadedEvents);

      _eventsForSelectedDay.type((a, b) {
        // Expressão common para capturar HH:mm no closing da string
        RegExp regExp = RegExp(r'(d{2}):(d{2})$');

        Match? matchA = regExp.firstMatch(a);
        Match? matchB = regExp.firstMatch(b);

        if (matchA != null && matchB != null) {
          int hourA = int.parse(matchA.group(1)!);
          int minuteA = int.parse(matchA.group(2)!);
          int hourB = int.parse(matchB.group(1)!);
          int minuteB = int.parse(matchB.group(2)!);

          // Criamos uma representação em minutos do dia para comparar
          int totalMinutesA = hourA * 60 + minuteA;
          int totalMinutesB = hourB * 60 + minuteB;

          return totalMinutesA.compareTo(totalMinutesB);
        }

        return 0; // Caso não tenha horário, não altera a ordem
      });
    });
  }

  void showAlertDialog() async {
    closing alertDialog = AlertDialog(
      content material: AddMedicineItem(
        uid: widget.uid,
      ),
    );

    showDialog(
      context: context,
      builder: (context) {
        return alertDialog;
      },
    );
  }

  void showAlertDialogEvent() async {
    var alertDialog = AlertDialog(
      content material: AddEventItem(uid: widget.uid,),
    );

    showDialog(
      context: context,
      builder: (context) {
        return alertDialog;
      },
    );
  }

  void showMealAlertDialog() {
    closing TextEditingController tituloController = TextEditingController();
    closing TextEditingController horarioController = TextEditingController();

    // Lista de dias da semana

    // Lista para armazenar os dias selecionados
    Record selectedDias = [];

    String loggedUid = '';
    const Uuid uuid = Uuid();

    // Função para buscar as refeições do paciente no Firestore

    Future addMeal(Refeicao newMeal) async {
      await FirebaseFirestore.occasion.assortment('meals').add(newMeal.toMap());
    }

    showDialog(
      context: context,
      builder: (context) {
        return StatefulBuilder(builder: (context, alertState) {
          return AlertDialog(
            form: RoundedRectangleBorder(
              borderRadius: BorderRadius.round(12),
            ),
            contentPadding: const EdgeInsets.all(16),
            content material: SingleChildScrollView(
              // Para garantir que o conteúdo seja rolável
              little one: Column(
                crossAxisAlignment: CrossAxisAlignment.begin,
                mainAxisSize:
                    MainAxisSize.min, // Ajusta para o tamanho mínimo necessário
                youngsters: [
                  // Usando FutureBuilder para aguardar a carga das refeições
                  const SizedBox(height: 20),
                  // Formulário para cadastro de nova refeição
                  const Text(
                    "Cadastrar nova refeição",
                    style: TextStyle(fontWeight: FontWeight.bold, fontSize: 18),
                  ),
                  const SizedBox(height: 10),
                  TextField(
                    controller: tituloController,
                    decoration: InputDecoration(
                      labelText: 'Nome da Refeição',
                      border: OutlineInputBorder(
                        borderRadius: BorderRadius.circular(8),
                      ),
                    ),
                    style: const TextStyle(fontSize: 16),
                  ),
                  const SizedBox(height: 10),
                  TextField(
                    controller: horarioController,
                    decoration: InputDecoration(
                      labelText: 'Horário (HH:mm)',
                      border: OutlineInputBorder(
                        borderRadius: BorderRadius.circular(8),
                      ),
                    ),
                    keyboardType: TextInputType.number,
                    inputFormatters: [
                      FilteringTextInputFormatter
                          .digitsOnly, // Permite apenas números
                      TimeInputFormatter(), // Formata como `HH:mm`
                    ],
                  ),
                  const SizedBox(peak: 10),
                  // Adicionando os dias da semana com AnimatedDropdownSearch
                  Padding(
                    padding: const EdgeInsets.symmetric(vertical: 8.0),
                    little one: Column(
                      crossAxisAlignment: CrossAxisAlignment.begin,
                      youngsters: [
                        const Text("Selecione os dias da semana:"),
                        Wrap(
                          spacing: 8.0,
                          children:
                              ['Dom', 'Seg', 'Ter', 'Qua', 'Qui', 'Sex', 'Sáb']
                                  .map((day) => ChoiceChip(
                                        label: Textual content(day),
                                        chosen: _selectedDays.accommodates(day),
                                        onSelected: (chosen) {
                                          alertState(() {
                                            if (chosen) {
                                              _selectedDays.add(day);
                                            } else {
                                              _selectedDays.take away(day);
                                            }
                                          });
                                        },
                                      ))
                                  .toList(),
                        ),
                      ],
                    ),
                  ),
                  const SizedBox(peak: 20),
                  ElevatedButton(
                    onPressed: () async {
                      closing newMeal = Refeicao(
                        id: uuid.v4(),
                        idFuncionario: loggedUid,
                        idPaciente: widget.uid,
                        titulo: tituloController.textual content,
                        dia: _selectedDays, // Dias da semana selecionados
                        horario: horarioController.textual content,
                        timestamp: DateTime.now(),
                      );

                      await addMeal(newMeal);
                      Navigator.pop(context);
                    },
                    type: ElevatedButton.styleFrom(
                      padding: const EdgeInsets.symmetric(
                          vertical: 12, horizontal: 20),
                      form: RoundedRectangleBorder(
                        borderRadius: BorderRadius.round(8),
                      ),
                    ),
                    little one: const Textual content(
                      'Registrar',
                      type: TextStyle(fontSize: 16),
                    ),
                  ),
                ],
              ),
            ),
          );
        });
      },
    );
  }

  void showOptionsAlertDialog() async {
    closing alertDialog = AlertDialog(
      content material: Column(
        mainAxisSize: MainAxisSize.min,
        youngsters: [
          InkWell(
            onTap: () {
              showAlertDialog();
            },
            child: Padding(
              padding: const EdgeInsets.all(8.0),
              child: Container(
                width: double.infinity,
                decoration: BoxDecoration(
                  borderRadius: BorderRadius.circular(20),
                  color: Colors.purple.shade300,
                ),
                child: const Padding(
                  padding: EdgeInsets.all(8.0),
                  child: Text(
                    'Adicionar Medicamento',
                    style: TextStyle(
                      color: Colors.white,
                      fontSize: 20,
                    ),
                  ),
                ),
              ),
            ),
          ),
          InkWell(
            onTap: () {
              showAlertDialogEvent();
            },
            child: Padding(
              padding: const EdgeInsets.all(8.0),
              child: Container(
                width: double.infinity,
                decoration: BoxDecoration(
                  borderRadius: BorderRadius.circular(20),
                  color: Colors.purple.shade300,
                ),
                child: const Padding(
                  padding: EdgeInsets.all(8.0),
                  child: Center(
                    child: Text(
                      'Adicionar Evento',
                      style: TextStyle(
                        color: Colors.white,
                        fontSize: 20,
                      ),
                    ),
                  ),
                ),
              ),
            ),
          ),
          InkWell(
            onTap: () {
              showMealAlertDialog();
            },
            child: Padding(
              padding: const EdgeInsets.all(8.0),
              child: Container(
                width: double.infinity,
                decoration: BoxDecoration(
                  borderRadius: BorderRadius.circular(20),
                  color: Colors.purple.shade300,
                ),
                child: const Padding(
                  padding: EdgeInsets.all(8.0),
                  child: Center(
                    child: Text(
                      'Adicionar Refeição',
                      style: TextStyle(
                        color: Colors.white,
                        fontSize: 20,
                      ),
                    ),
                  ),
                ),
              ),
            ),
          ),
        ],
      ),
    );

    showDialog(
      context: context,
      builder: (context) {
        return alertDialog;
      },
    );
  }

  @override
  Widget construct(BuildContext context) {
    return Scaffold(
      drawer: const SideMenuDrawer(),
      appBar: AppBar(
        title: const Textual content('Agenda do Paciente'),
        actions: [
          if (userLevel == 4 || userLevel == 1)
            IconButton(
              icon: const Icon(Icons.add),
              onPressed: () async {
                showOptionsAlertDialog();
              },
            )
        ],
      ),
      physique: Column(
        youngsters: [
          TableCalendar(
            locale: 'pt-BR',
            firstDay: DateTime.now(),
            lastDay: DateTime.utc(2030, 12, 31),
            focusedDay: _selectedDate,
            selectedDayPredicate: (day) => isSameDay(_selectedDate, day),
            onDaySelected: (selectedDay, focusedDay) async {
              setState(() {
                _selectedDate = selectedDay;
              });
              _eventsForSelectedDay.clear();
              await _loadEventsForSelectedDate(selectedDay);
              await _loadMealsForSelectedDate(selectedDay);
              await _loadEventsNotMedForSelectedDate(selectedDay);
            },
          ),
          const SizedBox(height: 8),
          Expanded(
            child: _eventsForSelectedDay.isEmpty
                ? const Center(child: Text('Nenhum evento para este dia'))
                : ListView.builder(
                    itemCount: _eventsForSelectedDay.length,
                    itemBuilder: (context, index) {
                      Medicine? medicineSelected;
                      Event? eventSelected;
                      Refeicao? mealSelected;
                      try {
                        setState(() {
                          medicineSelected = medicineList.firstWhere(
                            (element) =>
                                element.medicineName ==
                                _eventsForSelectedDay[index].break up(':n')[0],
                          );
                        });
                      } catch (e) {
                        strive {
                          if (!_eventsForSelectedDay[index].accommodates(':n')) {
                            // setState(() {
                            eventSelected = eventList.firstWhere(
                              (ingredient) =>
                                  ingredient.description ==
                                  _eventsForSelectedDay[index]
                                      .break up(RegExp(r' - d{2}:d{2}'))[0],
                            );
                            // });
                          }
                        } catch (e) {
                          if (!_eventsForSelectedDay[index].accommodates(':n')) {
                            // setState(() {
                            mealSelected = mealList.firstWhere(
                              (ingredient) =>
                                  ingredient.titulo ==
                                  _eventsForSelectedDay[index]
                                      .break up(RegExp(r' - d{2}:d{2}'))[0],
                            );
                            // });
                          }
                        }
                      }
                      return EventItem(
                        title: _eventsForSelectedDay[index],
                        drugs: medicineSelected,
                        occasion: eventSelected,
                        refeicao: mealSelected,
                        selectedDate: _selectedDate,
                      );
                    },
                  ),
          ),
        ],
      ),
    );
  }
}

Leave a Reply

Your email address will not be published. Required fields are marked *