diff --git a/README.md b/README.md
index 9ffb02c..d571116 100644
--- a/README.md
+++ b/README.md
@@ -1,5 +1,5 @@
-# GestiónUH
+# Gestión UH
A UH managment app.
-[![tests](https://github.com/rmarticedeno/gestionapp/actions/workflows/tests.yml/badge.svg)](https://github.com/rmarticedeno/gestionapp/actions/workflows/tests.yml)
+[![tests](https://github.com/NODO-UH/gestionapp/actions/workflows/tests.yml/badge.svg)](https://github.com/NODO-UH/gestionapp/actions/workflows/tests.yml) [![Codemagic build status](https://api.codemagic.io/apps/607a1a18d35b7a12ffb6c7dc/607a1a18d35b7a12ffb6c7db/status_badge.svg)](https://codemagic.io/apps/607a1a18d35b7a12ffb6c7dc/607a1a18d35b7a12ffb6c7db/latest_build)
diff --git a/analysis_options.yaml b/analysis_options.yaml
index f23403b..ed0d062 100644
--- a/analysis_options.yaml
+++ b/analysis_options.yaml
@@ -2,6 +2,7 @@ include: package:lint/analysis_options.yaml
linter:
rules:
+ always_use_package_imports: true
avoid_classes_with_only_static_members: false
avoid_positional_boolean_parameters: false
constant_identifier_names: false
diff --git a/android/app/build.gradle b/android/app/build.gradle
index 9799334..b467d7a 100644
--- a/android/app/build.gradle
+++ b/android/app/build.gradle
@@ -25,6 +25,12 @@ apply plugin: 'com.android.application'
apply plugin: 'kotlin-android'
apply from: "$flutterRoot/packages/flutter_tools/gradle/flutter.gradle"
+def keystoreProperties = new Properties()
+def keystorePropertiesFile = rootProject.file('key.properties')
+if (keystorePropertiesFile.exists()) {
+ keystoreProperties.load(new FileInputStream(keystorePropertiesFile))
+}
+
android {
compileSdkVersion 29
@@ -37,7 +43,6 @@ android {
}
defaultConfig {
- // TODO: Specify your own unique Application ID (https://developer.android.com/studio/build/application-id.html).
applicationId "cu.uh.gestionuh"
minSdkVersion 18
targetSdkVersion 29
@@ -45,13 +50,20 @@ android {
versionName flutterVersionName
}
- buildTypes {
- release {
- // TODO: Add your own signing config for the release build.
- // Signing with the debug keys for now, so `flutter run --release` works.
- signingConfig signingConfigs.debug
- }
- }
+ signingConfigs {
+ release {
+ keyAlias keystoreProperties['keyAlias']
+ keyPassword keystoreProperties['keyPassword']
+ storeFile keystoreProperties['storeFile'] ? file(keystoreProperties['storeFile']) : null
+ storePassword keystoreProperties['storePassword']
+ }
+ }
+
+ buildTypes {
+ release {
+ signingConfig signingConfigs.release
+ }
+ }
}
flutter {
diff --git a/android/app/src/main/AndroidManifest.xml b/android/app/src/main/AndroidManifest.xml
index 14c5d1d..c07c30f 100644
--- a/android/app/src/main/AndroidManifest.xml
+++ b/android/app/src/main/AndroidManifest.xml
@@ -8,7 +8,7 @@
CFBundleInfoDictionaryVersion
6.0
CFBundleName
- gestionuh
+ Gestión UH
CFBundlePackageType
APPL
CFBundleShortVersionString
diff --git a/lib/app.dart b/lib/app.dart
index aab982d..acdcf5d 100644
--- a/lib/app.dart
+++ b/lib/app.dart
@@ -1,16 +1,14 @@
import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
-
-import 'deps_injector.dart';
-import 'src/data/repository/auth_repository/auth_repository.dart';
-import 'src/presentation/blocs.dart';
-import 'src/presentation/blocs/reset_password_bloc/resetpassword_bloc.dart';
-import 'src/presentation/pages.dart';
-import 'src/presentation/pages/about_page.dart';
-import 'src/presentation/pages/register_page.dart';
-import 'src/presentation/theme.dart';
-import 'src/utils/constants.dart';
-import 'src/utils/constants/routes.dart';
+import 'package:gestionuh/deps_injector.dart';
+import 'package:gestionuh/src/data/repository/auth_repository/auth_repository.dart';
+import 'package:gestionuh/src/presentation/blocs.dart';
+import 'package:gestionuh/src/presentation/pages.dart';
+import 'package:gestionuh/src/presentation/pages/about_page.dart';
+import 'package:gestionuh/src/presentation/pages/register_page.dart';
+import 'package:gestionuh/src/presentation/theme.dart';
+import 'package:gestionuh/src/utils/constants.dart';
+import 'package:gestionuh/src/utils/constants/routes.dart';
class GestionUhApp extends StatelessWidget {
@override
@@ -67,9 +65,15 @@ class GestionUhApp extends StatelessWidget {
);
case REGISTER_ROUTE_NAME:
return MaterialPageRoute(
- builder: (_) => BlocProvider(
- create: (_) => di()..add(QuestionsRequestedRegister()),
- child: const RegisterPage(),
+ builder: (_) => Overlay(
+ initialEntries: [
+ OverlayEntry(builder: (context) {
+ return BlocProvider(
+ create: (_) => di()..add(QuestionsRequestedRegister()),
+ child: const RegisterPage(),
+ );
+ }),
+ ],
),
);
case ABOUT_ROUTE_NAME:
diff --git a/lib/deps_injector.dart b/lib/deps_injector.dart
index 8e8f7d3..1dff131 100644
--- a/lib/deps_injector.dart
+++ b/lib/deps_injector.dart
@@ -1,13 +1,11 @@
import 'package:flutter_secure_storage/flutter_secure_storage.dart';
+import 'package:gestionuh/src/data/api/api.dart';
+import 'package:gestionuh/src/data/local.dart';
+import 'package:gestionuh/src/data/repository.dart';
+import 'package:gestionuh/src/presentation/blocs.dart';
import 'package:get_it/get_it.dart';
import 'package:shared_preferences/shared_preferences.dart';
-import 'src/data/api/api.dart';
-import 'src/data/local.dart';
-import 'src/data/repository.dart';
-import 'src/presentation/blocs.dart';
-import 'src/presentation/blocs/reset_password_bloc/resetpassword_bloc.dart';
-
final di = GetIt.instance;
Future init() async {
diff --git a/lib/main.dart b/lib/main.dart
index a4643f6..76adcfe 100644
--- a/lib/main.dart
+++ b/lib/main.dart
@@ -1,8 +1,7 @@
import 'package:flutter/material.dart';
-
-import 'app.dart';
-import 'deps_injector.dart';
-import 'src/data/repository/auth_repository/auth_repository.dart';
+import 'package:gestionuh/app.dart';
+import 'package:gestionuh/deps_injector.dart';
+import 'package:gestionuh/src/data/repository/auth_repository/auth_repository.dart';
Future main() async {
await initialize();
diff --git a/lib/src/data/api/api.dart b/lib/src/data/api/api.dart
index 12d68bf..0e4119b 100644
--- a/lib/src/data/api/api.dart
+++ b/lib/src/data/api/api.dart
@@ -1,9 +1,8 @@
import 'dart:convert';
import 'package:dio/dio.dart';
-
-import '../../utils/constants.dart';
-import '../models.dart';
+import 'package:gestionuh/src/data/models.dart';
+import 'package:gestionuh/src/utils/constants.dart';
typedef ClassBuilder = T Function(
Map json);
@@ -88,7 +87,7 @@ class GestionApi {
);
}
- UserData response = await apiRequest(
+ final UserData response = await apiRequest(
Constants.userDataUrl,
() => UserData(),
null,
@@ -252,16 +251,16 @@ class GestionApi {
queryParameters: queryParams,
);
} catch (error) {
- target.error = error.toString();
+ target.error = Errors.retrieveError(error.toString());
return target;
}
if (builder != null) {
try {
if (response.statusCode! >= 300) {
- Error error = Error.fromJson(
+ final Error error = Error.fromJson(
jsonDecode(response.data!) as Map);
- target.error = error.message;
+ target.error = error.code.toString();
} else {
target = builder(jsonDecode(response.data!) as Map);
}
@@ -270,6 +269,10 @@ class GestionApi {
}
}
+ if (target.error != null) {
+ target.error = Errors.retrieveError(target.error!);
+ }
+
return target;
}
}
diff --git a/lib/src/data/models/auth.dart b/lib/src/data/models/auth.dart
index e4be754..33ca826 100644
--- a/lib/src/data/models/auth.dart
+++ b/lib/src/data/models/auth.dart
@@ -12,5 +12,6 @@ class Auth extends BaseModel {
static Auth fromJson(Map json) => _$AuthFromJson(json);
+ @override
Map toJson() => _$AuthToJson(this);
}
diff --git a/lib/src/data/models/error.dart b/lib/src/data/models/error.dart
index 5493e6d..cfef5e1 100644
--- a/lib/src/data/models/error.dart
+++ b/lib/src/data/models/error.dart
@@ -12,5 +12,6 @@ class Error extends BaseModel {
static Error fromJson(Map json) => _$ErrorFromJson(json);
+ @override
Map toJson() => _$ErrorToJson(this);
}
diff --git a/lib/src/data/models/login.dart b/lib/src/data/models/login.dart
index 379c4c6..8dadb47 100644
--- a/lib/src/data/models/login.dart
+++ b/lib/src/data/models/login.dart
@@ -12,5 +12,6 @@ class Login extends BaseModel {
static Login fromJson(Map json) => _$LoginFromJson(json);
+ @override
Map toJson() => _$LoginToJson(this);
}
diff --git a/lib/src/data/models/mail_quota.dart b/lib/src/data/models/mail_quota.dart
index 7e81579..df8ad54 100644
--- a/lib/src/data/models/mail_quota.dart
+++ b/lib/src/data/models/mail_quota.dart
@@ -13,5 +13,6 @@ class MailQuota extends BaseModel {
static MailQuota fromJson(Map json) =>
_$MailQuotaFromJson(json);
+ @override
Map toJson() => _$MailQuotaToJson(this);
}
diff --git a/lib/src/data/models/pass_reset.dart b/lib/src/data/models/pass_reset.dart
index 5d5105f..8e66386 100644
--- a/lib/src/data/models/pass_reset.dart
+++ b/lib/src/data/models/pass_reset.dart
@@ -13,5 +13,6 @@ class PassReset extends BaseModel {
static PassReset fromJson(Map json) =>
_$PassResetFromJson(json);
+ @override
Map toJson() => _$PassResetToJson(this);
}
diff --git a/lib/src/data/models/password_edit_data.dart b/lib/src/data/models/password_edit_data.dart
index bafc070..b507bb0 100644
--- a/lib/src/data/models/password_edit_data.dart
+++ b/lib/src/data/models/password_edit_data.dart
@@ -15,5 +15,6 @@ class PasswordEditData extends BaseModel {
static PasswordEditData fromJson(Map json) =>
_$PasswordEditDataFromJson(json);
+ @override
Map toJson() => _$PasswordEditDataToJson(this);
}
diff --git a/lib/src/data/models/password_reset_data.dart b/lib/src/data/models/password_reset_data.dart
index 3499045..3b0cf4b 100644
--- a/lib/src/data/models/password_reset_data.dart
+++ b/lib/src/data/models/password_reset_data.dart
@@ -15,5 +15,6 @@ class PasswordResetData extends BaseModel {
static PasswordResetData fromJson(Map json) =>
_$PasswordResetDataFromJson(json);
+ @override
Map toJson() => _$PasswordResetDataToJson(this);
}
diff --git a/lib/src/data/models/password_reset_user_id.dart b/lib/src/data/models/password_reset_user_id.dart
index 89e2fa4..e93c51e 100644
--- a/lib/src/data/models/password_reset_user_id.dart
+++ b/lib/src/data/models/password_reset_user_id.dart
@@ -12,5 +12,6 @@ class PasswordResetUserId extends BaseModel {
static PasswordResetUserId fromJson(Map json) =>
_$PasswordResetUserIdFromJson(json);
+ @override
Map toJson() => _$PasswordResetUserIdToJson(this);
}
diff --git a/lib/src/data/models/quota.dart b/lib/src/data/models/quota.dart
index 314af8f..e8eeff7 100644
--- a/lib/src/data/models/quota.dart
+++ b/lib/src/data/models/quota.dart
@@ -13,5 +13,6 @@ class Quota extends BaseModel {
static Quota fromJson(Map json) => _$QuotaFromJson(json);
+ @override
Map toJson() => _$QuotaToJson(this);
}
diff --git a/lib/src/data/models/security_questions.dart b/lib/src/data/models/security_questions.dart
index ee220db..2aa4a69 100644
--- a/lib/src/data/models/security_questions.dart
+++ b/lib/src/data/models/security_questions.dart
@@ -12,5 +12,6 @@ class SecurityQuestions extends BaseModel {
static SecurityQuestions fromJson(Map json) =>
_$SecurityQuestionsFromJson(json);
+ @override
Map toJson() => _$SecurityQuestionsToJson(this);
}
diff --git a/lib/src/data/models/user_ci.dart b/lib/src/data/models/user_ci.dart
index c1d20ea..10a6beb 100644
--- a/lib/src/data/models/user_ci.dart
+++ b/lib/src/data/models/user_ci.dart
@@ -11,5 +11,6 @@ class UserCi extends BaseModel {
static UserCi fromJson(Map json) => _$UserCiFromJson(json);
+ @override
Map toJson() => _$UserCiToJson(this);
}
diff --git a/lib/src/data/models/user_data.dart b/lib/src/data/models/user_data.dart
index 98bf6bd..4112b0e 100644
--- a/lib/src/data/models/user_data.dart
+++ b/lib/src/data/models/user_data.dart
@@ -28,5 +28,6 @@ class UserData extends BaseModel {
static UserData fromJson(Map json) =>
_$UserDataFromJson(json);
+ @override
Map toJson() => _$UserDataToJson(this);
}
diff --git a/lib/src/data/models/user_id.dart b/lib/src/data/models/user_id.dart
index e17b127..da65fc3 100644
--- a/lib/src/data/models/user_id.dart
+++ b/lib/src/data/models/user_id.dart
@@ -11,5 +11,6 @@ class UserId extends BaseModel {
static UserId fromJson(Map json) => _$UserIdFromJson(json);
+ @override
Map toJson() => _$UserIdToJson(this);
}
diff --git a/lib/src/data/repository/auth_repository/auth_repository.dart b/lib/src/data/repository/auth_repository/auth_repository.dart
index 38a1db7..382b648 100644
--- a/lib/src/data/repository/auth_repository/auth_repository.dart
+++ b/lib/src/data/repository/auth_repository/auth_repository.dart
@@ -1,10 +1,10 @@
import 'dart:developer';
-import '../../../utils/constants/storage_keys.dart';
-import '../../api/api.dart';
-import '../../local/local_storage.dart';
-import '../../models.dart';
-import '../../models/status.dart';
+import 'package:gestionuh/src/data/api/api.dart';
+import 'package:gestionuh/src/data/local/local_storage.dart';
+import 'package:gestionuh/src/data/models.dart';
+import 'package:gestionuh/src/data/models/status.dart';
+import 'package:gestionuh/src/utils/constants/storage_keys.dart';
class AuthRepository {
final GestionApi api;
diff --git a/lib/src/presentation/blocs/login_bloc/login_bloc.dart b/lib/src/presentation/blocs/login_bloc/login_bloc.dart
index 40cf59f..88e2ec7 100644
--- a/lib/src/presentation/blocs/login_bloc/login_bloc.dart
+++ b/lib/src/presentation/blocs/login_bloc/login_bloc.dart
@@ -1,6 +1,6 @@
import 'package:flutter_bloc/flutter_bloc.dart';
-
-import '../../../data/repository.dart';
+import 'package:gestionuh/src/data/repository.dart';
+import 'package:gestionuh/src/utils/constants.dart';
part 'login_event.dart';
part 'login_state.dart';
@@ -28,7 +28,7 @@ class LoginBloc extends Bloc {
);
if (result == null) {
yield LoginAttemptInitial(
- error: 'Ha ocurrido un error inesperado.',
+ error: Errors.DefaultError,
);
} else if (result.error != null) {
yield LoginAttemptInitial(
diff --git a/lib/src/presentation/blocs/mail_quota_bloc/mail_quota_bloc.dart b/lib/src/presentation/blocs/mail_quota_bloc/mail_quota_bloc.dart
index b62aeaa..77f8cca 100644
--- a/lib/src/presentation/blocs/mail_quota_bloc/mail_quota_bloc.dart
+++ b/lib/src/presentation/blocs/mail_quota_bloc/mail_quota_bloc.dart
@@ -1,6 +1,7 @@
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:gestionuh/src/data/models.dart';
import 'package:gestionuh/src/data/repository.dart';
+import 'package:gestionuh/src/utils/constants.dart';
part 'mail_quota_event.dart';
part 'mail_quota_state.dart';
@@ -25,7 +26,7 @@ class MailQuotaBloc extends Bloc {
final result = await mailQuotasRepository.getQuota();
if (result == null) {
yield MailQuotaLoadedFailure(
- error: 'Ha ocurrido un error inesperado.',
+ error: Errors.DefaultError,
);
} else if (result.error != null) {
yield MailQuotaLoadedFailure(
diff --git a/lib/src/presentation/blocs/profile_bloc/profile_bloc.dart b/lib/src/presentation/blocs/profile_bloc/profile_bloc.dart
index fb3c1df..bac8cbd 100644
--- a/lib/src/presentation/blocs/profile_bloc/profile_bloc.dart
+++ b/lib/src/presentation/blocs/profile_bloc/profile_bloc.dart
@@ -1,6 +1,7 @@
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:gestionuh/src/data/models.dart';
import 'package:gestionuh/src/data/repository.dart';
+import 'package:gestionuh/src/utils/constants.dart';
part 'profile_event.dart';
part 'profile_state.dart';
@@ -25,7 +26,7 @@ class ProfileBloc extends Bloc {
final result = await profileRepository.getUserData();
if (result == null) {
yield ProfileLoadedFailure(
- error: 'Ha ocurrido un error inesperado.',
+ error: Errors.DefaultError,
);
} else if (result.error != null) {
yield ProfileLoadedFailure(
diff --git a/lib/src/presentation/blocs/quota_bloc/quota_bloc.dart b/lib/src/presentation/blocs/quota_bloc/quota_bloc.dart
index 80174dd..4ec5bf5 100644
--- a/lib/src/presentation/blocs/quota_bloc/quota_bloc.dart
+++ b/lib/src/presentation/blocs/quota_bloc/quota_bloc.dart
@@ -1,6 +1,7 @@
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:gestionuh/src/data/models.dart';
import 'package:gestionuh/src/data/repository.dart';
+import 'package:gestionuh/src/utils/constants.dart';
part 'quota_event.dart';
part 'quota_state.dart';
@@ -24,7 +25,7 @@ class QuotaBloc extends Bloc {
final result = await quotasRepository.getQuota();
if (result == null) {
yield QuotaLoadedFailure(
- error: 'Ha ocurrido un error inesperado.',
+ error: Errors.DefaultError,
);
} else if (result.error != null) {
yield QuotaLoadedFailure(
diff --git a/lib/src/presentation/blocs/recover_password_bloc/recover_password_bloc.dart b/lib/src/presentation/blocs/recover_password_bloc/recover_password_bloc.dart
index a123b7f..16da32c 100644
--- a/lib/src/presentation/blocs/recover_password_bloc/recover_password_bloc.dart
+++ b/lib/src/presentation/blocs/recover_password_bloc/recover_password_bloc.dart
@@ -5,6 +5,7 @@ import 'package:flutter/material.dart';
import 'package:gestionuh/src/data/models.dart';
import 'package:gestionuh/src/data/repository.dart';
import 'package:meta/meta.dart';
+import 'package:gestionuh/src/utils/constants.dart';
part 'recover_password_event.dart';
part 'recover_password_state.dart';
@@ -38,7 +39,7 @@ class RecoverPasswordBloc
if (result == null) {
yield RecoverPasswordCIError(
ci: event.state.ci,
- error: 'Ha ocurrido un error inesperado.',
+ error: Errors.DefaultError,
);
} else if (result.error != null) {
yield RecoverPasswordCIError(
@@ -48,7 +49,7 @@ class RecoverPasswordBloc
} else if (result.questions == null) {
yield RecoverPasswordCIError(
ci: event.state.ci,
- error: 'Ha ocurrido un error inesperado.',
+ error: Errors.DefaultError,
);
} else {
yield RecoverPasswordQuestions(
@@ -83,7 +84,7 @@ class RecoverPasswordBloc
questions: event.state.questions,
answers: event.state.answers,
password: event.state.password,
- error: 'Ha ocurrido un error inesperado.',
+ error: Errors.DefaultError,
);
} else if (result.error != null) {
yield RecoverPasswordQuestionsError(
@@ -99,7 +100,7 @@ class RecoverPasswordBloc
questions: event.state.questions,
answers: event.state.answers,
password: event.state.password,
- error: 'Ha ocurrido un error inesperado.',
+ error: Errors.DefaultError,
);
} else {
yield RecoverPasswordSuccess(userId: result.userId!);
diff --git a/lib/src/presentation/blocs/register_bloc/register_bloc.dart b/lib/src/presentation/blocs/register_bloc/register_bloc.dart
index 5f6142a..e09599f 100644
--- a/lib/src/presentation/blocs/register_bloc/register_bloc.dart
+++ b/lib/src/presentation/blocs/register_bloc/register_bloc.dart
@@ -1,9 +1,8 @@
import 'dart:async';
import 'package:bloc/bloc.dart';
-
-import '../../../data/models/password_edit_data.dart';
-import '../../../data/repository/auth_repository/auth_repository.dart';
+import 'package:gestionuh/src/data/models/password_edit_data.dart';
+import 'package:gestionuh/src/data/repository/auth_repository/auth_repository.dart';
part 'register_event.dart';
part 'register_state.dart';
diff --git a/lib/src/presentation/blocs/reset_password_bloc/resetpassword_bloc.dart b/lib/src/presentation/blocs/reset_password_bloc/resetpassword_bloc.dart
index 959c90e..c2737c3 100644
--- a/lib/src/presentation/blocs/reset_password_bloc/resetpassword_bloc.dart
+++ b/lib/src/presentation/blocs/reset_password_bloc/resetpassword_bloc.dart
@@ -1,8 +1,7 @@
import 'dart:async';
import 'package:bloc/bloc.dart';
-
-import '../../../data/repository.dart';
+import 'package:gestionuh/src/data/repository.dart';
part 'resetpassword_event.dart';
part 'resetpassword_state.dart';
diff --git a/lib/src/presentation/pages/about_page.dart b/lib/src/presentation/pages/about_page.dart
index d579fcb..fe1a8cb 100644
--- a/lib/src/presentation/pages/about_page.dart
+++ b/lib/src/presentation/pages/about_page.dart
@@ -1,9 +1,8 @@
-import 'package:flash/flash.dart';
import 'package:flutter/material.dart';
+import 'package:gestionuh/src/presentation/widgets/flash_helper.dart';
+import 'package:gestionuh/src/utils/constants.dart';
import 'package:url_launcher/url_launcher.dart';
-import '../../utils/constants.dart';
-
class AboutInformationPage extends StatelessWidget {
const AboutInformationPage({Key? key}) : super(key: key);
@@ -89,9 +88,9 @@ class AboutInformationPage extends StatelessWidget {
if (await canLaunch(e.link!)) {
await launch(e.link!);
} else {
- _showCenterFlash(
+ FlashHelper.errorBar(
context,
- error:
+ message:
'No puede acceder a ${e.link}',
);
}
@@ -126,9 +125,9 @@ class AboutInformationPage extends StatelessWidget {
if (await canLaunch(url)) {
await launch(url);
} else {
- _showCenterFlash(
+ FlashHelper.errorBar(
context,
- error: 'No puede acceder a $url',
+ message: 'No puede acceder a $url',
);
}
},
@@ -168,41 +167,6 @@ class AboutInformationPage extends StatelessWidget {
),
);
}
-
- void _showCenterFlash(
- BuildContext context, {
- String? error,
- FlashPosition position = FlashPosition.top,
- FlashStyle style = FlashStyle.floating,
- Alignment? alignment,
- }) {
- showFlash(
- context: context,
- duration: const Duration(seconds: 5),
- builder: (_, controller) {
- return Flash(
- controller: controller,
- backgroundColor: Colors.black87,
- borderRadius: BorderRadius.circular(8.0),
- borderColor: Colors.blue,
- position: position,
- style: style,
- alignment: alignment,
- enableDrag: false,
- onTap: () => controller.dismiss(),
- child: Padding(
- padding: const EdgeInsets.all(12.0),
- child: DefaultTextStyle(
- style: const TextStyle(color: Colors.white),
- child: Text(
- error!,
- ),
- ),
- ),
- );
- },
- );
- }
}
class DeveloperInfo {
diff --git a/lib/src/presentation/pages/login_page.dart b/lib/src/presentation/pages/login_page.dart
index 8295410..bbdeb4c 100644
--- a/lib/src/presentation/pages/login_page.dart
+++ b/lib/src/presentation/pages/login_page.dart
@@ -1,13 +1,12 @@
-import 'package:flash/flash.dart';
import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
-
-import '../../../deps_injector.dart';
-import '../../data/repository.dart';
-import '../../utils/constants/routes.dart';
-import '../blocs.dart';
-import '../widgets.dart';
-import '../widgets/bottom_sheet.dart';
+import 'package:gestionuh/deps_injector.dart';
+import 'package:gestionuh/src/data/repository.dart';
+import 'package:gestionuh/src/presentation/blocs.dart';
+import 'package:gestionuh/src/presentation/widgets.dart';
+import 'package:gestionuh/src/presentation/widgets/bottom_sheet.dart';
+import 'package:gestionuh/src/presentation/widgets/flash_helper.dart';
+import 'package:gestionuh/src/utils/constants/routes.dart';
class LoginPage extends StatefulWidget {
const LoginPage({Key? key}) : super(key: key);
@@ -61,11 +60,7 @@ class _LoginPageState extends State {
Navigator.of(context).pushReplacementNamed(PROFILE_ROUTE_NAME);
}
if (state is LoginAttemptInitial) {
- _showCenterFlash(
- error: state.error,
- position: FlashPosition.top,
- style: FlashStyle.floating,
- );
+ FlashHelper.errorBar(context, message: state.error);
}
},
builder: (context, state) {
@@ -188,38 +183,4 @@ class _LoginPageState extends State {
),
);
}
-
- void _showCenterFlash({
- required String error,
- FlashPosition? position,
- FlashStyle? style,
- Alignment? alignment,
- }) {
- showFlash(
- context: context,
- duration: const Duration(seconds: 5),
- builder: (_, controller) {
- return Flash(
- controller: controller,
- backgroundColor: Colors.black87,
- borderRadius: BorderRadius.circular(8.0),
- borderColor: Colors.blue,
- position: position,
- style: style,
- alignment: alignment,
- enableDrag: false,
- onTap: () => controller.dismiss(),
- child: Padding(
- padding: const EdgeInsets.all(12.0),
- child: DefaultTextStyle(
- style: const TextStyle(color: Colors.white),
- child: Text(
- error,
- ),
- ),
- ),
- );
- },
- );
- }
}
diff --git a/lib/src/presentation/pages/mail_quotas_page.dart b/lib/src/presentation/pages/mail_quotas_page.dart
index df3bc50..a54b113 100644
--- a/lib/src/presentation/pages/mail_quotas_page.dart
+++ b/lib/src/presentation/pages/mail_quotas_page.dart
@@ -1,9 +1,8 @@
import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
-
-import '../blocs.dart';
-import '../widgets.dart';
-import '../widgets/bottom_sheet.dart';
+import 'package:gestionuh/src/presentation/blocs.dart';
+import 'package:gestionuh/src/presentation/widgets.dart';
+import 'package:gestionuh/src/presentation/widgets/bottom_sheet.dart';
class MailQuotaPage extends StatefulWidget {
const MailQuotaPage({Key? key}) : super(key: key);
diff --git a/lib/src/presentation/pages/profile_page.dart b/lib/src/presentation/pages/profile_page.dart
index 663f476..01fc82b 100644
--- a/lib/src/presentation/pages/profile_page.dart
+++ b/lib/src/presentation/pages/profile_page.dart
@@ -1,9 +1,8 @@
import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
-
-import '../blocs.dart';
-import '../widgets.dart';
-import '../widgets/bottom_sheet.dart';
+import 'package:gestionuh/src/presentation/blocs.dart';
+import 'package:gestionuh/src/presentation/widgets.dart';
+import 'package:gestionuh/src/presentation/widgets/bottom_sheet.dart';
class ProfilePage extends StatefulWidget {
const ProfilePage({Key? key}) : super(key: key);
diff --git a/lib/src/presentation/pages/quota_page.dart b/lib/src/presentation/pages/quota_page.dart
index 2b96743..aed4694 100644
--- a/lib/src/presentation/pages/quota_page.dart
+++ b/lib/src/presentation/pages/quota_page.dart
@@ -1,9 +1,8 @@
import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
-
-import '../blocs.dart';
-import '../widgets.dart';
-import '../widgets/bottom_sheet.dart';
+import 'package:gestionuh/src/presentation/blocs.dart';
+import 'package:gestionuh/src/presentation/widgets.dart';
+import 'package:gestionuh/src/presentation/widgets/bottom_sheet.dart';
class QuotaPage extends StatefulWidget {
const QuotaPage({Key? key}) : super(key: key);
diff --git a/lib/src/presentation/pages/recover_password_page.dart b/lib/src/presentation/pages/recover_password_page.dart
index e894342..185da32 100644
--- a/lib/src/presentation/pages/recover_password_page.dart
+++ b/lib/src/presentation/pages/recover_password_page.dart
@@ -1,8 +1,8 @@
-import 'package:flash/flash.dart';
import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:gestionuh/src/presentation/blocs.dart';
import 'package:gestionuh/src/presentation/widgets.dart';
+import 'package:gestionuh/src/presentation/widgets/flash_helper.dart';
import 'package:gestionuh/src/utils/validators.dart';
class RecoverPasswordPage extends StatelessWidget {
@@ -19,11 +19,7 @@ class RecoverPasswordPage extends StatelessWidget {
body: BlocConsumer(
listener: (context, state) {
if (state is RecoverPasswordError) {
- _showCenterFlash(
- context: context,
- message: state.error,
- borderColor: Colors.red,
- );
+ FlashHelper.errorBar(context, message: state.error);
}
},
builder: (context, state) {
@@ -219,40 +215,4 @@ class RecoverPasswordPage extends StatelessWidget {
},
));
}
-
- void _showCenterFlash({
- required BuildContext context,
- required String message,
- FlashPosition position = FlashPosition.top,
- FlashStyle style = FlashStyle.floating,
- Alignment? alignment,
- Color? borderColor,
- }) {
- showFlash(
- context: context,
- duration: const Duration(seconds: 5),
- builder: (_, controller) {
- return Flash(
- controller: controller,
- backgroundColor: Colors.black87,
- borderRadius: BorderRadius.circular(8.0),
- borderColor: borderColor ?? Colors.black,
- position: position,
- style: style,
- alignment: alignment,
- enableDrag: false,
- onTap: () => controller.dismiss(),
- child: Padding(
- padding: const EdgeInsets.all(12.0),
- child: DefaultTextStyle(
- style: const TextStyle(color: Colors.white),
- child: Text(
- message,
- ),
- ),
- ),
- );
- },
- );
- }
}
diff --git a/lib/src/presentation/pages/register_page.dart b/lib/src/presentation/pages/register_page.dart
index 5722c37..4b1f967 100644
--- a/lib/src/presentation/pages/register_page.dart
+++ b/lib/src/presentation/pages/register_page.dart
@@ -1,14 +1,13 @@
import 'package:collection/collection.dart' show IterableExtension;
-import 'package:flash/flash.dart';
import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
-
-import '../../utils/constants.dart';
-import '../../utils/pair.dart';
-import '../../utils/validators.dart';
-import '../blocs.dart';
-import '../widgets.dart';
-import '../widgets/bottom_sheet.dart';
+import 'package:gestionuh/src/presentation/blocs.dart';
+import 'package:gestionuh/src/presentation/widgets.dart';
+import 'package:gestionuh/src/presentation/widgets/bottom_sheet.dart';
+import 'package:gestionuh/src/presentation/widgets/flash_helper.dart';
+import 'package:gestionuh/src/utils/constants.dart';
+import 'package:gestionuh/src/utils/pair.dart';
+import 'package:gestionuh/src/utils/validators.dart';
class RegisterPage extends StatefulWidget {
const RegisterPage({Key? key}) : super(key: key);
@@ -95,10 +94,7 @@ class _RegisterPageState extends State {
body: BlocConsumer(
listener: (context, state) async {
if (state is RegisterUserFailure) {
- _showCenterFlash(
- message: state.error,
- borderColor: Colors.red,
- );
+ FlashHelper.errorBar(context, message: state.error);
} else if (state is LoadInitialDataFailure) {
Future.delayed(
const Duration(seconds: 2),
@@ -107,16 +103,8 @@ class _RegisterPageState extends State {
.add(QuestionsRequestedRegister()),
);
} else if (state is RegisterUserSuccess) {
- _showCenterFlash(
- message:
- 'Operación Completada. Su correo electrónico es ${state.userEmail}.',
- borderColor: Colors.green,
- );
- Future.delayed(
- const Duration(seconds: 4),
- () => Navigator.of(context)
- ..popUntil((_) => Navigator.of(context).canPop())
- ..pushNamed(LOGIN_ROUTE_NAME));
+ FlashHelper.infoBar(context,
+ message: 'El usuario fue registrado correctamente.');
}
},
builder: (context, state) {
@@ -127,129 +115,164 @@ class _RegisterPageState extends State {
.toList();
questionsTaken = List.filled(questions.length, -1);
}
- return SingleChildScrollView(
- child: Padding(
- padding: const EdgeInsets.only(
- top: 30, bottom: 9, left: 18, right: 18),
- child: Form(
- key: _formKey,
- autovalidateMode: AutovalidateMode.disabled,
- child: Column(
- mainAxisSize: MainAxisSize.min,
- children: [
- Text(
- 'Todos los campos son obligatorios.*',
- style: Theme.of(context)
- .textTheme
- .headline6!
- .copyWith(fontSize: 14, color: Colors.black45),
- textAlign: TextAlign.center,
- ),
- const SizedBox(
- height: 30,
- ),
- Column(
- crossAxisAlignment: CrossAxisAlignment.start,
- children: [
- Text(
- 'Número de Carnet De Identidad',
- style: headlineTextsTheme,
- ),
- GestionUhDefaultTextField(
- hintText: '###########',
- autovalidateMode: AutovalidateMode.disabled,
- controller: ciController,
- validator: identityNumberCIValidator,
- keyboardType: TextInputType.number,
- ),
- ]),
- const SizedBox(
- height: 15,
- ),
- Column(
- crossAxisAlignment: CrossAxisAlignment.start,
- children: [
- Text(
- 'Contraseña',
- style: headlineTextsTheme,
- ),
- GestionUhDefaultTextField(
- hintText: '********',
- autovalidateMode: AutovalidateMode.disabled,
- controller: passwordFirstController,
- validator: safetyPasswordValidator,
- keyboardType: TextInputType.visiblePassword,
- borderRadius: const BorderRadius.only(
- topLeft: Radius.circular(5),
- bottomLeft: Radius.circular(5),
+ if (state is RegisterUserFailure ||
+ state is LoadInitialDataSuccess ||
+ state is LoadInitialDataInProgress ||
+ state is LoadInitialDataFailure) {
+ return SingleChildScrollView(
+ child: Padding(
+ padding: const EdgeInsets.only(
+ top: 30, bottom: 9, left: 18, right: 18),
+ child: Form(
+ key: _formKey,
+ autovalidateMode: AutovalidateMode.disabled,
+ child: Column(
+ mainAxisSize: MainAxisSize.min,
+ children: [
+ Text(
+ 'Todos los campos son obligatorios.*',
+ style: Theme.of(context)
+ .textTheme
+ .headline6!
+ .copyWith(fontSize: 14, color: Colors.black45),
+ textAlign: TextAlign.center,
+ ),
+ const SizedBox(
+ height: 30,
+ ),
+ Column(
+ crossAxisAlignment: CrossAxisAlignment.start,
+ children: [
+ Text(
+ 'Número de Carnet De Identidad',
+ style: headlineTextsTheme,
),
- ),
- ]),
- const SizedBox(
- height: 20,
- ),
- Column(
- crossAxisAlignment: CrossAxisAlignment.start,
+ GestionUhDefaultTextField(
+ hintText: '###########',
+ autovalidateMode: AutovalidateMode.disabled,
+ controller: ciController,
+ validator: identityNumberCIValidator,
+ keyboardType: TextInputType.number,
+ ),
+ ]),
+ const SizedBox(
+ height: 15,
+ ),
+ Column(
+ crossAxisAlignment: CrossAxisAlignment.start,
+ children: [
+ Text(
+ 'Contraseña',
+ style: headlineTextsTheme,
+ ),
+ GestionUhDefaultTextField(
+ hintText: '********',
+ autovalidateMode: AutovalidateMode.disabled,
+ controller: passwordFirstController,
+ validator: safetyPasswordValidator,
+ keyboardType: TextInputType.visiblePassword,
+ borderRadius: const BorderRadius.only(
+ topLeft: Radius.circular(5),
+ bottomLeft: Radius.circular(5),
+ ),
+ ),
+ ]),
+ const SizedBox(
+ height: 20,
+ ),
+ Column(
+ crossAxisAlignment: CrossAxisAlignment.start,
+ children: [
+ Text(
+ 'Repetir Contraseña',
+ style: headlineTextsTheme,
+ ),
+ GestionUhDefaultTextField(
+ hintText: '********',
+ autovalidateMode: AutovalidateMode.disabled,
+ controller: passwordSecondController,
+ validator: safetyPasswordValidator,
+ keyboardType: TextInputType.visiblePassword,
+ borderRadius: const BorderRadius.only(
+ topLeft: Radius.circular(5),
+ bottomLeft: Radius.circular(5),
+ ),
+ ),
+ ]),
+ const SizedBox(
+ height: 20,
+ ),
+ Text(
+ 'Introduzca respuesta para las preguntas de seguridad de su preferencia.',
+ style: Theme.of(context)
+ .textTheme
+ .headline6!
+ .copyWith(fontSize: 14, color: Colors.black45),
+ textAlign: TextAlign.center,
+ ),
+ Builder(
+ builder: (BuildContext context) {
+ final childrenQuest = [];
+ const length = NUMBER_OF_SECURITY_QUESTIONS_NEEDED;
+ for (int i = 0; i < length; i++) {
+ childrenQuest.add(buildQuestionZone(i));
+ }
+ return Column(
+ crossAxisAlignment: CrossAxisAlignment.stretch,
+ children: childrenQuest,
+ );
+ },
+ ),
+ const SizedBox(height: 10),
+ GestionUhDefaultButton(
+ text: 'Finalizar',
+ onPressed: _onRegisterAction,
+ ),
+ const SizedBox(height: 30),
+ ],
+ ),
+ ),
+ ),
+ );
+ } else if (state is RegisterUserSuccess) {
+ return Container(
+ margin: const EdgeInsets.all(30),
+ child: Column(
+ mainAxisAlignment: MainAxisAlignment.center,
+ children: [
+ RichText(
+ textAlign: TextAlign.center,
+ text: TextSpan(
+ style: Theme.of(context).textTheme.subtitle1,
children: [
- Text(
- 'Repetir Contraseña',
- style: headlineTextsTheme,
+ const TextSpan(
+ text: 'Se ha registrado correctamente '
+ 'su correo es ',
),
- GestionUhDefaultTextField(
- hintText: '********',
- autovalidateMode: AutovalidateMode.disabled,
- controller: passwordSecondController,
- validator: safetyPasswordValidator,
- keyboardType: TextInputType.visiblePassword,
- borderRadius: const BorderRadius.only(
- topLeft: Radius.circular(5),
- bottomLeft: Radius.circular(5),
- ),
+ TextSpan(
+ text: '"${state.userEmail}"',
+ style: Theme.of(context)
+ .textTheme
+ .subtitle1
+ ?.copyWith(color: Colors.red),
+ ),
+ const TextSpan(
+ text: ', anótelo de ser necesario '
+ 'no se mostrará otra vez',
),
]),
- const SizedBox(
- height: 20,
- ),
- Text(
- 'Introduzca respuesta para las preguntas de seguridad de su preferencia.',
- style: Theme.of(context)
- .textTheme
- .headline6!
- .copyWith(fontSize: 14, color: Colors.black45),
- textAlign: TextAlign.center,
- ),
- Builder(
- builder: (BuildContext context) {
- final childrenQuest = [];
- const length = NUMBER_OF_SECURITY_QUESTIONS_NEEDED;
- for (int i = 0; i < length; i++) {
- childrenQuest.add(buildQuestionZone(i));
- }
- return Column(
- crossAxisAlignment: CrossAxisAlignment.stretch,
- children: childrenQuest,
- );
- },
- ),
- const SizedBox(height: 10),
- GestionUhDefaultButton(
- text: 'Finalizar',
- onPressed: _onRegisterAction,
- ),
- const SizedBox(height: 30),
- ],
- ),
+ ),
+ const SizedBox(height: 30),
+ GestionUhDefaultButton(
+ onPressed: () => Navigator.of(context).pop(),
+ child: const Text('Ok'),
+ ),
+ ],
),
- ),
- );
- // return Center(
- // child: Column(
- // mainAxisAlignment: MainAxisAlignment.center,
- // children: [
- // GestionUhLoadingIndicator(),
- // ],
- // ),
- // );
+ );
+ } else {
+ return Container();
+ }
},
),
);
@@ -313,39 +336,4 @@ class _RegisterPageState extends State {
),
);
}
-
- void _showCenterFlash({
- required String message,
- FlashPosition position = FlashPosition.top,
- FlashStyle style = FlashStyle.floating,
- Alignment? alignment,
- Color? borderColor,
- }) {
- showFlash(
- context: context,
- duration: const Duration(seconds: 5),
- builder: (_, controller) {
- return Flash(
- controller: controller,
- backgroundColor: Colors.black87,
- borderRadius: BorderRadius.circular(8.0),
- borderColor: borderColor ?? Colors.black,
- position: position,
- style: style,
- alignment: alignment,
- enableDrag: false,
- onTap: () => controller.dismiss(),
- child: Padding(
- padding: const EdgeInsets.all(12.0),
- child: DefaultTextStyle(
- style: const TextStyle(color: Colors.white),
- child: Text(
- message,
- ),
- ),
- ),
- );
- },
- );
- }
}
diff --git a/lib/src/presentation/pages/reset_password_page.dart b/lib/src/presentation/pages/reset_password_page.dart
index 4bf9f06..26067f1 100644
--- a/lib/src/presentation/pages/reset_password_page.dart
+++ b/lib/src/presentation/pages/reset_password_page.dart
@@ -1,13 +1,12 @@
import 'dart:developer';
-import 'package:flash/flash.dart';
import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
-
-import '../../utils/validators.dart';
-import '../blocs/reset_password_bloc/resetpassword_bloc.dart';
-import '../widgets.dart';
-import '../widgets/bottom_sheet.dart';
+import 'package:gestionuh/src/presentation/blocs/reset_password_bloc/resetpassword_bloc.dart';
+import 'package:gestionuh/src/presentation/widgets.dart';
+import 'package:gestionuh/src/presentation/widgets/bottom_sheet.dart';
+import 'package:gestionuh/src/presentation/widgets/flash_helper.dart';
+import 'package:gestionuh/src/utils/validators.dart';
class ResetPasswordPage extends StatefulWidget {
const ResetPasswordPage({Key? key}) : super(key: key);
@@ -39,16 +38,11 @@ class _ResetPasswordPageState extends State {
body: BlocConsumer(
listener: (context, state) {
if (state is ResetPasswordInitial) {
- _showCenterFlash(
- message: state.error,
- borderColor: Colors.red,
- );
+ FlashHelper.errorBar(context, message: state.error);
}
if (state is ResetPasswordSuccess) {
- _showCenterFlash(
- message: 'Operación Completada.',
- borderColor: Colors.green,
- );
+ FlashHelper.infoBar(context,
+ message: 'La contraseña ha sido actualizada correctamente.');
}
},
builder: (context, state) {
@@ -165,39 +159,4 @@ class _ResetPasswordPageState extends State {
);
}
}
-
- void _showCenterFlash({
- required String message,
- FlashPosition position = FlashPosition.top,
- FlashStyle style = FlashStyle.floating,
- Alignment? alignment,
- Color? borderColor,
- }) {
- showFlash(
- context: context,
- duration: const Duration(seconds: 5),
- builder: (_, controller) {
- return Flash(
- controller: controller,
- backgroundColor: Colors.black87,
- borderRadius: BorderRadius.circular(8.0),
- borderColor: borderColor ?? Colors.black,
- position: position,
- style: style,
- alignment: alignment,
- enableDrag: false,
- onTap: () => controller.dismiss(),
- child: Padding(
- padding: const EdgeInsets.all(12.0),
- child: DefaultTextStyle(
- style: const TextStyle(color: Colors.white),
- child: Text(
- message,
- ),
- ),
- ),
- );
- },
- );
- }
}
diff --git a/lib/src/presentation/theme/theme_data.dart b/lib/src/presentation/theme/theme_data.dart
index 83250f8..ed914d1 100644
--- a/lib/src/presentation/theme/theme_data.dart
+++ b/lib/src/presentation/theme/theme_data.dart
@@ -10,10 +10,10 @@ const titlesAndParagraphsColor = Color(0xff5d5d5d);
const subtitlesColor = Color(0xffababab);
const linesColor = Color(0xffdfe1e1);
//per background
-const backgroundColor = Color(0xfdfdfdfd);
+const backgroundColor = Color(0xfffdfdfd);
const backgroundAccentColor = Color(0xffffffff);
const backgroundCategoriesColor = Color(0xffcccfce);
-const backgroundSecundaryColor = Color(0xfdfdfdfd);
+const backgroundSecundaryColor = Color(0xfffdfdfd);
final ThemeData light = ThemeData.light();
diff --git a/lib/src/presentation/widgets/bottom_sheet.dart b/lib/src/presentation/widgets/bottom_sheet.dart
index 0eb82bb..db9a523 100644
--- a/lib/src/presentation/widgets/bottom_sheet.dart
+++ b/lib/src/presentation/widgets/bottom_sheet.dart
@@ -8,22 +8,26 @@ class GestionUHBottomSheet extends StatelessWidget {
@override
Widget build(BuildContext context) {
- return Center(
- heightFactor: 2.2,
- child: RichText(
- text: TextSpan(
- style: Theme.of(context).textTheme.bodyText1!.copyWith(fontSize: 11),
- children: [
- const TextSpan(text: '\u00a9 2021'),
- TextSpan(
- text: Constants.copyRight,
- style: Theme.of(context).textTheme.bodyText1!.copyWith(
- fontSize: 11,
- color: Theme.of(context).primaryColor,
- ))
- ],
+ return SafeArea(
+ minimum: const EdgeInsets.only(bottom: 3),
+ child: Center(
+ heightFactor: 2.2,
+ child: RichText(
+ text: TextSpan(
+ style:
+ Theme.of(context).textTheme.bodyText1!.copyWith(fontSize: 11),
+ children: [
+ const TextSpan(text: '\u00a9 2021'),
+ TextSpan(
+ text: Constants.copyRight,
+ style: Theme.of(context).textTheme.bodyText1!.copyWith(
+ fontSize: 11,
+ color: Theme.of(context).primaryColor,
+ ))
+ ],
+ ),
+ textAlign: TextAlign.center,
),
- textAlign: TextAlign.center,
),
);
}
diff --git a/lib/src/presentation/widgets/flash_helper.dart b/lib/src/presentation/widgets/flash_helper.dart
new file mode 100644
index 0000000..62c87c2
--- /dev/null
+++ b/lib/src/presentation/widgets/flash_helper.dart
@@ -0,0 +1,404 @@
+import 'dart:async';
+import 'dart:collection';
+
+import 'package:flash/flash.dart';
+import 'package:flutter/material.dart';
+import 'package:flutter/widgets.dart';
+
+class _MessageItem {
+ final String message;
+ Completer> completer;
+
+ _MessageItem(this.message) : completer = Completer>();
+}
+
+class FlashHelper {
+ static Completer _buildCompleter = Completer();
+ static final Queue<_MessageItem> _messageQueue = Queue<_MessageItem>();
+ static Completer? _previousCompleter;
+
+ static void init(BuildContext context) {
+ if (_buildCompleter.isCompleted == false) {
+ _buildCompleter.complete(context);
+ }
+ }
+
+ static void dispose() {
+ _messageQueue.clear();
+
+ if (_buildCompleter.isCompleted == false) {
+ _buildCompleter.completeError('NotInitialize');
+ }
+ _buildCompleter = Completer();
+ }
+
+ static Future toast(String message) async {
+ final context = await _buildCompleter.future;
+
+ // Wait previous toast dismissed.
+ if (_previousCompleter?.isCompleted == false) {
+ final item = _MessageItem(message);
+ _messageQueue.add(item);
+ return await item.completer.future;
+ }
+
+ _previousCompleter = Completer();
+
+ Future showToast(String message) {
+ return showFlash(
+ context: context,
+ builder: (context, controller) {
+ return SafeArea(
+ child: Flash.dialog(
+ controller: controller,
+ alignment: const Alignment(0, 0.5),
+ margin:
+ const EdgeInsets.symmetric(horizontal: 16.0, vertical: 8.0),
+ borderRadius: const BorderRadius.all(Radius.circular(8.0)),
+ enableDrag: false,
+ backgroundColor: Colors.black87,
+ child: DefaultTextStyle(
+ style: const TextStyle(fontSize: 16.0, color: Colors.white),
+ child: Padding(
+ padding: const EdgeInsets.symmetric(
+ horizontal: 16.0, vertical: 8.0),
+ child: Text(message),
+ ),
+ ),
+ ),
+ );
+ },
+ duration: const Duration(seconds: 3),
+ ).whenComplete(() {
+ if (_messageQueue.isNotEmpty) {
+ final item = _messageQueue.removeFirst();
+ item.completer.complete(showToast(item.message));
+ } else {
+ _previousCompleter?.complete();
+ }
+ });
+ }
+
+ return showToast(message);
+ }
+
+ static Color _backgroundColor(BuildContext context) {
+ final theme = Theme.of(context);
+ return theme.dialogTheme.backgroundColor ?? theme.dialogBackgroundColor;
+ }
+
+ static TextStyle _titleStyle(BuildContext context, [Color? color]) {
+ final theme = Theme.of(context);
+ return (theme.dialogTheme.titleTextStyle ?? theme.textTheme.headline6)
+ ?.copyWith(color: color) ??
+ const TextStyle(fontSize: 21.0, fontWeight: FontWeight.w700);
+ }
+
+ static TextStyle _contentStyle(BuildContext context, [Color? color]) {
+ final theme = Theme.of(context);
+ return (theme.dialogTheme.contentTextStyle ?? theme.textTheme.bodyText2)
+ ?.copyWith(color: color) ??
+ const TextStyle(fontSize: 15.0, fontWeight: FontWeight.w400);
+ }
+
+ static Future infoBar(
+ BuildContext context, {
+ String? title,
+ required String message,
+ Duration duration = const Duration(seconds: 3),
+ }) {
+ return showFlash(
+ context: context,
+ duration: duration,
+ builder: (context, controller) {
+ return SafeArea(
+ child: Flash(
+ controller: controller,
+ horizontalDismissDirection: HorizontalDismissDirection.horizontal,
+ backgroundColor: Colors.black87,
+ child: FlashBar(
+ title: title == null
+ ? null
+ : Text(title, style: _titleStyle(context, Colors.white)),
+ message:
+ Text(message, style: _contentStyle(context, Colors.white)),
+ icon: Icon(Icons.info_outline, color: Colors.green[300]),
+ leftBarIndicatorColor: Colors.green[300],
+ ),
+ ),
+ );
+ },
+ );
+ }
+
+ static Future successBar(
+ BuildContext context, {
+ String? title,
+ required String message,
+ Duration duration = const Duration(seconds: 3),
+ }) {
+ return showFlash(
+ context: context,
+ duration: duration,
+ builder: (context, controller) {
+ return SafeArea(
+ child: Flash(
+ controller: controller,
+ horizontalDismissDirection: HorizontalDismissDirection.horizontal,
+ backgroundColor: Colors.black87,
+ child: FlashBar(
+ title: title == null
+ ? null
+ : Text(title, style: _titleStyle(context, Colors.white)),
+ message:
+ Text(message, style: _contentStyle(context, Colors.white)),
+ icon: Icon(Icons.check_circle, color: Colors.blue[300]),
+ leftBarIndicatorColor: Colors.blue[300],
+ ),
+ ),
+ );
+ },
+ );
+ }
+
+ static Future errorBar(
+ BuildContext context, {
+ String? title,
+ required String message,
+ ChildBuilder? primaryAction,
+ Duration duration = const Duration(seconds: 3),
+ }) {
+ return showFlash(
+ context: context,
+ duration: duration,
+ builder: (context, controller) {
+ return StatefulBuilder(builder: (context, setState) {
+ return SafeArea(
+ child: Flash(
+ controller: controller,
+ horizontalDismissDirection: HorizontalDismissDirection.horizontal,
+ backgroundColor: Colors.black87,
+ child: FlashBar(
+ title: title == null
+ ? null
+ : Text(title, style: _titleStyle(context, Colors.white)),
+ message:
+ Text(message, style: _contentStyle(context, Colors.white)),
+ primaryAction:
+ primaryAction?.call(context, controller, setState),
+ icon: Icon(Icons.warning, color: Colors.red[300]),
+ leftBarIndicatorColor: Colors.red[300],
+ ),
+ ),
+ );
+ });
+ },
+ );
+ }
+
+ static Future actionBar(
+ BuildContext context, {
+ String? title,
+ required String message,
+ required ChildBuilder primaryAction,
+ Duration duration = const Duration(seconds: 3),
+ }) {
+ return showFlash(
+ context: context,
+ duration: duration,
+ builder: (context, controller) {
+ return StatefulBuilder(builder: (context, setState) {
+ return SafeArea(
+ child: Flash(
+ controller: controller,
+ horizontalDismissDirection: HorizontalDismissDirection.horizontal,
+ backgroundColor: Colors.black87,
+ child: FlashBar(
+ title: title == null
+ ? null
+ : Text(title, style: _titleStyle(context, Colors.white)),
+ message:
+ Text(message, style: _contentStyle(context, Colors.white)),
+ primaryAction:
+ primaryAction.call(context, controller, setState),
+ ),
+ ),
+ );
+ });
+ },
+ );
+ }
+
+ static Future simpleDialog(
+ BuildContext context, {
+ String? title,
+ required String message,
+ Color? messageColor,
+ ChildBuilder? negativeAction,
+ ChildBuilder? positiveAction,
+ }) {
+ return showFlash(
+ context: context,
+ persistent: false,
+ onWillPop: () async => false,
+ builder: (_context, controller) {
+ return StatefulBuilder(
+ builder: (context, setState) {
+ return SafeArea(
+ child: Flash.dialog(
+ boxShadows: kElevationToShadow[6],
+ barrierBlur: 1,
+ controller: controller,
+ backgroundColor: _backgroundColor(_context),
+ margin: const EdgeInsets.only(left: 40.0, right: 40.0),
+ borderRadius: const BorderRadius.all(Radius.circular(8.0)),
+ child: FlashBar(
+ title: title == null
+ ? null
+ : Text(title, style: _titleStyle(_context)),
+ message: Text(message,
+ style: _contentStyle(_context, messageColor)),
+ actions: [
+ if (negativeAction != null)
+ negativeAction(_context, controller, setState),
+ if (positiveAction != null)
+ positiveAction(_context, controller, setState),
+ ],
+ ),
+ ),
+ );
+ },
+ );
+ },
+ );
+ }
+
+ static Future customDialog(
+ BuildContext context, {
+ ChildBuilder? titleBuilder,
+ required ChildBuilder messageBuilder,
+ ChildBuilder? negativeAction,
+ ChildBuilder? positiveAction,
+ }) {
+ return showFlash(
+ context: context,
+ persistent: false,
+ builder: (context, controller) {
+ return StatefulBuilder(
+ builder: (context, setState) {
+ return SafeArea(
+ child: Flash.dialog(
+ controller: controller,
+ backgroundColor: _backgroundColor(context),
+ margin: const EdgeInsets.only(left: 40.0, right: 40.0),
+ borderRadius: const BorderRadius.all(Radius.circular(8.0)),
+ child: FlashBar(
+ title: titleBuilder == null
+ ? null
+ : DefaultTextStyle(
+ style: _titleStyle(context),
+ child:
+ titleBuilder.call(context, controller, setState),
+ ),
+ message: DefaultTextStyle(
+ style: _contentStyle(context),
+ child: messageBuilder.call(context, controller, setState),
+ ),
+ actions: [
+ if (negativeAction != null)
+ negativeAction(context, controller, setState),
+ if (positiveAction != null)
+ positiveAction(context, controller, setState),
+ ],
+ ),
+ ),
+ );
+ },
+ );
+ },
+ );
+ }
+
+ static Future blockDialog(
+ BuildContext context, {
+ required Completer dismissCompleter,
+ }) {
+ final controller = FlashController(
+ context,
+ (context, FlashController controller) {
+ return SafeArea(
+ child: Flash.dialog(
+ controller: controller,
+ barrierDismissible: false,
+ backgroundColor: Colors.black87,
+ margin: const EdgeInsets.only(left: 40.0, right: 40.0),
+ borderRadius: const BorderRadius.all(Radius.circular(8.0)),
+ child: const Padding(
+ padding: EdgeInsets.all(16.0),
+ child: CircularProgressIndicator(strokeWidth: 2.0),
+ ),
+ ),
+ );
+ },
+ persistent: false,
+ onWillPop: () => Future.value(false),
+ );
+ dismissCompleter.future.then((value) => controller.dismiss(value));
+ return controller.show();
+ }
+
+ static Future inputDialog(
+ BuildContext context, {
+ String? title,
+ String? message,
+ String? defaultValue,
+ bool persistent = true,
+ WillPopCallback? onWillPop,
+ }) {
+ final editingController = TextEditingController(text: defaultValue);
+ return showFlash(
+ context: context,
+ persistent: persistent,
+ onWillPop: onWillPop,
+ builder: (context, controller) {
+ final theme = Theme.of(context);
+ return SafeArea(
+ child: Flash.bar(
+ controller: controller,
+ barrierColor: Colors.black54,
+ borderWidth: 3,
+ borderRadius:
+ const BorderRadius.vertical(top: Radius.circular(8.0)),
+ child: FlashBar(
+ title: title == null
+ ? null
+ : Text(title, style: const TextStyle(fontSize: 24.0)),
+ message: Column(
+ children: [
+ if (message != null) Text(message),
+ Form(
+ child: TextFormField(
+ controller: editingController,
+ autofocus: true,
+ ),
+ ),
+ ],
+ ),
+ leftBarIndicatorColor: theme.primaryColor,
+ primaryAction: IconButton(
+ onPressed: () {
+ final message = editingController.text;
+ controller.dismiss(message);
+ },
+ icon: Icon(Icons.send, color: theme.colorScheme.secondary),
+ ),
+ ),
+ ),
+ );
+ },
+ );
+ }
+}
+
+typedef ChildBuilder = Widget Function(
+ BuildContext context, FlashController controller, StateSetter setState);
diff --git a/lib/src/utils/constants.dart b/lib/src/utils/constants.dart
index 77e64ea..eaec5ff 100644
--- a/lib/src/utils/constants.dart
+++ b/lib/src/utils/constants.dart
@@ -1,5 +1,6 @@
export 'constants/about.dart';
export 'constants/constants.dart';
+export 'constants/errors.dart';
export 'constants/misc.dart';
export 'constants/routes.dart';
export 'constants/sample_data.dart';
diff --git a/lib/src/utils/constants/errors.dart b/lib/src/utils/constants/errors.dart
new file mode 100644
index 0000000..0049080
--- /dev/null
+++ b/lib/src/utils/constants/errors.dart
@@ -0,0 +1,14 @@
+class Errors {
+ static const Messages = {1: 'Datos inválidos.', 2: 'Credenciales inválidas.'};
+
+ static const DefaultError = 'Ha ocurrido un error.';
+
+ static String? retrieveError(String message) {
+ try {
+ final index = int.parse(message);
+ return Messages[index];
+ } catch (_) {}
+
+ return DefaultError;
+ }
+}
diff --git a/pubspec.yaml b/pubspec.yaml
index d74cadb..17a2a7d 100644
--- a/pubspec.yaml
+++ b/pubspec.yaml
@@ -39,7 +39,7 @@ flutter:
flutter_native_splash:
image: assets/images/splash2.png
- color: '#5b0101'
+ color: '#fdfdfd'
fill: false
flutter_icons: