From a4c03af4e9461cec99f7dd00cea12ec7587983a8 Mon Sep 17 00:00:00 2001
From: Francisco Solis <30329003+im-fran@users.noreply.github.com>
Date: Thu, 2 Nov 2023 12:23:41 -0300
Subject: [PATCH 001/194] patch: ordenado algunos archivos
* Se han movido algunos archivos a sus carpetas correspondientes para tener un mejor orden.
---
ios/Runner.xcodeproj/xcshareddata/xcschemes/dev.xcscheme | 7 +++++++
lib/config/router.dart | 6 +++---
.../{ => asignatura}/asignatura_controller.dart | 0
.../{ => asignatura}/asignaturas_controller.dart | 2 +-
.../{ => asignatura}/asignatura_detalle_screen.dart | 8 ++++----
.../{ => asignatura}/asignatura_estudiantes_tab.dart | 0
lib/screens/{ => asignatura}/asignatura_notas_tab.dart | 2 +-
lib/screens/{ => asignatura}/asignatura_resumen_tab.dart | 0
.../{ => asignatura}/asignaturas_lista_screen.dart | 2 +-
9 files changed, 17 insertions(+), 10 deletions(-)
rename lib/controllers/{ => asignatura}/asignatura_controller.dart (100%)
rename lib/controllers/{ => asignatura}/asignaturas_controller.dart (95%)
rename lib/screens/{ => asignatura}/asignatura_detalle_screen.dart (92%)
rename lib/screens/{ => asignatura}/asignatura_estudiantes_tab.dart (100%)
rename lib/screens/{ => asignatura}/asignatura_notas_tab.dart (99%)
rename lib/screens/{ => asignatura}/asignatura_resumen_tab.dart (100%)
rename lib/screens/{ => asignatura}/asignaturas_lista_screen.dart (98%)
diff --git a/ios/Runner.xcodeproj/xcshareddata/xcschemes/dev.xcscheme b/ios/Runner.xcodeproj/xcshareddata/xcschemes/dev.xcscheme
index 77d0e8a..70cb7d0 100644
--- a/ios/Runner.xcodeproj/xcshareddata/xcschemes/dev.xcscheme
+++ b/ios/Runner.xcodeproj/xcshareddata/xcschemes/dev.xcscheme
@@ -50,6 +50,13 @@
ReferencedContainer = "container:Runner.xcodeproj">
+
+
+
+
Date: Thu, 2 Nov 2023 12:25:23 -0300
Subject: [PATCH 002/194] =?UTF-8?q?patch:=20reduccion=20de=20tama=C3=B1o?=
=?UTF-8?q?=20para=20notas=20tab?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
* Se ha reducido el tamaño de asignatura notas tab al mover distintas secciones de la clase a sus propios widgets como las notas de presentacion y examen, ademas de la nota final.
---
.../asignatura/asignatura_notas_tab.dart | 259 +++++-------------
.../notas_tab/labeled_nota_display.dart | 54 ++++
.../notas_tab/nota_final_display.dart | 33 +++
.../asignatura/notas_tab/notas_display.dart | 78 ++++++
4 files changed, 235 insertions(+), 189 deletions(-)
create mode 100644 lib/widgets/asignatura/notas_tab/labeled_nota_display.dart
create mode 100644 lib/widgets/asignatura/notas_tab/nota_final_display.dart
create mode 100644 lib/widgets/asignatura/notas_tab/notas_display.dart
diff --git a/lib/screens/asignatura/asignatura_notas_tab.dart b/lib/screens/asignatura/asignatura_notas_tab.dart
index 318238a..fd0fe03 100644
--- a/lib/screens/asignatura/asignatura_notas_tab.dart
+++ b/lib/screens/asignatura/asignatura_notas_tab.dart
@@ -1,199 +1,80 @@
-import 'package:flutter/material.dart';
-import 'package:flutter_masked_text/flutter_masked_text.dart';
-import 'package:get/get_state_manager/get_state_manager.dart';
-import 'package:mi_utem/controllers/asignatura/asignatura_controller.dart';
-import 'package:mi_utem/models/evaluacion.dart';
-import 'package:mi_utem/themes/theme.dart';
-import 'package:mi_utem/widgets/custom_error_widget.dart';
-import 'package:mi_utem/widgets/loading_indicator.dart';
-import 'package:mi_utem/widgets/nota_list_item.dart';
-import 'package:mi_utem/widgets/pull_to_refresh.dart';
+ import 'package:flutter/material.dart';
+ import 'package:flutter_masked_text/flutter_masked_text.dart';
+ import 'package:get/get_state_manager/get_state_manager.dart';
+ import 'package:mi_utem/controllers/asignatura/asignatura_controller.dart';
+ import 'package:mi_utem/models/evaluacion.dart';
+ import 'package:mi_utem/themes/theme.dart';
+ import 'package:mi_utem/widgets/asignatura/notas_tab/notas_display.dart';
+ import 'package:mi_utem/widgets/custom_error_widget.dart';
+ import 'package:mi_utem/widgets/loading_indicator.dart';
+ import 'package:mi_utem/widgets/nota_list_item.dart';
+ import 'package:mi_utem/widgets/pull_to_refresh.dart';
-class AsignaturaNotasTab extends GetView {
- final String asignaturaId;
+ class AsignaturaNotasTab extends GetView {
+ final String asignaturaId;
- AsignaturaNotasTab({
- Key? key,
- required this.asignaturaId,
- }) : super(key: key);
+ AsignaturaNotasTab({
+ Key? key,
+ required this.asignaturaId,
+ }) : super(key: key);
- @override
- String get tag => asignaturaId;
+ @override
+ String get tag => asignaturaId;
- Future _onRefresh() async {
- controller.refreshData();
- }
-
- @override
- Widget build(BuildContext context) {
- return PullToRefresh(
- onRefresh: _onRefresh,
- child: controller.obx(
- (asignatura) {
- final examGradeController = MaskedTextController(
- mask: '0.0',
- text: asignatura?.grades?.notaExamen?.toStringAsFixed(1) ?? "",
- );
- final presentationGradeController = MaskedTextController(
- mask: '0.0',
- text:
- asignatura?.grades?.notaPresentacion?.toStringAsFixed(1) ?? "",
- );
+ Future _onRefresh() async {
+ controller.refreshData();
+ }
- return ListView(
- physics: AlwaysScrollableScrollPhysics(),
- padding: EdgeInsets.all(10),
- children: [
- Card(
- child: Row(
- children: [
- Container(
- height: 130,
- width: 10,
- color: asignatura?.colorPorEstado,
- ),
- Expanded(
- child: Container(
- padding: EdgeInsets.fromLTRB(15, 20, 20, 20),
- child: Row(
- crossAxisAlignment: CrossAxisAlignment.center,
- mainAxisAlignment: MainAxisAlignment.spaceBetween,
- children: [
- Column(
- children: [
- Text(
- asignatura?.grades?.notaFinal
- ?.toStringAsFixed(1) ??
- "S/N",
- style: TextStyle(
- fontSize: 40,
- fontWeight: FontWeight.bold,
- ),
- ),
- Text(
- asignatura?.estado ?? "---",
- style: TextStyle(
- fontSize: 16,
- fontWeight: FontWeight.bold,
- ),
- ),
- ],
- ),
- Container(width: 10),
- Container(
- height: 80,
- width: 0.5,
- color: Colors.grey,
- ),
- Container(width: 10),
- Column(
- crossAxisAlignment: CrossAxisAlignment.end,
- children: [
- Row(
- crossAxisAlignment: CrossAxisAlignment.center,
- children: [
- Text(
- "Examen",
- style: TextStyle(fontSize: 16),
- ),
- Container(
- width: 60,
- margin: EdgeInsets.only(left: 15),
- child: TextField(
- controller: examGradeController,
- textAlign: TextAlign.center,
- enabled: false,
- decoration: InputDecoration(
- disabledBorder: MainTheme.theme
- .inputDecorationTheme.border!
- .copyWith(
- borderSide: BorderSide(
- color: Colors.transparent,
- )),
- ),
- keyboardType:
- TextInputType.numberWithOptions(
- decimal: true),
- ),
- ),
- ],
- ),
- Container(height: 10),
- Row(
- children: [
- Text(
- "Presentación",
- style: TextStyle(fontSize: 16),
- ),
- Container(
- width: 60,
- margin: EdgeInsets.only(left: 15),
- child: TextField(
- controller: presentationGradeController,
- textAlign: TextAlign.center,
- enabled: false,
- decoration: InputDecoration(
- hintText: "--",
- disabledBorder: MainTheme.theme
- .inputDecorationTheme.border!
- .copyWith(
- borderSide: BorderSide(
- color: Colors.transparent,
- )),
- ),
- keyboardType:
- TextInputType.numberWithOptions(
- decimal: true),
- ),
- ),
- ],
- )
- ],
- ),
- ],
- ),
- ),
- ),
- ],
+ @override
+ Widget build(BuildContext context) {
+ return PullToRefresh(
+ onRefresh: _onRefresh,
+ child: controller.obx((asignatura) => ListView(
+ physics: AlwaysScrollableScrollPhysics(),
+ padding: EdgeInsets.all(10),
+ children: [
+ NotasDisplayWidget(
+ notaFinal: asignatura?.grades?.notaFinal,
+ notaExamen: asignatura?.grades?.notaExamen,
+ notaPresentacion: asignatura?.grades?.notaPresentacion,
+ estado: asignatura?.estado,
+ colorPorEstado: asignatura?.colorPorEstado,
),
- ),
- Card(
- child: Container(
- padding: EdgeInsets.all(20),
- child: asignatura?.grades?.notasParciales.isNotEmpty == true
- ? ListView.builder(
- shrinkWrap: true,
- physics: ClampingScrollPhysics(),
- itemBuilder: (context, i) {
- REvaluacion evaluacion =
- asignatura!.grades!.notasParciales[i];
- return NotaListItem(
- evaluacion: IEvaluacion.fromRemote(evaluacion),
- /* onChanged: (evaluacion) {
- _controller.chag(evaluacion, nota);
- } */
- );
- },
- itemCount: asignatura!.grades!.notasParciales.length,
- )
- : CustomErrorWidget(
- emoji: "🤔",
- title: "Parece que aún no hay notas ni ponderadores",
- ),
+ Card(
+ child: Container(
+ padding: EdgeInsets.all(20),
+ child: asignatura?.grades?.notasParciales.isNotEmpty == true
+ ? ListView.builder(
+ shrinkWrap: true,
+ physics: ClampingScrollPhysics(),
+ itemBuilder: (context, i) {
+ REvaluacion evaluacion = asignatura!.grades!.notasParciales[i];
+ return NotaListItem(
+ evaluacion: IEvaluacion.fromRemote(evaluacion),
+ /* onChanged: (evaluacion) {
+ _controller.chag(evaluacion, nota);
+ } */
+ );
+ },
+ itemCount: asignatura!.grades!.notasParciales.length,
+ )
+ : CustomErrorWidget(
+ emoji: "🤔",
+ title: "Parece que aún no hay notas ni ponderadores",
+ ),
+ ),
),
- ),
- ],
- );
- },
- onLoading: LoadingIndicator(),
- onError: (error) => SingleChildScrollView(
- physics: AlwaysScrollableScrollPhysics(),
- child: CustomErrorWidget(
- title: "Ocurrió un error al cargar las notas",
- error: '',
+ ],
+ ),
+ onLoading: LoadingIndicator(),
+ onError: (error) => SingleChildScrollView(
+ physics: AlwaysScrollableScrollPhysics(),
+ child: CustomErrorWidget(
+ title: "Ocurrió un error al cargar las notas",
+ error: '',
+ ),
),
),
- ),
- );
+ );
+ }
}
-}
diff --git a/lib/widgets/asignatura/notas_tab/labeled_nota_display.dart b/lib/widgets/asignatura/notas_tab/labeled_nota_display.dart
new file mode 100644
index 0000000..76d228a
--- /dev/null
+++ b/lib/widgets/asignatura/notas_tab/labeled_nota_display.dart
@@ -0,0 +1,54 @@
+ import 'package:flutter/material.dart';
+ import 'package:flutter_masked_text/flutter_masked_text.dart';
+ import 'package:mi_utem/themes/theme.dart';
+
+ class LabeledNotaDisplayWidget extends StatelessWidget {
+
+ final String label;
+ final num? nota;
+ final String? hint;
+
+ LabeledNotaDisplayWidget({
+ Key? key,
+ required this.label,
+ this.nota,
+ this.hint,
+ }) : super(key: key);
+
+ @override
+ Widget build(BuildContext context) {
+ final notaController = MaskedTextController(
+ mask: '0.0',
+ text: nota?.toStringAsFixed(1) ?? "",
+ );
+
+ return Row(
+ crossAxisAlignment: CrossAxisAlignment.center,
+ children: [
+ Text(label,
+ style: TextStyle(fontSize: 16),
+ ),
+ Container(
+ width: 60,
+ margin: EdgeInsets.only(left: 15),
+ child: TextField(
+ controller: notaController,
+ textAlign: TextAlign.center,
+ enabled: false,
+ decoration: InputDecoration(
+ hintText: hint,
+ disabledBorder: MainTheme.theme
+ .inputDecorationTheme.border!
+ .copyWith(borderSide: BorderSide(color: Colors.transparent)),
+ ),
+ keyboardType:
+ TextInputType.numberWithOptions(
+ decimal: true,
+ ),
+ ),
+ ),
+ ],
+ );
+ }
+
+ }
\ No newline at end of file
diff --git a/lib/widgets/asignatura/notas_tab/nota_final_display.dart b/lib/widgets/asignatura/notas_tab/nota_final_display.dart
new file mode 100644
index 0000000..35a7da8
--- /dev/null
+++ b/lib/widgets/asignatura/notas_tab/nota_final_display.dart
@@ -0,0 +1,33 @@
+import 'package:flutter/material.dart';
+
+class NotaFinalDisplayWidget extends StatelessWidget {
+
+ final num? notaFinal;
+ final String? estado;
+
+ NotaFinalDisplayWidget({
+ Key? key,
+ this.notaFinal,
+ this.estado,
+ }) : super(key: key);
+
+ @override
+ Widget build(BuildContext context) {
+ return Column(
+ children: [
+ Text(notaFinal?.toStringAsFixed(1) ?? "S/N",
+ style: TextStyle(
+ fontSize: 40,
+ fontWeight: FontWeight.bold,
+ ),
+ ),
+ Text(estado ?? "---",
+ style: TextStyle(
+ fontSize: 16,
+ fontWeight: FontWeight.bold,
+ ),
+ ),
+ ],
+ );
+ }
+}
\ No newline at end of file
diff --git a/lib/widgets/asignatura/notas_tab/notas_display.dart b/lib/widgets/asignatura/notas_tab/notas_display.dart
new file mode 100644
index 0000000..7705e21
--- /dev/null
+++ b/lib/widgets/asignatura/notas_tab/notas_display.dart
@@ -0,0 +1,78 @@
+ import 'package:flutter/material.dart';
+ import 'package:flutter_masked_text/flutter_masked_text.dart';
+ import 'package:mi_utem/themes/theme.dart';
+ import 'package:mi_utem/widgets/asignatura/notas_tab/labeled_nota_display.dart';
+ import 'package:mi_utem/widgets/asignatura/notas_tab/nota_final_display.dart';
+
+ class NotasDisplayWidget extends StatelessWidget {
+
+ final num? notaFinal;
+ final num? notaExamen;
+ final num? notaPresentacion;
+ final String? estado;
+ final Color? colorPorEstado;
+
+ NotasDisplayWidget({
+ Key? key,
+ this.notaFinal,
+ this.notaExamen,
+ this.notaPresentacion,
+ this.estado,
+ this.colorPorEstado,
+ }) : super(key: key);
+
+
+ @override
+ Widget build(BuildContext context) {
+ return Card(
+ child: Row(
+ children: [
+ Container(
+ height: 130,
+ width: 10,
+ color: colorPorEstado,
+ ),
+ Expanded(
+ child: Container(
+ padding: EdgeInsets.fromLTRB(15, 20, 20, 20),
+ child: Row(
+ crossAxisAlignment: CrossAxisAlignment.center,
+ mainAxisAlignment: MainAxisAlignment.spaceBetween,
+ children: [
+ NotaFinalDisplayWidget(
+ notaFinal: notaFinal,
+ estado: estado,
+ ),
+ Container(width: 10),
+ Container(
+ height: 80,
+ width: 0.5,
+ color: Colors.grey,
+ ),
+ Container(width: 10),
+ Column(
+ crossAxisAlignment: CrossAxisAlignment.end,
+ children: [
+ LabeledNotaDisplayWidget(
+ label: "Examen",
+ nota: notaExamen,
+ ),
+ Container(height: 10),
+ LabeledNotaDisplayWidget(
+ label: "Presentación",
+ nota: notaPresentacion,
+ hint: "--"
+ ),
+ ],
+ ),
+ ],
+ ),
+ ),
+ ),
+ ],
+ ),
+ );
+ }
+
+
+ }
\ No newline at end of file
From b5256adfcabd4bdabaaa33cdce85943fb321b724 Mon Sep 17 00:00:00 2001
From: Francisco Solis <30329003+im-fran@users.noreply.github.com>
Date: Thu, 2 Nov 2023 12:25:58 -0300
Subject: [PATCH 003/194] rem: removido algunos imports no utilizados
---
lib/screens/asignatura/asignatura_notas_tab.dart | 2 --
lib/widgets/asignatura/notas_tab/notas_display.dart | 2 --
2 files changed, 4 deletions(-)
diff --git a/lib/screens/asignatura/asignatura_notas_tab.dart b/lib/screens/asignatura/asignatura_notas_tab.dart
index fd0fe03..1730e74 100644
--- a/lib/screens/asignatura/asignatura_notas_tab.dart
+++ b/lib/screens/asignatura/asignatura_notas_tab.dart
@@ -1,9 +1,7 @@
import 'package:flutter/material.dart';
- import 'package:flutter_masked_text/flutter_masked_text.dart';
import 'package:get/get_state_manager/get_state_manager.dart';
import 'package:mi_utem/controllers/asignatura/asignatura_controller.dart';
import 'package:mi_utem/models/evaluacion.dart';
- import 'package:mi_utem/themes/theme.dart';
import 'package:mi_utem/widgets/asignatura/notas_tab/notas_display.dart';
import 'package:mi_utem/widgets/custom_error_widget.dart';
import 'package:mi_utem/widgets/loading_indicator.dart';
diff --git a/lib/widgets/asignatura/notas_tab/notas_display.dart b/lib/widgets/asignatura/notas_tab/notas_display.dart
index 7705e21..8786058 100644
--- a/lib/widgets/asignatura/notas_tab/notas_display.dart
+++ b/lib/widgets/asignatura/notas_tab/notas_display.dart
@@ -1,6 +1,4 @@
import 'package:flutter/material.dart';
- import 'package:flutter_masked_text/flutter_masked_text.dart';
- import 'package:mi_utem/themes/theme.dart';
import 'package:mi_utem/widgets/asignatura/notas_tab/labeled_nota_display.dart';
import 'package:mi_utem/widgets/asignatura/notas_tab/nota_final_display.dart';
From 274f0fd76ab78b54a035e41a26d6bcc084d61b5e Mon Sep 17 00:00:00 2001
From: Francisco Solis <30329003+Im-Fran@users.noreply.github.com>
Date: Tue, 7 Nov 2023 22:41:14 -0300
Subject: [PATCH 004/194] patch: error al refrescar token
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Había un error que al intentar refrescar la token y las credenciales son nulas no pasa nada. Ahora el usuario es redirigido al login informando del error.
---
ios/Runner/Runner.entitlements | 4 ++++
lib/services/auth_service.dart | 23 +++++++++++++++--------
2 files changed, 19 insertions(+), 8 deletions(-)
diff --git a/ios/Runner/Runner.entitlements b/ios/Runner/Runner.entitlements
index 903def2..a8b7773 100644
--- a/ios/Runner/Runner.entitlements
+++ b/ios/Runner/Runner.entitlements
@@ -4,5 +4,9 @@
aps-environment
development
+ com.apple.developer.associated-domains
+
+ webcredentials:mi.utem.cl
+
diff --git a/lib/services/auth_service.dart b/lib/services/auth_service.dart
index 29d756f..c871591 100644
--- a/lib/services/auth_service.dart
+++ b/lib/services/auth_service.dart
@@ -1,6 +1,9 @@
import 'package:dio/dio.dart';
import 'package:flutter_secure_storage/flutter_secure_storage.dart';
+import 'package:get/get.dart' as GetX;
import 'package:get_storage/get_storage.dart';
+import 'package:mi_utem/config/routes.dart';
+import 'package:mi_utem/helpers/snackbars.dart';
import 'package:mi_utem/models/usuario.dart';
import 'package:mi_utem/services/perfil_service.dart';
import 'package:mi_utem/utils/dio_miutem_client.dart';
@@ -116,17 +119,21 @@ class AuthService {
String? correo = box.read("correoUtem");
String? contrasenia = await secureStorage.read(key: "contrasenia");
- if (correo != null && contrasenia != null) {
- dynamic data = {'correo': correo, 'contrasenia': contrasenia};
+ if(correo == null || contrasenia == null) {
+ await logOut();
+ GetX.Get.toNamed(Routes.login);
+ showDefaultSnackbar("Error", "Lo sentimos, pero parece que tus credenciales no son válidas. Por favor, vuelve a iniciar sesión.");
+ throw Exception("No se pudo refrescar el token (no hay credenciales)");
+ }
+
+ dynamic data = {'correo': correo, 'contrasenia': contrasenia};
- Response response = await DioMiUtemClient.authDio.post(uri, data: data);
+ Response response = await DioMiUtemClient.authDio.post(uri, data: data);
- String token = response.data['token'];
- _storeToken(token);
+ String token = response.data['token'];
+ _storeToken(token);
- return token;
- }
- throw Exception("No se pudo refrescar el token");
+ return token;
} catch (e) {
print(e.toString());
rethrow;
From 85a13b191d441acdb0a44a74298b7a3a3d1b2fbf Mon Sep 17 00:00:00 2001
From: Francisco Solis <30329003+Im-Fran@users.noreply.github.com>
Date: Wed, 8 Nov 2023 14:56:40 -0300
Subject: [PATCH 005/194] patch: actualizadas dependencias
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
* Se han actualizado varias dependencias para soportar la última version de flutter
* Se ha cambiado charts_flutter (descontinuado) a community_charts_flutter (una version de la comunidad con arreglos y que sigue en desarrollo activo)
* Se actualizó en android/build.gradle la version sdk de 33 a 34.
Signed-off-by: Francisco Solis <30329003+Im-Fran@users.noreply.github.com>
---
android/build.gradle | 4 +--
lib/widgets/asistencia_chart.dart | 4 +--
pubspec.lock | 57 +++++++++++++++----------------
pubspec.yaml | 11 +++---
4 files changed, 35 insertions(+), 41 deletions(-)
diff --git a/android/build.gradle b/android/build.gradle
index 74e4842..ca02cfb 100644
--- a/android/build.gradle
+++ b/android/build.gradle
@@ -1,8 +1,8 @@
buildscript {
ext.kotlin_version = '1.7.21'
ext {
- compileSdkVersion = 33 // or latest
- targetSdkVersion = 33 // or latest
+ compileSdkVersion = 34 // or latest
+ targetSdkVersion = 34 // or latest
appCompatVersion = "1.4.2" // or latest
}
repositories {
diff --git a/lib/widgets/asistencia_chart.dart b/lib/widgets/asistencia_chart.dart
index 34a33f1..da2c689 100644
--- a/lib/widgets/asistencia_chart.dart
+++ b/lib/widgets/asistencia_chart.dart
@@ -1,9 +1,7 @@
import 'dart:math';
+import 'package:community_charts_flutter/community_charts_flutter.dart' as charts;
import 'package:flutter/material.dart';
-
-import 'package:charts_flutter/flutter.dart' as charts;
-
import 'package:mi_utem/models/asignatura.dart';
import 'package:mi_utem/themes/theme.dart';
diff --git a/pubspec.lock b/pubspec.lock
index 994e81d..a5e0cb1 100644
--- a/pubspec.lock
+++ b/pubspec.lock
@@ -53,10 +53,10 @@ packages:
dependency: "direct main"
description:
name: awesome_notifications
- sha256: "2b430c75cc879d6cfd52bb6eb2b5c1591ed425347816408cdcbd3f6916bba14c"
+ sha256: "327162c36a1476978f89638741da618cac42356aabc39a5035b6c206d8fca978"
url: "https://pub.dev"
source: hosted
- version: "0.7.4+1"
+ version: "0.7.7"
awesome_notifications_core:
dependency: "direct main"
description:
@@ -177,23 +177,6 @@ packages:
url: "https://pub.dev"
source: hosted
version: "1.3.0"
- charts_common:
- dependency: transitive
- description:
- name: charts_common
- sha256: "7b8922f9b0d9b134122756a787dab1c3946ae4f3fc5022ff323ba0014998ea02"
- url: "https://pub.dev"
- source: hosted
- version: "0.12.0"
- charts_flutter:
- dependency: "direct main"
- description:
- path: charts_flutter
- ref: HEAD
- resolved-ref: fcd0c524ac573ae4d0b79f3bdd6491fbbcdbfb61
- url: "https://github.com/google/charts"
- source: git
- version: "0.12.0"
checked_yaml:
dependency: transitive
description:
@@ -266,6 +249,22 @@ packages:
url: "https://pub.dev"
source: hosted
version: "1.17.2"
+ community_charts_common:
+ dependency: transitive
+ description:
+ name: community_charts_common
+ sha256: "20697244c826df0545237ebe01d61caa96a2a2e4d23c6f88890441636a4d5220"
+ url: "https://pub.dev"
+ source: hosted
+ version: "1.0.2"
+ community_charts_flutter:
+ dependency: "direct main"
+ description:
+ name: community_charts_flutter
+ sha256: ca5bd07337e162daee13c19679f602cd8b3f704520d242beeebbc2e312f84f89
+ url: "https://pub.dev"
+ source: hosted
+ version: "1.0.2"
convert:
dependency: transitive
description:
@@ -454,10 +453,10 @@ packages:
dependency: "direct main"
description:
name: firebase_core
- sha256: dcf54c170c5371ad0e79229d0fb372c58262ae0968b7de222bf28e51dd236be0
+ sha256: "675c209c94a1817649137cbd113fc4c9ae85e48d03dd578629abbec6d8a4d93d"
url: "https://pub.dev"
source: hosted
- version: "2.11.0"
+ version: "2.16.0"
firebase_core_platform_interface:
dependency: transitive
description:
@@ -470,10 +469,10 @@ packages:
dependency: transitive
description:
name: firebase_core_web
- sha256: "4cf4d2161530332ddc3c562f19823fb897ff37a9a774090d28df99f47370e973"
+ sha256: e8c408923cd3a25bd342c576a114f2126769cd1a57106a4edeaa67ea4a84e962
url: "https://pub.dev"
source: hosted
- version: "2.7.0"
+ version: "2.8.0"
firebase_in_app_messaging:
dependency: "direct main"
description:
@@ -926,10 +925,10 @@ packages:
dependency: "direct main"
description:
name: intl
- sha256: "910f85bce16fb5c6f614e117efa303e85a1731bb0081edf3604a2ae6e9a3cc91"
+ sha256: "3bc132a9dbce73a7e4a21a17d06e1878839ffbf975568bc875c60537824b0c4d"
url: "https://pub.dev"
source: hosted
- version: "0.17.0"
+ version: "0.18.1"
js:
dependency: transitive
description:
@@ -1294,18 +1293,18 @@ packages:
dependency: transitive
description:
name: sentry
- sha256: "830667eadc0398fea3a3424ed1b74568e2db603a42758d0922e2f2974ce55a60"
+ sha256: "9cfd325611ab54b57d5e26957466823f05bea9d6cfcc8d48f11817b8bcedf0d1"
url: "https://pub.dev"
source: hosted
- version: "7.10.1"
+ version: "7.12.0"
sentry_flutter:
dependency: "direct main"
description:
name: sentry_flutter
- sha256: "6730f41b304c6fb0fa590dacccaf73ba11082fc64b274cfe8a79776f2b95309c"
+ sha256: "0cd7d622cb63c94fd1b2f87ab508e158b950bd281e2a80f327ebf73bb217eaf3"
url: "https://pub.dev"
source: hosted
- version: "7.10.1"
+ version: "7.12.0"
share_plus:
dependency: "direct main"
description:
diff --git a/pubspec.yaml b/pubspec.yaml
index 2bef81c..de7b3c8 100644
--- a/pubspec.yaml
+++ b/pubspec.yaml
@@ -17,10 +17,7 @@ dependencies:
barcode_image: ^2.0.2
cached_network_image: ^3.2.0
carousel_slider: ^4.0.0
- charts_flutter:
- git:
- url: https://github.com/google/charts
- path: charts_flutter
+ community_charts_flutter: ^1.0.2
circular_profile_avatar: ^2.0.5
clipboard: ^0.1.3
cloud_firestore: ^4.3.1
@@ -30,7 +27,7 @@ dependencies:
dio_cache_interceptor_hive_store: ^3.1.1
dotted_border: ^2.0.0+2
extended_image: ^8.1.1
- firebase_core: 2.11.0
+ firebase_core: 2.16.0
firebase_analytics: 10.2.1
firebase_in_app_messaging: ^0.7.0+10
firebase_remote_config: ^3.0.9
@@ -63,14 +60,14 @@ dependencies:
recase: ^4.0.0
responsive_framework: ^0.2.0
screenshot: ^2.1.0
- sentry_flutter: ^7.10.1
+ sentry_flutter: ^7.12.0
share_plus: ^7.2.1
simple_gesture_detector: ^0.2.0
url_launcher: ^6.1.7
video_player: ^2.6.1
dio_http_cache: ^0.3.0
image: ^3.1.0
- intl: ^0.17.0
+ intl: ^0.18.1
get_storage: ^2.0.3
hexcolor: ^3.0.1
shared_preferences: ^2.0.20
From 87cba841c59195d0f796a4a30944ab89caa1ade5 Mon Sep 17 00:00:00 2001
From: Francisco Solis <30329003+im-fran@users.noreply.github.com>
Date: Wed, 8 Nov 2023 15:52:39 -0300
Subject: [PATCH 006/194] patch: actualizadas unas dependencias para reparar
cocoapods install.
Signed-off-by: Francisco Solis <30329003+Im-Fran@users.noreply.github.com>
---
ios/Podfile.lock | 89 ++++++++++++++++++++++++++++++++++--------------
pubspec.lock | 28 +++++++++++----
pubspec.yaml | 4 +--
3 files changed, 88 insertions(+), 33 deletions(-)
diff --git a/ios/Podfile.lock b/ios/Podfile.lock
index 1a54867..e00ae90 100644
--- a/ios/Podfile.lock
+++ b/ios/Podfile.lock
@@ -596,18 +596,18 @@ PODS:
- abseil/base/base_internal
- abseil/base/config
- abseil/meta/type_traits
- - awesome_notifications (0.0.5):
+ - awesome_notifications (0.8.1):
- Flutter
- - IosAwnCore (= 0.7.3)
+ - IosAwnCore (~> 0.8.0)
- awesome_notifications_core (0.0.1):
- Flutter
- - awesome_notifications_fcm (0.7.3):
+ - awesome_notifications_fcm (0.8.1):
- awesome_notifications
- - Firebase
- Firebase/Messaging
+ - FirebaseCore
- Flutter
- - IosAwnCore (= 0.7.3)
- - IosAwnFcmDist (= 0.7.5)
+ - IosAwnCore (~> 0.8.0)
+ - IosAwnFcmDist (~> 0.8.0)
- background_fetch (1.2.1):
- Flutter
- BoringSSL-GRPC (0.0.24):
@@ -621,8 +621,6 @@ PODS:
- firebase_core
- Flutter
- nanopb (< 2.30910.0, >= 2.30908.0)
- - Firebase (10.7.0):
- - Firebase/Core (= 10.7.0)
- Firebase/Analytics (10.7.0):
- Firebase/Core
- Firebase/Core (10.7.0):
@@ -630,6 +628,9 @@ PODS:
- FirebaseAnalytics (~> 10.7.0)
- Firebase/CoreOnly (10.7.0):
- FirebaseCore (= 10.7.0)
+ - Firebase/Crashlytics (10.7.0):
+ - Firebase/CoreOnly
+ - FirebaseCrashlytics (~> 10.7.0)
- Firebase/Firestore (10.7.0):
- Firebase/CoreOnly
- FirebaseFirestore (~> 10.7.0)
@@ -646,9 +647,13 @@ PODS:
- Firebase/Analytics (= 10.7.0)
- firebase_core
- Flutter
- - firebase_core (2.11.0):
+ - firebase_core (2.16.0):
- Firebase/CoreOnly (= 10.7.0)
- Flutter
+ - firebase_crashlytics (3.3.6):
+ - Firebase/Crashlytics (= 10.7.0)
+ - firebase_core
+ - Flutter
- firebase_in_app_messaging (0.7.0-15):
- Firebase/InAppMessaging (= 10.7.0)
- firebase_core
@@ -681,8 +686,18 @@ PODS:
- FirebaseCoreInternal (~> 10.0)
- GoogleUtilities/Environment (~> 7.8)
- GoogleUtilities/Logger (~> 7.8)
+ - FirebaseCoreExtension (10.17.0):
+ - FirebaseCore (~> 10.0)
- FirebaseCoreInternal (10.16.0):
- "GoogleUtilities/NSData+zlib (~> 7.8)"
+ - FirebaseCrashlytics (10.7.0):
+ - FirebaseCore (~> 10.5)
+ - FirebaseInstallations (~> 10.0)
+ - FirebaseSessions (~> 10.5)
+ - GoogleDataTransport (~> 9.2)
+ - GoogleUtilities/Environment (~> 7.8)
+ - nanopb (< 2.30910.0, >= 2.30908.0)
+ - PromisesObjC (~> 2.1)
- FirebaseFirestore (10.7.0):
- abseil/algorithm (~> 1.20211102.0)
- abseil/base (~> 1.20211102.0)
@@ -722,6 +737,14 @@ PODS:
- FirebaseInstallations (~> 10.0)
- GoogleUtilities/Environment (~> 7.8)
- "GoogleUtilities/NSData+zlib (~> 7.8)"
+ - FirebaseSessions (10.17.0):
+ - FirebaseCore (~> 10.5)
+ - FirebaseCoreExtension (~> 10.0)
+ - FirebaseInstallations (~> 10.0)
+ - GoogleDataTransport (~> 9.2)
+ - GoogleUtilities/Environment (~> 7.10)
+ - nanopb (< 2.30910.0, >= 2.30908.0)
+ - PromisesSwift (~> 2.1)
- Flutter (1.0.0)
- flutter_keyboard_visibility (0.0.1):
- Flutter
@@ -833,9 +856,11 @@ PODS:
- Flutter
- in_app_review (0.2.0):
- Flutter
- - IosAwnCore (0.7.3)
- - IosAwnFcmDist (0.7.5):
- - IosAwnCore (= 0.7.3)
+ - IosAwnCore (0.8.0)
+ - IosAwnFcmDist (0.8.0):
+ - FirebaseCore
+ - FirebaseMessaging
+ - IosAwnCore (~> 0.8.0)
- leveldb-library (1.22.2)
- Libuv-gRPC (0.0.10):
- Libuv-gRPC/Implementation (= 0.0.10)
@@ -856,13 +881,15 @@ PODS:
- permission_handler_apple (9.1.1):
- Flutter
- PromisesObjC (2.3.1)
- - Sentry/HybridSDK (8.11.0):
- - SentryPrivate (= 8.11.0)
+ - PromisesSwift (2.3.1):
+ - PromisesObjC (= 2.3.1)
+ - Sentry/HybridSDK (8.14.2):
+ - SentryPrivate (= 8.14.2)
- sentry_flutter (0.0.1):
- Flutter
- FlutterMacOS
- - Sentry/HybridSDK (= 8.11.0)
- - SentryPrivate (8.11.0)
+ - Sentry/HybridSDK (= 8.14.2)
+ - SentryPrivate (8.14.2)
- share_plus (0.0.1):
- Flutter
- shared_preferences_foundation (0.0.1):
@@ -885,6 +912,7 @@ DEPENDENCIES:
- cloud_firestore (from `.symlinks/plugins/cloud_firestore/ios`)
- firebase_analytics (from `.symlinks/plugins/firebase_analytics/ios`)
- firebase_core (from `.symlinks/plugins/firebase_core/ios`)
+ - firebase_crashlytics (from `.symlinks/plugins/firebase_crashlytics/ios`)
- firebase_in_app_messaging (from `.symlinks/plugins/firebase_in_app_messaging/ios`)
- firebase_remote_config (from `.symlinks/plugins/firebase_remote_config/ios`)
- Flutter (from `Flutter`)
@@ -912,12 +940,15 @@ SPEC REPOS:
- FirebaseABTesting
- FirebaseAnalytics
- FirebaseCore
+ - FirebaseCoreExtension
- FirebaseCoreInternal
+ - FirebaseCrashlytics
- FirebaseFirestore
- FirebaseInAppMessaging
- FirebaseInstallations
- FirebaseMessaging
- FirebaseRemoteConfig
+ - FirebaseSessions
- FMDB
- GoogleAppMeasurement
- GoogleDataTransport
@@ -930,6 +961,7 @@ SPEC REPOS:
- Libuv-gRPC
- nanopb
- PromisesObjC
+ - PromisesSwift
- Sentry
- SentryPrivate
- UXCam
@@ -949,6 +981,8 @@ EXTERNAL SOURCES:
:path: ".symlinks/plugins/firebase_analytics/ios"
firebase_core:
:path: ".symlinks/plugins/firebase_core/ios"
+ firebase_crashlytics:
+ :path: ".symlinks/plugins/firebase_crashlytics/ios"
firebase_in_app_messaging:
:path: ".symlinks/plugins/firebase_in_app_messaging/ios"
firebase_remote_config:
@@ -988,26 +1022,30 @@ EXTERNAL SOURCES:
SPEC CHECKSUMS:
abseil: ebe5b5529fb05d93a8bdb7951607be08b7fa71bc
- awesome_notifications: d63d9a25f126860f9a600850d99772237895b3ba
+ awesome_notifications: db394d2e061e4583ba0f738ddea611e3986cc3fb
awesome_notifications_core: d02eed89738fa362d56cbd372850e9adcd2c6bef
- awesome_notifications_fcm: 7e2d7ab4ca1826fe3a9a5ca96771ace73e05db48
+ awesome_notifications_fcm: 554a9088f81a91dbe8a318abee6b48f43e4a9417
background_fetch: 896944864b038d2837fc750d470e9841e1e6a363
BoringSSL-GRPC: 3175b25143e648463a56daeaaa499c6cb86dad33
cloud_firestore: e0da2eedba479416c908433ac8879fdd81f61157
Firebase: 0219acf760880eeec8ce479895bd7767466d9f81
firebase_analytics: e8e294333de66e5429d4aac365966281b4dbfb7d
- firebase_core: dee76ded6c693fdb38b8ea39aef7129e32e587a3
+ firebase_core: 27bc73423698d0960be189ccf29bdc2d373f2746
+ firebase_crashlytics: 1b3768f2e118b0281ad30f2931369e0d1921789c
firebase_in_app_messaging: 2b36a1746f4fefbd6f578a2f6659358a0d3f2c94
firebase_remote_config: e5f1ed5b29191424280b7b249228f0ed64bc90ee
FirebaseABTesting: 03f0a8b88cf618350527f2c6a2234e29b9c65064
FirebaseAnalytics: f8133442ee6f8512e28ff19e62ce15398bfaeace
FirebaseCore: e317665b9d744727a97e623edbbed009320afdd7
+ FirebaseCoreExtension: 47720bb330d7041047c0935a34a3a4b92f818074
FirebaseCoreInternal: 26233f705cc4531236818a07ac84d20c333e505a
+ FirebaseCrashlytics: 35fdd1a433b31e28adcf5c8933f4c526691a1e0b
FirebaseFirestore: 3963a6edd1c84b4748dab3e2c62624a29d03eca1
FirebaseInAppMessaging: d04732fe9c37c3d026d66435abba60120087a7f5
FirebaseInstallations: b822f91a61f7d1ba763e5ccc9d4f2e6f2ed3b3ee
FirebaseMessaging: ac9062bcc35ed56e15a0241d8fd317022499baf8
FirebaseRemoteConfig: d5de62211e2eaa2152d8ee85a23c301b70887a74
+ FirebaseSessions: 49f39e5c10e3f9fdd38d01b748329bae2a2fa8ed
Flutter: f04841e97a9d0b0a8025694d0796dd46242b2854
flutter_keyboard_visibility: 0339d06371254c3eb25eeb90ba8d17dca8f9c069
flutter_secure_storage: 23fc622d89d073675f2eaa109381aefbcf5a49be
@@ -1021,8 +1059,8 @@ SPEC CHECKSUMS:
image_editor_common: d6f6644ae4a6de80481e89fe6d0a8c49e30b4b43
image_picker_ios: 4a8aadfbb6dc30ad5141a2ce3832af9214a705b5
in_app_review: 318597b3a06c22bb46dc454d56828c85f444f99d
- IosAwnCore: 6494e0e174d49f04f513e8a002187be226889a37
- IosAwnFcmDist: 47578dd46472304b20f1965ad12cc893c877e57c
+ IosAwnCore: ed1b2b6d84962a758354dbacd9ce525c72ce28a9
+ IosAwnFcmDist: 0ac4da8f9ef8f2db9e5ec5d0c10c8db793ce447d
leveldb-library: f03246171cce0484482ec291f88b6d563699ee06
Libuv-gRPC: 55e51798e14ef436ad9bc45d12d43b77b49df378
nanopb: b552cce312b6c8484180ef47159bc0f65a1f0431
@@ -1030,9 +1068,10 @@ SPEC CHECKSUMS:
path_provider_foundation: 29f094ae23ebbca9d3d0cec13889cd9060c0e943
permission_handler_apple: e76247795d700c14ea09e3a2d8855d41ee80a2e6
PromisesObjC: c50d2056b5253dadbd6c2bea79b0674bd5a52fa4
- Sentry: 39d57e691e311bdb73bc1ab5bbebbd6bc890050d
- sentry_flutter: b2feefdad5b0f06602347172bc7257e8e9da5562
- SentryPrivate: 48712023cdfd523735c2edb6b06bedf26c4730a3
+ PromisesSwift: 28dca69a9c40779916ac2d6985a0192a5cb4a265
+ Sentry: e0ea366f95ebb68f26d6030d8c22d6b2e6d23dd0
+ sentry_flutter: 9a04c51c373d76ee22167bf1e65bc468c0a91fed
+ SentryPrivate: 949a21fa59872427edc73b524c3ec8456761d97f
share_plus: c3fef564749587fc939ef86ffb283ceac0baf9f5
shared_preferences_foundation: 5b919d13b803cadd15ed2dc053125c68730e5126
sqflite: 31f7eba61e3074736dff8807a9b41581e4f7f15a
@@ -1042,4 +1081,4 @@ SPEC CHECKSUMS:
PODFILE CHECKSUM: 816280d49dfc997733647f095bf1e4c52c291937
-COCOAPODS: 1.13.0
+COCOAPODS: 1.14.2
diff --git a/pubspec.lock b/pubspec.lock
index a5e0cb1..0f9c2fd 100644
--- a/pubspec.lock
+++ b/pubspec.lock
@@ -13,10 +13,10 @@ packages:
dependency: transitive
description:
name: _flutterfire_internals
- sha256: "867b77e2367bc502dcd4d5a66302615409f04eb20ed82ba1c0ba073f9107e018"
+ sha256: "2d8e8e123ca3675625917f535fcc0d3a50092eef44334168f9b18adc050d4c6e"
url: "https://pub.dev"
source: hosted
- version: "1.2.0"
+ version: "1.3.6"
analyzer:
dependency: transitive
description:
@@ -53,10 +53,10 @@ packages:
dependency: "direct main"
description:
name: awesome_notifications
- sha256: "327162c36a1476978f89638741da618cac42356aabc39a5035b6c206d8fca978"
+ sha256: "65f730f9c0e73a346039ef746384bcff1773f9f03821b859705a7ab8db977b23"
url: "https://pub.dev"
source: hosted
- version: "0.7.7"
+ version: "0.8.2"
awesome_notifications_core:
dependency: "direct main"
description:
@@ -69,10 +69,10 @@ packages:
dependency: "direct main"
description:
name: awesome_notifications_fcm
- sha256: "3bcfc54360128bd9a83f558c6652681d58ba158a5237f15536fd4c6da46d99f2"
+ sha256: "0e44272fc734a5f42af063688fa172bac58f79fcc98d8930cc3604a0ecba0bea"
url: "https://pub.dev"
source: hosted
- version: "0.7.4+1"
+ version: "0.8.0"
background_fetch:
dependency: "direct main"
description:
@@ -473,6 +473,22 @@ packages:
url: "https://pub.dev"
source: hosted
version: "2.8.0"
+ firebase_crashlytics:
+ dependency: transitive
+ description:
+ name: firebase_crashlytics
+ sha256: f4a4b046606e306b589bef5c1e268afbfab2e5fddde6de7e4340400465c8d231
+ url: "https://pub.dev"
+ source: hosted
+ version: "3.3.6"
+ firebase_crashlytics_platform_interface:
+ dependency: transitive
+ description:
+ name: firebase_crashlytics_platform_interface
+ sha256: "8666b935e29b143297e2923dc8112663854f828d10954a92b8215e7249b55d59"
+ url: "https://pub.dev"
+ source: hosted
+ version: "3.6.6"
firebase_in_app_messaging:
dependency: "direct main"
description:
diff --git a/pubspec.yaml b/pubspec.yaml
index de7b3c8..4a125cb 100644
--- a/pubspec.yaml
+++ b/pubspec.yaml
@@ -10,8 +10,8 @@ environment:
dependencies:
awesome_notifications_core: ^0.8.1
- awesome_notifications: any
- awesome_notifications_fcm: any
+ awesome_notifications: ^0.8.2
+ awesome_notifications_fcm: ^0.8.0
badges: ^2.0.2
barcode_widget: ^2.0.3
barcode_image: ^2.0.2
From d42ae1e98643e82b20e56e5e88765bee80fa42cd Mon Sep 17 00:00:00 2001
From: Francisco Solis <30329003+im-fran@users.noreply.github.com>
Date: Mon, 13 Nov 2023 14:33:33 -0300
Subject: [PATCH 007/194] patch: mejorado widget acerca_screen
* se ha separado el acerca de en una carpeta propia
* se ha separado en otros widgets acerca del club y acerca de los desarrolladores.
Signed-off-by: Francisco Solis <30329003+Im-Fran@users.noreply.github.com>
---
lib/config/router.dart | 2 +-
lib/screens/login_screen/login_screen.dart | 2 +-
.../acerca_aplicacion_content.dart | 0
lib/widgets/{ => acerca}/acerca_dialog.dart | 2 +-
lib/widgets/acerca/club/acerca_club.dart | 55 ++++++++
.../club/acerca_club_desarrolladores.dart | 133 ++++++++++++++++++
.../acerca/club/acerca_club_redes.dart | 51 +++++++
7 files changed, 242 insertions(+), 3 deletions(-)
rename lib/widgets/{ => acerca}/acerca_aplicacion_content.dart (100%)
rename lib/widgets/{ => acerca}/acerca_dialog.dart (98%)
create mode 100644 lib/widgets/acerca/club/acerca_club.dart
create mode 100644 lib/widgets/acerca/club/acerca_club_desarrolladores.dart
create mode 100644 lib/widgets/acerca/club/acerca_club_redes.dart
diff --git a/lib/config/router.dart b/lib/config/router.dart
index 9aa0b0e..ea9f974 100644
--- a/lib/config/router.dart
+++ b/lib/config/router.dart
@@ -15,7 +15,7 @@ import 'package:mi_utem/screens/splash_screen.dart';
import 'package:mi_utem/screens/usuario_screen.dart';
import 'package:mi_utem/services/auth_service.dart';
import 'package:mi_utem/services/perfil_service.dart';
-import 'package:mi_utem/widgets/acerca_screen.dart';
+import 'package:mi_utem/widgets/acerca/acerca_screen.dart';
final _loginPage = GetPage(
name: Routes.login,
diff --git a/lib/screens/login_screen/login_screen.dart b/lib/screens/login_screen/login_screen.dart
index ca11827..f2c976c 100644
--- a/lib/screens/login_screen/login_screen.dart
+++ b/lib/screens/login_screen/login_screen.dart
@@ -14,7 +14,7 @@ import 'package:mi_utem/models/usuario.dart';
import 'package:mi_utem/services/analytics_service.dart';
import 'package:mi_utem/services/auth_service.dart';
import 'package:mi_utem/services/remote_config/remote_config.dart';
-import 'package:mi_utem/widgets/acerca_dialog.dart';
+import 'package:mi_utem/widgets/acerca/acerca_dialog.dart';
import 'package:mi_utem/widgets/dialogs/monkey_error_dialog.dart';
import 'package:mi_utem/widgets/dialogs/not_ready_dialog.dart';
import 'package:mi_utem/widgets/loading_dialog.dart';
diff --git a/lib/widgets/acerca_aplicacion_content.dart b/lib/widgets/acerca/acerca_aplicacion_content.dart
similarity index 100%
rename from lib/widgets/acerca_aplicacion_content.dart
rename to lib/widgets/acerca/acerca_aplicacion_content.dart
diff --git a/lib/widgets/acerca_dialog.dart b/lib/widgets/acerca/acerca_dialog.dart
similarity index 98%
rename from lib/widgets/acerca_dialog.dart
rename to lib/widgets/acerca/acerca_dialog.dart
index 9aba895..ca1e8f2 100644
--- a/lib/widgets/acerca_dialog.dart
+++ b/lib/widgets/acerca/acerca_dialog.dart
@@ -3,7 +3,7 @@ import 'dart:async';
import 'package:flutter/material.dart';
import 'package:get/get.dart';
import 'package:mi_utem/config/routes.dart';
-import 'package:mi_utem/widgets/acerca_aplicacion_content.dart';
+import 'package:mi_utem/widgets/acerca/acerca_aplicacion_content.dart';
class AcercaDialog extends StatefulWidget {
AcercaDialog({
diff --git a/lib/widgets/acerca/club/acerca_club.dart b/lib/widgets/acerca/club/acerca_club.dart
new file mode 100644
index 0000000..18c16d9
--- /dev/null
+++ b/lib/widgets/acerca/club/acerca_club.dart
@@ -0,0 +1,55 @@
+import 'package:flutter/material.dart';
+import 'package:flutter_markdown/flutter_markdown.dart';
+
+import '../../../services/remote_config/remote_config.dart';
+import '../../default_network_image.dart';
+import 'acerca_club_redes.dart';
+
+class AcercaClub extends StatelessWidget {
+
+ @override
+ Widget build(BuildContext context) {
+ return Card(
+ shape: RoundedRectangleBorder(
+ borderRadius: BorderRadius.circular(15.0),
+ ),
+ child: Container(
+ padding: EdgeInsets.all(20),
+ child: Column(
+ children: [
+ Container(
+ width: 150,
+ height: 150,
+ child: DefaultNetworkImage(
+ url: RemoteConfigService.clubLogo,
+ )),
+ Container(height: 20),
+ Text(
+ RemoteConfigService.clubNombre,
+ textAlign: TextAlign.center,
+ style: TextStyle(
+ fontSize: 20,
+ color: Colors.grey[700],
+ fontWeight: FontWeight.bold,
+ ),
+ ),
+ Container(height: 20),
+ MarkdownBody(
+ selectable: false,
+ styleSheet: MarkdownStyleSheet(
+ textAlign: WrapAlignment.center,
+ p: TextStyle(
+ fontSize: 16,
+ color: Colors.grey[700],
+ ),
+ ),
+ data: RemoteConfigService.clubDescripcion,
+ ),
+ Container(height: 20),
+ AcercaClubRedes(),
+ ],
+ ),
+ ),
+ );
+ }
+}
\ No newline at end of file
diff --git a/lib/widgets/acerca/club/acerca_club_desarrolladores.dart b/lib/widgets/acerca/club/acerca_club_desarrolladores.dart
new file mode 100644
index 0000000..9f06b87
--- /dev/null
+++ b/lib/widgets/acerca/club/acerca_club_desarrolladores.dart
@@ -0,0 +1,133 @@
+import 'dart:convert';
+
+import 'package:flutter/material.dart';
+import 'package:font_awesome_flutter/font_awesome_flutter.dart';
+import 'package:get/get.dart';
+import 'package:url_launcher/url_launcher.dart';
+
+import '../../../config/routes.dart';
+import '../../../models/usuario.dart';
+import '../../../services/analytics_service.dart';
+import '../../../services/remote_config/remote_config.dart';
+import '../../image_view_screen.dart';
+import '../../profile_photo.dart';
+
+class AcercaClubDesarrolladores extends StatelessWidget {
+
+ @override
+ Widget build(BuildContext context) {
+ return Card(
+ shape: RoundedRectangleBorder(
+ borderRadius: BorderRadius.circular(15.0),
+ ),
+ child: Container(
+ padding: EdgeInsets.all(20),
+ child: Column(
+ mainAxisAlignment: MainAxisAlignment.center,
+ crossAxisAlignment: CrossAxisAlignment.start,
+ children: [
+ Container(
+ padding: EdgeInsets.symmetric(horizontal: 10),
+ child: Text(
+ "Desarrolladores",
+ textAlign: TextAlign.center,
+ style: TextStyle(
+ fontSize: 20,
+ color: Colors.grey[700],
+ fontWeight: FontWeight.bold,
+ ),
+ ),
+ ),
+ Container(height: 10),
+ ...jsonDecode(RemoteConfigService.miutemDesarrolladores).map((creador) => Container (
+ padding: EdgeInsets.symmetric(vertical: 10),
+ child: Row(
+ children: [
+ ProfilePhoto(
+ usuario: Usuario(nombres: creador['nombre'], fotoUrl: creador['fotoUrl']),
+ onImageTap: (context, imageProvider) {
+ AnalyticsService.logEvent("acerca_person_image_tap", parameters: {
+ "persona": creador['nombre'],
+ });
+ Get.to(() => ImageViewScreen(imageProvider: imageProvider),
+ routeName: Routes.imageView,
+ );
+ }),
+ Container(width: 20),
+ Expanded(
+ child: Column(
+ crossAxisAlignment:
+ CrossAxisAlignment.start,
+ children: [
+ Text(
+ creador["nombre"],
+ style: TextStyle(
+ fontWeight: FontWeight.bold,
+ color: Colors.grey[800],
+ fontSize: 16,
+ ),
+ ),
+ Text(
+ creador["rol"],
+ style: TextStyle(
+ fontSize: 16,
+ color: Colors.grey[700],
+ ),
+ ),
+ Container(height: 5),
+ Row(
+ mainAxisAlignment: MainAxisAlignment.start,
+ children: creador['redes'].map((red) => Container(
+ margin: EdgeInsets.only(right: 8),
+ decoration: new BoxDecoration(
+ shape: BoxShape.circle,
+ color: Color(red["color"]),
+ ),
+ child: InkWell(
+ customBorder:
+ CircleBorder(),
+ onTap: () async {
+ AnalyticsService.logEvent("acerca_person_social_tap",
+ parameters: {
+ "persona":
+ creador['nombre'],
+ "red": red['nombre'],
+ },
+ );
+ await launchUrl(
+ Uri.parse(red["url"]),
+ );
+ },
+ child: Container(
+ padding:
+ const EdgeInsets.all(
+ 8),
+ decoration:
+ new BoxDecoration(
+ shape: BoxShape.circle,
+ ),
+ child: Icon(
+ IconDataBrands(red["icono"]),
+ size: 15,
+ color: Colors.white,
+ ),
+ ),
+ ),
+ ),
+ )
+ .toList(),
+ ),
+ ],
+ ),
+ ),
+ ],
+ ),
+ ),
+ )
+ .toList()
+ ],
+ ),
+ ),
+ );
+ }
+}
\ No newline at end of file
diff --git a/lib/widgets/acerca/club/acerca_club_redes.dart b/lib/widgets/acerca/club/acerca_club_redes.dart
new file mode 100644
index 0000000..6049ae0
--- /dev/null
+++ b/lib/widgets/acerca/club/acerca_club_redes.dart
@@ -0,0 +1,51 @@
+import 'dart:convert';
+
+import 'package:flutter/material.dart';
+import 'package:font_awesome_flutter/font_awesome_flutter.dart';
+import 'package:mi_utem/services/analytics_service.dart';
+import 'package:mi_utem/services/remote_config/remote_config.dart';
+import 'package:url_launcher/url_launcher.dart';
+
+class AcercaClubRedes extends StatelessWidget {
+
+
+ @override
+ Widget build(BuildContext context) {
+ return Row(
+ mainAxisAlignment: MainAxisAlignment.center,
+ children: jsonDecode(RemoteConfigService.clubRedes)
+ .map(
+ (red) => Container(
+ margin: EdgeInsets.symmetric(horizontal: 5),
+ decoration: new BoxDecoration(
+ shape: BoxShape.circle,
+ color: Color(red["color"]),
+ ),
+ child: InkWell(
+ customBorder: CircleBorder(),
+ onTap: () async {
+ AnalyticsService.logEvent("acerca_club_social_tap",
+ parameters: {
+ "red": red['nombre'],
+ },
+ );
+ await launchUrl(Uri.parse(red["url"]));
+ },
+ child: Container(
+ padding: const EdgeInsets.all(10),
+ decoration: new BoxDecoration(
+ shape: BoxShape.circle,
+ ),
+ child: Icon(
+ IconDataBrands(red["icono"]),
+ size: 20,
+ color: Colors.white,
+ ),
+ ),
+ ),
+ ),
+ ).toList()
+ );
+ }
+
+}
\ No newline at end of file
From f8774622ac73956cb440ec4f6d64c47b3a3d111c Mon Sep 17 00:00:00 2001
From: Francisco Solis <30329003+Im-Fran@users.noreply.github.com>
Date: Mon, 13 Nov 2023 14:34:43 -0300
Subject: [PATCH 008/194] patch: movido un archivo a su carpeta
Signed-off-by: Francisco Solis <30329003+Im-Fran@users.noreply.github.com>
---
lib/widgets/acerca/acerca_screen.dart | 44 +++++
lib/widgets/acerca_screen.dart | 259 --------------------------
2 files changed, 44 insertions(+), 259 deletions(-)
create mode 100644 lib/widgets/acerca/acerca_screen.dart
delete mode 100644 lib/widgets/acerca_screen.dart
diff --git a/lib/widgets/acerca/acerca_screen.dart b/lib/widgets/acerca/acerca_screen.dart
new file mode 100644
index 0000000..7de53a0
--- /dev/null
+++ b/lib/widgets/acerca/acerca_screen.dart
@@ -0,0 +1,44 @@
+
+import 'package:flutter/material.dart';
+import 'package:mi_utem/widgets/acerca/acerca_aplicacion_content.dart';
+import 'package:mi_utem/widgets/acerca/club/acerca_club.dart';
+import 'package:mi_utem/widgets/acerca/club/acerca_club_desarrolladores.dart';
+import 'package:mi_utem/widgets/custom_app_bar.dart';
+
+class AcercaScreen extends StatelessWidget {
+ AcercaScreen({
+ Key? key,
+ }) : super(key: key);
+
+ @override
+ Widget build(BuildContext context) {
+ return Scaffold(
+ backgroundColor: Colors.grey[200],
+ appBar: CustomAppBar(
+ title: Text(
+ "Acerca de Mi UTEM",
+ ),
+ ),
+ body: SingleChildScrollView(
+ child: Padding(
+ padding: EdgeInsets.all(10),
+ child: Column(
+ mainAxisAlignment: MainAxisAlignment.center,
+ crossAxisAlignment: CrossAxisAlignment.center,
+ mainAxisSize: MainAxisSize.min,
+ children: [
+ AcercaClub(),
+ Card(
+ shape: RoundedRectangleBorder(
+ borderRadius: BorderRadius.circular(15.0),
+ ),
+ child: AcercaAplicacionContent(),
+ ),
+ AcercaClubDesarrolladores()
+ ],
+ ),
+ ),
+ ),
+ );
+ }
+}
diff --git a/lib/widgets/acerca_screen.dart b/lib/widgets/acerca_screen.dart
deleted file mode 100644
index 30a7613..0000000
--- a/lib/widgets/acerca_screen.dart
+++ /dev/null
@@ -1,259 +0,0 @@
-import 'dart:convert';
-
-import 'package:flutter/material.dart';
-import 'package:flutter_markdown/flutter_markdown.dart';
-import 'package:font_awesome_flutter/font_awesome_flutter.dart';
-import 'package:get/get.dart';
-import 'package:mi_utem/config/routes.dart';
-import 'package:mi_utem/models/usuario.dart';
-import 'package:mi_utem/services/analytics_service.dart';
-import 'package:mi_utem/services/remote_config/remote_config.dart';
-import 'package:mi_utem/widgets/acerca_aplicacion_content.dart';
-import 'package:mi_utem/widgets/custom_app_bar.dart';
-import 'package:mi_utem/widgets/default_network_image.dart';
-import 'package:mi_utem/widgets/image_view_screen.dart';
-import 'package:mi_utem/widgets/profile_photo.dart';
-import 'package:url_launcher/url_launcher.dart';
-
-class AcercaScreen extends StatelessWidget {
- AcercaScreen({
- Key? key,
- }) : super(key: key);
-
- @override
- Widget build(BuildContext context) {
- return Scaffold(
- backgroundColor: Colors.grey[200],
- appBar: CustomAppBar(
- title: Text(
- "Acerca de Mi UTEM",
- ),
- ),
- body: SingleChildScrollView(
- child: Padding(
- padding: EdgeInsets.all(10),
- child: Column(
- mainAxisAlignment: MainAxisAlignment.center,
- crossAxisAlignment: CrossAxisAlignment.center,
- mainAxisSize: MainAxisSize.min,
- children: [
- Card(
- shape: RoundedRectangleBorder(
- borderRadius: BorderRadius.circular(15.0),
- ),
- child: Container(
- padding: EdgeInsets.all(20),
- child: Column(
- children: [
- Container(
- width: 150,
- height: 150,
- child: DefaultNetworkImage(
- url: RemoteConfigService.clubLogo,
- )),
- Container(height: 20),
- Text(
- RemoteConfigService.clubNombre,
- textAlign: TextAlign.center,
- style: TextStyle(
- fontSize: 20,
- color: Colors.grey[700],
- fontWeight: FontWeight.bold,
- ),
- ),
- Container(height: 20),
- MarkdownBody(
- selectable: false,
- styleSheet: MarkdownStyleSheet(
- textAlign: WrapAlignment.center,
- p: TextStyle(
- fontSize: 16,
- color: Colors.grey[700],
- ),
- ),
- data: RemoteConfigService.clubDescripcion,
- ),
- Container(height: 20),
- Row(
- mainAxisAlignment: MainAxisAlignment.center,
- children: jsonDecode(RemoteConfigService.clubRedes)
- .map(
- (red) => Container(
- margin: EdgeInsets.symmetric(horizontal: 5),
- decoration: new BoxDecoration(
- shape: BoxShape.circle,
- color: Color(red["color"]),
- ),
- child: InkWell(
- customBorder: CircleBorder(),
- onTap: () async {
- AnalyticsService.logEvent(
- "acerca_club_social_tap",
- parameters: {
- "red": red['nombre'],
- },
- );
- await launchUrl(Uri.parse(red["url"]));
- },
- child: Container(
- padding: const EdgeInsets.all(10),
- decoration: new BoxDecoration(
- shape: BoxShape.circle,
- ),
- child: Icon(
- IconDataBrands(red["icono"]),
- size: 20,
- color: Colors.white,
- ),
- ),
- ),
- ),
- )
- .toList(),
- ),
- ],
- ),
- ),
- ),
- Card(
- shape: RoundedRectangleBorder(
- borderRadius: BorderRadius.circular(15.0),
- ),
- child: AcercaAplicacionContent(),
- ),
- Card(
- shape: RoundedRectangleBorder(
- borderRadius: BorderRadius.circular(15.0),
- ),
- child: Container(
- padding: EdgeInsets.all(20),
- child: Column(
- mainAxisAlignment: MainAxisAlignment.center,
- crossAxisAlignment: CrossAxisAlignment.start,
- children: [
- Container(
- padding: EdgeInsets.symmetric(horizontal: 10),
- child: Text(
- "Desarrolladores",
- textAlign: TextAlign.center,
- style: TextStyle(
- fontSize: 20,
- color: Colors.grey[700],
- fontWeight: FontWeight.bold,
- ),
- ),
- ),
- Container(height: 10),
- ...jsonDecode(RemoteConfigService.miutemDesarrolladores)
- .map(
- (creador) => Container(
- padding: EdgeInsets.symmetric(vertical: 10),
- child: Row(
- children: [
- ProfilePhoto(
- usuario: Usuario(
- nombres: creador['nombre'],
- fotoUrl: creador['fotoUrl']),
- onImageTap: (context, imageProvider) {
- AnalyticsService.logEvent(
- "acerca_person_image_tap",
- parameters: {
- "persona": creador['nombre'],
- },
- );
- Get.to(
- () => ImageViewScreen(
- imageProvider: imageProvider,
- ),
- routeName: Routes.imageView,
- );
- }),
- Container(width: 20),
- Expanded(
- child: Column(
- crossAxisAlignment:
- CrossAxisAlignment.start,
- children: [
- Text(
- creador["nombre"],
- style: TextStyle(
- fontWeight: FontWeight.bold,
- color: Colors.grey[800],
- fontSize: 16,
- ),
- ),
- Text(
- creador["rol"],
- style: TextStyle(
- fontSize: 16,
- color: Colors.grey[700],
- ),
- ),
- Container(height: 5),
- Row(
- mainAxisAlignment:
- MainAxisAlignment.start,
- children: creador['redes']
- .map(
- (red) => Container(
- margin:
- EdgeInsets.only(right: 8),
- decoration: new BoxDecoration(
- shape: BoxShape.circle,
- color: Color(red["color"]),
- ),
- child: InkWell(
- customBorder:
- CircleBorder(),
- onTap: () async {
- AnalyticsService.logEvent(
- "acerca_person_social_tap",
- parameters: {
- "persona":
- creador['nombre'],
- "red": red['nombre'],
- },
- );
- await launchUrl(
- Uri.parse(red["url"]),
- );
- },
- child: Container(
- padding:
- const EdgeInsets.all(
- 8),
- decoration:
- new BoxDecoration(
- shape: BoxShape.circle,
- ),
- child: Icon(
- IconDataBrands(
- red["icono"]),
- size: 15,
- color: Colors.white,
- ),
- ),
- ),
- ),
- )
- .toList(),
- ),
- ],
- ),
- ),
- ],
- ),
- ),
- )
- .toList()
- ],
- ),
- ),
- ),
- ],
- ),
- ),
- ),
- );
- }
-}
From 07f62203a6b736e1dcb1b937afa3fb8631ef7cb9 Mon Sep 17 00:00:00 2001
From: Francisco Solis <30329003+Im-Fran@users.noreply.github.com>
Date: Wed, 15 Nov 2023 12:57:35 -0300
Subject: [PATCH 009/194] wip: trabajando en reduccion de login_screen.dart y
otros widgets.
* Reducido login_screen
* Reducido acerca de dialog.
* Se necesita revisar otros widgets que modifique (creo que utilice stateless widgets para algunos que debieron ser stateful)
Signed-off-by: Francisco Solis <30329003+Im-Fran@users.noreply.github.com>
---
lib/screens/login_screen/login_screen.dart | 126 +++---------------
lib/widgets/acerca/acerca_screen.dart | 2 +-
.../acerca_aplicacion_content.dart | 0
.../acerca/{ => dialog}/acerca_dialog.dart | 16 +--
lib/widgets/login_screen/creditos_app.dart | 51 +++++++
.../login_screen/formulario_credenciales.dart | 68 ++++++++++
6 files changed, 144 insertions(+), 119 deletions(-)
rename lib/widgets/acerca/{ => dialog}/acerca_aplicacion_content.dart (100%)
rename lib/widgets/acerca/{ => dialog}/acerca_dialog.dart (88%)
create mode 100644 lib/widgets/login_screen/creditos_app.dart
create mode 100644 lib/widgets/login_screen/formulario_credenciales.dart
diff --git a/lib/screens/login_screen/login_screen.dart b/lib/screens/login_screen/login_screen.dart
index f2c976c..25c2027 100644
--- a/lib/screens/login_screen/login_screen.dart
+++ b/lib/screens/login_screen/login_screen.dart
@@ -1,24 +1,21 @@
-import 'dart:convert';
-import 'dart:math';
import 'package:dio/dio.dart';
import 'package:flutter/material.dart';
import 'package:flutter/scheduler.dart';
import 'package:flutter/services.dart';
import 'package:flutter_keyboard_visibility/flutter_keyboard_visibility.dart';
-import 'package:flutter_markdown/flutter_markdown.dart';
import 'package:get/get.dart';
import 'package:mi_utem/config/routes.dart';
import 'package:mi_utem/helpers/snackbars.dart';
import 'package:mi_utem/models/usuario.dart';
import 'package:mi_utem/services/analytics_service.dart';
import 'package:mi_utem/services/auth_service.dart';
-import 'package:mi_utem/services/remote_config/remote_config.dart';
-import 'package:mi_utem/widgets/acerca/acerca_dialog.dart';
+import 'package:mi_utem/widgets/acerca/dialog/acerca_dialog.dart';
import 'package:mi_utem/widgets/dialogs/monkey_error_dialog.dart';
import 'package:mi_utem/widgets/dialogs/not_ready_dialog.dart';
import 'package:mi_utem/widgets/loading_dialog.dart';
-import 'package:mi_utem/widgets/login_text_form_field.dart';
+import 'package:mi_utem/widgets/login_screen/creditos_app.dart';
+import 'package:mi_utem/widgets/login_screen/formulario_credenciales.dart';
import 'package:video_player/video_player.dart';
part '_background.dart';
@@ -31,8 +28,8 @@ class LoginScreen extends StatefulWidget {
}
class _LoginScreenState extends State {
- TextEditingController _correoController = TextEditingController();
- TextEditingController _contraseniaController = TextEditingController();
+ TextEditingController correoController = TextEditingController();
+ TextEditingController contraseniaController = TextEditingController();
GlobalKey _formKey = GlobalKey();
@@ -50,8 +47,8 @@ class _LoginScreenState extends State {
),
);
- _correoController.text = "";
- _contraseniaController.text = "";
+ correoController.text = "";
+ contraseniaController.text = "";
SchedulerBinding.instance.addPostFrameCallback((_) {
_checkAndPerformUpdate();
@@ -94,14 +91,6 @@ class _LoginScreenState extends State {
} */
}
- String get _creditText {
- List texts = jsonDecode(RemoteConfigService.creditos);
-
- Random random = new Random();
-
- return texts[random.nextInt(texts.length)];
- }
-
@override
Widget build(BuildContext context) {
return Scaffold(
@@ -143,84 +132,14 @@ class _LoginScreenState extends State {
),
),
Container(height: constraints.maxHeight * 0.1),
- AutofillGroup(
- child: Column(
- children: [
- LoginTextFormField(
- controller: _correoController,
- hintText: 'nombre@utem.cl',
- labelText: 'Correo UTEM',
- textCapitalization: TextCapitalization.none,
- keyboardType: TextInputType.emailAddress,
- inputFormatters: [
- FilteringTextInputFormatter.deny(
- RegExp(" ")),
- ],
- icon: Icons.person,
- autofillHints: [AutofillHints.username],
- validator: (String value) {
- if (value.isEmpty) {
- return 'Debe ingresar un correo UTEM';
- } else if (value.contains("@") &&
- !value.endsWith("@utem.cl")) {
- return 'Debe ingresar un correo UTEM';
- }
- },
- ),
- LoginTextFormField(
- controller: _contraseniaController,
- hintText: '• • • • • • • • •',
- labelText: 'Contraseña',
- textCapitalization: TextCapitalization.none,
- icon: Icons.lock,
- obscureText: true,
- autofillHints: [AutofillHints.password],
- validator: (String value) {
- if (value.isEmpty) {
- return 'Debe ingresar una contraseña';
- }
- },
- )
- ],
- ),
- ),
+ FormularioCredenciales(correoController: correoController, contraseniaController: contraseniaController),
TextButton(
onPressed: () => _login(),
child: Text("Iniciar"),
),
Container(height: constraints.maxHeight * 0.1),
if (!isKeyboardVisible)
- Expanded(
- child: SafeArea(
- child: Column(
- mainAxisAlignment: MainAxisAlignment.end,
- children: [
- Padding(
- padding: EdgeInsets.all(10),
- child: SafeArea(
- child: GestureDetector(
- child: MarkdownBody(
- selectable: false,
- styleSheet: MarkdownStyleSheet(
- textAlign: WrapAlignment.center,
- p: TextStyle(
- color: Colors.white,
- ),
- ),
- data: _creditText,
- ),
- onTap: () {
- Get.toNamed(
- Routes.about,
- );
- },
- ),
- ),
- ),
- ],
- ),
- ),
- ),
+ CreditosApp(),
],
),
),
@@ -236,8 +155,8 @@ class _LoginScreenState extends State {
}
Future _login() async {
- final correo = _correoController.text;
- final contrasenia = _contraseniaController.text;
+ final correo = correoController.text;
+ final contrasenia = contraseniaController.text;
if (correo == "error@utem.cl") {
Get.dialog(MonkeyErrorDialog());
@@ -260,14 +179,10 @@ class _LoginScreenState extends State {
AnalyticsService.logEvent('login');
AnalyticsService.setUser(usuario);
- Get.toNamed(
- Routes.home,
- );
+ Get.toNamed(Routes.home);
- if (esPrimeraVez) {
- Get.dialog(
- AcercaDialog(),
- );
+ if (esPrimeraVez || true) {
+ Get.dialog(AcercaDialog());
}
} on DioError catch (e) {
print(e.message);
@@ -276,21 +191,14 @@ class _LoginScreenState extends State {
if (e.response?.data["codigoInterno"]?.toString() == "4") {
Get.dialog(NotReadyDialog());
} else {
- showDefaultSnackbar(
- "Error",
- "Usuario o contraseña incorrecta",
- );
+ showDefaultSnackbar("Error", "Usuario o contraseña incorrecta");
}
- } else if (e.response?.statusCode != null &&
- e.response!.statusCode.toString().startsWith("5")) {
+ } else if (e.response?.statusCode != null && e.response!.statusCode.toString().startsWith("5")) {
print(e.response?.data);
Get.dialog(MonkeyErrorDialog());
} else {
print(e.response?.data);
- showDefaultSnackbar(
- "Error",
- "Ocurrió un error inesperado 😢",
- );
+ showDefaultSnackbar("Error", "Ocurrió un error inesperado 😢");
}
} catch (e) {
print(e.toString());
diff --git a/lib/widgets/acerca/acerca_screen.dart b/lib/widgets/acerca/acerca_screen.dart
index 7de53a0..7a05433 100644
--- a/lib/widgets/acerca/acerca_screen.dart
+++ b/lib/widgets/acerca/acerca_screen.dart
@@ -1,6 +1,6 @@
import 'package:flutter/material.dart';
-import 'package:mi_utem/widgets/acerca/acerca_aplicacion_content.dart';
+import 'package:mi_utem/widgets/acerca/dialog/acerca_aplicacion_content.dart';
import 'package:mi_utem/widgets/acerca/club/acerca_club.dart';
import 'package:mi_utem/widgets/acerca/club/acerca_club_desarrolladores.dart';
import 'package:mi_utem/widgets/custom_app_bar.dart';
diff --git a/lib/widgets/acerca/acerca_aplicacion_content.dart b/lib/widgets/acerca/dialog/acerca_aplicacion_content.dart
similarity index 100%
rename from lib/widgets/acerca/acerca_aplicacion_content.dart
rename to lib/widgets/acerca/dialog/acerca_aplicacion_content.dart
diff --git a/lib/widgets/acerca/acerca_dialog.dart b/lib/widgets/acerca/dialog/acerca_dialog.dart
similarity index 88%
rename from lib/widgets/acerca/acerca_dialog.dart
rename to lib/widgets/acerca/dialog/acerca_dialog.dart
index ca1e8f2..9a74f48 100644
--- a/lib/widgets/acerca/acerca_dialog.dart
+++ b/lib/widgets/acerca/dialog/acerca_dialog.dart
@@ -3,7 +3,7 @@ import 'dart:async';
import 'package:flutter/material.dart';
import 'package:get/get.dart';
import 'package:mi_utem/config/routes.dart';
-import 'package:mi_utem/widgets/acerca/acerca_aplicacion_content.dart';
+import 'package:mi_utem/widgets/acerca/dialog/acerca_aplicacion_content.dart';
class AcercaDialog extends StatefulWidget {
AcercaDialog({
@@ -90,14 +90,12 @@ class _AcercaDialogState extends State {
: "Saber más",
style: TextStyle(color: Colors.white),
),
- onPressed: _isActive
- ? null
- : () {
- Get.back();
- Get.toNamed(
- Routes.about,
- );
- },
+ onPressed: () {
+ if (!_isActive) {
+ Get.back();
+ Get.toNamed(Routes.about);
+ }
+ }
),
],
),
diff --git a/lib/widgets/login_screen/creditos_app.dart b/lib/widgets/login_screen/creditos_app.dart
new file mode 100644
index 0000000..71c5247
--- /dev/null
+++ b/lib/widgets/login_screen/creditos_app.dart
@@ -0,0 +1,51 @@
+import 'dart:convert';
+import 'dart:math';
+
+import 'package:flutter/material.dart';
+import 'package:flutter_markdown/flutter_markdown.dart';
+import 'package:get/get.dart';
+import 'package:mi_utem/widgets/acerca/dialog/acerca_dialog.dart';
+
+import '../../services/remote_config/remote_config.dart';
+
+class CreditosApp extends StatelessWidget {
+
+ String get _creditText {
+ List texts = jsonDecode(RemoteConfigService.creditos);
+
+ Random random = new Random();
+
+ return texts[random.nextInt(texts.length)];
+ }
+
+ @override
+ Widget build(BuildContext context) {
+ return Expanded(
+ child: SafeArea(
+ child: Column(
+ mainAxisAlignment: MainAxisAlignment.end,
+ children: [
+ Padding(
+ padding: EdgeInsets.all(10),
+ child: SafeArea(
+ child: GestureDetector(
+ child: MarkdownBody(
+ selectable: false,
+ styleSheet: MarkdownStyleSheet(
+ textAlign: WrapAlignment.center,
+ p: TextStyle(color: Colors.white),
+ ),
+ data: _creditText,
+ ),
+ onTap: () {
+ Get.dialog(AcercaDialog());
+ },
+ ),
+ ),
+ ),
+ ],
+ ),
+ ),
+ );
+ }
+}
\ No newline at end of file
diff --git a/lib/widgets/login_screen/formulario_credenciales.dart b/lib/widgets/login_screen/formulario_credenciales.dart
new file mode 100644
index 0000000..c8328d8
--- /dev/null
+++ b/lib/widgets/login_screen/formulario_credenciales.dart
@@ -0,0 +1,68 @@
+import 'package:flutter/material.dart';
+import 'package:flutter/services.dart';
+
+import '../login_text_form_field.dart';
+
+class FormularioCredenciales extends StatefulWidget {
+
+ final TextEditingController correoController;
+ final TextEditingController contraseniaController;
+
+
+ FormularioCredenciales({ required this.correoController, required this.contraseniaController });
+
+ @override
+ State createState() => _FormularioCredencialesState(correoController: correoController, contraseniaController: contraseniaController);
+}
+
+class _FormularioCredencialesState extends State {
+
+ final TextEditingController correoController;
+ final TextEditingController contraseniaController;
+
+ _FormularioCredencialesState({ required this.correoController, required this.contraseniaController });
+
+ @override
+ Widget build(BuildContext context) {
+ return AutofillGroup(
+ child: Column(
+ children: [
+ LoginTextFormField(
+ controller: correoController,
+ hintText: 'nombre@utem.cl',
+ labelText: 'Correo UTEM',
+ textCapitalization: TextCapitalization.none,
+ keyboardType: TextInputType.emailAddress,
+ inputFormatters: [
+ FilteringTextInputFormatter.deny(RegExp(" ")),
+ ],
+ icon: Icons.person,
+ autofillHints: [AutofillHints.username],
+ validator: (String value) {
+ if (value.isEmpty) {
+ return 'Debe ingresar un correo UTEM';
+ } else if (value.contains("@") &&
+ !value.endsWith("@utem.cl")) {
+ return 'Debe ingresar un correo UTEM';
+ }
+ },
+ ),
+ LoginTextFormField(
+ controller: contraseniaController,
+ hintText: '• • • • • • • • •',
+ labelText: 'Contraseña',
+ textCapitalization: TextCapitalization.none,
+ icon: Icons.lock,
+ obscureText: true,
+ autofillHints: [AutofillHints.password],
+ validator: (String value) {
+ if (value.isEmpty) {
+ return 'Debe ingresar una contraseña';
+ }
+ },
+ )
+ ],
+ ),
+ );
+ }
+}
\ No newline at end of file
From 1b4f6ecf251fc5a3885379b1743603753119b8bf Mon Sep 17 00:00:00 2001
From: Francisco Solis <30329003+Im-Fran@users.noreply.github.com>
Date: Thu, 16 Nov 2023 08:41:30 -0300
Subject: [PATCH 010/194] patch: reduccion de login_screen, acerca_dialog y
reparado algunos widgets.
* Se ha reducido login_screen a distintos widgets
* Se ha reducido acerca_dialog a distintos widgets
* Se han reparado algunos widgets que configure como stateless siendo stateful.
Signed-off-by: Francisco Solis <30329003+Im-Fran@users.noreply.github.com>
---
lib/screens/login_screen/login_screen.dart | 139 ++---------------
lib/services/update_service.dart | 46 ++++++
lib/widgets/acerca/acerca_screen.dart | 4 +-
lib/widgets/acerca/dialog/acerca_dialog.dart | 29 +---
.../dialog/acerca_dialog_action_button.dart | 44 ++++++
.../notas_tab/labeled_nota_display.dart | 95 ++++++------
.../notas_tab/nota_final_display.dart | 27 ++--
.../asignatura/notas_tab/notas_display.dart | 143 +++++++++---------
lib/widgets/login_screen/creditos_app.dart | 4 +-
.../login_screen/formulario_credenciales.dart | 17 +--
lib/widgets/login_screen/login_button.dart | 98 ++++++++++++
11 files changed, 352 insertions(+), 294 deletions(-)
create mode 100644 lib/services/update_service.dart
create mode 100644 lib/widgets/acerca/dialog/acerca_dialog_action_button.dart
create mode 100644 lib/widgets/login_screen/login_button.dart
diff --git a/lib/screens/login_screen/login_screen.dart b/lib/screens/login_screen/login_screen.dart
index 25c2027..7d0a4e8 100644
--- a/lib/screens/login_screen/login_screen.dart
+++ b/lib/screens/login_screen/login_screen.dart
@@ -1,26 +1,23 @@
-import 'package:dio/dio.dart';
import 'package:flutter/material.dart';
-import 'package:flutter/scheduler.dart';
import 'package:flutter/services.dart';
import 'package:flutter_keyboard_visibility/flutter_keyboard_visibility.dart';
import 'package:get/get.dart';
-import 'package:mi_utem/config/routes.dart';
-import 'package:mi_utem/helpers/snackbars.dart';
-import 'package:mi_utem/models/usuario.dart';
-import 'package:mi_utem/services/analytics_service.dart';
-import 'package:mi_utem/services/auth_service.dart';
-import 'package:mi_utem/widgets/acerca/dialog/acerca_dialog.dart';
-import 'package:mi_utem/widgets/dialogs/monkey_error_dialog.dart';
-import 'package:mi_utem/widgets/dialogs/not_ready_dialog.dart';
-import 'package:mi_utem/widgets/loading_dialog.dart';
+import 'package:mi_utem/services/update_service.dart';
import 'package:mi_utem/widgets/login_screen/creditos_app.dart';
import 'package:mi_utem/widgets/login_screen/formulario_credenciales.dart';
+import 'package:mi_utem/widgets/login_screen/login_button.dart';
import 'package:video_player/video_player.dart';
part '_background.dart';
class LoginScreen extends StatefulWidget {
+
+ final TextEditingController _correoController = TextEditingController();
+ final TextEditingController _contraseniaController = TextEditingController();
+
+ final GlobalKey _formKey = GlobalKey();
+
LoginScreen({Key? key}) : super(key: key);
@override
@@ -28,10 +25,6 @@ class LoginScreen extends StatefulWidget {
}
class _LoginScreenState extends State {
- TextEditingController correoController = TextEditingController();
- TextEditingController contraseniaController = TextEditingController();
-
- GlobalKey _formKey = GlobalKey();
@override
void initState() {
@@ -47,48 +40,10 @@ class _LoginScreenState extends State {
),
);
- correoController.text = "";
- contraseniaController.text = "";
-
- SchedulerBinding.instance.addPostFrameCallback((_) {
- _checkAndPerformUpdate();
- });
- }
-
- Future _checkAndPerformUpdate() async {
- /* try {
- VersionStatus status =
- await NewVersion(context: context).getVersionStatus();
- print("status.localVersion ${status.localVersion}");
- print("status.storeVersion ${status.storeVersion}");
-
- var localVersion = status.localVersion.split(".");
- var storeVersion = status.storeVersion.split(".");
- if (storeVersion[0].compareTo(localVersion[0]) > 0) {
- if (Platform.isAndroid) {
- AppUpdateInfo info = await InAppUpdate.checkForUpdate();
-
- if (info.updateAvailable == true) {
- await InAppUpdate.performImmediateUpdate();
- }
- }
- } else if (storeVersion[1].compareTo(localVersion[1]) > 0) {
- if (Platform.isAndroid) {
- AppUpdateInfo info = await InAppUpdate.checkForUpdate();
-
- if (info.updateAvailable == true) {
- await InAppUpdate.startFlexibleUpdate();
- await InAppUpdate.completeFlexibleUpdate();
- }
- }
- } else if (storeVersion[2].compareTo(localVersion[2]) > 0) {
- print("MINOR");
- }
+ widget._correoController.text = "";
+ widget._contraseniaController.text = "";
- return;
- } catch (error) {
- print("_checkAndPerformUpdate Error: ${error.toString()}");
- } */
+ UpdateService();
}
@override
@@ -109,7 +64,7 @@ class _LoginScreenState extends State {
),
child: IntrinsicHeight(
child: Form(
- key: _formKey,
+ key: widget._formKey,
child: Column(
mainAxisSize: MainAxisSize.max,
mainAxisAlignment: MainAxisAlignment.spaceBetween,
@@ -122,21 +77,15 @@ class _LoginScreenState extends State {
children: [
Hero(
tag: 'utemLogo',
- child: Image.asset(
- 'assets/images/utem_logo_color_blanco.png',
- width: 250,
- ),
+ child: Image.asset('assets/images/utem_logo_color_blanco.png', width: 250),
),
],
),
),
),
Container(height: constraints.maxHeight * 0.1),
- FormularioCredenciales(correoController: correoController, contraseniaController: contraseniaController),
- TextButton(
- onPressed: () => _login(),
- child: Text("Iniciar"),
- ),
+ FormularioCredenciales(correoController: widget._correoController, contraseniaController: widget._contraseniaController),
+ LoginButton(correoController: widget._correoController, contraseniaController: widget._contraseniaController, formKey: widget._formKey),
Container(height: constraints.maxHeight * 0.1),
if (!isKeyboardVisible)
CreditosApp(),
@@ -153,62 +102,4 @@ class _LoginScreenState extends State {
),
);
}
-
- Future _login() async {
- final correo = correoController.text;
- final contrasenia = contraseniaController.text;
-
- if (correo == "error@utem.cl") {
- Get.dialog(MonkeyErrorDialog());
- } else if (correo == "test@utem.cl" && contrasenia == "test") {
- showDefaultSnackbar(
- "Error",
- "Usuario o contraseña incorrecta",
- );
- } else {
- if (_formKey.currentState?.validate() ?? false) {
- Get.dialog(
- LoadingDialog(),
- barrierDismissible: false,
- );
-
- try {
- bool esPrimeraVez = await AuthService.esPrimeraVez();
- Usuario usuario = await AuthService.login(correo, contrasenia, true);
-
- AnalyticsService.logEvent('login');
- AnalyticsService.setUser(usuario);
-
- Get.toNamed(Routes.home);
-
- if (esPrimeraVez || true) {
- Get.dialog(AcercaDialog());
- }
- } on DioError catch (e) {
- print(e.message);
- Get.back();
- if (e.response?.statusCode == 403) {
- if (e.response?.data["codigoInterno"]?.toString() == "4") {
- Get.dialog(NotReadyDialog());
- } else {
- showDefaultSnackbar("Error", "Usuario o contraseña incorrecta");
- }
- } else if (e.response?.statusCode != null && e.response!.statusCode.toString().startsWith("5")) {
- print(e.response?.data);
- Get.dialog(MonkeyErrorDialog());
- } else {
- print(e.response?.data);
- showDefaultSnackbar("Error", "Ocurrió un error inesperado 😢");
- }
- } catch (e) {
- print(e.toString());
- Get.back();
- showDefaultSnackbar(
- "Error",
- "Ocurrió un error inesperado 😢",
- );
- }
- }
- }
- }
}
diff --git a/lib/services/update_service.dart b/lib/services/update_service.dart
new file mode 100644
index 0000000..2f9c8c7
--- /dev/null
+++ b/lib/services/update_service.dart
@@ -0,0 +1,46 @@
+import 'package:flutter/scheduler.dart';
+
+class UpdateService {
+
+ UpdateService(){
+ SchedulerBinding.instance.addPostFrameCallback((_) => _checkAndPerformUpdate());
+ }
+
+ /* try {
+ VersionStatus status =
+ await NewVersion(context: context).getVersionStatus();
+ print("status.localVersion ${status.localVersion}");
+ print("status.storeVersion ${status.storeVersion}");
+
+ var localVersion = status.localVersion.split(".");
+ var storeVersion = status.storeVersion.split(".");
+ if (storeVersion[0].compareTo(localVersion[0]) > 0) {
+ if (Platform.isAndroid) {
+ AppUpdateInfo info = await InAppUpdate.checkForUpdate();
+
+ if (info.updateAvailable == true) {
+ await InAppUpdate.performImmediateUpdate();
+ }
+ }
+ } else if (storeVersion[1].compareTo(localVersion[1]) > 0) {
+ if (Platform.isAndroid) {
+ AppUpdateInfo info = await InAppUpdate.checkForUpdate();
+
+ if (info.updateAvailable == true) {
+ await InAppUpdate.startFlexibleUpdate();
+ await InAppUpdate.completeFlexibleUpdate();
+ }
+ }
+ } else if (storeVersion[2].compareTo(localVersion[2]) > 0) {
+ print("MINOR");
+ }
+
+ return;
+ } catch (error) {
+ print("_checkAndPerformUpdate Error: ${error.toString()}");
+ } */
+
+ Future _checkAndPerformUpdate() async {
+
+ }
+}
\ No newline at end of file
diff --git a/lib/widgets/acerca/acerca_screen.dart b/lib/widgets/acerca/acerca_screen.dart
index 7a05433..55971c7 100644
--- a/lib/widgets/acerca/acerca_screen.dart
+++ b/lib/widgets/acerca/acerca_screen.dart
@@ -15,9 +15,7 @@ class AcercaScreen extends StatelessWidget {
return Scaffold(
backgroundColor: Colors.grey[200],
appBar: CustomAppBar(
- title: Text(
- "Acerca de Mi UTEM",
- ),
+ title: Text("Acerca de Mi UTEM"),
),
body: SingleChildScrollView(
child: Padding(
diff --git a/lib/widgets/acerca/dialog/acerca_dialog.dart b/lib/widgets/acerca/dialog/acerca_dialog.dart
index 9a74f48..fab64e0 100644
--- a/lib/widgets/acerca/dialog/acerca_dialog.dart
+++ b/lib/widgets/acerca/dialog/acerca_dialog.dart
@@ -2,8 +2,8 @@ import 'dart:async';
import 'package:flutter/material.dart';
import 'package:get/get.dart';
-import 'package:mi_utem/config/routes.dart';
import 'package:mi_utem/widgets/acerca/dialog/acerca_aplicacion_content.dart';
+import 'package:mi_utem/widgets/acerca/dialog/acerca_dialog_action_button.dart';
class AcercaDialog extends StatefulWidget {
AcercaDialog({
@@ -76,33 +76,10 @@ class _AcercaDialogState extends State {
preTitulo: "Antes de empezar...",
titulo: "Bienvenido a Mi UTEM",
),
- Wrap(
- spacing: 10,
- runSpacing: 10,
- crossAxisAlignment: WrapCrossAlignment.center,
- alignment: WrapAlignment.center,
- runAlignment: WrapAlignment.center,
- children: [
- TextButton(
- child: Text(
- _isActive
- ? "Podrás cerrar en $_timeLeft"
- : "Saber más",
- style: TextStyle(color: Colors.white),
- ),
- onPressed: () {
- if (!_isActive) {
- Get.back();
- Get.toNamed(Routes.about);
- }
- }
- ),
- ],
- ),
+ AcercaDialogActionButton(isActive: _isActive, timeLeft: _timeLeft),
if (!_isActive)
OutlinedButton(
- child: Text(
- "Cerrar",
+ child: Text("Cerrar",
style: TextStyle(color: Get.theme.primaryColor),
),
onPressed: () {
diff --git a/lib/widgets/acerca/dialog/acerca_dialog_action_button.dart b/lib/widgets/acerca/dialog/acerca_dialog_action_button.dart
new file mode 100644
index 0000000..26db494
--- /dev/null
+++ b/lib/widgets/acerca/dialog/acerca_dialog_action_button.dart
@@ -0,0 +1,44 @@
+import 'package:flutter/material.dart';
+import 'package:get/get.dart';
+
+import '../../../config/routes.dart';
+
+class AcercaDialogActionButton extends StatefulWidget {
+
+ final bool isActive;
+ final int timeLeft;
+
+ const AcercaDialogActionButton({
+ Key? key,
+ required this.isActive,
+ required this.timeLeft,
+ }) : super(key: key);
+
+ @override
+ State createState() => _AcercaDialogActionButtonState();
+}
+
+class _AcercaDialogActionButtonState extends State {
+
+ @override
+ Widget build(BuildContext context) => Wrap(
+ spacing: 10,
+ runSpacing: 10,
+ crossAxisAlignment: WrapCrossAlignment.center,
+ alignment: WrapAlignment.center,
+ runAlignment: WrapAlignment.center,
+ children: [
+ TextButton(
+ child: Text(widget.isActive ? "Podrás cerrar en ${widget.timeLeft}" : "Saber más",
+ style: TextStyle(color: Colors.white),
+ ),
+ onPressed: () {
+ if (!widget.isActive) {
+ Get.back();
+ Get.toNamed(Routes.about);
+ }
+ }
+ ),
+ ],
+ );
+}
\ No newline at end of file
diff --git a/lib/widgets/asignatura/notas_tab/labeled_nota_display.dart b/lib/widgets/asignatura/notas_tab/labeled_nota_display.dart
index 76d228a..16dab8f 100644
--- a/lib/widgets/asignatura/notas_tab/labeled_nota_display.dart
+++ b/lib/widgets/asignatura/notas_tab/labeled_nota_display.dart
@@ -1,54 +1,55 @@
- import 'package:flutter/material.dart';
- import 'package:flutter_masked_text/flutter_masked_text.dart';
- import 'package:mi_utem/themes/theme.dart';
+import 'package:flutter/material.dart';
+import 'package:flutter_masked_text/flutter_masked_text.dart';
+import 'package:mi_utem/themes/theme.dart';
- class LabeledNotaDisplayWidget extends StatelessWidget {
+class LabeledNotaDisplayWidget extends StatefulWidget {
+ final String _label;
+ final num? _nota;
+ final String? _hint;
- final String label;
- final num? nota;
- final String? hint;
+ LabeledNotaDisplayWidget({required String label, num? nota, String? hint})
+ : _label = label,
+ _nota = nota,
+ _hint = hint;
- LabeledNotaDisplayWidget({
- Key? key,
- required this.label,
- this.nota,
- this.hint,
- }) : super(key: key);
+ @override
+ _LabeledNotaDisplayWidgetState createState() =>
+ _LabeledNotaDisplayWidgetState();
+}
- @override
- Widget build(BuildContext context) {
- final notaController = MaskedTextController(
- mask: '0.0',
- text: nota?.toStringAsFixed(1) ?? "",
- );
+class _LabeledNotaDisplayWidgetState extends State {
+ @override
+ Widget build(BuildContext context) {
+ final notaController = MaskedTextController(
+ mask: '0.0',
+ text: widget._nota?.toStringAsFixed(1) ?? "",
+ );
- return Row(
- crossAxisAlignment: CrossAxisAlignment.center,
- children: [
- Text(label,
- style: TextStyle(fontSize: 16),
- ),
- Container(
- width: 60,
- margin: EdgeInsets.only(left: 15),
- child: TextField(
- controller: notaController,
- textAlign: TextAlign.center,
- enabled: false,
- decoration: InputDecoration(
- hintText: hint,
- disabledBorder: MainTheme.theme
- .inputDecorationTheme.border!
- .copyWith(borderSide: BorderSide(color: Colors.transparent)),
- ),
- keyboardType:
- TextInputType.numberWithOptions(
- decimal: true,
- ),
+ return Row(
+ crossAxisAlignment: CrossAxisAlignment.center,
+ children: [
+ Text(
+ widget._label,
+ style: TextStyle(fontSize: 16),
+ ),
+ Container(
+ width: 60,
+ margin: EdgeInsets.only(left: 15),
+ child: TextField(
+ controller: notaController,
+ textAlign: TextAlign.center,
+ enabled: false,
+ decoration: InputDecoration(
+ hintText: widget._hint,
+ disabledBorder: MainTheme.theme.inputDecorationTheme.border!
+ .copyWith(borderSide: BorderSide(color: Colors.transparent)),
+ ),
+ keyboardType: TextInputType.numberWithOptions(
+ decimal: true,
),
),
- ],
- );
- }
-
- }
\ No newline at end of file
+ ),
+ ],
+ );
+ }
+}
diff --git a/lib/widgets/asignatura/notas_tab/nota_final_display.dart b/lib/widgets/asignatura/notas_tab/nota_final_display.dart
index 35a7da8..527c187 100644
--- a/lib/widgets/asignatura/notas_tab/nota_final_display.dart
+++ b/lib/widgets/asignatura/notas_tab/nota_final_display.dart
@@ -1,27 +1,32 @@
import 'package:flutter/material.dart';
-class NotaFinalDisplayWidget extends StatelessWidget {
+class NotaFinalDisplayWidget extends StatefulWidget {
+ final num? _notaFinal;
+ final String? _estado;
- final num? notaFinal;
- final String? estado;
+ NotaFinalDisplayWidget({Key? key, num? notaFinal, String? estado})
+ : _notaFinal = notaFinal,
+ _estado = estado,
+ super(key: key);
- NotaFinalDisplayWidget({
- Key? key,
- this.notaFinal,
- this.estado,
- }) : super(key: key);
+ @override
+ _NotaFinalDisplayWidgetState createState() => _NotaFinalDisplayWidgetState();
+}
+class _NotaFinalDisplayWidgetState extends State {
@override
Widget build(BuildContext context) {
return Column(
children: [
- Text(notaFinal?.toStringAsFixed(1) ?? "S/N",
+ Text(
+ widget._notaFinal?.toStringAsFixed(1) ?? "S/N",
style: TextStyle(
fontSize: 40,
fontWeight: FontWeight.bold,
),
),
- Text(estado ?? "---",
+ Text(
+ widget._estado ?? "---",
style: TextStyle(
fontSize: 16,
fontWeight: FontWeight.bold,
@@ -30,4 +35,4 @@ class NotaFinalDisplayWidget extends StatelessWidget {
],
);
}
-}
\ No newline at end of file
+}
diff --git a/lib/widgets/asignatura/notas_tab/notas_display.dart b/lib/widgets/asignatura/notas_tab/notas_display.dart
index 8786058..c0c16ef 100644
--- a/lib/widgets/asignatura/notas_tab/notas_display.dart
+++ b/lib/widgets/asignatura/notas_tab/notas_display.dart
@@ -1,76 +1,79 @@
- import 'package:flutter/material.dart';
- import 'package:mi_utem/widgets/asignatura/notas_tab/labeled_nota_display.dart';
- import 'package:mi_utem/widgets/asignatura/notas_tab/nota_final_display.dart';
+import 'package:flutter/material.dart';
+import 'package:mi_utem/widgets/asignatura/notas_tab/labeled_nota_display.dart';
+import 'package:mi_utem/widgets/asignatura/notas_tab/nota_final_display.dart';
- class NotasDisplayWidget extends StatelessWidget {
+class NotasDisplayWidget extends StatefulWidget {
+ final num? _notaFinal;
+ final num? _notaExamen;
+ final num? _notaPresentacion;
+ final String? _estado;
+ final Color? _colorPorEstado;
- final num? notaFinal;
- final num? notaExamen;
- final num? notaPresentacion;
- final String? estado;
- final Color? colorPorEstado;
+ NotasDisplayWidget({
+ notaFinal,
+ notaExamen,
+ notaPresentacion,
+ estado,
+ colorPorEstado,
+ }) : _notaFinal = notaFinal,
+ _notaExamen = notaExamen,
+ _notaPresentacion = notaPresentacion,
+ _estado = estado,
+ _colorPorEstado = colorPorEstado;
- NotasDisplayWidget({
- Key? key,
- this.notaFinal,
- this.notaExamen,
- this.notaPresentacion,
- this.estado,
- this.colorPorEstado,
- }) : super(key: key);
+ @override
+ State createState() => NotasDisplayWidgetState();
+}
-
- @override
- Widget build(BuildContext context) {
- return Card(
- child: Row(
- children: [
- Container(
- height: 130,
- width: 10,
- color: colorPorEstado,
- ),
- Expanded(
- child: Container(
- padding: EdgeInsets.fromLTRB(15, 20, 20, 20),
- child: Row(
- crossAxisAlignment: CrossAxisAlignment.center,
- mainAxisAlignment: MainAxisAlignment.spaceBetween,
- children: [
- NotaFinalDisplayWidget(
- notaFinal: notaFinal,
- estado: estado,
- ),
- Container(width: 10),
- Container(
- height: 80,
- width: 0.5,
- color: Colors.grey,
- ),
- Container(width: 10),
- Column(
- crossAxisAlignment: CrossAxisAlignment.end,
- children: [
- LabeledNotaDisplayWidget(
- label: "Examen",
- nota: notaExamen,
- ),
- Container(height: 10),
- LabeledNotaDisplayWidget(
- label: "Presentación",
- nota: notaPresentacion,
- hint: "--"
- ),
- ],
- ),
- ],
- ),
+class NotasDisplayWidgetState extends State {
+ @override
+ Widget build(BuildContext context) {
+ return Card(
+ child: Row(
+ children: [
+ Container(
+ height: 130,
+ width: 10,
+ color: widget._colorPorEstado,
+ ),
+ Expanded(
+ child: Container(
+ padding: EdgeInsets.fromLTRB(15, 20, 20, 20),
+ child: Row(
+ crossAxisAlignment: CrossAxisAlignment.center,
+ mainAxisAlignment: MainAxisAlignment.spaceBetween,
+ children: [
+ NotaFinalDisplayWidget(
+ notaFinal: widget._notaFinal,
+ estado: widget._estado,
+ ),
+ Container(width: 10),
+ Container(
+ height: 80,
+ width: 0.5,
+ color: Colors.grey,
+ ),
+ Container(width: 10),
+ Column(
+ crossAxisAlignment: CrossAxisAlignment.end,
+ children: [
+ LabeledNotaDisplayWidget(
+ label: "Examen",
+ nota: widget._notaExamen,
+ ),
+ Container(height: 10),
+ LabeledNotaDisplayWidget(
+ label: "Presentación",
+ nota: widget._notaPresentacion,
+ hint: "--"),
+ ],
+ ),
+ ],
),
),
- ],
- ),
- );
- }
-
-
- }
\ No newline at end of file
+ ),
+ ],
+ ),
+ );
+ }
+}
diff --git a/lib/widgets/login_screen/creditos_app.dart b/lib/widgets/login_screen/creditos_app.dart
index 71c5247..c28c3cb 100644
--- a/lib/widgets/login_screen/creditos_app.dart
+++ b/lib/widgets/login_screen/creditos_app.dart
@@ -4,8 +4,8 @@ import 'dart:math';
import 'package:flutter/material.dart';
import 'package:flutter_markdown/flutter_markdown.dart';
import 'package:get/get.dart';
-import 'package:mi_utem/widgets/acerca/dialog/acerca_dialog.dart';
+import '../../config/routes.dart';
import '../../services/remote_config/remote_config.dart';
class CreditosApp extends StatelessWidget {
@@ -38,7 +38,7 @@ class CreditosApp extends StatelessWidget {
data: _creditText,
),
onTap: () {
- Get.dialog(AcercaDialog());
+ Get.toNamed(Routes.about);
},
),
),
diff --git a/lib/widgets/login_screen/formulario_credenciales.dart b/lib/widgets/login_screen/formulario_credenciales.dart
index c8328d8..58e1d91 100644
--- a/lib/widgets/login_screen/formulario_credenciales.dart
+++ b/lib/widgets/login_screen/formulario_credenciales.dart
@@ -5,30 +5,25 @@ import '../login_text_form_field.dart';
class FormularioCredenciales extends StatefulWidget {
- final TextEditingController correoController;
- final TextEditingController contraseniaController;
+ final TextEditingController _correoController;
+ final TextEditingController _contraseniaController;
- FormularioCredenciales({ required this.correoController, required this.contraseniaController });
+ FormularioCredenciales({ required TextEditingController correoController, required TextEditingController contraseniaController }) : _contraseniaController = contraseniaController, _correoController = correoController;
@override
- State createState() => _FormularioCredencialesState(correoController: correoController, contraseniaController: contraseniaController);
+ State createState() => _FormularioCredencialesState();
}
class _FormularioCredencialesState extends State {
- final TextEditingController correoController;
- final TextEditingController contraseniaController;
-
- _FormularioCredencialesState({ required this.correoController, required this.contraseniaController });
-
@override
Widget build(BuildContext context) {
return AutofillGroup(
child: Column(
children: [
LoginTextFormField(
- controller: correoController,
+ controller: widget._correoController,
hintText: 'nombre@utem.cl',
labelText: 'Correo UTEM',
textCapitalization: TextCapitalization.none,
@@ -48,7 +43,7 @@ class _FormularioCredencialesState extends State {
},
),
LoginTextFormField(
- controller: contraseniaController,
+ controller: widget._contraseniaController,
hintText: '• • • • • • • • •',
labelText: 'Contraseña',
textCapitalization: TextCapitalization.none,
diff --git a/lib/widgets/login_screen/login_button.dart b/lib/widgets/login_screen/login_button.dart
new file mode 100644
index 0000000..849e78b
--- /dev/null
+++ b/lib/widgets/login_screen/login_button.dart
@@ -0,0 +1,98 @@
+import 'package:dio/dio.dart';
+import 'package:flutter/material.dart';
+import 'package:get/get.dart';
+import 'package:mi_utem/config/routes.dart';
+import 'package:mi_utem/helpers/snackbars.dart';
+import 'package:mi_utem/models/usuario.dart';
+import 'package:mi_utem/services/analytics_service.dart';
+import 'package:mi_utem/services/auth_service.dart';
+import 'package:mi_utem/widgets/acerca/dialog/acerca_dialog.dart';
+import 'package:mi_utem/widgets/dialogs/monkey_error_dialog.dart';
+import 'package:mi_utem/widgets/dialogs/not_ready_dialog.dart';
+import 'package:mi_utem/widgets/loading_dialog.dart';
+
+
+class LoginButton extends StatefulWidget {
+
+ final TextEditingController _correoController;
+ final TextEditingController _contraseniaController;
+
+ final GlobalKey _formKey;
+
+ LoginButton({
+ required TextEditingController correoController,
+ required TextEditingController contraseniaController,
+ required GlobalKey formKey,
+ }) :
+ _correoController = correoController,
+ _contraseniaController = contraseniaController,
+ _formKey = formKey;
+
+ @override
+ _LoginButtonState createState() => _LoginButtonState();
+
+}
+
+class _LoginButtonState extends State {
+
+ @override
+ Widget build(BuildContext context) {
+ return TextButton(
+ onPressed: () => _login(),
+ child: Text("Iniciar"),
+ );
+ }
+
+ Future _login() async {
+ final correo = widget._correoController.text;
+ final contrasenia = widget._contraseniaController.text;
+
+ if (correo == "error@utem.cl") {
+ Get.dialog(MonkeyErrorDialog());
+ return;
+ } else if (correo == "test@utem.cl" && contrasenia == "test") {
+ showDefaultSnackbar("Error", "Usuario o contraseña incorrecta");
+ return;
+ }
+
+ if(widget._formKey.currentState?.validate() == false) {
+ return;
+ }
+
+ Get.dialog(LoadingDialog(), barrierDismissible: false);
+
+ try {
+ bool esPrimeraVez = await AuthService.esPrimeraVez();
+ Usuario usuario = await AuthService.login(correo, contrasenia, true);
+
+ AnalyticsService.logEvent('login');
+ AnalyticsService.setUser(usuario);
+
+ Get.toNamed(Routes.home);
+
+ if (esPrimeraVez) {
+ Get.dialog(AcercaDialog());
+ }
+ } on DioError catch (e) {
+ print(e.message);
+ Get.back();
+ if (e.response?.statusCode == 403) {
+ if (e.response?.data["codigoInterno"]?.toString() == "4") {
+ Get.dialog(NotReadyDialog());
+ } else {
+ showDefaultSnackbar("Error", "Usuario o contraseña incorrecta");
+ }
+ } else if (e.response?.statusCode != null && e.response!.statusCode.toString().startsWith("5")) {
+ print(e.response?.data);
+ Get.dialog(MonkeyErrorDialog());
+ } else {
+ print(e.response?.data);
+ showDefaultSnackbar("Error", "Ocurrió un error inesperado 😢");
+ }
+ } catch (e) {
+ print(e.toString());
+ Get.back();
+ showDefaultSnackbar("Error", "Ocurrió un error inesperado 😢");
+ }
+ }
+}
\ No newline at end of file
From b351354f408b87098be31fbc180176aca0f8923a Mon Sep 17 00:00:00 2001
From: Francisco Solis <30329003+Im-Fran@users.noreply.github.com>
Date: Thu, 16 Nov 2023 13:04:45 -0300
Subject: [PATCH 011/194] =?UTF-8?q?wip:=20trabajando=20en=20actualizaci?=
=?UTF-8?q?=C3=B3n=20dentro=20de=20la=20app.?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Signed-off-by: Francisco Solis <30329003+Im-Fran@users.noreply.github.com>
---
lib/services/update_service.dart | 18 ++++++++++++++++--
pubspec.lock | 8 ++++++++
pubspec.yaml | 3 ++-
3 files changed, 26 insertions(+), 3 deletions(-)
diff --git a/lib/services/update_service.dart b/lib/services/update_service.dart
index 2f9c8c7..6013ba0 100644
--- a/lib/services/update_service.dart
+++ b/lib/services/update_service.dart
@@ -1,5 +1,14 @@
-import 'package:flutter/scheduler.dart';
+import 'dart:io';
+import 'package:flutter/scheduler.dart';
+import 'package:in_app_update/in_app_update.dart';
+
+/*
+ * Clase que se encarga de verificar si hay una nueva versión de la aplicación
+ * y de actualizarla si es necesario.
+ *
+ * Para iOS muestra una notificación de que hay una nueva versión disponible.
+ */
class UpdateService {
UpdateService(){
@@ -41,6 +50,11 @@ class UpdateService {
} */
Future _checkAndPerformUpdate() async {
-
+ if (Platform.isAndroid) {
+ final AppUpdateInfo appUpdateInfo = await InAppUpdate.checkForUpdate();
+ if (appUpdateInfo.immediateUpdateAllowed) {
+ await InAppUpdate.performImmediateUpdate();
+ }
+ }
}
}
\ No newline at end of file
diff --git a/pubspec.lock b/pubspec.lock
index 0f9c2fd..80babec 100644
--- a/pubspec.lock
+++ b/pubspec.lock
@@ -937,6 +937,14 @@ packages:
url: "https://pub.dev"
source: hosted
version: "2.0.4"
+ in_app_update:
+ dependency: "direct main"
+ description:
+ name: in_app_update
+ sha256: b6ccb757281a96a4b18536f68fe2567aeca865134218719364212da8fe94615c
+ url: "https://pub.dev"
+ source: hosted
+ version: "4.2.2"
intl:
dependency: "direct main"
description:
diff --git a/pubspec.yaml b/pubspec.yaml
index 4a125cb..f680e9b 100644
--- a/pubspec.yaml
+++ b/pubspec.yaml
@@ -3,7 +3,7 @@ description: Plataforma académica para estudiantes de la Universidad Tecnológi
Metropolitana (UTEM)
publish_to: none
-version: 2.11.2
+version: 2.11.10
environment:
sdk: ">=2.14.4 <3.0.0"
@@ -73,6 +73,7 @@ dependencies:
shared_preferences: ^2.0.20
background_fetch: ^1.1.5
flutter_uxcam: ^2.3.0
+ in_app_update: ^4.2.2
dependency_overrides:
qr: ^3.0.0
From 9c1e896639f427a72e8c384ab5740f28165f5f00 Mon Sep 17 00:00:00 2001
From: Francisco Solis <30329003+Im-Fran@users.noreply.github.com>
Date: Fri, 17 Nov 2023 14:30:29 -0300
Subject: [PATCH 012/194] patch: reducido lista de asignaturas y usuario_screen
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
* Se redujo la lista de asignaturas a distintos widgets
* Se mejoró la pantalla de usuario.
* Se arreglaron algunos widgets que importaban archivos relativos en lugar de usar el package:mi_utem
Signed-off-by: Francisco Solis <30329003+Im-Fran@users.noreply.github.com>
---
.../asignatura/asignatura_resumen_tab.dart | 45 +---
.../asignatura/asignaturas_lista_screen.dart | 95 +------
lib/screens/usuario_screen.dart | 235 ++++++++----------
lib/widgets/acerca/club/acerca_club.dart | 4 +-
.../club/acerca_club_desarrolladores.dart | 13 +-
.../dialog/acerca_dialog_action_button.dart | 3 +-
.../lista/asignatura_list_tile.dart | 53 ++++
.../asignatura/lista/lista_asignaturas.dart | 19 ++
.../lista/sin_asignaturas_mensaje.dart | 24 ++
lib/widgets/field_list_tile.dart | 46 ++--
lib/widgets/login_screen/creditos_app.dart | 5 +-
.../login_screen/formulario_credenciales.dart | 3 +-
12 files changed, 244 insertions(+), 301 deletions(-)
create mode 100644 lib/widgets/asignatura/lista/asignatura_list_tile.dart
create mode 100644 lib/widgets/asignatura/lista/lista_asignaturas.dart
create mode 100644 lib/widgets/asignatura/lista/sin_asignaturas_mensaje.dart
diff --git a/lib/screens/asignatura/asignatura_resumen_tab.dart b/lib/screens/asignatura/asignatura_resumen_tab.dart
index 497f019..c93b79b 100644
--- a/lib/screens/asignatura/asignatura_resumen_tab.dart
+++ b/lib/screens/asignatura/asignatura_resumen_tab.dart
@@ -57,39 +57,18 @@ class AsignaturaResumenTab extends StatelessWidget {
),
],
Divider(height: 5, indent: 20, endIndent: 20),
- FieldListTile(
- title: "Docente",
- value: asignatura?.docente ?? "Sin docente",
- // trailing: _asignatura.docente != null
- // ? Badge(
- // shape: BadgeShape.square,
- // borderRadius: BorderRadius.circular(10),
- // padding: EdgeInsets.symmetric(
- // horizontal: 6, vertical: 3),
- // elevation: 0,
- // badgeContent: Text(
- // 'Nuevo',
- // style: TextStyle(
- // color: Colors.white,
- // fontSize: 10,
- // fontWeight: FontWeight.bold,
- // ),
- // ),
- // )
- // : null,
- // onTap: _asignatura.docente != null
- // ? () async {
- // await Get.to(() =>
- // UsuarioScreen(
- // tipo: 2,
- // query: {
- // "nombre": _asignatura.docente
- // },
- // asignatura: widget.asignatura,
- // ),
- // );
- // }
- // : null,
+ GestureDetector(
+ child: FieldListTile(
+ title: "Docente",
+ value: asignatura?.docente?.split(" ").where((element) => int.tryParse(element) == null).join(" ") ?? "Sin docente", // Se filtran enteros, al parecer hay algunos textos que incluyen un identificador.
+ ),
+ onTap: () async {
+ /*await Get.to(() => UsuarioScreen(
+ tipo: 2,
+ query: { "nombre": asignatura?.docente },
+ asignatura: asignatura,
+ ));*/
+ },
),
Divider(height: 5, indent: 20, endIndent: 20),
if (asignatura?.tipoAsignatura != null) ...[
diff --git a/lib/screens/asignatura/asignaturas_lista_screen.dart b/lib/screens/asignatura/asignaturas_lista_screen.dart
index cbad3f2..f343080 100644
--- a/lib/screens/asignatura/asignaturas_lista_screen.dart
+++ b/lib/screens/asignatura/asignaturas_lista_screen.dart
@@ -3,11 +3,10 @@ import 'package:get/get.dart';
import 'package:mdi/mdi.dart';
import 'package:mi_utem/config/routes.dart';
import 'package:mi_utem/controllers/asignatura/asignaturas_controller.dart';
-import 'package:mi_utem/models/asignatura.dart';
import 'package:mi_utem/services/remote_config/remote_config.dart';
-import 'package:mi_utem/themes/theme.dart';
+import 'package:mi_utem/widgets/asignatura/lista/lista_asignaturas.dart';
+import 'package:mi_utem/widgets/asignatura/lista/sin_asignaturas_mensaje.dart';
import 'package:mi_utem/widgets/custom_app_bar.dart';
-import 'package:mi_utem/widgets/custom_error_widget.dart';
import 'package:mi_utem/widgets/loading_indicator.dart';
import 'package:mi_utem/widgets/pull_to_refresh.dart';
@@ -32,47 +31,16 @@ class AsignaturasListaScreen extends GetView {
IconButton(
icon: Icon(Mdi.calculator),
tooltip: "Calculadora",
- onPressed: () {
- Get.toNamed(
- Routes.calculadoraNotas,
- );
- },
+ onPressed: () => Get.toNamed(Routes.calculadoraNotas),
),
]
: [],
),
body: PullToRefresh(
- onRefresh: () async {
- await _onRefresh();
- },
+ onRefresh: () async => await _onRefresh(),
child: controller.obx(
- (asignaturas) => asignaturas == null || asignaturas.isEmpty
- ? Center(
- child: SingleChildScrollView(
- physics: AlwaysScrollableScrollPhysics(),
- child: CustomErrorWidget(
- emoji: "🤔",
- title: "Parece que no se encontraron asignaturas",
- ),
- ),
- )
- : ListView.builder(
- physics: AlwaysScrollableScrollPhysics(),
- itemBuilder: (BuildContext context, int i) {
- Asignatura asignatura = asignaturas[i];
- return AsignaturaListTile(asignatura: asignatura);
- },
- itemCount: asignaturas.length,
- ),
- onError: (error) => Center(
- child: SingleChildScrollView(
- physics: AlwaysScrollableScrollPhysics(),
- child: CustomErrorWidget(
- emoji: "🤔",
- title: "Ocurrió un error al obtener las asignaturas",
- ),
- ),
- ),
+ (asignaturas) => asignaturas == null || asignaturas.isEmpty ? SinAsignaturasMensaje(mensaje: "Parece que no se encontraron asignaturas.", emoji: "🤔") : ListaAsignaturas(asignaturas: asignaturas),
+ onError: (error) => SinAsignaturasMensaje(mensaje: "Ocurrió un error al obtener las asignaturas", emoji: "😢"),
onLoading: Container(
padding: EdgeInsets.all(20),
child: Column(
@@ -91,54 +59,3 @@ class AsignaturasListaScreen extends GetView {
);
}
}
-
-class AsignaturaListTile extends StatelessWidget {
- const AsignaturaListTile({
- Key? key,
- required this.asignatura,
- }) : super(key: key);
-
- final Asignatura asignatura;
-
- @override
- Widget build(BuildContext context) {
- final ThemeData theme = MainTheme.theme;
-
- return Padding(
- padding: const EdgeInsets.symmetric(
- horizontal: 10.0,
- ),
- child: Card(
- child: InkWell(
- onTap: () => Get.toNamed('${Routes.asignatura}/${asignatura.id}'),
- child: Container(
- padding: EdgeInsets.all(20),
- width: double.infinity,
- child: Column(
- mainAxisAlignment: MainAxisAlignment.center,
- crossAxisAlignment: CrossAxisAlignment.start,
- children: [
- Text(
- asignatura.nombre!,
- maxLines: 2,
- overflow: TextOverflow.ellipsis,
- style: theme.textTheme.titleMedium,
- textAlign: TextAlign.start,
- ),
- Container(height: 10),
- Row(
- mainAxisSize: MainAxisSize.max,
- mainAxisAlignment: MainAxisAlignment.spaceBetween,
- children: [
- Text(asignatura.codigo!),
- Text(asignatura.tipoHora!),
- ],
- )
- ],
- ),
- ),
- ),
- ),
- );
- }
-}
diff --git a/lib/screens/usuario_screen.dart b/lib/screens/usuario_screen.dart
index 33e7fdc..d8c2589 100644
--- a/lib/screens/usuario_screen.dart
+++ b/lib/screens/usuario_screen.dart
@@ -101,141 +101,47 @@ class _UsuarioScreenState extends State {
List get _datosPersonales {
List lista = [];
- if (_usuario != null) {
- if (_usuario!.nombre != null && _usuario!.nombre!.isNotEmpty) {
- lista.add(ListTile(
- title: Text(
- "Nombre",
- style: TextStyle(
- color: Colors.grey,
- ),
- ),
- subtitle: Text(
- _usuario!.nombreCompleto!,
- style: TextStyle(
- color: Colors.grey[900],
- fontSize: 18,
- ),
+ if(_usuario == null) {
+ return lista;
+ }
+
+ if (_usuario?.nombre?.isEmpty == false) {
+ lista.add(ListTile(
+ title: Text("Nombre",
+ style: TextStyle(color: Colors.grey),
+ ),
+ subtitle: Text(_usuario!.nombreCompleto!,
+ style: TextStyle(
+ color: Colors.grey[900],
+ fontSize: 18,
),
- ));
- } else {
- if (_usuario!.nombres != null && _usuario!.nombres!.isNotEmpty) {
- lista.add(
- ListTile(
- title: Text(
- "Nombres",
- style: TextStyle(
- color: Colors.grey,
- ),
- ),
- subtitle: Text(
- _usuario!.nombres!,
- style: TextStyle(
- color: Colors.grey[900],
- fontSize: 18,
- ),
- ),
+ ),
+ ));
+ } else {
+ if (_usuario?.nombres?.isEmpty == false) {
+ lista.add(
+ ListTile(
+ title: Text("Nombres",
+ style: TextStyle(color: Colors.grey),
),
- );
- }
-
- if (_usuario!.apellidos != null && _usuario!.apellidos!.isNotEmpty) {
- lista.add(Divider(height: 1));
- lista.add(
- ListTile(
- title: Text(
- "Apellidos",
- style: TextStyle(
- color: Colors.grey,
- ),
- ),
- subtitle: Text(
- _usuario!.apellidos!,
- style: TextStyle(
- color: Colors.grey[900],
- fontSize: 18,
- ),
+ subtitle: Text(_usuario!.nombres!,
+ style: TextStyle(
+ color: Colors.grey[900],
+ fontSize: 18,
),
),
- );
- }
- }
-
- if (_usuario!.correoUtem != null && _usuario!.correoUtem!.isNotEmpty) {
- lista.add(Divider(height: 1));
- lista.add(ListTile(
- title: Text(
- "Correo",
- style: TextStyle(
- color: Colors.grey,
- ),
- ),
- onLongPress: widget.tipo != 0
- ? () async {
- await FlutterClipboard.copy(_usuario!.correoUtem!);
- Get.snackbar(
- "¡Copiado!",
- "Correo copiado al portapapeles",
- colorText: Colors.white,
- backgroundColor: Get.theme.primaryColor,
- snackPosition: SnackPosition.BOTTOM,
- margin: EdgeInsets.all(20),
- );
- }
- : null,
- onTap: widget.tipo != 0
- ? () async {
- await launchUrl(
- Uri.parse(
- "mailto:${_usuario!.correoUtem}",
- ),
- );
- }
- : null,
- subtitle: Text(
- _usuario!.correoUtem ?? "",
- style: TextStyle(
- color: Colors.grey[900],
- fontSize: 18,
- ),
),
- ));
+ );
}
- if (_usuario!.correoPersonal != null &&
- _usuario!.correoPersonal!.isNotEmpty) {
+
+ if (_usuario?.apellidos?.isEmpty == false) {
lista.add(Divider(height: 1));
lista.add(
ListTile(
- title: Text(
- "Correo",
- style: TextStyle(
- color: Colors.grey,
- ),
+ title: Text("Apellidos",
+ style: TextStyle(color: Colors.grey),
),
- onLongPress: widget.tipo != 0
- ? () async {
- await FlutterClipboard.copy(_usuario!.correoPersonal!);
- Get.snackbar(
- "¡Copiado!",
- "Correo copiado al portapapeles",
- colorText: Colors.white,
- backgroundColor: Get.theme.primaryColor,
- snackPosition: SnackPosition.BOTTOM,
- margin: EdgeInsets.all(20),
- );
- }
- : null,
- onTap: widget.tipo != 0
- ? () async {
- await launchUrl(
- Uri.parse(
- "mailto:${_usuario!.correoPersonal}",
- ),
- );
- }
- : null,
- subtitle: Text(
- _usuario!.correoPersonal ?? "",
+ subtitle: Text(_usuario!.apellidos!,
style: TextStyle(
color: Colors.grey[900],
fontSize: 18,
@@ -244,25 +150,80 @@ class _UsuarioScreenState extends State {
),
);
}
+ }
- if (widget.tipo == 0 && _usuario!.rut != null) {
- lista.add(Divider(height: 1));
- lista.add(ListTile(
- title: Text(
- "RUT",
- style: TextStyle(
- color: Colors.grey,
- ),
+ if (_usuario?.correoUtem?.isEmpty == false) {
+ lista.add(Divider(height: 1));
+ lista.add(ListTile(
+ title: Text("Correo Institucional",
+ style: TextStyle(color: Colors.grey),
+ ),
+ onLongPress: widget.tipo != 0 ? () async {
+ await FlutterClipboard.copy(_usuario!.correoUtem!);
+ Get.snackbar(
+ "¡Copiado!",
+ "Correo copiado al portapapeles",
+ colorText: Colors.white,
+ backgroundColor: Get.theme.primaryColor,
+ snackPosition: SnackPosition.BOTTOM,
+ margin: EdgeInsets.all(20),
+ );
+ } : null,
+ onTap: widget.tipo != 0 ? () async {
+ await launchUrl(Uri.parse("mailto:${_usuario?.correoUtem ?? ""}"));
+ } : null,
+ subtitle: Text(_usuario!.correoUtem ?? "",
+ style: TextStyle(
+ color: Colors.grey[900],
+ fontSize: 18,
),
- subtitle: Text(
- _usuario!.rut!.formateado(true),
+ ),
+ ));
+ }
+ if (_usuario?.correoPersonal?.isEmpty == false) {
+ lista.add(Divider(height: 1));
+ lista.add(
+ ListTile(
+ title: Text("Correo Personal",
+ style: TextStyle(color: Colors.grey),
+ ),
+ onLongPress: widget.tipo != 0 ? () async {
+ await FlutterClipboard.copy(_usuario!.correoPersonal!);
+ Get.snackbar(
+ "¡Copiado!",
+ "Correo copiado al portapapeles",
+ colorText: Colors.white,
+ backgroundColor: Get.theme.primaryColor,
+ snackPosition: SnackPosition.BOTTOM,
+ margin: EdgeInsets.all(20),
+ );
+ } : null,
+ onTap: widget.tipo != 0 ? () async {
+ await launchUrl(Uri.parse("mailto:${_usuario?.correoPersonal ?? ""}"));
+ } : null,
+ subtitle: Text(_usuario!.correoPersonal ?? "",
style: TextStyle(
color: Colors.grey[900],
fontSize: 18,
),
),
- ));
- }
+ ),
+ );
+ }
+
+ if (widget.tipo == 0 && _usuario!.rut != null) {
+ lista.add(Divider(height: 1));
+ lista.add(ListTile(
+ title: Text("RUT",
+ style: TextStyle(color: Colors.grey),
+ ),
+ subtitle: Text(_usuario!.rut!.formateado(true),
+ style: TextStyle(
+ color: Colors.grey[900],
+ fontSize: 18,
+ ),
+ ),
+ ));
}
return lista;
diff --git a/lib/widgets/acerca/club/acerca_club.dart b/lib/widgets/acerca/club/acerca_club.dart
index 18c16d9..218e978 100644
--- a/lib/widgets/acerca/club/acerca_club.dart
+++ b/lib/widgets/acerca/club/acerca_club.dart
@@ -1,8 +1,8 @@
import 'package:flutter/material.dart';
import 'package:flutter_markdown/flutter_markdown.dart';
+import 'package:mi_utem/services/remote_config/remote_config.dart';
+import 'package:mi_utem/widgets/default_network_image.dart';
-import '../../../services/remote_config/remote_config.dart';
-import '../../default_network_image.dart';
import 'acerca_club_redes.dart';
class AcercaClub extends StatelessWidget {
diff --git a/lib/widgets/acerca/club/acerca_club_desarrolladores.dart b/lib/widgets/acerca/club/acerca_club_desarrolladores.dart
index 9f06b87..1e9dd22 100644
--- a/lib/widgets/acerca/club/acerca_club_desarrolladores.dart
+++ b/lib/widgets/acerca/club/acerca_club_desarrolladores.dart
@@ -3,15 +3,14 @@ import 'dart:convert';
import 'package:flutter/material.dart';
import 'package:font_awesome_flutter/font_awesome_flutter.dart';
import 'package:get/get.dart';
+import 'package:mi_utem/config/routes.dart';
+import 'package:mi_utem/models/usuario.dart';
+import 'package:mi_utem/services/analytics_service.dart';
+import 'package:mi_utem/services/remote_config/remote_config.dart';
+import 'package:mi_utem/widgets/image_view_screen.dart';
+import 'package:mi_utem/widgets/profile_photo.dart';
import 'package:url_launcher/url_launcher.dart';
-import '../../../config/routes.dart';
-import '../../../models/usuario.dart';
-import '../../../services/analytics_service.dart';
-import '../../../services/remote_config/remote_config.dart';
-import '../../image_view_screen.dart';
-import '../../profile_photo.dart';
-
class AcercaClubDesarrolladores extends StatelessWidget {
@override
diff --git a/lib/widgets/acerca/dialog/acerca_dialog_action_button.dart b/lib/widgets/acerca/dialog/acerca_dialog_action_button.dart
index 26db494..ac961dd 100644
--- a/lib/widgets/acerca/dialog/acerca_dialog_action_button.dart
+++ b/lib/widgets/acerca/dialog/acerca_dialog_action_button.dart
@@ -1,7 +1,6 @@
import 'package:flutter/material.dart';
import 'package:get/get.dart';
-
-import '../../../config/routes.dart';
+import 'package:mi_utem/config/routes.dart';
class AcercaDialogActionButton extends StatefulWidget {
diff --git a/lib/widgets/asignatura/lista/asignatura_list_tile.dart b/lib/widgets/asignatura/lista/asignatura_list_tile.dart
new file mode 100644
index 0000000..2cbda6e
--- /dev/null
+++ b/lib/widgets/asignatura/lista/asignatura_list_tile.dart
@@ -0,0 +1,53 @@
+import 'package:flutter/material.dart';
+import 'package:get/get.dart';
+import 'package:mi_utem/config/routes.dart';
+import 'package:mi_utem/models/asignatura.dart';
+import 'package:mi_utem/themes/theme.dart';
+
+class AsignaturaListTile extends StatelessWidget {
+
+ const AsignaturaListTile({
+ Key? key,
+ required this.asignatura,
+ }) : super(key: key);
+
+ final Asignatura asignatura;
+
+ @override
+ Widget build(BuildContext context) => Padding(
+ padding: const EdgeInsets.symmetric(
+ horizontal: 10.0,
+ ),
+ child: Card(
+ child: InkWell(
+ onTap: () => Get.toNamed('${Routes.asignatura}/${asignatura.id}'),
+ child: Container(
+ padding: EdgeInsets.all(20),
+ width: double.infinity,
+ child: Column(
+ mainAxisAlignment: MainAxisAlignment.center,
+ crossAxisAlignment: CrossAxisAlignment.start,
+ children: [
+ Text(
+ asignatura.nombre!,
+ maxLines: 2,
+ overflow: TextOverflow.ellipsis,
+ style: MainTheme.theme.textTheme.titleMedium,
+ textAlign: TextAlign.start,
+ ),
+ Container(height: 10),
+ Row(
+ mainAxisSize: MainAxisSize.max,
+ mainAxisAlignment: MainAxisAlignment.spaceBetween,
+ children: [
+ Text(asignatura.codigo!),
+ Text(asignatura.tipoHora!),
+ ],
+ )
+ ],
+ ),
+ ),
+ ),
+ ),
+ );
+}
\ No newline at end of file
diff --git a/lib/widgets/asignatura/lista/lista_asignaturas.dart b/lib/widgets/asignatura/lista/lista_asignaturas.dart
new file mode 100644
index 0000000..5679e37
--- /dev/null
+++ b/lib/widgets/asignatura/lista/lista_asignaturas.dart
@@ -0,0 +1,19 @@
+import 'package:flutter/material.dart';
+import 'package:mi_utem/models/asignatura.dart';
+import 'package:mi_utem/widgets/asignatura/lista/asignatura_list_tile.dart';
+
+class ListaAsignaturas extends StatelessWidget {
+ final List asignaturas;
+
+ const ListaAsignaturas({
+ Key? key,
+ required this.asignaturas,
+ }) : super(key: key);
+
+ @override
+ Widget build(BuildContext context) => ListView.builder(
+ physics: AlwaysScrollableScrollPhysics(),
+ itemBuilder: (BuildContext context, int i) => AsignaturaListTile(asignatura: asignaturas[i]),
+ itemCount: asignaturas.length,
+ );
+}
diff --git a/lib/widgets/asignatura/lista/sin_asignaturas_mensaje.dart b/lib/widgets/asignatura/lista/sin_asignaturas_mensaje.dart
new file mode 100644
index 0000000..a161909
--- /dev/null
+++ b/lib/widgets/asignatura/lista/sin_asignaturas_mensaje.dart
@@ -0,0 +1,24 @@
+import 'package:flutter/material.dart';
+import 'package:mi_utem/widgets/custom_error_widget.dart';
+
+class SinAsignaturasMensaje extends StatelessWidget {
+
+ final String mensaje, emoji;
+
+ const SinAsignaturasMensaje({
+ Key? key,
+ required this.mensaje,
+ required this.emoji,
+ }) : super(key: key);
+
+ @override
+ Widget build(BuildContext context) => Center(
+ child: SingleChildScrollView(
+ physics: AlwaysScrollableScrollPhysics(),
+ child: CustomErrorWidget(
+ emoji: emoji,
+ title: mensaje,
+ ),
+ ),
+ );
+}
\ No newline at end of file
diff --git a/lib/widgets/field_list_tile.dart b/lib/widgets/field_list_tile.dart
index 6074ca2..5f3bfd5 100644
--- a/lib/widgets/field_list_tile.dart
+++ b/lib/widgets/field_list_tile.dart
@@ -17,31 +17,25 @@ class FieldListTile extends StatelessWidget {
final EdgeInsetsGeometry padding;
@override
- Widget build(BuildContext context) {
- return Padding(
- padding: padding,
- child: Row(
- children: [
- Expanded(
- child: Column(
- crossAxisAlignment: CrossAxisAlignment.start,
- children: [
- Text(
- title.toUpperCase(),
- maxLines: 2,
- style: Get.textTheme.bodySmall!.copyWith(
- fontWeight: FontWeight.bold,
- ),
- ),
- Text(
- value ?? "Sin información",
- style: Get.textTheme.bodyMedium,
- ),
- ],
- ),
+ Widget build(BuildContext context) => Padding(
+ padding: padding,
+ child: Row(
+ children: [
+ Expanded(
+ child: Column(
+ crossAxisAlignment: CrossAxisAlignment.start,
+ children: [
+ Text(title.toUpperCase(),
+ maxLines: 2,
+ style: Get.textTheme.bodySmall!.copyWith(fontWeight: FontWeight.bold),
+ ),
+ Text(value ?? "Sin información",
+ style: Get.textTheme.bodyMedium,
+ ),
+ ],
),
- ],
- ),
- );
- }
+ ),
+ ],
+ ),
+ );
}
diff --git a/lib/widgets/login_screen/creditos_app.dart b/lib/widgets/login_screen/creditos_app.dart
index c28c3cb..1b2fd64 100644
--- a/lib/widgets/login_screen/creditos_app.dart
+++ b/lib/widgets/login_screen/creditos_app.dart
@@ -4,9 +4,8 @@ import 'dart:math';
import 'package:flutter/material.dart';
import 'package:flutter_markdown/flutter_markdown.dart';
import 'package:get/get.dart';
-
-import '../../config/routes.dart';
-import '../../services/remote_config/remote_config.dart';
+import 'package:mi_utem/config/routes.dart';
+import 'package:mi_utem/services/remote_config/remote_config.dart';
class CreditosApp extends StatelessWidget {
diff --git a/lib/widgets/login_screen/formulario_credenciales.dart b/lib/widgets/login_screen/formulario_credenciales.dart
index 58e1d91..19b3fbf 100644
--- a/lib/widgets/login_screen/formulario_credenciales.dart
+++ b/lib/widgets/login_screen/formulario_credenciales.dart
@@ -1,7 +1,6 @@
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
-
-import '../login_text_form_field.dart';
+import 'package:mi_utem/widgets/login_text_form_field.dart';
class FormularioCredenciales extends StatefulWidget {
From 1dd2555867ede7a264d359d779da65e5b21e78e1 Mon Sep 17 00:00:00 2001
From: Francisco Solis <30329003+Im-Fran@users.noreply.github.com>
Date: Fri, 15 Dec 2023 12:57:30 -0300
Subject: [PATCH 013/194] patch: actualizados servicios de noticias y widgets *
Se ha actualizado a nuestra API de noticias * Se han mejorado y reducido los
widgets de noticias * Se ha cambiado el servicio de noticias para usar
GetConnect
Signed-off-by: Francisco Solis <30329003+Im-Fran@users.noreply.github.com>
---
lib/config/constants.dart | 6 +-
lib/models/noticia.dart | 80 +++++--------------
lib/screens/main_screen.dart | 4 +-
lib/services/noticias_service.dart | 37 ++-------
lib/widgets/noticia_card.dart | 75 -----------------
lib/widgets/noticias/NoticiaCardWidget.dart | 77 ++++++++++++++++++
.../NoticiasCarruselWidget.dart} | 43 +++-------
7 files changed, 116 insertions(+), 206 deletions(-)
delete mode 100644 lib/widgets/noticia_card.dart
create mode 100644 lib/widgets/noticias/NoticiaCardWidget.dart
rename lib/widgets/{noticias_carrusel.dart => noticias/NoticiasCarruselWidget.dart} (57%)
diff --git a/lib/config/constants.dart b/lib/config/constants.dart
index 08a447a..1568527 100644
--- a/lib/config/constants.dart
+++ b/lib/config/constants.dart
@@ -1,6 +1,8 @@
+import 'package:flutter_dotenv/flutter_dotenv.dart';
+
class Constants {
- static const String sentryDsn =
- 'https://0af59b2ad2b44f4e8c9cad4ea8d5f32e@o507661.ingest.sentry.io/5599080';
+ static const String sentryDsn = 'https://0af59b2ad2b44f4e8c9cad4ea8d5f32e@o507661.ingest.sentry.io/5599080';
static const String uxCamDevKey = '0y6p88obpgiug1g';
static const String uxCamProdKey = 'fxkjj5ulr7vb4yf';
+ static String apiUrl = bool.fromEnvironment('dart.vm.product') ? 'https://api.exdev.cl' : (dotenv.env['MI_UTEM_API_DEBUG'] ?? 'https://api.exdev.cl');
}
diff --git a/lib/models/noticia.dart b/lib/models/noticia.dart
index 461b4e2..dfc1fa2 100644
--- a/lib/models/noticia.dart
+++ b/lib/models/noticia.dart
@@ -1,67 +1,25 @@
-import 'package:html/parser.dart';
-
class Noticia {
- int? id, featuredMediaId;
- String? titulo, subtitulo, link;
- FeaturedMedia? featuredMedia;
-
-
- Noticia(
- this.id,
- this.titulo,
- this.subtitulo,
- this.link,
- this.featuredMediaId
- );
-
- Noticia.empty()
- : id = null,
- titulo = "",
- subtitulo = "",
- link = "",
- featuredMedia = FeaturedMedia.empty(),
- featuredMediaId = null;
-
- factory Noticia.fromJson(Map json) {
- return Noticia(
- json['id'],
- parse(json['title']['rendered']).body!.text.trim(),
- parse(json['excerpt']['rendered']).body!.text.trim(),
- json['link'],
- json['featured_media']
- );
- }
+ int? id;
+ String? titulo, subtitulo, link, imagen;
- static List fromJsonList(List json) {
- List lista = [];
- for (var elemento in json) {
- lista.add(Noticia.fromJson(elemento));
- }
- return lista;
- }
-}
+ Noticia({this.id, this.titulo, this.subtitulo, this.link, this.imagen});
-class FeaturedMedia {
- int? id;
- String? guid;
-
-
- FeaturedMedia({
- this.id,
- this.guid
- });
+ Noticia.empty()
+ : id = null,
+ titulo = "",
+ subtitulo = "",
+ link = "",
+ imagen = "";
- factory FeaturedMedia.empty() {
- return FeaturedMedia(
- id: null,
- guid: "https://noticias.utem.cl/wp-content/uploads/2017/07/en-preparacion.jpg"
- );
- }
+ factory Noticia.fromApiJson(Map json) =>
+ Noticia(
+ id: json["id"],
+ titulo: json["titulo"],
+ subtitulo: json["subtitulo"],
+ link: json["link"],
+ imagen: json["imagen"],
+ );
- factory FeaturedMedia.fromJson(Map json) {
- return FeaturedMedia(
- id: json['id'],
- guid: json['guid'] != null && json['guid']['rendered'] != null && json['guid']['rendered'] != "" ? json['guid']['rendered'] : "https://noticias.utem.cl/wp-content/uploads/2017/07/en-preparacion.jpg"
- );
- }
+ static List fromApiJsonList(List json) =>
+ json.map((e) => Noticia.fromApiJson(e)).toList();
}
diff --git a/lib/screens/main_screen.dart b/lib/screens/main_screen.dart
index bd0759d..7639dd7 100644
--- a/lib/screens/main_screen.dart
+++ b/lib/screens/main_screen.dart
@@ -14,7 +14,7 @@ import "package:mi_utem/services/review_service.dart";
import 'package:mi_utem/widgets/banners_section.dart';
import "package:mi_utem/widgets/custom_app_bar.dart";
import "package:mi_utem/widgets/custom_drawer.dart";
-import "package:mi_utem/widgets/noticias_carrusel.dart";
+import "package:mi_utem/widgets/noticias/NoticiasCarruselWidget.dart";
import "package:mi_utem/widgets/permisos_section.dart";
import "package:mi_utem/widgets/quick_menu_section.dart";
@@ -105,7 +105,7 @@ class _MainScreenState extends State {
),
Container(height: 20),
],
- NoticiasSection(),
+ NoticiasCarruselWidget(),
],
),
),
diff --git a/lib/services/noticias_service.dart b/lib/services/noticias_service.dart
index 3ae6931..aaee8e4 100644
--- a/lib/services/noticias_service.dart
+++ b/lib/services/noticias_service.dart
@@ -1,38 +1,11 @@
-import 'package:dio/dio.dart';
+import 'package:get/get.dart';
+import 'package:mi_utem/config/constants.dart';
import 'package:mi_utem/models/noticia.dart';
-import 'package:mi_utem/utils/dio_wordpress_client.dart';
-class NoticiasService {
- static final Dio _dio = DioWordpressClient.initDio;
+class NoticiasService extends GetConnect {
- static Future> getNoticias() async {
- String uri = "/posts";
+ Future> getNoticias() async =>
+ get("${Constants.apiUrl}/v1/noticias").then((response) => response.statusCode == 200 ? Noticia.fromApiJsonList(response.body) : []);
- try {
- Response response = await _dio.get(uri);
-
- List noticias = Noticia.fromJsonList(response.data);
-
- return await Future.wait(noticias.map((noticia) async {
- String uri = '/media/${noticia.featuredMediaId}';
- try {
- if (noticia.featuredMediaId != null && noticia.featuredMediaId != 0) {
- Response response = await _dio.get(uri);
- noticia.featuredMedia = FeaturedMedia.fromJson(response.data);
- } else {
- noticia.featuredMedia = FeaturedMedia.empty();
- }
- return noticia;
- } catch (e) {
- print(e);
- noticia.featuredMedia = FeaturedMedia.empty();
- return noticia;
- }
- }).toList());
- } on DioError catch (e) {
- print(e.message);
- throw e;
- }
- }
}
diff --git a/lib/widgets/noticia_card.dart b/lib/widgets/noticia_card.dart
deleted file mode 100644
index a2c97f1..0000000
--- a/lib/widgets/noticia_card.dart
+++ /dev/null
@@ -1,75 +0,0 @@
-import 'package:flutter/material.dart';
-
-import 'package:get/get.dart';
-import 'package:mdi/mdi.dart';
-
-class NoticiaCard extends StatelessWidget {
- const NoticiaCard(
- {Key? key, this.titulo, this.subtitulo, this.imagenUrl, this.onTap})
- : super(key: key);
-
- final String? titulo, subtitulo, imagenUrl;
- final Function? onTap;
-
- @override
- Widget build(BuildContext context) {
- return SizedBox(
- height: 200,
- width: 200,
- child: Card(
- child: Material(
- color: Colors.transparent,
- child: InkWell(
- onTap: () => this.onTap!(),
- borderRadius: BorderRadius.all(Radius.circular(15)),
- child: Column(
- crossAxisAlignment: CrossAxisAlignment.center,
- mainAxisSize: MainAxisSize.min,
- children: [
- imagenUrl != null
- ? Image.network(
- imagenUrl!,
- height: 110,
- fit: BoxFit.cover,
- )
- : Container(
- height: 110,
- width: double.infinity,
- color: Colors.grey,
- child: Icon(
- Mdi.imageOff,
- color: Colors.white,
- ),
- ),
- Container(
- padding: const EdgeInsets.symmetric(horizontal: 10),
- height: 70,
- child: Column(
- crossAxisAlignment: CrossAxisAlignment.center,
- children: [
- Spacer(),
- Text(
- titulo!,
- maxLines: 3,
- overflow: TextOverflow.ellipsis,
- style: Get.theme.textTheme.bodyLarge,
- ),
-
- /* Text(
- subtitulo,
- overflow: TextOverflow.ellipsis,
- style: Get.theme.textTheme.bodyText2,
- maxLines: 2
- ) */
- Spacer(),
- ],
- ),
- )
- ],
- ),
- ),
- ),
- ),
- );
- }
-}
diff --git a/lib/widgets/noticias/NoticiaCardWidget.dart b/lib/widgets/noticias/NoticiaCardWidget.dart
new file mode 100644
index 0000000..0793f0f
--- /dev/null
+++ b/lib/widgets/noticias/NoticiaCardWidget.dart
@@ -0,0 +1,77 @@
+import 'package:flutter/material.dart';
+import 'package:get/get.dart';
+import 'package:mdi/mdi.dart';
+import 'package:mi_utem/models/noticia.dart';
+import 'package:mi_utem/services/analytics_service.dart';
+import 'package:url_launcher/url_launcher.dart';
+
+class NoticiaCardWidget extends StatefulWidget {
+
+ final Noticia _noticia;
+
+ NoticiaCardWidget(this._noticia);
+
+ @override
+ State createState() => _NoticiaCardWidgetState();
+}
+
+class _NoticiaCardWidgetState extends State {
+
+ @override
+ Widget build(BuildContext context) => SizedBox(
+ height: 200,
+ width: 200,
+ child: Card(
+ child: Material(
+ color: Colors.transparent,
+ child: InkWell(
+ onTap: () {
+ AnalyticsService.logEvent("noticia_card_tap");
+ this._launchURL(widget._noticia.link!);
+ },
+ borderRadius: BorderRadius.all(Radius.circular(15)),
+ child: Column(
+ crossAxisAlignment: CrossAxisAlignment.center,
+ mainAxisSize: MainAxisSize.min,
+ children: [
+ widget._noticia.imagen != null ? Image.network(widget._noticia.imagen!, height: 110, fit: BoxFit.cover) : Container(
+ height: 110,
+ width: double.infinity,
+ color: Colors.grey,
+ child: Icon(
+ Mdi.imageOff,
+ color: Colors.white,
+ ),
+ ),
+ Container(
+ padding: const EdgeInsets.symmetric(horizontal: 10),
+ height: 70,
+ child: Column(
+ crossAxisAlignment: CrossAxisAlignment.center,
+ children: [
+ Spacer(),
+ Text(
+ widget._noticia.titulo!,
+ maxLines: 3,
+ overflow: TextOverflow.ellipsis,
+ style: Get.theme.textTheme.bodyLarge,
+ ),
+ Spacer(),
+ ],
+ ),
+ )
+ ],
+ ),
+ ),
+ ),
+ ),
+ );
+
+ Future _launchURL(String url) async {
+ if (await canLaunchUrl(Uri.parse(url))) {
+ await launchUrl(Uri.parse(url));
+ } else {
+ throw 'Could not launch $url';
+ }
+ }
+}
diff --git a/lib/widgets/noticias_carrusel.dart b/lib/widgets/noticias/NoticiasCarruselWidget.dart
similarity index 57%
rename from lib/widgets/noticias_carrusel.dart
rename to lib/widgets/noticias/NoticiasCarruselWidget.dart
index fa0ec57..56eb8d0 100644
--- a/lib/widgets/noticias_carrusel.dart
+++ b/lib/widgets/noticias/NoticiasCarruselWidget.dart
@@ -2,21 +2,19 @@ import 'package:carousel_slider/carousel_slider.dart';
import 'package:flutter/material.dart';
import 'package:get/get.dart';
import 'package:mi_utem/models/noticia.dart';
-import 'package:mi_utem/services/analytics_service.dart';
import 'package:mi_utem/services/noticias_service.dart';
import 'package:mi_utem/widgets/custom_error_widget.dart';
import 'package:mi_utem/widgets/loading_indicator.dart';
-import 'package:mi_utem/widgets/noticia_card.dart';
-import 'package:url_launcher/url_launcher.dart';
+import 'package:mi_utem/widgets/noticias/NoticiaCardWidget.dart';
-class NoticiasSection extends StatefulWidget {
- NoticiasSection({Key? key}) : super(key: key);
+class NoticiasCarruselWidget extends StatefulWidget {
+ NoticiasCarruselWidget({Key? key}) : super(key: key);
@override
- State createState() => _NoticiasSectionState();
+ State createState() => _NoticiasCarruselWidgetState();
}
-class _NoticiasSectionState extends State {
+class _NoticiasCarruselWidgetState extends State {
Future>? _noticiasFuture;
@override
@@ -25,18 +23,7 @@ class _NoticiasSectionState extends State {
_noticiasFuture = _getNoticias();
}
- Future> _getNoticias() async {
- List noticias = await NoticiasService.getNoticias();
- return noticias;
- }
-
- Future _launchURL(String url) async {
- if (await canLaunchUrl(Uri.parse(url))) {
- await launchUrl(Uri.parse(url));
- } else {
- throw 'Could not launch $url';
- }
- }
+ Future> _getNoticias() async => await NoticiasService().getNoticias();
@override
Widget build(BuildContext context) {
@@ -46,8 +33,7 @@ class _NoticiasSectionState extends State {
children: [
Container(
padding: EdgeInsets.symmetric(horizontal: 20),
- child: Text(
- "Noticias".toUpperCase(),
+ child: Text("Noticias".toUpperCase(),
style: Get.textTheme.titleMedium!.copyWith(
fontWeight: FontWeight.bold,
),
@@ -58,9 +44,7 @@ class _NoticiasSectionState extends State {
future: _noticiasFuture,
builder: (context, snapshot) {
if (snapshot.hasError) {
- return CustomErrorWidget(
- title: "Ocurrió un error al obtener las noticias",
- error: snapshot.error);
+ return CustomErrorWidget(title: "Ocurrió un error al obtener las noticias", error: snapshot.error);
} else {
if (snapshot.hasData && snapshot.data!.length > 0) {
List noticias = snapshot.data!;
@@ -71,16 +55,7 @@ class _NoticiasSectionState extends State {
viewportFraction: 0.5,
initialPage: 0,
),
- itemBuilder: (BuildContext context, int i, int rI) =>
- NoticiaCard(
- titulo: noticias[i].titulo,
- subtitulo: noticias[i].subtitulo,
- imagenUrl: noticias[i].featuredMedia?.guid,
- onTap: () {
- AnalyticsService.logEvent("noticia_tap");
- _launchURL(noticias[i].link!);
- },
- ),
+ itemBuilder: (BuildContext context, int i, int rI) => NoticiaCardWidget(noticias[i]),
itemCount: noticias.length,
);
} else {
From 434a6e2cfdd2da1776994199cebb8ed7f7e0fc17 Mon Sep 17 00:00:00 2001
From: Francisco Solis <30329003+Im-Fran@users.noreply.github.com>
Date: Fri, 15 Dec 2023 16:26:40 -0300
Subject: [PATCH 014/194] patch: reducido calculadora de notas * Se redujo la
calculadora de notas a varios widgets
Signed-off-by: Francisco Solis <30329003+Im-Fran@users.noreply.github.com>
---
lib/screens/calculadora_notas_screen.dart | 235 +-----------------
.../calculadora_notas/DisplayNotasWidget.dart | 51 ++++
.../calculadora_notas/EditarNotasWidget.dart | 52 ++++
.../ModoSimulacionWidget.dart | 22 ++
.../NotaExamenDisplayWidget.dart | 52 ++++
.../NotaFinalDisplayWidget.dart | 24 ++
.../NotaPresentacionDisplayWidget.dart | 45 ++++
.../NotasCalculadoraWidget.dart | 40 +++
8 files changed, 290 insertions(+), 231 deletions(-)
create mode 100644 lib/widgets/calculadora_notas/DisplayNotasWidget.dart
create mode 100644 lib/widgets/calculadora_notas/EditarNotasWidget.dart
create mode 100644 lib/widgets/calculadora_notas/ModoSimulacionWidget.dart
create mode 100644 lib/widgets/calculadora_notas/NotaExamenDisplayWidget.dart
create mode 100644 lib/widgets/calculadora_notas/NotaFinalDisplayWidget.dart
create mode 100644 lib/widgets/calculadora_notas/NotaPresentacionDisplayWidget.dart
create mode 100644 lib/widgets/calculadora_notas/NotasCalculadoraWidget.dart
diff --git a/lib/screens/calculadora_notas_screen.dart b/lib/screens/calculadora_notas_screen.dart
index 3324e29..53a5fc4 100644
--- a/lib/screens/calculadora_notas_screen.dart
+++ b/lib/screens/calculadora_notas_screen.dart
@@ -1,11 +1,8 @@
import 'package:flutter/material.dart';
-import 'package:get/get.dart';
import 'package:mi_utem/controllers/calculator_controller.dart';
-import 'package:mi_utem/models/evaluacion.dart';
-import 'package:mi_utem/services/analytics_service.dart';
-import 'package:mi_utem/themes/theme.dart';
+import 'package:mi_utem/widgets/calculadora_notas/DisplayNotasWidget.dart';
+import 'package:mi_utem/widgets/calculadora_notas/EditarNotasWidget.dart';
import 'package:mi_utem/widgets/custom_app_bar.dart';
-import 'package:mi_utem/widgets/nota_list_item.dart';
class CalculadoraNotasScreen extends StatelessWidget {
CalculadoraNotasScreen({
@@ -25,234 +22,10 @@ class CalculadoraNotasScreen extends StatelessWidget {
body: ListView(
padding: EdgeInsets.all(10),
children: [
- Card(
- child: Stack(
- alignment: Alignment.center,
- children: [
- Container(
- padding: EdgeInsets.all(20),
- width: double.infinity,
- child: RotationTransition(
- turns: AlwaysStoppedAnimation(-20 / 360),
- child: Text(
- "Modo simulación".toUpperCase(),
- style: TextStyle(
- color: Colors.grey[200],
- fontWeight: FontWeight.bold,
- fontSize: 25,
- ),
- textAlign: TextAlign.center,
- ),
- ),
- ),
- Container(
- padding: EdgeInsets.symmetric(vertical: 20, horizontal: 30),
- child: Row(
- crossAxisAlignment: CrossAxisAlignment.center,
- mainAxisAlignment: MainAxisAlignment.spaceBetween,
- children: [
- Column(
- children: [
- Obx(
- () => Text(
- controller.calculatedFinalGrade
- ?.toStringAsFixed(1) ??
- "--",
- style: TextStyle(
- fontSize: 40,
- fontWeight: FontWeight.bold,
- ),
- ),
- ),
- /* Text(
- _asignatura!.estadoCalculado,
- style: TextStyle(
- fontSize: 16,
- fontWeight: FontWeight.bold,
- ),
- ), */
- ],
- ),
- Container(width: 10),
- Container(
- height: 80,
- width: 0.5,
- color: Colors.grey,
- ),
- Container(width: 10),
- Column(
- crossAxisAlignment: CrossAxisAlignment.end,
- children: [
- Row(
- crossAxisAlignment: CrossAxisAlignment.center,
- children: [
- Text(
- "Examen",
- style: TextStyle(fontSize: 16),
- ),
- Container(
- width: 80,
- margin: EdgeInsets.only(left: 15),
- child: Obx(
- () => TextField(
- controller:
- controller.examGradeTextFieldController,
- textAlign: TextAlign.center,
- onChanged: (String value) {
- controller.examGrade.value =
- double.tryParse(
- value.replaceAll(",", "."),
- );
- },
- enabled: controller.canTakeExam,
- decoration: InputDecoration(
- hintText: controller
- .minimumRequiredExamGrade
- ?.toStringAsFixed(1) ??
- "",
- filled: !controller.canTakeExam,
- fillColor: Colors.grey.withOpacity(0.2),
- disabledBorder: MainTheme
- .theme.inputDecorationTheme.border!
- .copyWith(
- borderSide: BorderSide(
- color: Colors.grey[300]!,
- ),
- ),
- ),
- keyboardType:
- TextInputType.numberWithOptions(
- decimal: true,
- ),
- ),
- ),
- ),
- ],
- ),
- Container(height: 10),
- Obx(
- () => Row(
- children: [
- Text(
- "Pres.",
- style: TextStyle(fontSize: 16),
- ),
- Container(
- width: 80,
- margin: EdgeInsets.only(left: 15),
- child: TextField(
- controller: TextEditingController(
- text: controller
- .calculatedPresentationGrade
- ?.toStringAsFixed(1) ??
- "",
- ),
- textAlign: TextAlign.center,
- enabled: false,
- decoration: InputDecoration(
- hintText: "Nota",
- disabledBorder: MainTheme
- .theme.inputDecorationTheme.border!
- .copyWith(
- borderSide: BorderSide(
- color: Colors.transparent,
- ),
- ),
- ),
- keyboardType:
- TextInputType.numberWithOptions(
- decimal: true,
- ),
- ),
- ),
- ],
- ),
- ),
- ],
- ),
- ],
- ),
- ),
- ],
- ),
- ),
- Card(
- child: Stack(
- alignment: Alignment.center,
- children: [
- Container(
- padding: EdgeInsets.all(20),
- width: double.infinity,
- child: RotationTransition(
- turns: AlwaysStoppedAnimation(-20 / 360),
- child: Text(
- "Modo simulación".toUpperCase(),
- style: TextStyle(
- color: Colors.grey[200],
- fontWeight: FontWeight.bold,
- fontSize: 25,
- ),
- textAlign: TextAlign.center,
- ),
- ),
- ),
- Container(
- padding: EdgeInsets.all(20),
- child: Column(
- children: [
- Obx(
- () => ListView.separated(
- shrinkWrap: true,
- physics: ClampingScrollPhysics(),
- separatorBuilder: (context, index) =>
- SizedBox(height: 10),
- itemBuilder: (context, i) {
- REvaluacion evaluacion =
- controller.partialGrades[i];
- return NotaListItem(
- evaluacion: IEvaluacion.fromRemote(evaluacion),
- editable: true,
- gradeController:
- controller.gradeTextFieldControllers[i],
- percentageController:
- controller.percentageTextFieldControllers[i],
- onChanged: (evaluacion) {
- controller.changeGradeAt(i, evaluacion);
- },
- onDelete: () => _deleteGrade(controller, i),
- );
- },
- itemCount: controller.partialGrades.length,
- ),
- ),
- SizedBox(height: 16),
- TextButton(
- onPressed: () => _addGrade(controller),
- child: Text("Agregar nota"),
- ),
- ],
- ),
- ),
- ],
- ),
- ),
+ DisplayNotasWidget(calculatorController: controller),
+ EditarNotasWidget(calculatorController: controller)
],
),
);
}
-
- void _deleteGrade(CalculatorController controller, int index) {
- AnalyticsService.logEvent("calculator_delete_grade");
- controller.removeGradeAt(index);
- }
-
- void _addGrade(CalculatorController controller) {
- AnalyticsService.logEvent("calculator_add_grade");
- controller.addGrade(
- IEvaluacion(
- nota: null,
- porcentaje: null,
- ),
- );
- }
}
diff --git a/lib/widgets/calculadora_notas/DisplayNotasWidget.dart b/lib/widgets/calculadora_notas/DisplayNotasWidget.dart
new file mode 100644
index 0000000..f001304
--- /dev/null
+++ b/lib/widgets/calculadora_notas/DisplayNotasWidget.dart
@@ -0,0 +1,51 @@
+import 'package:flutter/material.dart';
+import 'package:mi_utem/controllers/calculator_controller.dart';
+import 'package:mi_utem/widgets/calculadora_notas/ModoSimulacionWidget.dart';
+import 'package:mi_utem/widgets/calculadora_notas/NotaExamenDisplayWidget.dart';
+import 'package:mi_utem/widgets/calculadora_notas/NotaFinalDisplayWidget.dart';
+import 'package:mi_utem/widgets/calculadora_notas/NotaPresentacionDisplayWidget.dart';
+
+class DisplayNotasWidget extends StatelessWidget {
+ final CalculatorController _calculatorController;
+
+ const DisplayNotasWidget({
+ Key? key,
+ required CalculatorController calculatorController,
+ }) : _calculatorController = calculatorController,
+ super(key: key);
+
+ @override
+ Widget build(BuildContext context) => Card(
+ child: Stack(
+ alignment: Alignment.center,
+ children: [
+ ModoSimulacionWidget(),
+ Container(
+ padding: EdgeInsets.symmetric(vertical: 20, horizontal: 30),
+ child: Row(
+ crossAxisAlignment: CrossAxisAlignment.center,
+ mainAxisAlignment: MainAxisAlignment.spaceBetween,
+ children: [
+ NotaFinalDisplayWidget(calculatorController: _calculatorController),
+ Container(width: 10),
+ Container(
+ height: 80,
+ width: 0.5,
+ color: Colors.grey,
+ ),
+ Container(width: 10),
+ Column(
+ crossAxisAlignment: CrossAxisAlignment.end,
+ children: [
+ NotaExamenDisplayWidget(calculatorController: _calculatorController),
+ Container(height: 10),
+ NotaPresentacionDisplayWidget(calculatorController: _calculatorController),
+ ],
+ ),
+ ],
+ ),
+ ),
+ ],
+ ),
+ );
+}
diff --git a/lib/widgets/calculadora_notas/EditarNotasWidget.dart b/lib/widgets/calculadora_notas/EditarNotasWidget.dart
new file mode 100644
index 0000000..9a008bd
--- /dev/null
+++ b/lib/widgets/calculadora_notas/EditarNotasWidget.dart
@@ -0,0 +1,52 @@
+import 'package:flutter/material.dart';
+import 'package:mi_utem/controllers/calculator_controller.dart';
+import 'package:mi_utem/models/evaluacion.dart';
+import 'package:mi_utem/services/analytics_service.dart';
+import 'package:mi_utem/widgets/calculadora_notas/ModoSimulacionWidget.dart';
+import 'package:mi_utem/widgets/calculadora_notas/NotasCalculadoraWidget.dart';
+
+class EditarNotasWidget extends StatelessWidget {
+ final CalculatorController _calculatorController;
+
+ const EditarNotasWidget({
+ Key? key,
+ required CalculatorController calculatorController,
+ }) : _calculatorController = calculatorController,
+ super(key: key);
+
+ @override
+ Widget build(BuildContext context) => Card(
+ child: Stack(
+ alignment: Alignment.center,
+ children: [
+ ModoSimulacionWidget(),
+ Container(
+ padding: EdgeInsets.all(20),
+ child: Column(
+ children: [
+ NotasCalculadoraWidget(calculatorController: _calculatorController, onDelete: (controller, index) => _deleteGrade(controller, index)),
+ SizedBox(height: 16),
+ TextButton(
+ onPressed: () => _addGrade(_calculatorController),
+ child: Text("Agregar nota"),
+ ),
+ ],
+ ),
+ ),
+ ],
+ ),
+ );
+
+ void _deleteGrade(CalculatorController controller, int index) {
+ AnalyticsService.logEvent("calculator_delete_grade");
+ controller.removeGradeAt(index);
+ }
+
+ void _addGrade(CalculatorController controller) {
+ AnalyticsService.logEvent("calculator_add_grade");
+ controller.addGrade(IEvaluacion(
+ nota: null,
+ porcentaje: null,
+ ));
+ }
+}
diff --git a/lib/widgets/calculadora_notas/ModoSimulacionWidget.dart b/lib/widgets/calculadora_notas/ModoSimulacionWidget.dart
new file mode 100644
index 0000000..9bd03a6
--- /dev/null
+++ b/lib/widgets/calculadora_notas/ModoSimulacionWidget.dart
@@ -0,0 +1,22 @@
+import 'package:flutter/material.dart';
+
+class ModoSimulacionWidget extends StatelessWidget {
+
+ @override
+ Widget build(BuildContext context) => Container(
+ padding: EdgeInsets.all(20),
+ width: double.infinity,
+ child: RotationTransition(
+ turns: AlwaysStoppedAnimation(-20 / 360),
+ child: Text(
+ "Modo simulación".toUpperCase(),
+ style: TextStyle(
+ color: Colors.grey[200],
+ fontWeight: FontWeight.bold,
+ fontSize: 25,
+ ),
+ textAlign: TextAlign.center,
+ ),
+ ),
+ );
+}
diff --git a/lib/widgets/calculadora_notas/NotaExamenDisplayWidget.dart b/lib/widgets/calculadora_notas/NotaExamenDisplayWidget.dart
new file mode 100644
index 0000000..766cd4c
--- /dev/null
+++ b/lib/widgets/calculadora_notas/NotaExamenDisplayWidget.dart
@@ -0,0 +1,52 @@
+import 'package:flutter/material.dart';
+import 'package:get/get.dart';
+import 'package:mi_utem/controllers/calculator_controller.dart';
+import 'package:mi_utem/themes/theme.dart';
+
+class NotaExamenDisplayWidget extends StatelessWidget {
+ final CalculatorController _calculatorController;
+
+ const NotaExamenDisplayWidget({
+ Key? key,
+ required CalculatorController calculatorController,
+ }) : _calculatorController = calculatorController,
+ super(key: key);
+
+ @override
+ Widget build(BuildContext context) => Row(
+ crossAxisAlignment: CrossAxisAlignment.center,
+ children: [
+ Text(
+ "Examen",
+ style: TextStyle(fontSize: 16),
+ ),
+ Container(
+ width: 80,
+ margin: EdgeInsets.only(left: 15),
+ child: Obx(() => TextField(
+ controller: _calculatorController.examGradeTextFieldController,
+ textAlign: TextAlign.center,
+ onChanged: (String value) {
+ _calculatorController.examGrade.value = double.tryParse(value.replaceAll(",", "."));
+ },
+ enabled: _calculatorController.canTakeExam,
+ decoration: InputDecoration(
+ hintText: _calculatorController.minimumRequiredExamGrade?.toStringAsFixed(1) ?? "",
+ filled: !_calculatorController.canTakeExam,
+ fillColor: Colors.grey.withOpacity(0.2),
+ disabledBorder: MainTheme.theme.inputDecorationTheme.border!.copyWith(
+ borderSide: BorderSide(
+ color: Colors.grey[300]!,
+ ),
+ ),
+ ),
+ keyboardType:
+ TextInputType.numberWithOptions(
+ decimal: true,
+ ),
+ ),
+ ),
+ ),
+ ],
+ );
+}
diff --git a/lib/widgets/calculadora_notas/NotaFinalDisplayWidget.dart b/lib/widgets/calculadora_notas/NotaFinalDisplayWidget.dart
new file mode 100644
index 0000000..3ded3ff
--- /dev/null
+++ b/lib/widgets/calculadora_notas/NotaFinalDisplayWidget.dart
@@ -0,0 +1,24 @@
+import 'package:flutter/material.dart';
+import 'package:get/get.dart';
+import 'package:mi_utem/controllers/calculator_controller.dart';
+
+class NotaFinalDisplayWidget extends StatelessWidget {
+ final CalculatorController _calculatorController;
+
+ const NotaFinalDisplayWidget({
+ Key? key,
+ required CalculatorController calculatorController,
+ }) : _calculatorController = calculatorController,
+ super(key: key);
+
+ @override
+ Widget build(BuildContext context) => Column(
+ children: [
+ Obx(() =>
+ Text(_calculatorController.calculatedFinalGrade?.toStringAsFixed(1) ?? "--",
+ style: TextStyle(fontSize: 40, fontWeight: FontWeight.bold),
+ ),
+ ),
+ ],
+ );
+}
diff --git a/lib/widgets/calculadora_notas/NotaPresentacionDisplayWidget.dart b/lib/widgets/calculadora_notas/NotaPresentacionDisplayWidget.dart
new file mode 100644
index 0000000..10e41c2
--- /dev/null
+++ b/lib/widgets/calculadora_notas/NotaPresentacionDisplayWidget.dart
@@ -0,0 +1,45 @@
+import 'package:flutter/material.dart';
+import 'package:get/get.dart';
+import 'package:mi_utem/controllers/calculator_controller.dart';
+import 'package:mi_utem/themes/theme.dart';
+
+class NotaPresentacionDisplayWidget extends StatelessWidget {
+ final CalculatorController _calculatorController;
+
+ const NotaPresentacionDisplayWidget({
+ Key? key,
+ required CalculatorController calculatorController,
+ }) : _calculatorController = calculatorController,
+ super(key: key);
+
+ @override
+ Widget build(BuildContext context) => Obx(
+ () => Row(
+ children: [
+ Text(
+ "Pres.",
+ style: TextStyle(fontSize: 16),
+ ),
+ Container(
+ width: 80,
+ margin: EdgeInsets.only(left: 15),
+ child: TextField(
+ controller: TextEditingController(text: _calculatorController.calculatedPresentationGrade?.toStringAsFixed(1) ?? ""),
+ textAlign: TextAlign.center,
+ enabled: false,
+ decoration: InputDecoration(
+ hintText: "Nota",
+ disabledBorder: MainTheme.theme.inputDecorationTheme.border!.copyWith(
+ borderSide: BorderSide(
+ color: Colors.transparent,
+ ),
+ ),
+ ),
+ keyboardType:
+ TextInputType.numberWithOptions(decimal: true),
+ ),
+ ),
+ ],
+ ),
+ );
+}
diff --git a/lib/widgets/calculadora_notas/NotasCalculadoraWidget.dart b/lib/widgets/calculadora_notas/NotasCalculadoraWidget.dart
new file mode 100644
index 0000000..dfc14b0
--- /dev/null
+++ b/lib/widgets/calculadora_notas/NotasCalculadoraWidget.dart
@@ -0,0 +1,40 @@
+import 'package:flutter/material.dart';
+import 'package:get/get.dart';
+import 'package:mi_utem/controllers/calculator_controller.dart';
+import 'package:mi_utem/models/evaluacion.dart';
+import 'package:mi_utem/widgets/nota_list_item.dart';
+
+class NotasCalculadoraWidget extends StatelessWidget {
+ final CalculatorController _calculatorController;
+ final Function onDelete;
+
+ const NotasCalculadoraWidget({
+ Key? key,
+ required CalculatorController calculatorController,
+ required this.onDelete,
+ }) : _calculatorController = calculatorController,
+ super(key: key);
+
+
+ @override
+ Widget build(BuildContext context) => Obx(() => ListView.separated(
+ shrinkWrap: true,
+ physics: ClampingScrollPhysics(),
+ separatorBuilder: (context, index) => SizedBox(height: 10),
+ itemBuilder: (context, i) {
+ REvaluacion evaluacion = _calculatorController.partialGrades[i];
+ return NotaListItem(
+ evaluacion: IEvaluacion.fromRemote(evaluacion),
+ editable: true,
+ gradeController: _calculatorController.gradeTextFieldControllers[i],
+ percentageController: _calculatorController.percentageTextFieldControllers[i],
+ onChanged: (evaluacion) {
+ _calculatorController.changeGradeAt(i, evaluacion);
+ },
+ onDelete: () => Function.apply(onDelete, [_calculatorController, i]),
+ );
+ },
+ itemCount: _calculatorController.partialGrades.length,
+ ),
+ );
+}
From 3a0fcc2cca0bc97dd1fc2d86d9e70b46b054857f Mon Sep 17 00:00:00 2001
From: Francisco Solis <30329003+Im-Fran@users.noreply.github.com>
Date: Tue, 5 Mar 2024 13:07:19 -0300
Subject: [PATCH 015/194] patch: cambio de versiones para funcionar con flutter
v3.7.2
---
.env.example | 2 +-
lib/controllers/carreras_controller.dart | 8 +-
pubspec.lock | 94 ++++++++++++------------
pubspec.yaml | 12 +--
4 files changed, 60 insertions(+), 56 deletions(-)
diff --git a/.env.example b/.env.example
index e66bfee..f301e49 100644
--- a/.env.example
+++ b/.env.example
@@ -1 +1 @@
-MI_UTEM_API_DEBUG=https://api-mi-utem.herokuapp.com/
\ No newline at end of file
+MI_UTEM_API_DEBUG=https://api.exdev.cl
\ No newline at end of file
diff --git a/lib/controllers/carreras_controller.dart b/lib/controllers/carreras_controller.dart
index 20eb963..a26aa56 100644
--- a/lib/controllers/carreras_controller.dart
+++ b/lib/controllers/carreras_controller.dart
@@ -17,10 +17,12 @@ class CarrerasController extends GetxController {
}
void getCarreras() async {
- final carreras = await CarreraService.getCarreras(forceRefresh: true);
+ try {
+ final carreras = await CarreraService.getCarreras(forceRefresh: true);
- this.carreras.value = carreras;
- _autoSelectCarreraActiva(carreras);
+ this.carreras.value = carreras;
+ _autoSelectCarreraActiva(carreras);
+ } catch(_) {}
}
void _autoSelectCarreraActiva(List carreras) {
diff --git a/pubspec.lock b/pubspec.lock
index 80babec..2347809 100644
--- a/pubspec.lock
+++ b/pubspec.lock
@@ -45,10 +45,10 @@ packages:
dependency: transitive
description:
name: async
- sha256: "947bfcf187f74dbc5e146c9eb9c0f10c9f8b30743e341481c1e2ed3ecc18c20c"
+ sha256: bfe67ef28df125b7dddcea62755991f807aa39a2492a23e1550161692950bbe0
url: "https://pub.dev"
source: hosted
- version: "2.11.0"
+ version: "2.10.0"
awesome_notifications:
dependency: "direct main"
description:
@@ -173,10 +173,10 @@ packages:
dependency: transitive
description:
name: characters
- sha256: "04a925763edad70e8443c99234dc3328f442e811f1d8fd1a72f1c8ad0f69a605"
+ sha256: e6a326c8af69605aec75ed6c187d06b349707a27fbff8222ca9cc2cff167975c
url: "https://pub.dev"
source: hosted
- version: "1.3.0"
+ version: "1.2.1"
checked_yaml:
dependency: transitive
description:
@@ -245,10 +245,10 @@ packages:
dependency: transitive
description:
name: collection
- sha256: f092b211a4319e98e5ff58223576de6c2803db36221657b46c82574721240687
+ sha256: cfc915e6923fe5ce6e153b0723c753045de46de1b4d63771530504004a45fae0
url: "https://pub.dev"
source: hosted
- version: "1.17.2"
+ version: "1.17.0"
community_charts_common:
dependency: transitive
description:
@@ -357,18 +357,18 @@ packages:
dependency: "direct main"
description:
name: extended_image
- sha256: b4d72a27851751cfadaf048936d42939db7cd66c08fdcfe651eeaa1179714ee6
+ sha256: "75e4b0ad0f8f63eed7935ff2506c809a670f5e6dd0f61304525879d53fc41a17"
url: "https://pub.dev"
source: hosted
- version: "8.1.1"
+ version: "7.0.2"
extended_image_library:
dependency: transitive
description:
name: extended_image_library
- sha256: "8bf87c0b14dcb59200c923a9a3952304e4732a0901e40811428834ef39018ee1"
+ sha256: "550743b43ab093aed35ef234500fcc7a304cbac1eca47b0cc991e07e88750758"
url: "https://pub.dev"
source: hosted
- version: "3.6.0"
+ version: "3.4.2"
fake_async:
dependency: transitive
description:
@@ -794,21 +794,29 @@ packages:
source: hosted
version: "0.15.4"
http:
- dependency: transitive
+ dependency: "direct main"
description:
name: http
- sha256: "759d1a329847dd0f39226c688d3e06a6b8679668e350e2891a6474f8b4bb8525"
+ sha256: "5895291c13fa8a3bd82e76d5627f69e0d85ca6a30dcac95c4ea19a5d555879c2"
url: "https://pub.dev"
source: hosted
- version: "1.1.0"
+ version: "0.13.6"
http_client_helper:
dependency: transitive
description:
name: http_client_helper
- sha256: "8a9127650734da86b5c73760de2b404494c968a3fd55602045ffec789dac3cb1"
+ sha256: "14c6e756644339f561321dab021215475ba4779aa962466f59ccb3ecf66b36c3"
url: "https://pub.dev"
source: hosted
- version: "3.0.0"
+ version: "2.0.4"
+ http_interceptor:
+ dependency: "direct main"
+ description:
+ name: http_interceptor
+ sha256: "5f3dde028e67789339c250252c09510a74aff21ce16b06d07d9096bda6582bab"
+ url: "https://pub.dev"
+ source: hosted
+ version: "1.0.2"
http_parser:
dependency: transitive
description:
@@ -957,10 +965,10 @@ packages:
dependency: transitive
description:
name: js
- sha256: f2c445dce49627136094980615a031419f7f3eb393237e4ecd97ac15dea343f3
+ sha256: "5528c2f391ededb7775ec1daa69e65a2d61276f7552de2b5f7b8d34ee9fd4ab7"
url: "https://pub.dev"
source: hosted
- version: "0.6.7"
+ version: "0.6.5"
json_annotation:
dependency: "direct overridden"
description:
@@ -1013,18 +1021,18 @@ packages:
dependency: transitive
description:
name: matcher
- sha256: "1803e76e6653768d64ed8ff2e1e67bea3ad4b923eb5c56a295c3e634bad5960e"
+ sha256: "16db949ceee371e9b99d22f88fa3a73c4e59fd0afed0bd25fc336eb76c198b72"
url: "https://pub.dev"
source: hosted
- version: "0.12.16"
+ version: "0.12.13"
material_color_utilities:
dependency: transitive
description:
name: material_color_utilities
- sha256: "9528f2f296073ff54cb9fee677df673ace1218163c3bc7628093e7eed5203d41"
+ sha256: d92141dc6fe1dad30722f9aa826c7fbc896d021d792f80678280601aff8cf724
url: "https://pub.dev"
source: hosted
- version: "0.5.0"
+ version: "0.2.0"
mdi:
dependency: "direct main"
description:
@@ -1037,10 +1045,10 @@ packages:
dependency: transitive
description:
name: meta
- sha256: "3c74dbf8763d36539f114c799d8a2d87343b5067e9d796ca22b5eb8437090ee3"
+ sha256: "6c268b42ed578a53088d834796959e4a1814b5e9e164f147f580a386e5decf42"
url: "https://pub.dev"
source: hosted
- version: "1.9.1"
+ version: "1.8.0"
mime:
dependency: transitive
description:
@@ -1085,10 +1093,10 @@ packages:
dependency: transitive
description:
name: path
- sha256: "8829d8a55c13fc0e37127c29fedf290c102f4e40ae94ada574091fe0ff96c917"
+ sha256: db9d4f58c908a4ba5953fcee2ae317c94889433e5024c27ce74a37f94267945b
url: "https://pub.dev"
source: hosted
- version: "1.8.3"
+ version: "1.8.2"
path_drawing:
dependency: transitive
description:
@@ -1309,26 +1317,26 @@ packages:
dependency: "direct main"
description:
name: screenshot
- sha256: "455284ff1f5b911d94a43c25e1385485cf6b4f288293eba68f15dad711c7b81c"
+ sha256: "30bb9fade6eb2578a1fc2e84f6b184141fc86883cda10988d4500ff00eb728e2"
url: "https://pub.dev"
source: hosted
- version: "2.1.0"
+ version: "1.3.0"
sentry:
dependency: transitive
description:
name: sentry
- sha256: "9cfd325611ab54b57d5e26957466823f05bea9d6cfcc8d48f11817b8bcedf0d1"
+ sha256: d2ee9c850d876d285f22e2e662f400ec2438df9939fe4acd5d780df9841794ce
url: "https://pub.dev"
source: hosted
- version: "7.12.0"
+ version: "7.16.1"
sentry_flutter:
dependency: "direct main"
description:
name: sentry_flutter
- sha256: "0cd7d622cb63c94fd1b2f87ab508e158b950bd281e2a80f327ebf73bb217eaf3"
+ sha256: "5b428c189c825f16fb14e9166529043f06b965d5b59bfc3a1415e39c082398c0"
url: "https://pub.dev"
source: hosted
- version: "7.12.0"
+ version: "7.16.1"
share_plus:
dependency: "direct main"
description:
@@ -1426,10 +1434,10 @@ packages:
dependency: transitive
description:
name: source_span
- sha256: "53e943d4206a5e30df338fd4c6e7a077e02254531b138a15aec3bd143c1a8b3c"
+ sha256: dd904f795d4b4f3b870833847c461801f6750a9fa8e61ea5ac53f9422b31f250
url: "https://pub.dev"
source: hosted
- version: "1.10.0"
+ version: "1.9.1"
sqflite:
dependency: transitive
description:
@@ -1490,10 +1498,10 @@ packages:
dependency: transitive
description:
name: test_api
- sha256: "75760ffd7786fffdfb9597c35c5b27eaeec82be8edfb6d71d32651128ed7aab8"
+ sha256: ad540f65f92caa91bf21dfc8ffb8c589d6e4dc0c2267818b4cc2792857706206
url: "https://pub.dev"
source: hosted
- version: "0.6.0"
+ version: "0.4.16"
tint:
dependency: transitive
description:
@@ -1646,22 +1654,14 @@ packages:
url: "https://pub.dev"
source: hosted
version: "1.0.2"
- web:
- dependency: transitive
- description:
- name: web
- sha256: dc8ccd225a2005c1be616fe02951e2e342092edf968cf0844220383757ef8f10
- url: "https://pub.dev"
- source: hosted
- version: "0.1.4-beta"
win32:
dependency: transitive
description:
name: win32
- sha256: f2add6fa510d3ae152903412227bda57d0d5a8da61d2c39c1fb022c9429a41c0
+ sha256: "5a751eddf9db89b3e5f9d50c20ab8612296e4e8db69009788d6c8b060a84191c"
url: "https://pub.dev"
source: hosted
- version: "5.0.6"
+ version: "4.1.4"
xdg_directories:
dependency: transitive
description:
@@ -1687,5 +1687,5 @@ packages:
source: hosted
version: "3.1.2"
sdks:
- dart: ">=3.1.0-185.0.dev <4.0.0"
- flutter: ">=3.13.0"
+ dart: ">=2.19.0 <3.0.0"
+ flutter: ">=3.7.0"
diff --git a/pubspec.yaml b/pubspec.yaml
index f680e9b..21ebfa4 100644
--- a/pubspec.yaml
+++ b/pubspec.yaml
@@ -3,10 +3,10 @@ description: Plataforma académica para estudiantes de la Universidad Tecnológi
Metropolitana (UTEM)
publish_to: none
-version: 2.11.10
+version: 3.0.0
environment:
- sdk: ">=2.14.4 <3.0.0"
+ sdk: ">=2.17.0 <3.0.0"
dependencies:
awesome_notifications_core: ^0.8.1
@@ -15,7 +15,6 @@ dependencies:
badges: ^2.0.2
barcode_widget: ^2.0.3
barcode_image: ^2.0.2
- cached_network_image: ^3.2.0
carousel_slider: ^4.0.0
community_charts_flutter: ^1.0.2
circular_profile_avatar: ^2.0.5
@@ -26,7 +25,6 @@ dependencies:
dio_cache_interceptor: ^3.2.6
dio_cache_interceptor_hive_store: ^3.1.1
dotted_border: ^2.0.0+2
- extended_image: ^8.1.1
firebase_core: 2.16.0
firebase_analytics: 10.2.1
firebase_in_app_messaging: ^0.7.0+10
@@ -59,7 +57,6 @@ dependencies:
qr_flutter: ^4.0.0
recase: ^4.0.0
responsive_framework: ^0.2.0
- screenshot: ^2.1.0
sentry_flutter: ^7.12.0
share_plus: ^7.2.1
simple_gesture_detector: ^0.2.0
@@ -74,6 +71,11 @@ dependencies:
background_fetch: ^1.1.5
flutter_uxcam: ^2.3.0
in_app_update: ^4.2.2
+ http: ^0.13.6
+ http_interceptor: ^1.0.2
+ screenshot: ^1.3.0
+ extended_image: ^7.0.2
+ cached_network_image: ^3.2.3
dependency_overrides:
qr: ^3.0.0
From 7a580046fb93342001725e16560e0dc8f6888f06 Mon Sep 17 00:00:00 2001
From: Francisco Solis <30329003+Im-Fran@users.noreply.github.com>
Date: Tue, 12 Mar 2024 07:58:47 -0300
Subject: [PATCH 016/194] feat: .fvmrc para usar flutter version manager
---
.fvmrc | 4 ++++
1 file changed, 4 insertions(+)
create mode 100644 .fvmrc
diff --git a/.fvmrc b/.fvmrc
new file mode 100644
index 0000000..2b19323
--- /dev/null
+++ b/.fvmrc
@@ -0,0 +1,4 @@
+{
+ "flutter": "3.7.12",
+ "flavors": {}
+}
\ No newline at end of file
From 64b16c26bf54608bbb3ddf967132325b5696a447 Mon Sep 17 00:00:00 2001
From: Francisco Solis <30329003+Im-Fran@users.noreply.github.com>
Date: Tue, 12 Mar 2024 07:59:47 -0300
Subject: [PATCH 017/194] =?UTF-8?q?patch:=20agregada=20configuraci=C3=B3n?=
=?UTF-8?q?=20de=20vscode=20para=20fvm?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
.vscode/settings.json | 3 +++
1 file changed, 3 insertions(+)
create mode 100644 .vscode/settings.json
diff --git a/.vscode/settings.json b/.vscode/settings.json
new file mode 100644
index 0000000..7100e0a
--- /dev/null
+++ b/.vscode/settings.json
@@ -0,0 +1,3 @@
+{
+ "dart.flutterSdkPath": ".fvm/versions/3.7.12"
+}
\ No newline at end of file
From c0cae280760cbaae2bbbe3745813f6fb706d1e29 Mon Sep 17 00:00:00 2001
From: Francisco Solis <30329003+Im-Fran@users.noreply.github.com>
Date: Tue, 12 Mar 2024 08:04:12 -0300
Subject: [PATCH 018/194] feat: se ordenaron muchas clases y se implementa
nuevo sistema de servicios.
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
* Se ordenaron muchas clases y widgets (ya no se cuales eran xD)
* Se cambió a un nuevo sistema de servicios usando GetIt que usa servicios bajo demanda de manera "floja" (lazy). De esta forma se mejora el rendimiento.
* Se cambia de dio a http como se recomienda en flutter.dev
* Se agrega constante de "secureStorage" para un fácil acceso al storage encriptado.
---
lib/config/constants.dart | 2 +
lib/config/http_client.dart | 52 ++++
lib/config/router.dart | 106 --------
lib/config/routes.dart | 17 --
lib/config/secure_storage.dart | 3 +
.../asignatura/asignatura_controller.dart | 62 -----
.../asignatura/asignaturas_controller.dart | 67 -----
lib/controllers/calculator_controller.dart | 209 --------------
lib/controllers/carreras_controller.dart | 50 ----
.../grades_changes_controller.dart | 249 -----------------
lib/controllers/horario_controller.dart | 16 +-
lib/controllers/notification_controller.dart | 17 +-
lib/controllers/qr_pass_controller.dart | 28 --
lib/controllers/qr_passes_controller.dart | 20 +-
lib/main.dart | 38 +--
lib/models/evaluacion.dart | 60 ++---
lib/models/exceptions/custom_exception.dart | 35 +++
lib/models/grades.dart | 28 +-
lib/models/permiso_covid.dart | 42 ++-
lib/models/user/credential.dart | 25 ++
lib/models/user/rut.dart | 35 +++
lib/models/user/user.dart | 80 ++++++
.../asignatura/asignatura_detalle_screen.dart | 157 ++++++-----
.../asignatura/asignatura_notas_tab.dart | 159 ++++++-----
.../asignatura/asignaturas_lista_screen.dart | 117 +++++---
lib/screens/calculadora_notas_screen.dart | 24 +-
lib/screens/credencial_screen.dart | 147 +++++-----
lib/screens/docentes_screen.dart | 157 +++++------
lib/screens/login_screen/login_screen.dart | 105 ++------
lib/screens/main_screen.dart | 66 ++---
lib/screens/permiso_covid_screen.dart | 178 ++++++------
lib/screens/splash_screen.dart | 134 +++++----
lib/screens/usuario_screen.dart | 189 ++++++-------
lib/services/analytics_service.dart | 102 ++-----
lib/services/asignaturas_service.dart | 63 -----
lib/services/auth_service.dart | 157 -----------
lib/services/background_service.dart | 5 +-
lib/services/carreras_service.dart | 27 --
lib/services/docentes_service.dart | 40 ++-
lib/services/grades_service.dart | 40 ---
lib/services/horarios_service.dart | 37 ---
lib/services/noticias_service.dart | 11 -
lib/services/perfil_service.dart | 109 --------
lib/services/permisos_covid_service.dart | 64 -----
.../implementations/asignaturas_service.dart | 73 +++++
.../implementations/auth_service.dart | 189 +++++++++++++
.../implementations/calculator_service.dart | 254 ++++++++++++++++++
.../implementations/carreras_service.dart | 66 +++++
.../implementations/credential_service.dart | 25 ++
.../implementations/grades_service.dart | 246 +++++++++++++++++
.../implementations/horario_service.dart | 39 +++
.../implementations/noticias_service.dart | 28 ++
.../implementations/qr_pass_service.dart | 72 +++++
.../interfaces/asignaturas_service.dart | 8 +
lib/services_new/interfaces/auth_service.dart | 23 ++
.../interfaces/calculator_service.dart | 84 ++++++
.../interfaces/carreras_service.dart | 15 ++
.../interfaces/credential_service.dart | 10 +
.../interfaces/grades_service.dart | 22 ++
.../interfaces/horario_service.dart | 6 +
.../interfaces/noticias_service.dart | 6 +
.../interfaces/qr_pass_service.dart | 8 +
lib/services_new/service_manager.dart | 31 +++
lib/utils/dio_miutem_client.dart | 7 +-
.../club/acerca_club_desarrolladores.dart | 91 +++----
.../dialog/acerca_dialog_action_button.dart | 23 +-
.../lista/asignatura_list_tile.dart | 20 +-
.../calculadora_notas/DisplayNotasWidget.dart | 26 +-
.../calculadora_notas/EditarNotasWidget.dart | 28 +-
.../ModoSimulacionWidget.dart | 11 +-
.../NotaExamenDisplayWidget.dart | 54 ++--
.../NotaFinalDisplayWidget.dart | 28 +-
.../NotaPresentacionDisplayWidget.dart | 33 +--
.../NotasCalculadoraWidget.dart | 56 ++--
lib/widgets/credencial_card.dart | 90 +++----
lib/widgets/custom_drawer.dart | 206 +++++++-------
lib/widgets/custom_error_widget.dart | 27 +-
lib/widgets/default_network_image.dart | 11 +-
lib/widgets/dialogs/not_ready_dialog.dart | 120 ++++-----
lib/widgets/loading_indicator.dart | 40 ++-
.../login_screen/background.dart} | 16 +-
lib/widgets/login_screen/creditos_app.dart | 61 +++--
.../login_screen/formulario_credenciales.dart | 82 +++---
lib/widgets/login_screen/login_button.dart | 85 +++---
lib/widgets/login_screen/login_form.dart | 101 +++++++
lib/widgets/login_text_form_field.dart | 3 +
lib/widgets/nota_list_item.dart | 28 +-
.../noticias/NoticiasCarruselWidget.dart | 93 ++++---
lib/widgets/permiso_card.dart | 10 +-
lib/widgets/permisos_section.dart | 31 ++-
lib/widgets/profile_photo.dart | 199 +++++++-------
lib/widgets/pull_to_refresh.dart | 95 +++----
lib/widgets/quick_menu_card.dart | 28 +-
lib/widgets/sad_dialog.dart | 8 +-
pubspec.lock | 34 ++-
pubspec.yaml | 3 +
96 files changed, 3170 insertions(+), 3112 deletions(-)
create mode 100644 lib/config/http_client.dart
delete mode 100644 lib/config/router.dart
delete mode 100644 lib/config/routes.dart
create mode 100644 lib/config/secure_storage.dart
delete mode 100644 lib/controllers/asignatura/asignatura_controller.dart
delete mode 100644 lib/controllers/asignatura/asignaturas_controller.dart
delete mode 100644 lib/controllers/calculator_controller.dart
delete mode 100644 lib/controllers/carreras_controller.dart
delete mode 100644 lib/controllers/grades_changes_controller.dart
delete mode 100644 lib/controllers/qr_pass_controller.dart
create mode 100644 lib/models/exceptions/custom_exception.dart
create mode 100644 lib/models/user/credential.dart
create mode 100644 lib/models/user/rut.dart
create mode 100644 lib/models/user/user.dart
delete mode 100644 lib/services/asignaturas_service.dart
delete mode 100644 lib/services/auth_service.dart
delete mode 100644 lib/services/carreras_service.dart
delete mode 100644 lib/services/grades_service.dart
delete mode 100644 lib/services/horarios_service.dart
delete mode 100644 lib/services/noticias_service.dart
delete mode 100644 lib/services/perfil_service.dart
delete mode 100644 lib/services/permisos_covid_service.dart
create mode 100644 lib/services_new/implementations/asignaturas_service.dart
create mode 100644 lib/services_new/implementations/auth_service.dart
create mode 100644 lib/services_new/implementations/calculator_service.dart
create mode 100644 lib/services_new/implementations/carreras_service.dart
create mode 100644 lib/services_new/implementations/credential_service.dart
create mode 100644 lib/services_new/implementations/grades_service.dart
create mode 100644 lib/services_new/implementations/horario_service.dart
create mode 100644 lib/services_new/implementations/noticias_service.dart
create mode 100644 lib/services_new/implementations/qr_pass_service.dart
create mode 100644 lib/services_new/interfaces/asignaturas_service.dart
create mode 100644 lib/services_new/interfaces/auth_service.dart
create mode 100644 lib/services_new/interfaces/calculator_service.dart
create mode 100644 lib/services_new/interfaces/carreras_service.dart
create mode 100644 lib/services_new/interfaces/credential_service.dart
create mode 100644 lib/services_new/interfaces/grades_service.dart
create mode 100644 lib/services_new/interfaces/horario_service.dart
create mode 100644 lib/services_new/interfaces/noticias_service.dart
create mode 100644 lib/services_new/interfaces/qr_pass_service.dart
create mode 100644 lib/services_new/service_manager.dart
rename lib/{screens/login_screen/_background.dart => widgets/login_screen/background.dart} (81%)
create mode 100644 lib/widgets/login_screen/login_form.dart
diff --git a/lib/config/constants.dart b/lib/config/constants.dart
index 1568527..11a0e8a 100644
--- a/lib/config/constants.dart
+++ b/lib/config/constants.dart
@@ -1,5 +1,7 @@
import 'package:flutter_dotenv/flutter_dotenv.dart';
+final apiUrl = bool.fromEnvironment('dart.vm.product') ? 'https://api.exdev.cl' : (dotenv.env['MI_UTEM_API_DEBUG'] ?? 'https://api.exdev.cl');
+
class Constants {
static const String sentryDsn = 'https://0af59b2ad2b44f4e8c9cad4ea8d5f32e@o507661.ingest.sentry.io/5599080';
static const String uxCamDevKey = '0y6p88obpgiug1g';
diff --git a/lib/config/http_client.dart b/lib/config/http_client.dart
new file mode 100644
index 0000000..475e061
--- /dev/null
+++ b/lib/config/http_client.dart
@@ -0,0 +1,52 @@
+import 'dart:convert';
+
+import 'package:http/http.dart' as http;
+import 'package:mi_utem/services_new/interfaces/auth_service.dart';
+import 'package:watch_it/watch_it.dart';
+
+class AuthClient extends http.BaseClient {
+
+ final _client = http.Client();
+
+ @override
+ Future send(http.BaseRequest request) async {
+ if(!request.headers.containsKey('user-agent')) {
+ request.headers['user-agent'] = "App/MiUTEM";
+ }
+
+ if(!request.headers.containsKey('content-type')) {
+ request.headers['content-type'] = "application/json";
+ }
+
+ if (!request.headers.containsKey('authorization')) {
+ final user = await di.get().getUser();
+ final token = user?.token;
+ if (token != null) {
+ request.headers['authorization'] = 'Bearer $token';
+ }
+ }
+
+ var response = await _client.send(request);
+ final json = jsonDecode(await response.stream.bytesToString());
+ if(response.statusCode == 401 && json is Map && json.containsKey("codigoInterno") && json["codigoInterno"] == 12) {
+ // Refrescar el token
+ final _authService = di.get();
+ await _authService.isLoggedIn();
+ final user = await _authService.getUser();
+ final token = user?.token;
+ if (token != null) {
+ request.headers['authorization'] = 'Bearer $token';
+ response = await _client.send(request);
+ }
+ }
+
+ return response;
+ }
+
+ @override
+ void close() {
+ _client.close();
+ super.close();
+ }
+
+}
\ No newline at end of file
diff --git a/lib/config/router.dart b/lib/config/router.dart
deleted file mode 100644
index ea9f974..0000000
--- a/lib/config/router.dart
+++ /dev/null
@@ -1,106 +0,0 @@
-import 'package:flutter/material.dart';
-import 'package:get/route_manager.dart';
-import 'package:mi_utem/config/routes.dart';
-import 'package:mi_utem/screens/asignatura/asignatura_detalle_screen.dart';
-import 'package:mi_utem/screens/asignatura/asignaturas_lista_screen.dart';
-import 'package:mi_utem/controllers/asignatura/asignaturas_controller.dart';
-import 'package:mi_utem/controllers/qr_passes_controller.dart';
-import 'package:mi_utem/screens/calculadora_notas_screen.dart';
-import 'package:mi_utem/screens/credencial_screen.dart';
-import 'package:mi_utem/screens/horario/horario_screen.dart';
-import 'package:mi_utem/screens/login_screen/login_screen.dart';
-import 'package:mi_utem/screens/main_screen.dart';
-import 'package:mi_utem/screens/permiso_covid_screen.dart';
-import 'package:mi_utem/screens/splash_screen.dart';
-import 'package:mi_utem/screens/usuario_screen.dart';
-import 'package:mi_utem/services/auth_service.dart';
-import 'package:mi_utem/services/perfil_service.dart';
-import 'package:mi_utem/widgets/acerca/acerca_screen.dart';
-
-final _loginPage = GetPage(
- name: Routes.login,
- page: () => LoginScreen(),
- middlewares: [OnlyNoAuthMiddleware()],
-);
-
-final _homePage = GetPage(
- name: Routes.home,
- bindings: [QrPassesBinding()],
- page: () {
- final usuario = PerfilService.getLocalUsuario();
-
- return MainScreen(usuario: usuario);
- },
- middlewares: [OnlyAuthMiddleware()],
-);
-
-final pages = [
- GetPage(
- name: Routes.splash,
- page: () => SplashScreen(),
- ),
- GetPage(
- name: Routes.about,
- page: () => AcercaScreen(),
- ),
- _loginPage,
- _homePage,
- GetPage(
- name: Routes.perfil,
- page: () => UsuarioScreen(),
- middlewares: [OnlyAuthMiddleware()],
- ),
- GetPage(
- name: Routes.credencial,
- page: () => CredencialScreen(),
- middlewares: [OnlyAuthMiddleware()],
- ),
- GetPage(
- name: Routes.calculadoraNotas,
- page: () => CalculadoraNotasScreen(),
- middlewares: [OnlyAuthMiddleware()],
- ),
- GetPage(
- name: Routes.horario,
- page: () => HorarioScreen(),
- binding: HorarioBinding(),
- middlewares: [OnlyAuthMiddleware()],
- ),
- GetPage(
- name: Routes.asignaturas,
- page: () => AsignaturasListaScreen(),
- middlewares: [OnlyAuthMiddleware()],
- binding: AsignaturasBinding(),
- ),
- GetPage(
- name: '${Routes.asignatura}/:asignaturaId',
- page: () => AsignaturaDetalleScreen(),
- ),
- GetPage(
- name: Routes.pass,
- page: () => PermisoCovidScreen(),
- middlewares: [OnlyAuthMiddleware()],
- ),
-];
-
-class OnlyAuthMiddleware extends GetMiddleware {
- @override
- RouteSettings? redirect(String? page) {
- final isLoggedIn = AuthService.isLoggedIn();
- if (!isLoggedIn) {
- return const RouteSettings(name: Routes.login);
- }
- return null;
- }
-}
-
-class OnlyNoAuthMiddleware extends GetMiddleware {
- @override
- RouteSettings? redirect(String? page) {
- final isLoggedIn = AuthService.isLoggedIn();
- if (isLoggedIn) {
- return const RouteSettings(name: Routes.home);
- }
- return null;
- }
-}
diff --git a/lib/config/routes.dart b/lib/config/routes.dart
deleted file mode 100644
index 1884123..0000000
--- a/lib/config/routes.dart
+++ /dev/null
@@ -1,17 +0,0 @@
-class Routes {
- static const splash = '/splash';
- static const login = '/login';
- static const home = '/';
- static const about = '/about';
- static const horario = '/horario';
- static const asignaturas = '/asignaturas';
- static const perfil = '/perfil';
- static const credencial = '/credencial';
- static const calculadoraNotas = '/calculadora-notas';
- static const imageView = '/image-view';
- static const asignatura = '/asignatura';
-
- static const passBase = '/pass';
- static const passParameter = 'passId';
- static const pass = '$passBase/:$passParameter';
-}
diff --git a/lib/config/secure_storage.dart b/lib/config/secure_storage.dart
new file mode 100644
index 0000000..5366ad9
--- /dev/null
+++ b/lib/config/secure_storage.dart
@@ -0,0 +1,3 @@
+import 'package:flutter_secure_storage/flutter_secure_storage.dart';
+
+final secureStorage = FlutterSecureStorage();
\ No newline at end of file
diff --git a/lib/controllers/asignatura/asignatura_controller.dart b/lib/controllers/asignatura/asignatura_controller.dart
deleted file mode 100644
index 544e732..0000000
--- a/lib/controllers/asignatura/asignatura_controller.dart
+++ /dev/null
@@ -1,62 +0,0 @@
-import 'package:get/get.dart';
-import 'package:mi_utem/controllers/carreras_controller.dart';
-import 'package:mi_utem/models/asignatura.dart';
-import 'package:mi_utem/models/carrera.dart';
-import 'package:mi_utem/models/grades.dart';
-import 'package:mi_utem/services/grades_service.dart';
-
-class AsignaturaController extends GetxController with StateMixin {
- late final String asignaturaId;
- late final Asignatura? _initialAsignatura;
-
- Carrera? _selectedCarrera;
-
- AsignaturaController(this.asignaturaId, {Asignatura? asignatura}) {
- if (asignatura != null) {
- _initialAsignatura = asignatura;
- }
- }
-
- @override
- void onInit() {
- _selectedCarrera = Get.find().selectedCarrera.value;
- if (_selectedCarrera != null) {
- getAsignaturaDetail(Get.find().selectedCarrera.value);
- }
-
- ever(
- Get.find().selectedCarrera,
- (carrera) {
- _selectedCarrera = carrera;
- getAsignaturaDetail(carrera, forceRefresh: true);
- },
- );
- super.onInit();
- }
-
- Future refreshData() async {
- await getAsignaturaDetail(_selectedCarrera, forceRefresh: true);
- }
-
- Future getAsignaturaDetail(Carrera? carrera,
- {bool forceRefresh = false}) async {
- final carreraId = carrera?.id;
- if (carreraId != null) {
- change(null, status: RxStatus.loading());
- try {
- Grades grades = await GradesService.getGrades(
- carreraId,
- asignaturaId,
- forceRefresh: forceRefresh,
- );
-
- Asignatura asignatura = _initialAsignatura!;
- asignatura.grades = grades;
-
- change(asignatura, status: RxStatus.success());
- } catch (e) {
- change(null, status: RxStatus.error(e.toString()));
- }
- }
- }
-}
diff --git a/lib/controllers/asignatura/asignaturas_controller.dart b/lib/controllers/asignatura/asignaturas_controller.dart
deleted file mode 100644
index d3d5be6..0000000
--- a/lib/controllers/asignatura/asignaturas_controller.dart
+++ /dev/null
@@ -1,67 +0,0 @@
-import 'package:get/get.dart';
-import 'package:mi_utem/controllers/asignatura/asignatura_controller.dart';
-import 'package:mi_utem/controllers/carreras_controller.dart';
-import 'package:mi_utem/models/asignatura.dart';
-import 'package:mi_utem/models/carrera.dart';
-import 'package:mi_utem/services/asignaturas_service.dart';
-
-class AsignaturasController extends GetxController
- with StateMixin> {
- @override
- void onInit() {
- change(null, status: RxStatus.loading());
-
- if (Get.find().selectedCarrera.value != null) {
- getAsignaturas(Get.find().selectedCarrera.value);
- }
-
- ever(
- Get.find().selectedCarrera,
- (carrera) => getAsignaturas(carrera, forceRefresh: true),
- );
- super.onInit();
- }
-
- void getAsignaturas(
- Carrera? carrera, {
- bool forceRefresh = false,
- }) async {
- change(null, status: RxStatus.loading());
-
- final carreraId = carrera?.id;
-
- if (carreraId == null) {
- change(null, status: RxStatus.error("No hay carrera seleccionada"));
- return;
- }
-
- List response = await AsignaturasService.getAsignaturas(
- carreraId,
- forceRefresh: forceRefresh,
- );
-
- change(response, status: RxStatus.success());
-
- for (var asignatura in response) {
- if (asignatura.id != null) {
- Get.put(
- AsignaturaController(asignatura.id!, asignatura: asignatura),
- tag: asignatura.id,
- permanent: true,
- );
- }
- }
- }
-
- void refreshAsignaturas() {
- final carrera = Get.find().selectedCarrera.value;
- getAsignaturas(carrera, forceRefresh: true);
- }
-}
-
-class AsignaturasBinding extends Bindings {
- @override
- void dependencies() {
- Get.put(AsignaturasController(), permanent: true);
- }
-}
diff --git a/lib/controllers/calculator_controller.dart b/lib/controllers/calculator_controller.dart
deleted file mode 100644
index c042466..0000000
--- a/lib/controllers/calculator_controller.dart
+++ /dev/null
@@ -1,209 +0,0 @@
-import 'package:flutter_masked_text/flutter_masked_text.dart';
-import 'package:get/get.dart';
-import 'package:mi_utem/models/evaluacion.dart';
-import 'package:mi_utem/models/grades.dart';
-
-class CalculatorController extends GetxController {
- static const maxPercentage = 100;
- static const maxGrade = 7;
- static const minimumGradeForExam = 2.95;
- static const passingGrade = 3.95;
- static const examFinalWeight = 0.4;
- static const presentationFinalWeight = 1 - examFinalWeight;
-
- final partialGrades = [].obs;
- final percentageTextFieldControllers = [].obs;
- final gradeTextFieldControllers = [].obs;
- final examGrade = Rxn();
- final examGradeTextFieldController = MaskedTextController(mask: "0.0");
- final freeEditable = false.obs;
-
- static CalculatorController get to => Get.find();
-
- double? get calculatedFinalGrade {
- if (calculatedPresentationGrade != null) {
- if (examGrade.value != null) {
- final weightedFinalGrade =
- calculatedPresentationGrade! * presentationFinalWeight;
- final weightedExamGrade = examGrade.value! * examFinalWeight;
-
- return weightedFinalGrade + weightedExamGrade;
- }
- return calculatedPresentationGrade;
- }
- return null;
- }
-
- double? get calculatedPresentationGrade {
- double presentationGrade = 0;
- for (var partialGrade in partialGrades) {
- final weight = (partialGrade.porcentaje ?? 0) / maxPercentage;
- presentationGrade += (partialGrade.nota ?? 0) * weight;
- }
-
- return presentationGrade != 0 ? presentationGrade : null;
- }
-
- int get numOfPartialGradesWithoutGrade {
- return partialGrades
- .where((partialGrade) => partialGrade.nota == null)
- .length;
- }
-
- bool get hasMissingPartialGrade {
- return numOfPartialGradesWithoutGrade > 0;
- }
-
- bool get canTakeExam {
- return !hasMissingPartialGrade &&
- calculatedPresentationGrade != null &&
- calculatedPresentationGrade! >= minimumGradeForExam &&
- calculatedPresentationGrade! < passingGrade;
- }
-
- double? get minimumRequiredExamGrade {
- if (canTakeExam) {
- final weightedPresentationGrade =
- calculatedPresentationGrade! * presentationFinalWeight;
- return (passingGrade - weightedPresentationGrade) / examFinalWeight;
- }
-
- return null;
- }
-
- double get percentageOfPartialGrades {
- double percentage = 0;
- for (var partialGrade in partialGrades) {
- percentage += (partialGrade.porcentaje ?? 0);
- }
- return percentage;
- }
-
- double get missingPercentage {
- return maxPercentage - percentageOfPartialGrades;
- }
-
- int get numOfPartialGradesWithoutPercentage {
- return partialGrades
- .where((partialGrade) => partialGrade.porcentaje == null)
- .length;
- }
-
- bool get hasMissingPercentage {
- return numOfPartialGradesWithoutPercentage > 0;
- }
-
- double? get suggestedPercentage {
- final percentage = missingPercentage / numOfPartialGradesWithoutPercentage;
- return 0 <= percentage && percentage <= maxPercentage ? percentage : null;
- }
-
- double? get suggestedPresentationGrade {
- double presentationGrade = 0;
- for (var partialGrade in partialGrades) {
- final weight = (partialGrade.porcentaje ?? (suggestedPercentage ?? 0)) /
- maxPercentage;
- presentationGrade += (partialGrade.nota ?? 0) * weight;
- }
- return 0 <= presentationGrade && presentationGrade <= maxGrade
- ? presentationGrade
- : null;
- }
-
- double get percentageWithoutGrade {
- double percentage = 0;
- for (var partialGrade in partialGrades) {
- if (partialGrade.nota == null) {
- percentage += (partialGrade.porcentaje ?? (suggestedPercentage ?? 0));
- }
- }
- return percentage;
- }
-
- bool get hasCorrectPercentage {
- return percentageOfPartialGrades == maxPercentage;
- }
-
- double? get suggestedGrade {
- if (hasMissingPartialGrade && percentageWithoutGrade > 0) {
- final weightOfMissingGrades = percentageWithoutGrade / maxPercentage;
- final requiredGradeValue =
- passingGrade - (suggestedPresentationGrade ?? 0);
- final missingGradesValue = requiredGradeValue / weightOfMissingGrades;
- return missingGradesValue;
- }
- return null;
- }
-
- void makeEditable() {
- freeEditable.value = true;
- }
-
- void makeNonEditable() {
- freeEditable.value = false;
- }
-
- void loadGrades(Grades grades) {
- partialGrades.clear();
- percentageTextFieldControllers.clear();
- gradeTextFieldControllers.clear();
-
- for (var evaluacion in grades.notasParciales) {
- final partialGrade = IEvaluacion.fromRemote(evaluacion);
- addGrade(partialGrade);
- }
-
- setExamGrade(grades.notaExamen);
- }
-
- void changeGradeAt(int index, IEvaluacion changedGrade) {
- final grade = partialGrades[index];
- if (grade.editable || freeEditable.value) {
- partialGrades[index] = changedGrade;
-
- if (hasMissingPartialGrade) {
- clearExamGrade();
- }
- } else {
- throw Exception("No se puede editar una nota que está asignada");
- }
- }
-
- void clearExamGrade() {
- examGrade.value = null;
- examGradeTextFieldController.text = "";
- }
-
- void setExamGrade(num? grade) {
- examGrade.value = grade?.toDouble();
- examGradeTextFieldController.text =
- grade?.toDouble().toStringAsFixed(1) ?? "";
- }
-
- void addGrade(IEvaluacion grade) {
- partialGrades.add(grade);
- percentageTextFieldControllers.add(
- MaskedTextController(
- mask: "000",
- text: grade.porcentaje?.toDouble().toStringAsFixed(0) ?? "",
- ),
- );
- gradeTextFieldControllers.add(
- MaskedTextController(
- mask: "0.0",
- text: grade.nota?.toDouble().toStringAsFixed(1) ?? "",
- ),
- );
- }
-
- void removeGradeAt(int index) {
- final grade = partialGrades[index];
- if (grade.editable || freeEditable.value) {
- partialGrades.removeRange(index, index + 1);
- percentageTextFieldControllers.removeRange(index, index + 1);
- gradeTextFieldControllers.removeRange(index, index + 1);
- } else {
- throw Exception("No se puede eliminar una nota que está asignada");
- }
- }
-}
diff --git a/lib/controllers/carreras_controller.dart b/lib/controllers/carreras_controller.dart
deleted file mode 100644
index a26aa56..0000000
--- a/lib/controllers/carreras_controller.dart
+++ /dev/null
@@ -1,50 +0,0 @@
-import 'package:get/get.dart';
-import 'package:mi_utem/models/carrera.dart';
-import 'package:mi_utem/services/analytics_service.dart';
-import 'package:mi_utem/services/carreras_service.dart';
-
-class CarrerasController extends GetxController {
- final carreras = [].obs;
- final selectedCarrera = Rxn();
-
- static CarrerasController get to => Get.find();
-
- @override
- void onInit() {
- getCarreras();
-
- super.onInit();
- }
-
- void getCarreras() async {
- try {
- final carreras = await CarreraService.getCarreras(forceRefresh: true);
-
- this.carreras.value = carreras;
- _autoSelectCarreraActiva(carreras);
- } catch(_) {}
- }
-
- void _autoSelectCarreraActiva(List carreras) {
- final estados = ["Regular", "Causal de Eliminacion"]
- .reversed
- .map((e) => e.toLowerCase())
- .toList();
-
- carreras.sort(
- (a, b) => estados.indexOf(b.estado!.toLowerCase()).compareTo(
- estados.indexOf(a.estado!.toLowerCase()),
- ),
- );
-
- Carrera activa = carreras.first;
-
- AnalyticsService.setCarreraToUser(activa);
-
- changeSelectedCarrera(activa);
- }
-
- void changeSelectedCarrera(Carrera carrera) {
- selectedCarrera.value = carrera;
- }
-}
diff --git a/lib/controllers/grades_changes_controller.dart b/lib/controllers/grades_changes_controller.dart
deleted file mode 100644
index 0be8fb7..0000000
--- a/lib/controllers/grades_changes_controller.dart
+++ /dev/null
@@ -1,249 +0,0 @@
-import 'dart:developer';
-
-import 'package:get_storage/get_storage.dart';
-import 'package:mi_utem/controllers/carreras_controller.dart';
-import 'package:mi_utem/models/asignatura.dart';
-import 'package:mi_utem/models/grades.dart';
-import 'package:mi_utem/services/asignaturas_service.dart';
-import 'package:mi_utem/services/auth_service.dart';
-import 'package:mi_utem/services/grades_service.dart';
-import 'package:mi_utem/services/notification_service.dart';
-import 'package:sentry_flutter/sentry_flutter.dart';
-
-class GradesChangesController {
- static const savedGradesPrefix = 'savedGrades_';
- static const suscribedAsignaturasPrefix = 'suscribedAsignaturas_';
-
- static final GetStorage box = GetStorage();
-
- static Future saveGrades(String asignaturaId, Grades grades) async {
- final jsonGrades = grades.toJson();
- jsonGrades['lastUpdate'] = DateTime.now().toIso8601String();
-
- log('Saving grades for $asignaturaId: $jsonGrades');
-
- return box.write('$savedGradesPrefix$asignaturaId', jsonGrades);
- }
-
- static GradeChangeType _getGradeValueChangeType(
- Grades oldGrades,
- Grades updatedGrades,
- ) {
- final oldGradesLength = oldGrades.notasParciales.length;
- final updatedGradesLength = updatedGrades.notasParciales.length;
-
- if (oldGradesLength == updatedGradesLength) {
- GradeChangeType? currentChange;
-
- for (int i = 0; i < oldGradesLength; i++) {
- final oldValue = oldGrades.notasParciales[i];
- final updatedValue = updatedGrades.notasParciales[i];
-
- if (oldValue.nota != updatedValue.nota) {
- if (oldValue.nota == null && updatedValue.nota != null) {
- Sentry.configureScope(
- (scope) => scope.setExtra('newGrade', updatedValue.nota),
- );
- currentChange = GradeChangeType.gradeSetted;
- } else if (oldValue.nota != null && updatedValue.nota == null) {
- currentChange = currentChange ?? GradeChangeType.gradeDeleted;
- } else {
- currentChange = currentChange ?? GradeChangeType.gradeUpdated;
- }
- }
- }
-
- if (currentChange != null) {
- return currentChange;
- }
- } else {
- Sentry.captureMessage(
- 'Asignatura $oldGrades.id has a different number of weighters in _getGradeValueChangeType function',
- level: SentryLevel.warning,
- );
- }
- return GradeChangeType.noChange;
- }
-
- static bool _hasAWeighterDiferrence(
- Grades oldGrades,
- Grades updatedGrades,
- ) {
- final oldGradesLength = oldGrades.notasParciales.length;
- final updatedGradesLength = updatedGrades.notasParciales.length;
-
- if (oldGradesLength == updatedGradesLength) {
- for (int i = 0; i < oldGradesLength; i++) {
- final oldWeighter = oldGrades.notasParciales[i];
- final updatedWeighter = updatedGrades.notasParciales[i];
-
- if (oldWeighter.porcentaje != updatedWeighter.porcentaje) {
- return true;
- }
- }
- } else {
- Sentry.captureMessage(
- 'Asignatura $oldGrades.id has a different number of weighters in _hasAWeighterDiferrence function',
- level: SentryLevel.warning,
- );
- }
- return false;
- }
-
- static bool _hasAGradeWithValue(Grades asignatura) {
- return asignatura.notasParciales.any((element) => element.nota != null);
- }
-
- static GradeChangeType compareGrades(
- String asignaturaId,
- Grades updatedGrades,
- ) {
- final oldGradesJson = box.read('$savedGradesPrefix$asignaturaId');
-
- if (oldGradesJson != null) {
- final oldGrades = Grades.fromJson(oldGradesJson);
-
- log(oldGrades.toString());
-
- final oldGradesLength = oldGrades.notasParciales.length;
- final updatedGradesLength = updatedGrades.notasParciales.length;
-
- if (oldGradesLength == 0) {
- if (updatedGradesLength == 0) {
- return GradeChangeType.noChange;
- } else {
- if (_hasAGradeWithValue(updatedGrades)) {
- return GradeChangeType.gradeSetted;
- } else {
- return GradeChangeType.weightersSetted;
- }
- }
- } else {
- if (updatedGradesLength == 0) {
- return GradeChangeType.weightersDeleted;
- } else {
- if (oldGradesLength != updatedGradesLength) {
- return GradeChangeType.weightersUpdated;
- } else {
- if (_hasAWeighterDiferrence(oldGrades, updatedGrades)) {
- return GradeChangeType.weightersUpdated;
- } else {
- return _getGradeValueChangeType(oldGrades, updatedGrades);
- }
- }
- }
- }
- } else {
- log('compareGrades oldGradesJson was null');
- }
-
- return GradeChangeType.noChange;
- }
-
- static Future