From bf925c3f8d43ddc76222e3f4d158936901ba1de4 Mon Sep 17 00:00:00 2001 From: dungngminh <63831488+dungngminh@users.noreply.github.com> Date: Wed, 31 Jan 2024 02:06:13 +0700 Subject: [PATCH 01/15] add chopper --- mobile/build.yaml | 10 + .../remote/auth/auth_service.chopper.dart | 34 ++ mobile/lib/data/remote/auth/auth_service.dart | 18 + .../auth/requests/login_request_body.dart | 13 + .../auth/requests/login_request_body.g.dart | 13 + .../auth/requests/register_request_body.dart | 19 + .../requests/register_request_body.g.dart | 16 + .../remote/auth/responses/login_response.dart | 14 + .../auth/responses/login_response.g.dart | 13 + mobile/lib/di/di.config.dart | 50 +++ mobile/lib/di/di.dart | 12 + mobile/lib/di/modules/local_module.dart | 0 mobile/lib/di/modules/network_module.dart | 34 ++ .../packages/http_client_handler/pubspec.yaml | 8 +- mobile/pubspec.lock | 406 +++++++++++++----- mobile/pubspec.yaml | 7 + 16 files changed, 557 insertions(+), 110 deletions(-) create mode 100644 mobile/build.yaml create mode 100644 mobile/lib/data/remote/auth/auth_service.chopper.dart create mode 100644 mobile/lib/data/remote/auth/auth_service.dart create mode 100644 mobile/lib/data/remote/auth/requests/login_request_body.dart create mode 100644 mobile/lib/data/remote/auth/requests/login_request_body.g.dart create mode 100644 mobile/lib/data/remote/auth/requests/register_request_body.dart create mode 100644 mobile/lib/data/remote/auth/requests/register_request_body.g.dart create mode 100644 mobile/lib/data/remote/auth/responses/login_response.dart create mode 100644 mobile/lib/data/remote/auth/responses/login_response.g.dart create mode 100644 mobile/lib/di/di.config.dart create mode 100644 mobile/lib/di/modules/local_module.dart create mode 100644 mobile/lib/di/modules/network_module.dart diff --git a/mobile/build.yaml b/mobile/build.yaml new file mode 100644 index 0000000..83f1cca --- /dev/null +++ b/mobile/build.yaml @@ -0,0 +1,10 @@ +targets: + $default: + builders: + json_serializable: + options: + # Options configure how source code is generated for every + # `@JsonSerializable`-annotated class in the package. + # + # The default value for each is listed. + field_rename: snake \ No newline at end of file diff --git a/mobile/lib/data/remote/auth/auth_service.chopper.dart b/mobile/lib/data/remote/auth/auth_service.chopper.dart new file mode 100644 index 0000000..20b5d83 --- /dev/null +++ b/mobile/lib/data/remote/auth/auth_service.chopper.dart @@ -0,0 +1,34 @@ +// GENERATED CODE - DO NOT MODIFY BY HAND + +part of 'auth_service.dart'; + +// ************************************************************************** +// ChopperGenerator +// ************************************************************************** + +// coverage:ignore-file +// ignore_for_file: type=lint +final class _$AuthService extends AuthService { + _$AuthService([ChopperClient? client]) { + if (client == null) return; + this.client = client; + } + + @override + final Type definitionType = AuthService; + + @override + Future login(LoginRequestBody body) async { + final Uri $url = Uri.parse('api/auth/login'); + final $body = body; + final Request $request = Request( + 'POST', + $url, + client.baseUrl, + body: $body, + ); + final Response $response = + await client.send($request); + return $response.bodyOrThrow; + } +} diff --git a/mobile/lib/data/remote/auth/auth_service.dart b/mobile/lib/data/remote/auth/auth_service.dart new file mode 100644 index 0000000..e28638a --- /dev/null +++ b/mobile/lib/data/remote/auth/auth_service.dart @@ -0,0 +1,18 @@ +import 'package:chopper/chopper.dart'; +import 'package:injectable/injectable.dart'; +import 'package:very_good_blog_app/data/remote/auth/requests/login_request_body.dart'; +import 'package:very_good_blog_app/data/remote/auth/responses/login_response.dart'; + +part 'auth_service.chopper.dart'; + +@lazySingleton +@ChopperApi(baseUrl: 'api/auth') +abstract class AuthService extends ChopperService { + @factoryMethod + static AuthService create(@Named('unAuthClient') ChopperClient client) { + return _$AuthService(client); + } + + @Post(path: 'login') + Future login(@Body() LoginRequestBody body); +} diff --git a/mobile/lib/data/remote/auth/requests/login_request_body.dart b/mobile/lib/data/remote/auth/requests/login_request_body.dart new file mode 100644 index 0000000..a36e49f --- /dev/null +++ b/mobile/lib/data/remote/auth/requests/login_request_body.dart @@ -0,0 +1,13 @@ +import 'package:json_annotation/json_annotation.dart'; + +part 'login_request_body.g.dart'; + +@JsonSerializable(createFactory: false) +class LoginRequestBody { + LoginRequestBody({required this.email, required this.password}); + + final String email; + final String password; + + Map toJson() => _$LoginRequestBodyToJson(this); +} diff --git a/mobile/lib/data/remote/auth/requests/login_request_body.g.dart b/mobile/lib/data/remote/auth/requests/login_request_body.g.dart new file mode 100644 index 0000000..c0c019b --- /dev/null +++ b/mobile/lib/data/remote/auth/requests/login_request_body.g.dart @@ -0,0 +1,13 @@ +// GENERATED CODE - DO NOT MODIFY BY HAND + +part of 'login_request_body.dart'; + +// ************************************************************************** +// JsonSerializableGenerator +// ************************************************************************** + +Map _$LoginRequestBodyToJson(LoginRequestBody instance) => + { + 'email': instance.email, + 'password': instance.password, + }; diff --git a/mobile/lib/data/remote/auth/requests/register_request_body.dart b/mobile/lib/data/remote/auth/requests/register_request_body.dart new file mode 100644 index 0000000..c0d4af0 --- /dev/null +++ b/mobile/lib/data/remote/auth/requests/register_request_body.dart @@ -0,0 +1,19 @@ +import 'package:json_annotation/json_annotation.dart'; + +part 'register_request_body.g.dart'; + +@JsonSerializable(createFactory: false) +class RegisterRequestBody { + RegisterRequestBody({ + required this.email, + required this.password, + required this.confirmationPassword, + required this.fullName, + }); + final String email; + final String password; + final String confirmationPassword; + final String fullName; + + Map toJson() => _$RegisterRequestBodyToJson(this); +} diff --git a/mobile/lib/data/remote/auth/requests/register_request_body.g.dart b/mobile/lib/data/remote/auth/requests/register_request_body.g.dart new file mode 100644 index 0000000..346bfeb --- /dev/null +++ b/mobile/lib/data/remote/auth/requests/register_request_body.g.dart @@ -0,0 +1,16 @@ +// GENERATED CODE - DO NOT MODIFY BY HAND + +part of 'register_request_body.dart'; + +// ************************************************************************** +// JsonSerializableGenerator +// ************************************************************************** + +Map _$RegisterRequestBodyToJson( + RegisterRequestBody instance) => + { + 'email': instance.email, + 'password': instance.password, + 'confirmation_password': instance.confirmationPassword, + 'full_name': instance.fullName, + }; diff --git a/mobile/lib/data/remote/auth/responses/login_response.dart b/mobile/lib/data/remote/auth/responses/login_response.dart new file mode 100644 index 0000000..f9ef1e4 --- /dev/null +++ b/mobile/lib/data/remote/auth/responses/login_response.dart @@ -0,0 +1,14 @@ +import 'package:json_annotation/json_annotation.dart'; + +part 'login_response.g.dart'; + +@JsonSerializable(createToJson: false) +class LoginResponse { + LoginResponse({required this.id, required this.token}); + + factory LoginResponse.fromJson(Map json) => + _$LoginResponseFromJson(json); + + final String id; + final String token; +} diff --git a/mobile/lib/data/remote/auth/responses/login_response.g.dart b/mobile/lib/data/remote/auth/responses/login_response.g.dart new file mode 100644 index 0000000..71a181d --- /dev/null +++ b/mobile/lib/data/remote/auth/responses/login_response.g.dart @@ -0,0 +1,13 @@ +// GENERATED CODE - DO NOT MODIFY BY HAND + +part of 'login_response.dart'; + +// ************************************************************************** +// JsonSerializableGenerator +// ************************************************************************** + +LoginResponse _$LoginResponseFromJson(Map json) => + LoginResponse( + id: json['id'] as String, + token: json['token'] as String, + ); diff --git a/mobile/lib/di/di.config.dart b/mobile/lib/di/di.config.dart new file mode 100644 index 0000000..d8401a2 --- /dev/null +++ b/mobile/lib/di/di.config.dart @@ -0,0 +1,50 @@ +// GENERATED CODE - DO NOT MODIFY BY HAND + +// ************************************************************************** +// InjectableConfigGenerator +// ************************************************************************** + +// ignore_for_file: type=lint +// coverage:ignore-file + +// ignore_for_file: no_leading_underscores_for_library_prefixes +import 'package:chopper/chopper.dart' as _i3; +import 'package:get_it/get_it.dart' as _i1; +import 'package:injectable/injectable.dart' as _i2; + +import '../data/remote/auth/auth_service.dart' as _i4; +import 'modules/network_module.dart' as _i5; + +extension GetItInjectableX on _i1.GetIt { +// initializes the registration of main-scope dependencies inside of GetIt + _i1.GetIt init({ + String? environment, + _i2.EnvironmentFilter? environmentFilter, + }) { + final gh = _i2.GetItHelper( + this, + environment, + environmentFilter, + ); + final networkModule = _$NetworkModule(); + gh.factory( + () => networkModule.baseUrl, + instanceName: 'baseUrl', + ); + gh.lazySingleton<_i3.ChopperClient>( + () => networkModule + .unAuthChopperClient(gh(instanceName: 'baseUrl')), + instanceName: 'unAuthClient', + ); + gh.lazySingleton<_i3.ChopperClient>( + () => + networkModule.authChopperClient(gh(instanceName: 'baseUrl')), + instanceName: 'authClient', + ); + gh.lazySingleton<_i4.AuthService>(() => _i4.AuthService.create( + gh<_i3.ChopperClient>(instanceName: 'unAuthClient'))); + return this; + } +} + +class _$NetworkModule extends _i5.NetworkModule {} diff --git a/mobile/lib/di/di.dart b/mobile/lib/di/di.dart index d1dae81..7a20bd4 100644 --- a/mobile/lib/di/di.dart +++ b/mobile/lib/di/di.dart @@ -1,14 +1,26 @@ import 'package:authentication_data_source/authentication_data_source.dart'; import 'package:blog_data_source/blog_data_source.dart'; import 'package:bookmark_data_source/bookmark_data_source.dart'; +import 'package:chopper/chopper.dart'; import 'package:firebase_storage/firebase_storage.dart'; import 'package:get_it/get_it.dart'; import 'package:hive_flutter/hive_flutter.dart'; +import 'package:injectable/injectable.dart'; import 'package:user_repository/user_repository.dart'; import 'package:very_good_blog_app/app/app.dart'; +import 'package:very_good_blog_app/data/remote/auth/auth_service.dart'; + +import 'di.config.dart'; final injector = GetIt.instance; +@InjectableInit( + initializerName: 'init', // default + preferRelativeImports: true, // default + asExtension: true, // default +) +void configureDependencies() => injector.init(); + Future initServices() async { await Hive.openBox(HiveBox.userPrefs); final _bookmarkBox = await Hive.openBox(HiveBox.bookmark); diff --git a/mobile/lib/di/modules/local_module.dart b/mobile/lib/di/modules/local_module.dart new file mode 100644 index 0000000..e69de29 diff --git a/mobile/lib/di/modules/network_module.dart b/mobile/lib/di/modules/network_module.dart new file mode 100644 index 0000000..b3f7922 --- /dev/null +++ b/mobile/lib/di/modules/network_module.dart @@ -0,0 +1,34 @@ +import 'package:chopper/chopper.dart'; +import 'package:injectable/injectable.dart'; + +@module +abstract class NetworkModule { + @Named('baseUrl') + String get baseUrl => 'https://very-good-blog-app.up.railway.app'; + + @Named('unAuthClient') + @lazySingleton + ChopperClient unAuthChopperClient(@Named('baseUrl') String baseUrl) { + return ChopperClient( + baseUrl: Uri.parse(baseUrl), + converter: const JsonConverter(), + interceptors: [ + CurlInterceptor(), + HttpLoggingInterceptor(), + ], + ); + } + + @Named('authClient') + @lazySingleton + ChopperClient authChopperClient(@Named('baseUrl') String baseUrl) { + return ChopperClient( + baseUrl: Uri.parse(baseUrl), + converter: const JsonConverter(), + interceptors: [ + CurlInterceptor(), + HttpLoggingInterceptor(), + ], + ); + } +} diff --git a/mobile/packages/http_client_handler/pubspec.yaml b/mobile/packages/http_client_handler/pubspec.yaml index c12f529..bff9f3a 100644 --- a/mobile/packages/http_client_handler/pubspec.yaml +++ b/mobile/packages/http_client_handler/pubspec.yaml @@ -4,10 +4,12 @@ version: 0.1.0+1 publish_to: none environment: - sdk: ">=2.17.0 <3.0.0" + sdk: ">=3.1.0 <4.0.0" + +dependencies: + http: ^1.2.0 + -dependencies: {http: ^0.13.5} - dev_dependencies: mocktail: ^0.3.0 diff --git a/mobile/pubspec.lock b/mobile/pubspec.lock index 8e81575..d4ae9b8 100644 --- a/mobile/pubspec.lock +++ b/mobile/pubspec.lock @@ -5,26 +5,26 @@ packages: dependency: transitive description: name: _fe_analyzer_shared - sha256: ae92f5d747aee634b87f89d9946000c2de774be1d6ac3e58268224348cd0101a + sha256: eb376e9acf6938204f90eb3b1f00b578640d3188b4c8a8ec054f9f479af8d051 url: "https://pub.dev" source: hosted - version: "61.0.0" + version: "64.0.0" _flutterfire_internals: dependency: transitive description: name: _flutterfire_internals - sha256: eb0ac20f704799b986049fbb3c1c16421eca319a1b872378d669513e12452ba5 + sha256: f5628cd9c92ed11083f425fd1f8f1bc60ecdda458c81d73b143aeda036c35fe7 url: "https://pub.dev" source: hosted - version: "1.3.14" + version: "1.3.16" analyzer: dependency: transitive description: name: analyzer - sha256: ea3d8652bda62982addfd92fdc2d0214e5f82e43325104990d4f4c4a2a313562 + sha256: "69f54f967773f6c26c7dcb13e93d7ccee8b17a641689da39e878d5cf13b06893" url: "https://pub.dev" source: hosted - version: "5.13.0" + version: "6.2.0" args: dependency: transitive description: @@ -107,30 +107,94 @@ packages: url: "https://pub.dev" source: hosted version: "2.1.1" + build: + dependency: transitive + description: + name: build + sha256: "80184af8b6cb3e5c1c4ec6d8544d27711700bc3e6d2efad04238c7b5290889f0" + url: "https://pub.dev" + source: hosted + version: "2.4.1" + build_config: + dependency: transitive + description: + name: build_config + sha256: bf80fcfb46a29945b423bd9aad884590fb1dc69b330a4d4700cac476af1708d1 + url: "https://pub.dev" + source: hosted + version: "1.1.1" + build_daemon: + dependency: transitive + description: + name: build_daemon + sha256: "0343061a33da9c5810b2d6cee51945127d8f4c060b7fbdd9d54917f0a3feaaa1" + url: "https://pub.dev" + source: hosted + version: "4.0.1" + build_resolvers: + dependency: transitive + description: + name: build_resolvers + sha256: "339086358431fa15d7eca8b6a36e5d783728cf025e559b834f4609a1fcfb7b0a" + url: "https://pub.dev" + source: hosted + version: "2.4.2" + build_runner: + dependency: "direct dev" + description: + name: build_runner + sha256: "581bacf68f89ec8792f5e5a0b2c4decd1c948e97ce659dc783688c8a88fbec21" + url: "https://pub.dev" + source: hosted + version: "2.4.8" + build_runner_core: + dependency: transitive + description: + name: build_runner_core + sha256: c9e32d21dd6626b5c163d48b037ce906bbe428bc23ab77bcd77bb21e593b6185 + url: "https://pub.dev" + source: hosted + version: "7.2.11" + built_collection: + dependency: transitive + description: + name: built_collection + sha256: "376e3dd27b51ea877c28d525560790aee2e6fbb5f20e2f85d5081027d94e2100" + url: "https://pub.dev" + source: hosted + version: "5.1.1" + built_value: + dependency: transitive + description: + name: built_value + sha256: a3ec2e0f967bc47f69f95009bb93db936288d61d5343b9436e378b28a2f830c6 + url: "https://pub.dev" + source: hosted + version: "8.9.0" cached_network_image: dependency: "direct main" description: name: cached_network_image - sha256: f98972704692ba679db144261172a8e20feb145636c617af0eb4022132a6797f + sha256: "28ea9690a8207179c319965c13cd8df184d5ee721ae2ce60f398ced1219cea1f" url: "https://pub.dev" source: hosted - version: "3.3.0" + version: "3.3.1" cached_network_image_platform_interface: dependency: transitive description: name: cached_network_image_platform_interface - sha256: "56aa42a7a01e3c9db8456d9f3f999931f1e05535b5a424271e9a38cabf066613" + sha256: "9e90e78ae72caa874a323d78fa6301b3fb8fa7ea76a8f96dc5b5bf79f283bf2f" url: "https://pub.dev" source: hosted - version: "3.0.0" + version: "4.0.0" cached_network_image_web: dependency: transitive description: name: cached_network_image_web - sha256: "759b9a9f8f6ccbb66c185df805fac107f05730b1dab9c64626d1008cca532257" + sha256: "42a835caa27c220d1294311ac409a43361088625a4f23c820b006dd9bffb3316" url: "https://pub.dev" source: hosted - version: "1.1.0" + version: "1.1.1" characters: dependency: transitive description: @@ -147,6 +211,30 @@ packages: url: "https://pub.dev" source: hosted version: "1.3.1" + checked_yaml: + dependency: transitive + description: + name: checked_yaml + sha256: feb6bed21949061731a7a75fc5d2aa727cf160b91af9a3e464c5e3a32e28b5ff + url: "https://pub.dev" + source: hosted + version: "2.0.3" + chopper: + dependency: "direct main" + description: + name: chopper + sha256: d1457197abb29ee354889fda35a7ac2e752eb5a687562148afb1faa78a61e36d + url: "https://pub.dev" + source: hosted + version: "7.1.1" + chopper_generator: + dependency: "direct dev" + description: + name: chopper_generator + sha256: "31e74e3b0cf6d694822c9fea0d28e28dc05e8523336c7aa109e40a61c467c048" + url: "https://pub.dev" + source: hosted + version: "7.1.1" clock: dependency: transitive description: @@ -162,6 +250,14 @@ packages: relative: true source: path version: "1.1.0-dev.2" + code_builder: + dependency: transitive + description: + name: code_builder + sha256: f692079e25e7869c14132d39f223f8eec9830eb76131925143b2129c4bb01b37 + url: "https://pub.dev" + source: hosted + version: "4.10.0" collection: dependency: transitive description: @@ -198,18 +294,18 @@ packages: dependency: transitive description: name: coverage - sha256: ac86d3abab0f165e4b8f561280ff4e066bceaac83c424dd19f1ae2c2fcd12ca9 + sha256: "8acabb8306b57a409bf4c83522065672ee13179297a6bb0cb9ead73948df7c76" url: "https://pub.dev" source: hosted - version: "1.7.1" + version: "1.7.2" cross_file: dependency: transitive description: name: cross_file - sha256: "2f9d2cbccb76127ba28528cb3ae2c2326a122446a83de5a056aaa3880d3882c5" + sha256: fedaadfa3a6996f75211d835aaeb8fede285dae94262485698afd832371b9a5e url: "https://pub.dev" source: hosted - version: "0.3.3+7" + version: "0.3.3+8" crypto: dependency: transitive description: @@ -234,6 +330,14 @@ packages: url: "https://pub.dev" source: hosted version: "0.0.1" + dart_style: + dependency: transitive + description: + name: dart_style + sha256: "40ae61a5d43feea6d24bd22c0537a6629db858963b99b4bc1c3db80676f32368" + url: "https://pub.dev" + source: hosted + version: "2.3.4" dbus: dependency: transitive description: @@ -334,10 +438,10 @@ packages: dependency: transitive description: name: file_selector_platform_interface - sha256: "0aa47a725c346825a2bd396343ce63ac00bda6eff2fbc43eabe99737dede8262" + sha256: a3994c26f10378a039faa11de174d7b78eb8f79e4dd0af2a451410c1a5c3f66b url: "https://pub.dev" source: hosted - version: "2.6.1" + version: "2.6.2" file_selector_windows: dependency: transitive description: @@ -350,10 +454,10 @@ packages: dependency: "direct main" description: name: firebase_core - sha256: d301561d614487688d797717bef013a264c517d1d09e4c5c1325c3a64c835efb + sha256: "96607c0e829a581c2a483c658f04e8b159964c3bae2730f73297070bc85d40bb" url: "https://pub.dev" source: hosted - version: "2.24.0" + version: "2.24.2" firebase_core_platform_interface: dependency: transitive description: @@ -366,50 +470,50 @@ packages: dependency: transitive description: name: firebase_core_web - sha256: "10159d9ee42c79f4548971d92f3f0fcd5791f6738cda3583a4e3b2c8b244c018" + sha256: d585bdf3c656c3f7821ba1bd44da5f13365d22fcecaf5eb75c4295246aaa83c0 url: "https://pub.dev" source: hosted - version: "2.9.0" + version: "2.10.0" firebase_messaging: dependency: transitive description: name: firebase_messaging - sha256: "260064e1b512a9e1970b5964d645eba888208ca3de42459c38e484c8ecdc37a9" + sha256: "980259425fa5e2afc03e533f33723335731d21a56fd255611083bceebf4373a8" url: "https://pub.dev" source: hosted - version: "14.7.6" + version: "14.7.10" firebase_messaging_platform_interface: dependency: transitive description: name: firebase_messaging_platform_interface - sha256: "81fb8c983356dd75ee660f276c918380325df7a1ab1e981ede911809e9ddff30" + sha256: "54e283a0e41d81d854636ad0dad73066adc53407a60a7c3189c9656e2f1b6107" url: "https://pub.dev" source: hosted - version: "4.5.15" + version: "4.5.18" firebase_messaging_web: dependency: transitive description: name: firebase_messaging_web - sha256: "1c5d9b6cf929ab471300143059d1641a26b73c9c24adb5266e241aea23c090aa" + sha256: "90dc7ed885e90a24bb0e56d661d4d2b5f84429697fd2cbb9e5890a0ca370e6f4" url: "https://pub.dev" source: hosted - version: "3.5.15" + version: "3.5.18" firebase_storage: dependency: "direct main" description: name: firebase_storage - sha256: ef1974043d48b0aa081ad055944ec74cad3a665545849cc6232f8ac1691fd901 + sha256: "75e6cb6bed65138b5bbd86bfd7cf9bc9a175fb0c31aacc400e9203df117ffbe6" url: "https://pub.dev" source: hosted - version: "11.5.3" + version: "11.6.0" firebase_storage_platform_interface: dependency: transitive description: name: firebase_storage_platform_interface - sha256: "7b5aa0bf53de4a983aa3df57ab2bc0509d75fe2d269a0029a814aa84484798d5" + sha256: "545a3a8edf337850403bb0fa03c8074a53deb87c0107d19755c77a82ce07919e" url: "https://pub.dev" source: hosted - version: "5.1.1" + version: "5.1.3" firebase_storage_service: dependency: "direct main" description: @@ -421,10 +525,18 @@ packages: dependency: transitive description: name: firebase_storage_web - sha256: bc5ede7fd6dfe7e23821cce007cd551cf77f47f44f8c3ea4f270dea0372051dc + sha256: ee6870ff79aa304b8996ba18a4aefe1e8b3fc31fd385eab6574180267aa8d393 url: "https://pub.dev" source: hosted - version: "3.6.15" + version: "3.6.17" + fixnum: + dependency: transitive + description: + name: fixnum + sha256: "25517a4deb0c03aa0f32fd12db525856438902d9c16536311e76cdc57b31d7d1" + url: "https://pub.dev" + source: hosted + version: "1.1.0" flutter: dependency: "direct main" description: flutter @@ -657,10 +769,10 @@ packages: dependency: "direct main" description: name: get_it - sha256: f79870884de16d689cf9a7d15eedf31ed61d750e813c538a6efb92660fea83c3 + sha256: e6017ce7fdeaf218dc51a100344d8cb70134b80e28b760f8bb23c242437bafd7 url: "https://pub.dev" source: hosted - version: "7.6.4" + version: "7.6.7" glob: dependency: transitive description: @@ -673,10 +785,18 @@ packages: dependency: "direct main" description: name: go_router - sha256: "3b40e751eaaa855179b416974d59d29669e750d2e50fcdb2b37f1cb0ca8c803a" + sha256: "07ee2436909f749d606f53521dc1725dd738dc5196e5ff815bc254253c594075" url: "https://pub.dev" source: hosted - version: "13.0.1" + version: "13.1.0" + graphs: + dependency: transitive + description: + name: graphs + sha256: aedc5a15e78fc65a6e23bcd927f24c64dd995062bcd1ca6eda65a3cff92a4d19 + url: "https://pub.dev" + source: hosted + version: "2.3.1" hive: dependency: "direct main" description: @@ -713,10 +833,10 @@ packages: dependency: transitive description: name: http - sha256: "5895291c13fa8a3bd82e76d5627f69e0d85ca6a30dcac95c4ea19a5d555879c2" + sha256: a2bbf9d017fcced29139daa8ed2bba4ece450ab222871df93ca9eec6f80c34ba url: "https://pub.dev" source: hosted - version: "0.13.6" + version: "1.2.0" http_client_handler: dependency: "direct main" description: @@ -744,34 +864,34 @@ packages: dependency: "direct main" description: name: image_picker - sha256: "7d7f2768df2a8b0a3cefa5ef4f84636121987d403130e70b17ef7e2cf650ba84" + sha256: "26222b01a0c9a2c8fe02fc90b8208bd3325da5ed1f4a2acabf75939031ac0bdd" url: "https://pub.dev" source: hosted - version: "1.0.4" + version: "1.0.7" image_picker_android: dependency: transitive description: name: image_picker_android - sha256: d6a6e78821086b0b737009b09363018309bbc6de3fd88cc5c26bc2bb44a4957f + sha256: "39f2bfe497e495450c81abcd44b62f56c2a36a37a175da7d137b4454977b51b1" url: "https://pub.dev" source: hosted - version: "0.8.8+2" + version: "0.8.9+3" image_picker_for_web: dependency: transitive description: name: image_picker_for_web - sha256: "50bc9ae6a77eea3a8b11af5eb6c661eeb858fdd2f734c2a4fd17086922347ef7" + sha256: e2423c53a68b579a7c37a1eda967b8ae536c3d98518e5db95ca1fe5719a730a3 url: "https://pub.dev" source: hosted - version: "3.0.1" + version: "3.0.2" image_picker_ios: dependency: transitive description: name: image_picker_ios - sha256: "76ec722aeea419d03aa915c2c96bf5b47214b053899088c9abb4086ceecf97a7" + sha256: fadafce49e8569257a0cad56d24438a6fa1f0cbd7ee0af9b631f7492818a4ca3 url: "https://pub.dev" source: hosted - version: "0.8.8+4" + version: "0.8.9+1" image_picker_linux: dependency: transitive description: @@ -792,10 +912,10 @@ packages: dependency: transitive description: name: image_picker_platform_interface - sha256: ed9b00e63977c93b0d2d2b343685bed9c324534ba5abafbb3dfbd6a780b1b514 + sha256: fa4e815e6fcada50e35718727d83ba1c92f1edf95c0b4436554cec301b56233b url: "https://pub.dev" source: hosted - version: "2.9.1" + version: "2.9.3" image_picker_windows: dependency: transitive description: @@ -804,6 +924,22 @@ packages: url: "https://pub.dev" source: hosted version: "0.2.1+1" + injectable: + dependency: "direct main" + description: + name: injectable + sha256: cd3c422e13270c81f64ab73c80406b2b2ed563fe59d0ff2093eb7eee63d0bbeb + url: "https://pub.dev" + source: hosted + version: "2.3.2" + injectable_generator: + dependency: "direct dev" + description: + name: injectable_generator + sha256: f9d3c05f0938403f79ad6c6d23ec8e37a7a05ad980b1bf9399493f3e41845788 + url: "https://pub.dev" + source: hosted + version: "2.4.1" intl: dependency: "direct main" description: @@ -845,21 +981,29 @@ packages: source: hosted version: "0.6.7" json_annotation: - dependency: transitive + dependency: "direct main" description: name: json_annotation sha256: b10a7b2ff83d83c777edba3c6a0f97045ddadd56c944e1a23a3fdf43a1bf4467 url: "https://pub.dev" source: hosted version: "4.8.1" + json_serializable: + dependency: "direct dev" + description: + name: json_serializable + sha256: aa1f5a8912615733e0fdc7a02af03308933c93235bdc8d50d0b0c8a8ccb0b969 + url: "https://pub.dev" + source: hosted + version: "6.7.1" lazy_load_indexed_stack: dependency: "direct main" description: name: lazy_load_indexed_stack - sha256: c56c9c292048ecd8c86008617c7d77aa4057cafcdae1c5269aec6fb75019eebf + sha256: e581426391c44708210b1f571046320ea52dea46740d4972d9e1820b4ef94827 url: "https://pub.dev" source: hosted - version: "1.0.1" + version: "1.1.0" logger: dependency: transitive description: @@ -912,18 +1056,18 @@ packages: dependency: transitive description: name: mime - sha256: e4ff8e8564c03f255408decd16e7899da1733852a9110a58fe6d1b817684a63e + sha256: "2e123074287cc9fd6c09de8336dae606d1ddb88d9ac47358826db698c176a1f2" url: "https://pub.dev" source: hosted - version: "1.0.4" + version: "1.0.5" mocktail: dependency: "direct dev" description: name: mocktail - sha256: bac151b31e4ed78bd59ab89aa4c0928f297b1180186d5daf03734519e5f596c1 + sha256: c4b5007d91ca4f67256e720cb1b6d704e79a510183a12fa551021f652577dce6 url: "https://pub.dev" source: hosted - version: "1.0.1" + version: "1.0.3" models: dependency: "direct main" description: @@ -991,26 +1135,26 @@ packages: dependency: "direct main" description: name: path_provider - sha256: a1aa8aaa2542a6bc57e381f132af822420216c80d4781f7aa085ca3229208aaa + sha256: b27217933eeeba8ff24845c34003b003b2b22151de3c908d0e679e8fe1aa078b url: "https://pub.dev" source: hosted - version: "2.1.1" + version: "2.1.2" path_provider_android: dependency: transitive description: name: path_provider_android - sha256: e595b98692943b4881b219f0a9e3945118d3c16bd7e2813f98ec6e532d905f72 + sha256: "477184d672607c0a3bf68fbbf601805f92ef79c82b64b4d6eb318cbca4c48668" url: "https://pub.dev" source: hosted - version: "2.2.1" + version: "2.2.2" path_provider_foundation: dependency: transitive description: name: path_provider_foundation - sha256: "19314d595120f82aca0ba62787d58dde2cc6b5df7d2f0daf72489e38d1b57f2d" + sha256: "5a7999be66e000916500be4f15a3633ebceb8302719b47b9cc49ce924125350f" url: "https://pub.dev" source: hosted - version: "2.3.1" + version: "2.3.2" path_provider_linux: dependency: transitive description: @@ -1023,10 +1167,10 @@ packages: dependency: transitive description: name: path_provider_platform_interface - sha256: "94b1e0dd80970c1ce43d5d4e050a9918fce4f4a775e6142424c30a29a363265c" + sha256: "88f5779f72ba699763fa3a3b06aa4bf6de76c8e5de842cf6f29e2e06476c2334" url: "https://pub.dev" source: hosted - version: "2.1.1" + version: "2.1.2" path_provider_windows: dependency: transitive description: @@ -1039,10 +1183,10 @@ packages: dependency: transitive description: name: petitparser - sha256: eeb2d1428ee7f4170e2bd498827296a18d4e7fc462b71727d111c0ac7707cfa6 + sha256: c15605cd28af66339f8eb6fbe0e541bfe2d1b72d5825efc6598f3e0a31b9ad27 url: "https://pub.dev" source: hosted - version: "6.0.1" + version: "6.0.2" phosphor_flutter: dependency: "direct main" description: @@ -1063,18 +1207,18 @@ packages: dependency: transitive description: name: platform - sha256: "0a279f0707af40c890e80b1e9df8bb761694c074ba7e1d4ab1bc4b728e200b59" + sha256: "12220bb4b65720483f8fa9450b4332347737cf8213dd2840d8b2c823e47243ec" url: "https://pub.dev" source: hosted - version: "3.1.3" + version: "3.1.4" plugin_platform_interface: dependency: transitive description: name: plugin_platform_interface - sha256: f4f88d4a900933e7267e2b353594774fc0d07fb072b47eedcd5b54e1ea3269f8 + sha256: "4820fbfdb9478b1ebae27888254d445073732dae3d6ea81f0b7e06d5dedc3f02" url: "https://pub.dev" source: hosted - version: "2.1.7" + version: "2.1.8" pool: dependency: transitive description: @@ -1107,6 +1251,14 @@ packages: url: "https://pub.dev" source: hosted version: "2.1.4" + pubspec_parse: + dependency: transitive + description: + name: pubspec_parse + sha256: c63b2876e58e194e4b0828fcb080ad0e06d051cb607a6be51a9e084f47cb9367 + url: "https://pub.dev" + source: hosted + version: "1.2.3" quiver: dependency: transitive description: @@ -1115,6 +1267,14 @@ packages: url: "https://pub.dev" source: hosted version: "3.2.1" + recase: + dependency: transitive + description: + name: recase + sha256: e4eb4ec2dcdee52dcf99cb4ceabaffc631d7424ee55e56f280bc039737f89213 + url: "https://pub.dev" + source: hosted + version: "4.1.0" rxdart: dependency: transitive description: @@ -1175,6 +1335,22 @@ packages: description: flutter source: sdk version: "0.0.99" + source_gen: + dependency: transitive + description: + name: source_gen + sha256: "14658ba5f669685cd3d63701d01b31ea748310f7ab854e471962670abcf57832" + url: "https://pub.dev" + source: hosted + version: "1.5.0" + source_helper: + dependency: transitive + description: + name: source_helper + sha256: "6adebc0006c37dd63fe05bca0a929b99f06402fc95aa35bf36d67f5c06de01fd" + url: "https://pub.dev" + source: hosted + version: "1.3.4" source_map_stack_trace: dependency: transitive description: @@ -1211,18 +1387,18 @@ packages: dependency: transitive description: name: sqflite - sha256: "591f1602816e9c31377d5f008c2d9ef7b8aca8941c3f89cc5fd9d84da0c38a9a" + sha256: a9016f495c927cb90557c909ff26a6d92d9bd54fc42ba92e19d4e79d61e798c6 url: "https://pub.dev" source: hosted - version: "2.3.0" + version: "2.3.2" sqflite_common: dependency: transitive description: name: sqflite_common - sha256: bb4738f15b23352822f4c42a531677e5c6f522e079461fd240ead29d8d8a54a6 + sha256: "28d8c66baee4968519fb8bd6cdbedad982d6e53359091f0b74544a9f32ec72d5" url: "https://pub.dev" source: hosted - version: "2.5.0+2" + version: "2.5.3" stack_trace: dependency: transitive description: @@ -1239,6 +1415,14 @@ packages: url: "https://pub.dev" source: hosted version: "2.1.2" + stream_transform: + dependency: transitive + description: + name: stream_transform + sha256: "14a00e794c7c11aa145a170587321aedce29769c08d7f58b1d141da75e3b1c6f" + url: "https://pub.dev" + source: hosted + version: "2.1.0" string_scanner: dependency: transitive description: @@ -1267,10 +1451,10 @@ packages: dependency: transitive description: name: synchronized - sha256: "5fcbd27688af6082f5abd611af56ee575342c30e87541d0245f7ff99faa02c60" + sha256: "539ef412b170d65ecdafd780f924e5be3f60032a1128df156adad6c5b373d558" url: "https://pub.dev" source: hosted - version: "3.1.0" + version: "3.1.0+1" term_glyph: dependency: transitive description: @@ -1307,10 +1491,10 @@ packages: dependency: "direct main" description: name: timeago - sha256: c44b80cbc6b44627c00d76960f2af571f6f50e5dbedef4d9215d455e4335165b + sha256: d3204eb4c788214883380253da7f23485320a58c11d145babc82ad16bf4e7764 url: "https://pub.dev" source: hosted - version: "3.6.0" + version: "3.6.1" timezone: dependency: transitive description: @@ -1319,6 +1503,14 @@ packages: url: "https://pub.dev" source: hosted version: "0.9.2" + timing: + dependency: transitive + description: + name: timing + sha256: "70a3b636575d4163c477e6de42f247a23b315ae20e86442bebe32d3cabf61c32" + url: "https://pub.dev" + source: hosted + version: "1.0.1" typed_data: dependency: transitive description: @@ -1331,34 +1523,34 @@ packages: dependency: transitive description: name: url_launcher - sha256: b1c9e98774adf8820c96fbc7ae3601231d324a7d5ebd8babe27b6dfac91357ba + sha256: c512655380d241a337521703af62d2c122bf7b77a46ff7dd750092aa9433499c url: "https://pub.dev" source: hosted - version: "6.2.1" + version: "6.2.4" url_launcher_android: dependency: transitive description: name: url_launcher_android - sha256: "31222ffb0063171b526d3e569079cf1f8b294075ba323443fdc690842bfd4def" + sha256: "507dc655b1d9cb5ebc756032eb785f114e415f91557b73bf60b7e201dfedeb2f" url: "https://pub.dev" source: hosted - version: "6.2.0" + version: "6.2.2" url_launcher_ios: dependency: transitive description: name: url_launcher_ios - sha256: bba3373219b7abb6b5e0d071b0fe66dfbe005d07517a68e38d4fc3638f35c6d3 + sha256: "75bb6fe3f60070407704282a2d295630cab232991eb52542b18347a8a941df03" url: "https://pub.dev" source: hosted - version: "6.2.1" + version: "6.2.4" url_launcher_linux: dependency: transitive description: name: url_launcher_linux - sha256: "9f2d390e096fdbe1e6e6256f97851e51afc2d9c423d3432f1d6a02a8a9a8b9fd" + sha256: ab360eb661f8879369acac07b6bb3ff09d9471155357da8443fd5d3cf7363811 url: "https://pub.dev" source: hosted - version: "3.1.0" + version: "3.1.1" url_launcher_macos: dependency: transitive description: @@ -1371,26 +1563,26 @@ packages: dependency: transitive description: name: url_launcher_platform_interface - sha256: "980e8d9af422f477be6948bdfb68df8433be71f5743a188968b0c1b887807e50" + sha256: a932c3a8082e118f80a475ce692fde89dc20fddb24c57360b96bc56f7035de1f url: "https://pub.dev" source: hosted - version: "2.2.0" + version: "2.3.1" url_launcher_web: dependency: transitive description: name: url_launcher_web - sha256: "138bd45b3a456dcfafc46d1a146787424f8d2edfbf2809c9324361e58f851cf7" + sha256: fff0932192afeedf63cdd50ecbb1bc825d31aed259f02bb8dba0f3b729a5e88b url: "https://pub.dev" source: hosted - version: "2.2.1" + version: "2.2.3" url_launcher_windows: dependency: transitive description: name: url_launcher_windows - sha256: "7754a1ad30ee896b265f8d14078b0513a4dba28d358eabb9d5f339886f4a1adc" + sha256: ecf9725510600aa2bb6d7ddabe16357691b6d2805f66216a97d1b881e21beff7 url: "https://pub.dev" source: hosted - version: "3.1.0" + version: "3.1.1" user_data_source: dependency: "direct main" description: @@ -1409,34 +1601,34 @@ packages: dependency: transitive description: name: uuid - sha256: df5a4d8f22ee4ccd77f8839ac7cb274ebc11ef9adcce8b92be14b797fe889921 + sha256: cd210a09f7c18cbe5a02511718e0334de6559871052c90a90c0cca46a4aa81c8 url: "https://pub.dev" source: hosted - version: "4.2.1" + version: "4.3.3" vector_graphics: dependency: transitive description: name: vector_graphics - sha256: "0f0c746dd2d6254a0057218ff980fc7f5670fd0fcf5e4db38a490d31eed4ad43" + sha256: "18f6690295af52d081f6808f2f7c69f0eed6d7e23a71539d75f4aeb8f0062172" url: "https://pub.dev" source: hosted - version: "1.1.9+1" + version: "1.1.9+2" vector_graphics_codec: dependency: transitive description: name: vector_graphics_codec - sha256: "0edf6d630d1bfd5589114138ed8fada3234deacc37966bec033d3047c29248b7" + sha256: "531d20465c10dfac7f5cd90b60bbe4dd9921f1ec4ca54c83ebb176dbacb7bb2d" url: "https://pub.dev" source: hosted - version: "1.1.9+1" + version: "1.1.9+2" vector_graphics_compiler: dependency: transitive description: name: vector_graphics_compiler - sha256: d24333727332d9bd20990f1483af4e09abdb9b1fc7c3db940b56ab5c42790c26 + sha256: "03012b0a33775c5530576b70240308080e1d5050f0faf000118c20e6463bc0ad" url: "https://pub.dev" source: hosted - version: "1.1.9+1" + version: "1.1.9+2" vector_math: dependency: transitive description: @@ -1497,18 +1689,18 @@ packages: dependency: transitive description: name: win32 - sha256: "5a751eddf9db89b3e5f9d50c20ab8612296e4e8db69009788d6c8b060a84191c" + sha256: "464f5674532865248444b4c3daca12bd9bf2d7c47f759ce2617986e7229494a8" url: "https://pub.dev" source: hosted - version: "4.1.4" + version: "5.2.0" win32_registry: dependency: transitive description: name: win32_registry - sha256: "1c52f994bdccb77103a6231ad4ea331a244dbcef5d1f37d8462f713143b0bfae" + sha256: "41fd8a189940d8696b1b810efb9abcf60827b6cbfab90b0c43e8439e3a39d85a" url: "https://pub.dev" source: hosted - version: "1.1.0" + version: "1.1.2" xdg_directories: dependency: transitive description: @@ -1521,10 +1713,10 @@ packages: dependency: transitive description: name: xml - sha256: af5e77e9b83f2f4adc5d3f0a4ece1c7f45a2467b695c2540381bac793e34e556 + sha256: b015a8ad1c488f66851d762d3090a21c600e479dc75e68328c52774040cf9226 url: "https://pub.dev" source: hosted - version: "6.4.2" + version: "6.5.0" yaml: dependency: transitive description: diff --git a/mobile/pubspec.yaml b/mobile/pubspec.yaml index 1dc957b..0db216f 100644 --- a/mobile/pubspec.yaml +++ b/mobile/pubspec.yaml @@ -22,6 +22,7 @@ dependencies: bookmark_repository: path: packages/bookmark_repository cached_network_image: ^3.2.3 + chopper: ^7.1.1 cloud_messaging_service: path: packages/cloud_messaging_service connectivity_plus: ^5.0.2 @@ -51,7 +52,9 @@ dependencies: http_client_handler: path: packages/http_client_handler image_picker: ^1.0.4 + injectable: ^2.3.2 intl: ^0.18.1 + json_annotation: ^4.8.1 lazy_load_indexed_stack: ^1.0.1 models: path: packages/models @@ -68,8 +71,12 @@ dependencies: dev_dependencies: bloc_test: ^9.1.0 + build_runner: ^2.4.8 + chopper_generator: ^7.1.1 flutter_test: sdk: flutter + injectable_generator: ^2.4.1 + json_serializable: ^6.7.1 mocktail: ^1.0.1 very_good_analysis: ^5.1.0 From c463a19d68f7b4c07da93e7160c71c146d982c67 Mon Sep 17 00:00:00 2001 From: dungngminh <63831488+dungngminh@users.noreply.github.com> Date: Wed, 31 Jan 2024 02:10:37 +0700 Subject: [PATCH 02/15] add register by chopper --- .../lib/data/remote/auth/auth_service.chopper.dart | 14 ++++++++++++++ mobile/lib/data/remote/auth/auth_service.dart | 4 ++++ 2 files changed, 18 insertions(+) diff --git a/mobile/lib/data/remote/auth/auth_service.chopper.dart b/mobile/lib/data/remote/auth/auth_service.chopper.dart index 20b5d83..dc281ac 100644 --- a/mobile/lib/data/remote/auth/auth_service.chopper.dart +++ b/mobile/lib/data/remote/auth/auth_service.chopper.dart @@ -31,4 +31,18 @@ final class _$AuthService extends AuthService { await client.send($request); return $response.bodyOrThrow; } + + @override + Future register(RegisterRequestBody body) async { + final Uri $url = Uri.parse('api/auth/register'); + final $body = body; + final Request $request = Request( + 'POST', + $url, + client.baseUrl, + body: $body, + ); + final Response $response = await client.send($request); + return $response.bodyOrThrow; + } } diff --git a/mobile/lib/data/remote/auth/auth_service.dart b/mobile/lib/data/remote/auth/auth_service.dart index e28638a..34f4a9d 100644 --- a/mobile/lib/data/remote/auth/auth_service.dart +++ b/mobile/lib/data/remote/auth/auth_service.dart @@ -1,6 +1,7 @@ import 'package:chopper/chopper.dart'; import 'package:injectable/injectable.dart'; import 'package:very_good_blog_app/data/remote/auth/requests/login_request_body.dart'; +import 'package:very_good_blog_app/data/remote/auth/requests/register_request_body.dart'; import 'package:very_good_blog_app/data/remote/auth/responses/login_response.dart'; part 'auth_service.chopper.dart'; @@ -15,4 +16,7 @@ abstract class AuthService extends ChopperService { @Post(path: 'login') Future login(@Body() LoginRequestBody body); + + @Post(path: 'register') + Future register(@Body() RegisterRequestBody body); } From cd054f8e82c1eae84a274b3868051db40656a58e Mon Sep 17 00:00:00 2001 From: dungngminh <63831488+dungngminh@users.noreply.github.com> Date: Thu, 1 Feb 2024 01:11:06 +0700 Subject: [PATCH 03/15] di and inject local storage --- .../local/user_secure_storage.dart | 42 +++++++++++++++ .../remote/auth/auth_service.chopper.dart | 0 .../remote/auth/auth_service.dart | 6 +-- .../auth/requests/login_request_body.dart | 0 .../auth/requests/login_request_body.g.dart | 0 .../auth/requests/register_request_body.dart | 0 .../requests/register_request_body.g.dart | 0 .../remote/auth/responses/login_response.dart | 0 .../auth/responses/login_response.g.dart | 0 .../repositories/auth_repository_impl.dart | 51 +++++++++++++++++++ mobile/lib/di/di.config.dart | 31 ++++++++--- mobile/lib/di/di.dart | 17 +++---- mobile/lib/di/modules/local_module.dart | 10 ++++ .../domain/repositories/auth_repository.dart | 12 +++++ mobile/pubspec.lock | 2 +- mobile/pubspec.yaml | 1 + 16 files changed, 150 insertions(+), 22 deletions(-) create mode 100644 mobile/lib/data/datasources/local/user_secure_storage.dart rename mobile/lib/data/{ => datasources}/remote/auth/auth_service.chopper.dart (100%) rename mobile/lib/data/{ => datasources}/remote/auth/auth_service.dart (63%) rename mobile/lib/data/{ => datasources}/remote/auth/requests/login_request_body.dart (100%) rename mobile/lib/data/{ => datasources}/remote/auth/requests/login_request_body.g.dart (100%) rename mobile/lib/data/{ => datasources}/remote/auth/requests/register_request_body.dart (100%) rename mobile/lib/data/{ => datasources}/remote/auth/requests/register_request_body.g.dart (100%) rename mobile/lib/data/{ => datasources}/remote/auth/responses/login_response.dart (100%) rename mobile/lib/data/{ => datasources}/remote/auth/responses/login_response.g.dart (100%) create mode 100644 mobile/lib/data/repositories/auth_repository_impl.dart create mode 100644 mobile/lib/domain/repositories/auth_repository.dart diff --git a/mobile/lib/data/datasources/local/user_secure_storage.dart b/mobile/lib/data/datasources/local/user_secure_storage.dart new file mode 100644 index 0000000..8e5ac20 --- /dev/null +++ b/mobile/lib/data/datasources/local/user_secure_storage.dart @@ -0,0 +1,42 @@ +import 'package:flutter_secure_storage/flutter_secure_storage.dart'; +import 'package:injectable/injectable.dart'; + +const accessTokenKey = 'ACCESS_TOKEN'; +const userIdKey = 'USER_ID'; + +abstract class UserSecureStorage { + Future get accessToken; + + Future get userId; + + Future setUserId(String userId); + + Future setAccessToken(String accessToken); + + Future removeAllKeys(); +} + +@LazySingleton(as: UserSecureStorage) +class UserSecureStorageImpl implements UserSecureStorage { + UserSecureStorageImpl({required FlutterSecureStorage secureStorage}) + : _secureStorage = secureStorage; + + final FlutterSecureStorage _secureStorage; + + @override + Future get accessToken => _secureStorage.read(key: accessTokenKey); + + @override + Future get userId => _secureStorage.read(key: userIdKey); + + @override + Future setAccessToken(String accessToken) => + _secureStorage.write(key: accessTokenKey, value: accessToken); + + @override + Future setUserId(String userId) => + _secureStorage.write(key: userIdKey, value: userId); + + @override + Future removeAllKeys() => _secureStorage.deleteAll(); +} diff --git a/mobile/lib/data/remote/auth/auth_service.chopper.dart b/mobile/lib/data/datasources/remote/auth/auth_service.chopper.dart similarity index 100% rename from mobile/lib/data/remote/auth/auth_service.chopper.dart rename to mobile/lib/data/datasources/remote/auth/auth_service.chopper.dart diff --git a/mobile/lib/data/remote/auth/auth_service.dart b/mobile/lib/data/datasources/remote/auth/auth_service.dart similarity index 63% rename from mobile/lib/data/remote/auth/auth_service.dart rename to mobile/lib/data/datasources/remote/auth/auth_service.dart index 34f4a9d..0945a11 100644 --- a/mobile/lib/data/remote/auth/auth_service.dart +++ b/mobile/lib/data/datasources/remote/auth/auth_service.dart @@ -1,8 +1,8 @@ import 'package:chopper/chopper.dart'; import 'package:injectable/injectable.dart'; -import 'package:very_good_blog_app/data/remote/auth/requests/login_request_body.dart'; -import 'package:very_good_blog_app/data/remote/auth/requests/register_request_body.dart'; -import 'package:very_good_blog_app/data/remote/auth/responses/login_response.dart'; +import 'package:very_good_blog_app/data/datasources/remote/auth/requests/login_request_body.dart'; +import 'package:very_good_blog_app/data/datasources/remote/auth/requests/register_request_body.dart'; +import 'package:very_good_blog_app/data/datasources/remote/auth/responses/login_response.dart'; part 'auth_service.chopper.dart'; diff --git a/mobile/lib/data/remote/auth/requests/login_request_body.dart b/mobile/lib/data/datasources/remote/auth/requests/login_request_body.dart similarity index 100% rename from mobile/lib/data/remote/auth/requests/login_request_body.dart rename to mobile/lib/data/datasources/remote/auth/requests/login_request_body.dart diff --git a/mobile/lib/data/remote/auth/requests/login_request_body.g.dart b/mobile/lib/data/datasources/remote/auth/requests/login_request_body.g.dart similarity index 100% rename from mobile/lib/data/remote/auth/requests/login_request_body.g.dart rename to mobile/lib/data/datasources/remote/auth/requests/login_request_body.g.dart diff --git a/mobile/lib/data/remote/auth/requests/register_request_body.dart b/mobile/lib/data/datasources/remote/auth/requests/register_request_body.dart similarity index 100% rename from mobile/lib/data/remote/auth/requests/register_request_body.dart rename to mobile/lib/data/datasources/remote/auth/requests/register_request_body.dart diff --git a/mobile/lib/data/remote/auth/requests/register_request_body.g.dart b/mobile/lib/data/datasources/remote/auth/requests/register_request_body.g.dart similarity index 100% rename from mobile/lib/data/remote/auth/requests/register_request_body.g.dart rename to mobile/lib/data/datasources/remote/auth/requests/register_request_body.g.dart diff --git a/mobile/lib/data/remote/auth/responses/login_response.dart b/mobile/lib/data/datasources/remote/auth/responses/login_response.dart similarity index 100% rename from mobile/lib/data/remote/auth/responses/login_response.dart rename to mobile/lib/data/datasources/remote/auth/responses/login_response.dart diff --git a/mobile/lib/data/remote/auth/responses/login_response.g.dart b/mobile/lib/data/datasources/remote/auth/responses/login_response.g.dart similarity index 100% rename from mobile/lib/data/remote/auth/responses/login_response.g.dart rename to mobile/lib/data/datasources/remote/auth/responses/login_response.g.dart diff --git a/mobile/lib/data/repositories/auth_repository_impl.dart b/mobile/lib/data/repositories/auth_repository_impl.dart new file mode 100644 index 0000000..b8c4784 --- /dev/null +++ b/mobile/lib/data/repositories/auth_repository_impl.dart @@ -0,0 +1,51 @@ +import 'package:injectable/injectable.dart'; +import 'package:very_good_blog_app/data/datasources/local/user_secure_storage.dart'; +import 'package:very_good_blog_app/data/datasources/remote/auth/auth_service.dart'; +import 'package:very_good_blog_app/data/datasources/remote/auth/requests/login_request_body.dart'; +import 'package:very_good_blog_app/data/datasources/remote/auth/requests/register_request_body.dart'; +import 'package:very_good_blog_app/domain/repositories/auth_repository.dart'; + +@LazySingleton(as: AuthRepository) +class AuthRepositoryImpl implements AuthRepository { + AuthRepositoryImpl({ + required AuthService authService, + required UserSecureStorage secureStorage, + }) : _authService = authService, + _secureStorage = secureStorage; + + final AuthService _authService; + final UserSecureStorage _secureStorage; + + @override + Future login({required String email, required String password}) { + return _authService + .login(LoginRequestBody(email: email, password: password)) + .then((response) { + _secureStorage + ..setAccessToken(response.token) + ..setUserId(response.id); + }); + } + + @override + Future register({ + required String email, + required String password, + required String confirmationPassword, + required String fullName, + }) { + return _authService.register( + RegisterRequestBody( + email: email, + password: password, + confirmationPassword: confirmationPassword, + fullName: fullName, + ), + ); + } + + @override + Future signOut() { + return _secureStorage.removeAllKeys(); + } +} diff --git a/mobile/lib/di/di.config.dart b/mobile/lib/di/di.config.dart index d8401a2..0efe1a6 100644 --- a/mobile/lib/di/di.config.dart +++ b/mobile/lib/di/di.config.dart @@ -8,12 +8,17 @@ // coverage:ignore-file // ignore_for_file: no_leading_underscores_for_library_prefixes -import 'package:chopper/chopper.dart' as _i3; +import 'package:chopper/chopper.dart' as _i5; +import 'package:flutter_secure_storage/flutter_secure_storage.dart' as _i3; import 'package:get_it/get_it.dart' as _i1; import 'package:injectable/injectable.dart' as _i2; -import '../data/remote/auth/auth_service.dart' as _i4; -import 'modules/network_module.dart' as _i5; +import '../data/datasources/local/user_secure_storage.dart' as _i4; +import '../data/datasources/remote/auth/auth_service.dart' as _i6; +import '../data/repositories/auth_repository_impl.dart' as _i8; +import '../domain/repositories/auth_repository.dart' as _i7; +import 'modules/local_module.dart' as _i9; +import 'modules/network_module.dart' as _i10; extension GetItInjectableX on _i1.GetIt { // initializes the registration of main-scope dependencies inside of GetIt @@ -26,25 +31,35 @@ extension GetItInjectableX on _i1.GetIt { environment, environmentFilter, ); + final localModule = _$LocalModule(); final networkModule = _$NetworkModule(); + gh.lazySingleton<_i3.FlutterSecureStorage>(() => localModule.secureStorage); gh.factory( () => networkModule.baseUrl, instanceName: 'baseUrl', ); - gh.lazySingleton<_i3.ChopperClient>( + gh.lazySingleton<_i4.UserSecureStorage>(() => _i4.UserSecureStorageImpl( + secureStorage: gh<_i3.FlutterSecureStorage>())); + gh.lazySingleton<_i5.ChopperClient>( () => networkModule .unAuthChopperClient(gh(instanceName: 'baseUrl')), instanceName: 'unAuthClient', ); - gh.lazySingleton<_i3.ChopperClient>( + gh.lazySingleton<_i5.ChopperClient>( () => networkModule.authChopperClient(gh(instanceName: 'baseUrl')), instanceName: 'authClient', ); - gh.lazySingleton<_i4.AuthService>(() => _i4.AuthService.create( - gh<_i3.ChopperClient>(instanceName: 'unAuthClient'))); + gh.lazySingleton<_i6.AuthService>(() => _i6.AuthService.create( + gh<_i5.ChopperClient>(instanceName: 'unAuthClient'))); + gh.lazySingleton<_i7.AuthRepository>(() => _i8.AuthRepositoryImpl( + authService: gh<_i6.AuthService>(), + secureStorage: gh<_i4.UserSecureStorage>(), + )); return this; } } -class _$NetworkModule extends _i5.NetworkModule {} +class _$LocalModule extends _i9.LocalModule {} + +class _$NetworkModule extends _i10.NetworkModule {} diff --git a/mobile/lib/di/di.dart b/mobile/lib/di/di.dart index 7a20bd4..5a50772 100644 --- a/mobile/lib/di/di.dart +++ b/mobile/lib/di/di.dart @@ -1,25 +1,22 @@ import 'package:authentication_data_source/authentication_data_source.dart'; import 'package:blog_data_source/blog_data_source.dart'; import 'package:bookmark_data_source/bookmark_data_source.dart'; -import 'package:chopper/chopper.dart'; import 'package:firebase_storage/firebase_storage.dart'; import 'package:get_it/get_it.dart'; import 'package:hive_flutter/hive_flutter.dart'; import 'package:injectable/injectable.dart'; import 'package:user_repository/user_repository.dart'; import 'package:very_good_blog_app/app/app.dart'; -import 'package:very_good_blog_app/data/remote/auth/auth_service.dart'; - -import 'di.config.dart'; +import 'package:very_good_blog_app/di/di.config.dart'; final injector = GetIt.instance; -@InjectableInit( - initializerName: 'init', // default - preferRelativeImports: true, // default - asExtension: true, // default -) -void configureDependencies() => injector.init(); +@InjectableInit( + initializerName: 'init', // default + preferRelativeImports: true, // default + asExtension: true, // default +) +void configureDependencies() => injector.init(); Future initServices() async { await Hive.openBox(HiveBox.userPrefs); diff --git a/mobile/lib/di/modules/local_module.dart b/mobile/lib/di/modules/local_module.dart index e69de29..9d1bf3d 100644 --- a/mobile/lib/di/modules/local_module.dart +++ b/mobile/lib/di/modules/local_module.dart @@ -0,0 +1,10 @@ +import 'package:flutter_secure_storage/flutter_secure_storage.dart'; +import 'package:injectable/injectable.dart'; + +@module +abstract class LocalModule { + @lazySingleton + FlutterSecureStorage get secureStorage => const FlutterSecureStorage( + aOptions: AndroidOptions(encryptedSharedPreferences: true), + ); +} diff --git a/mobile/lib/domain/repositories/auth_repository.dart b/mobile/lib/domain/repositories/auth_repository.dart new file mode 100644 index 0000000..6b14988 --- /dev/null +++ b/mobile/lib/domain/repositories/auth_repository.dart @@ -0,0 +1,12 @@ +abstract class AuthRepository { + Future login({required String email, required String password}); + + Future register({ + required String email, + required String password, + required String confirmationPassword, + required String fullName, + }); + + Future signOut(); +} diff --git a/mobile/pubspec.lock b/mobile/pubspec.lock index d4ae9b8..ec7f053 100644 --- a/mobile/pubspec.lock +++ b/mobile/pubspec.lock @@ -668,7 +668,7 @@ packages: source: hosted version: "9.2.10" flutter_secure_storage: - dependency: transitive + dependency: "direct main" description: name: flutter_secure_storage sha256: f2afec1f1762c040a349ea2a588e32f442da5d0db3494a52a929a97c9e550bc5 diff --git a/mobile/pubspec.yaml b/mobile/pubspec.yaml index 0db216f..945173e 100644 --- a/mobile/pubspec.yaml +++ b/mobile/pubspec.yaml @@ -41,6 +41,7 @@ dependencies: flutter_localizations: sdk: flutter flutter_quill: ^9.2.10 + flutter_secure_storage: ^7.0.1 flutter_slidable: ^3.0.1 flutter_svg: ^2.0.9 fluttertoast: ^8.1.2 From f9dba18c3a9f9e10a693b9ad9449d7527270e945 Mon Sep 17 00:00:00 2001 From: dungngminh <63831488+dungngminh@users.noreply.github.com> Date: Sat, 3 Feb 2024 22:53:09 +0700 Subject: [PATCH 04/15] refactor: login bloc --- .../config/extensions/context_extension.dart | 5 + .../config/extensions/string_extension.dart | 13 ++ mobile/lib/login/bloc/login_bloc.dart | 28 +-- mobile/lib/login/bloc/login_event.dart | 8 +- mobile/lib/login/bloc/login_state.dart | 10 +- mobile/lib/login/model/email.dart | 21 ++ mobile/lib/login/model/models.dart | 2 +- mobile/lib/login/model/username.dart | 13 -- mobile/lib/login/view/login_form.dart | 194 ++++++++---------- mobile/lib/login/view/login_view.dart | 5 +- mobile/pubspec.lock | 24 +++ mobile/pubspec.yaml | 2 + mobile/test/login/bloc/login_bloc_test.dart | 41 ++-- mobile/test/login/bloc/login_event_test.dart | 4 +- mobile/test/login/bloc/login_state_test.dart | 6 +- mobile/test/login/model/username_test.dart | 10 +- mobile/test/register/model/username_test.dart | 10 +- 17 files changed, 211 insertions(+), 185 deletions(-) create mode 100644 mobile/lib/app/config/extensions/string_extension.dart create mode 100644 mobile/lib/login/model/email.dart delete mode 100644 mobile/lib/login/model/username.dart diff --git a/mobile/lib/app/config/extensions/context_extension.dart b/mobile/lib/app/config/extensions/context_extension.dart index c3fe3e8..6cf5157 100644 --- a/mobile/lib/app/config/extensions/context_extension.dart +++ b/mobile/lib/app/config/extensions/context_extension.dart @@ -1,3 +1,4 @@ +import 'package:flutter/material.dart'; import 'package:flutter/widgets.dart'; import 'package:go_router/go_router.dart'; @@ -17,4 +18,8 @@ extension ContextExtension on BuildContext { String get currentLocation { return GoRouterState.of(this).uri.toString(); } + + ThemeData get theme { + return Theme.of(this); + } } diff --git a/mobile/lib/app/config/extensions/string_extension.dart b/mobile/lib/app/config/extensions/string_extension.dart new file mode 100644 index 0000000..2f7e3e9 --- /dev/null +++ b/mobile/lib/app/config/extensions/string_extension.dart @@ -0,0 +1,13 @@ +import 'package:dartx/dartx.dart'; + +extension StringExtension on String? { + bool isEmail() { + if (isNullOrEmpty || isNullOrBlank) { + return false; + } + final emailRegex = RegExp( + r'^(([^<>()[\]\\.,;:\s@\"]+(\.[^<>()[\]\\.,;:\s@\"]+)*)|(\".+\"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$', + ); + return emailRegex.hasMatch(this!); + } +} diff --git a/mobile/lib/login/bloc/login_bloc.dart b/mobile/lib/login/bloc/login_bloc.dart index 6789f9f..eb2bedb 100644 --- a/mobile/lib/login/bloc/login_bloc.dart +++ b/mobile/lib/login/bloc/login_bloc.dart @@ -1,7 +1,7 @@ -import 'package:authentication_repository/authentication_repository.dart'; import 'package:bloc/bloc.dart'; import 'package:equatable/equatable.dart'; import 'package:formz/formz.dart'; +import 'package:very_good_blog_app/domain/repositories/auth_repository.dart'; import 'package:very_good_blog_app/login/model/models.dart'; part 'login_event.dart'; @@ -9,28 +9,28 @@ part 'login_state.dart'; class LoginBloc extends Bloc { LoginBloc({ - required AuthenticationRepository authenticationRepository, - }) : _authenticationRepository = authenticationRepository, + required AuthRepository authRepository, + }) : _authRepository = authRepository, super(const LoginState()) { - on(_onUsernameChanged); + on(_onEmailChanged); on(_onPasswordChanged); on(_onSubmitted); } - final AuthenticationRepository _authenticationRepository; + final AuthRepository _authRepository; - void _onUsernameChanged( - LoginUsernameChanged event, + void _onEmailChanged( + LoginEmailChanged event, Emitter emit, ) { - final username = Username.dirty(event.username); + final email = Email.dirty(event.email); emit( state.copyWith( - username: username, + email: email, password: state.password, isValid: Formz.validate( [ - username, + email, state.password, ], ), @@ -45,9 +45,9 @@ class LoginBloc extends Bloc { final password = Password.dirty(event.password); emit( state.copyWith( - username: state.username, + email: state.email, password: password, - isValid: Formz.validate([state.username, password]), + isValid: Formz.validate([state.email, password]), ), ); } @@ -58,8 +58,8 @@ class LoginBloc extends Bloc { ) async { if (!state.isValid) return; emit(state.copyWith(status: FormzSubmissionStatus.inProgress)); - return _authenticationRepository - .login(password: state.password.value, username: state.username.value) + await _authRepository + .login(password: state.password.value, email: state.email.value) .then( (_) => emit(state.copyWith(status: FormzSubmissionStatus.success)), ) diff --git a/mobile/lib/login/bloc/login_event.dart b/mobile/lib/login/bloc/login_event.dart index 7c63fbf..04cc3b7 100644 --- a/mobile/lib/login/bloc/login_event.dart +++ b/mobile/lib/login/bloc/login_event.dart @@ -7,13 +7,13 @@ abstract class LoginEvent extends Equatable { List get props => []; } -class LoginUsernameChanged extends LoginEvent { - const LoginUsernameChanged(this.username); +class LoginEmailChanged extends LoginEvent { + const LoginEmailChanged(this.email); - final String username; + final String email; @override - List get props => [username]; + List get props => [email]; } class LoginPasswordChanged extends LoginEvent { diff --git a/mobile/lib/login/bloc/login_state.dart b/mobile/lib/login/bloc/login_state.dart index 53c4844..a6e365a 100644 --- a/mobile/lib/login/bloc/login_state.dart +++ b/mobile/lib/login/bloc/login_state.dart @@ -3,30 +3,30 @@ part of 'login_bloc.dart'; class LoginState extends Equatable { const LoginState({ this.status = FormzSubmissionStatus.initial, - this.username = const Username.isPure(), + this.email = const Email.isPure(), this.password = const Password.isPure(), this.isValid = false, }); final FormzSubmissionStatus status; - final Username username; + final Email email; final Password password; final bool isValid; LoginState copyWith({ FormzSubmissionStatus? status, - Username? username, + Email? email, Password? password, bool? isValid, }) { return LoginState( status: status ?? this.status, - username: username ?? this.username, + email: email ?? this.email, password: password ?? this.password, isValid: isValid ?? this.isValid, ); } @override - List get props => [status, username, password, isValid]; + List get props => [status, email, password, isValid]; } diff --git a/mobile/lib/login/model/email.dart b/mobile/lib/login/model/email.dart new file mode 100644 index 0000000..3ad5f6f --- /dev/null +++ b/mobile/lib/login/model/email.dart @@ -0,0 +1,21 @@ +import 'package:dartx/dartx.dart'; +import 'package:formz/formz.dart'; +import 'package:very_good_blog_app/app/config/extensions/string_extension.dart'; + +enum EmailValidationError { empty, invalid } + +class Email extends FormzInput { + const Email.isPure() : super.pure(''); + const Email.dirty([super.value = '']) : super.dirty(); + + @override + EmailValidationError? validator(String? value) { + if (value.isNullOrEmpty) { + return EmailValidationError.empty; + } + if (!value.isEmail()) { + return EmailValidationError.invalid; + } + return null; + } +} diff --git a/mobile/lib/login/model/models.dart b/mobile/lib/login/model/models.dart index 58be313..31cc892 100644 --- a/mobile/lib/login/model/models.dart +++ b/mobile/lib/login/model/models.dart @@ -1,2 +1,2 @@ +export 'email.dart'; export 'password.dart'; -export 'username.dart'; diff --git a/mobile/lib/login/model/username.dart b/mobile/lib/login/model/username.dart deleted file mode 100644 index b2a58f7..0000000 --- a/mobile/lib/login/model/username.dart +++ /dev/null @@ -1,13 +0,0 @@ -import 'package:formz/formz.dart'; - -enum UsernameValidationError { empty } - -class Username extends FormzInput { - const Username.isPure() : super.pure(''); - const Username.dirty([super.value = '']) : super.dirty(); - - @override - UsernameValidationError? validator(String? value) { - return value?.isNotEmpty == true ? null : UsernameValidationError.empty; - } -} diff --git a/mobile/lib/login/view/login_form.dart b/mobile/lib/login/view/login_form.dart index e575287..d654d1b 100644 --- a/mobile/lib/login/view/login_form.dart +++ b/mobile/lib/login/view/login_form.dart @@ -1,6 +1,7 @@ import 'package:flutter/material.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:formz/formz.dart'; +import 'package:gap/gap.dart'; import 'package:very_good_blog_app/app/app.dart'; import 'package:very_good_blog_app/authentication/authentication.dart'; import 'package:very_good_blog_app/l10n/l10n.dart'; @@ -14,22 +15,21 @@ class LoginForm extends StatelessWidget { Widget build(BuildContext context) { final l10n = context.l10n; + void showSnackbarError(String message) { + ScaffoldMessenger.of(context) + ..hideCurrentSnackBar() + ..showSnackBar( + SnackBar( + content: Text(message), + ), + ); + } + return BlocListener( listener: (context, state) { if (state.status.isFailure) { - ScaffoldMessenger.of(context) - ..hideCurrentSnackBar() - ..showSnackBar( - SnackBar( - content: Builder( - builder: (context) { - final message = - context.watch().state.status; - return Text(message.toString()); - }, - ), - ), - ); + final message = context.watch().state.status; + showSnackbarError(message.toString()); } }, child: Padding( @@ -38,13 +38,11 @@ class LoginForm extends StatelessWidget { crossAxisAlignment: CrossAxisAlignment.stretch, children: [ TitleOfTextField(l10n.username), - _UsernameInput(), - const Padding(padding: EdgeInsets.all(12)), + _EmailInput(), + const Gap(24), TitleOfTextField(l10n.password), _PasswordInput(), - const SizedBox( - height: 24, - ), + const Gap(24), Align( alignment: Alignment.centerRight, child: Text( @@ -55,10 +53,8 @@ class LoginForm extends StatelessWidget { ), ), ), - const Padding(padding: EdgeInsets.all(12)), - Center( - child: _LoginButton(), - ), + const Gap(24), + Center(child: _LoginButton()), ], ), ), @@ -66,30 +62,26 @@ class LoginForm extends StatelessWidget { } } -class _UsernameInput extends StatelessWidget { +class _EmailInput extends StatelessWidget { @override Widget build(BuildContext context) { final l10n = context.l10n; - return BlocBuilder( - buildWhen: (previous, current) => previous.username != current.username, - builder: (context, state) { - return TextFieldDecoration( - child: TextField( - key: const Key('loginForm_usernameInput_textField'), - onChanged: (username) => - context.read().add(LoginUsernameChanged(username)), - decoration: InputDecoration( - contentPadding: const EdgeInsets.only(left: 16, right: 16), - border: InputBorder.none, - hintText: l10n.usernameHint, - errorText: state.username.displayError != null - ? l10n.usernameEmpty - : null, - ), - textInputAction: TextInputAction.next, - ), - ); - }, + final email = context.select((LoginBloc bloc) => bloc.state.email); + return TextFieldDecoration( + child: TextField( + key: const Key('loginForm_usernameInput_textField'), + onChanged: (value) { + if (value.trim().isEmpty) return; + context.read().add(LoginEmailChanged(value)); + }, + decoration: InputDecoration( + contentPadding: const EdgeInsets.only(left: 16, right: 16), + border: InputBorder.none, + hintText: l10n.usernameHint, + errorText: email.displayError != null ? l10n.usernameEmpty : null, + ), + textInputAction: TextInputAction.next, + ), ); } } @@ -100,47 +92,37 @@ class _PasswordInput extends StatefulWidget { } class _PasswordInputState extends State<_PasswordInput> { - late bool _isHidePassword; - - @override - void initState() { - _isHidePassword = true; - super.initState(); - } + bool _isHidePassword = true; @override Widget build(BuildContext context) { final l10n = context.l10n; - return BlocBuilder( - buildWhen: (previous, current) => previous.password != current.password, - builder: (context, state) { - return TextFieldDecoration( - child: TextField( - key: const Key('loginForm_passwordInput_textField'), - onChanged: (password) => - context.read().add(LoginPasswordChanged(password)), - obscureText: _isHidePassword, - decoration: InputDecoration( - contentPadding: const EdgeInsets.only(left: 16, right: 16), - border: InputBorder.none, - hintText: l10n.passwordHint, - errorText: getErrorMessage(state.password.displayError, l10n), - suffixIcon: IconButton( - icon: _isHidePassword - ? Assets.icons.show.svg(color: AppPalette.primaryColor) - : Assets.icons.hide.svg(color: AppPalette.primaryColor), - onPressed: () { - setState(() { - _isHidePassword = !_isHidePassword; - }); - }, - splashRadius: 24, - ), - ), - textAlignVertical: TextAlignVertical.center, + final password = context.select((LoginBloc bloc) => bloc.state.password); + final showOrHideIcon = + _isHidePassword ? Assets.icons.show.svg() : Assets.icons.hide.svg(); + return TextFieldDecoration( + child: TextField( + key: const Key('loginForm_passwordInput_textField'), + onChanged: (password) => + context.read().add(LoginPasswordChanged(password)), + obscureText: _isHidePassword, + decoration: InputDecoration( + contentPadding: const EdgeInsets.only(left: 16, right: 16), + border: InputBorder.none, + hintText: l10n.passwordHint, + errorText: getErrorMessage(password.displayError, l10n), + suffixIcon: IconButton( + icon: showOrHideIcon, + onPressed: () { + setState(() { + _isHidePassword = !_isHidePassword; + }); + }, + splashRadius: 24, ), - ); - }, + ), + textAlignVertical: TextAlignVertical.center, + ), ); } @@ -160,38 +142,30 @@ class _LoginButton extends StatelessWidget { @override Widget build(BuildContext context) { final l10n = context.l10n; + final formStatus = context.select((LoginBloc bloc) => bloc.state.status); + if (formStatus.isInProgress) { + return const CircularProgressIndicator( + color: AppPalette.primaryColor, + ); + } + void onLoginPressed() { + context.read().add(const LoginSubmitted()); + } - return BlocBuilder( - buildWhen: (previous, current) => previous.status != current.status, - builder: (context, state) { - return state.status.isInProgress - ? const CircularProgressIndicator( - color: AppPalette.primaryColor, - ) - : ElevatedButton( - key: const Key('loginForm_continue_raisedButton'), - onPressed: state.status.isInitial - ? () { - context.read().add(const LoginSubmitted()); - } - : null, - style: ElevatedButton.styleFrom( - fixedSize: const Size(130, 50), - backgroundColor: Theme.of(context).primaryColor, - shape: RoundedRectangleBorder( - borderRadius: BorderRadius.circular(50), - ), - ), - child: Text( - l10n.login, - style: const TextStyle( - fontWeight: FontWeight.w500, - fontSize: 16, - color: AppPalette.whiteBackgroundColor, - ), - ), - ); - }, + return ElevatedButton( + key: const Key('loginForm_continue_raisedButton'), + onPressed: onLoginPressed, + style: ElevatedButton.styleFrom( + backgroundColor: context.theme.primaryColor, + ), + child: Text( + l10n.login, + style: const TextStyle( + fontWeight: FontWeight.w500, + fontSize: 16, + color: AppPalette.whiteBackgroundColor, + ), + ), ); } } diff --git a/mobile/lib/login/view/login_view.dart b/mobile/lib/login/view/login_view.dart index 8f45287..b113738 100644 --- a/mobile/lib/login/view/login_view.dart +++ b/mobile/lib/login/view/login_view.dart @@ -5,6 +5,8 @@ import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:go_router/go_router.dart'; import 'package:very_good_blog_app/app/app.dart'; import 'package:very_good_blog_app/authentication/authentication.dart'; +import 'package:very_good_blog_app/di/di.dart'; +import 'package:very_good_blog_app/domain/repositories/auth_repository.dart'; import 'package:very_good_blog_app/l10n/l10n.dart'; import 'package:very_good_blog_app/login/login.dart'; import 'package:very_good_blog_app/widgets/dismiss_focus_keyboard.dart'; @@ -45,8 +47,7 @@ class LoginView extends StatelessWidget { height: context.screenHeight * 0.65, child: BlocProvider( create: (context) => LoginBloc( - authenticationRepository: - context.read(), + authRepository: injector(), ), child: const LoginForm(), ), diff --git a/mobile/pubspec.lock b/mobile/pubspec.lock index ec7f053..01b4e44 100644 --- a/mobile/pubspec.lock +++ b/mobile/pubspec.lock @@ -338,6 +338,14 @@ packages: url: "https://pub.dev" source: hosted version: "2.3.4" + dartx: + dependency: "direct main" + description: + name: dartx + sha256: "8b25435617027257d43e6508b5fe061012880ddfdaa75a71d607c3de2a13d244" + url: "https://pub.dev" + source: hosted + version: "1.2.0" dbus: dependency: transitive description: @@ -765,6 +773,14 @@ packages: url: "https://pub.dev" source: hosted version: "3.2.0" + gap: + dependency: "direct main" + description: + name: gap + sha256: f19387d4e32f849394758b91377f9153a1b41d79513ef7668c088c77dbc6955d + url: "https://pub.dev" + source: hosted + version: "3.0.1" get_it: dependency: "direct main" description: @@ -1487,6 +1503,14 @@ packages: url: "https://pub.dev" source: hosted version: "0.5.9" + time: + dependency: transitive + description: + name: time + sha256: ad8e018a6c9db36cb917a031853a1aae49467a93e0d464683e029537d848c221 + url: "https://pub.dev" + source: hosted + version: "2.1.4" timeago: dependency: "direct main" description: diff --git a/mobile/pubspec.yaml b/mobile/pubspec.yaml index 945173e..caff2b6 100644 --- a/mobile/pubspec.yaml +++ b/mobile/pubspec.yaml @@ -26,6 +26,7 @@ dependencies: cloud_messaging_service: path: packages/cloud_messaging_service connectivity_plus: ^5.0.2 + dartx: ^1.2.0 draggable_home: ^1.0.5 easy_debounce: ^2.0.3 equatable: ^2.0.5 @@ -46,6 +47,7 @@ dependencies: flutter_svg: ^2.0.9 fluttertoast: ^8.1.2 formz: ^0.6.1 + gap: ^3.0.1 get_it: ^7.2.0 go_router: ^13.0.1 hive: ^2.2.3 diff --git a/mobile/test/login/bloc/login_bloc_test.dart b/mobile/test/login/bloc/login_bloc_test.dart index 3eeb4fa..4ef7e93 100644 --- a/mobile/test/login/bloc/login_bloc_test.dart +++ b/mobile/test/login/bloc/login_bloc_test.dart @@ -1,24 +1,23 @@ -import 'package:authentication_repository/authentication_repository.dart'; import 'package:bloc_test/bloc_test.dart'; import 'package:flutter_test/flutter_test.dart'; import 'package:formz/formz.dart'; import 'package:mocktail/mocktail.dart'; +import 'package:very_good_blog_app/domain/repositories/auth_repository.dart'; import 'package:very_good_blog_app/login/login.dart'; -class MockAuthenticationRepository extends Mock - implements AuthenticationRepository {} +class MockAuthRepository extends Mock implements AuthRepository {} void main() { - late AuthenticationRepository authenticationRepository; + late AuthRepository authenticationRepository; setUp(() { - authenticationRepository = MockAuthenticationRepository(); + authenticationRepository = MockAuthRepository(); }); group('LoginBloc', () { test('initial state is LoginState', () { final loginBloc = LoginBloc( - authenticationRepository: authenticationRepository, + authRepository: authenticationRepository, ); expect(loginBloc.state, const LoginState()); }); @@ -30,43 +29,43 @@ void main() { setUp: () { when( () => authenticationRepository.login( - username: 'username', + email: 'username', password: 'password', ), // ignore: void_checks ).thenAnswer((_) => Future.value('user')); }, build: () => LoginBloc( - authenticationRepository: authenticationRepository, + authRepository: authenticationRepository, ), act: (bloc) { bloc - ..add(const LoginUsernameChanged('username')) + ..add(const LoginEmailChanged('username')) ..add(const LoginPasswordChanged('password')) ..add(const LoginSubmitted()); }, expect: () => const [ LoginState( - username: Username.dirty('username'), + email: Email.dirty('username'), ), LoginState( - username: Username.dirty('username'), + email: Email.dirty('username'), password: Password.dirty('password'), isValid: true, ), LoginState( - username: Username.dirty('username'), + email: Email.dirty('username'), password: Password.dirty('password'), isValid: true, status: FormzSubmissionStatus.inProgress, ), LoginState( - username: Username.dirty('username'), + email: Email.dirty('username'), password: Password.dirty('password'), status: FormzSubmissionStatus.inProgress, ), LoginState( - username: Username.dirty('username'), + email: Email.dirty('username'), password: Password.dirty('password'), status: FormzSubmissionStatus.success, ), @@ -78,37 +77,37 @@ void main() { setUp: () { when( () => authenticationRepository.login( - username: 'username', + email: 'username', password: 'password', ), ).thenThrow(Exception('oops')); }, build: () => LoginBloc( - authenticationRepository: authenticationRepository, + authRepository: authenticationRepository, ), act: (bloc) { bloc - ..add(const LoginUsernameChanged('username')) + ..add(const LoginEmailChanged('username')) ..add(const LoginPasswordChanged('password')) ..add(const LoginSubmitted()); }, expect: () => const [ LoginState( - username: Username.dirty('username'), + email: Email.dirty('username'), ), LoginState( - username: Username.dirty('username'), + email: Email.dirty('username'), password: Password.dirty('password'), isValid: true, ), LoginState( - username: Username.dirty('username'), + email: Email.dirty('username'), password: Password.dirty('password'), isValid: true, status: FormzSubmissionStatus.inProgress, ), LoginState( - username: Username.dirty('username'), + email: Email.dirty('username'), password: Password.dirty('password'), isValid: true, status: FormzSubmissionStatus.failure, diff --git a/mobile/test/login/bloc/login_event_test.dart b/mobile/test/login/bloc/login_event_test.dart index ba0c23d..e158075 100644 --- a/mobile/test/login/bloc/login_event_test.dart +++ b/mobile/test/login/bloc/login_event_test.dart @@ -8,8 +8,8 @@ void main() { group('LoginUsernameChanged', () { test('supports value comparisons', () { expect( - const LoginUsernameChanged(username), - const LoginUsernameChanged(username), + const LoginEmailChanged(username), + const LoginEmailChanged(username), ); }); }); diff --git a/mobile/test/login/bloc/login_state_test.dart b/mobile/test/login/bloc/login_state_test.dart index bdec8bd..02fa8bc 100644 --- a/mobile/test/login/bloc/login_state_test.dart +++ b/mobile/test/login/bloc/login_state_test.dart @@ -2,7 +2,7 @@ import 'package:flutter_test/flutter_test.dart'; import 'package:very_good_blog_app/login/login.dart'; void main() { - const username = Username.dirty('username'); + const username = Email.dirty('username'); const password = Password.dirty('password'); group('LoginState', () { test('supports value comparisons', () { @@ -22,8 +22,8 @@ void main() { test('returns object with updated username when username is passed', () { expect( - const LoginState().copyWith(username: username), - const LoginState(username: username), + const LoginState().copyWith(email: username), + const LoginState(email: username), ); }); diff --git a/mobile/test/login/model/username_test.dart b/mobile/test/login/model/username_test.dart index 8d72023..ff9bee9 100644 --- a/mobile/test/login/model/username_test.dart +++ b/mobile/test/login/model/username_test.dart @@ -6,13 +6,13 @@ void main() { group('Login Username', () { group('constructors', () { test('pure creates correct instance', () { - const username = Username.isPure(); + const username = Email.isPure(); expect(username.value, ''); expect(username.isPure, true); }); test('dirty creates correct instance', () { - const username = Username.dirty(usernameString); + const username = Email.dirty(usernameString); expect(username.value, usernameString); expect(username.isPure, false); }); @@ -21,14 +21,14 @@ void main() { group('validator', () { test('returns empty error when username is empty', () { expect( - const Username.dirty().error, - UsernameValidationError.empty, + const Email.dirty().error, + EmailValidationError.empty, ); }); test('is valid when username is not empty', () { expect( - const Username.dirty(usernameString).error, + const Email.dirty(usernameString).error, isNull, ); }); diff --git a/mobile/test/register/model/username_test.dart b/mobile/test/register/model/username_test.dart index 8d72023..ff9bee9 100644 --- a/mobile/test/register/model/username_test.dart +++ b/mobile/test/register/model/username_test.dart @@ -6,13 +6,13 @@ void main() { group('Login Username', () { group('constructors', () { test('pure creates correct instance', () { - const username = Username.isPure(); + const username = Email.isPure(); expect(username.value, ''); expect(username.isPure, true); }); test('dirty creates correct instance', () { - const username = Username.dirty(usernameString); + const username = Email.dirty(usernameString); expect(username.value, usernameString); expect(username.isPure, false); }); @@ -21,14 +21,14 @@ void main() { group('validator', () { test('returns empty error when username is empty', () { expect( - const Username.dirty().error, - UsernameValidationError.empty, + const Email.dirty().error, + EmailValidationError.empty, ); }); test('is valid when username is not empty', () { expect( - const Username.dirty(usernameString).error, + const Email.dirty(usernameString).error, isNull, ); }); From 39b0de5881e8336151b7bbc25cfa0b037541232b Mon Sep 17 00:00:00 2001 From: dungngminh <63831488+dungngminh@users.noreply.github.com> Date: Mon, 5 Feb 2024 10:00:15 +0700 Subject: [PATCH 05/15] add some stuff --- mobile/.gitignore | 3 +++ mobile/lib/di/modules/network_module.dart | 2 +- mobile/lib/login/view/login_view.dart | 7 ++----- .../lib/src/authentication_status.dart | 17 +++++++++++++++++ 4 files changed, 23 insertions(+), 6 deletions(-) diff --git a/mobile/.gitignore b/mobile/.gitignore index 318877e..8c5bce3 100644 --- a/mobile/.gitignore +++ b/mobile/.gitignore @@ -129,3 +129,6 @@ app.*.map.json !.idea/runConfigurations/ .mason + + +**/config.json \ No newline at end of file diff --git a/mobile/lib/di/modules/network_module.dart b/mobile/lib/di/modules/network_module.dart index b3f7922..cbea99f 100644 --- a/mobile/lib/di/modules/network_module.dart +++ b/mobile/lib/di/modules/network_module.dart @@ -4,7 +4,7 @@ import 'package:injectable/injectable.dart'; @module abstract class NetworkModule { @Named('baseUrl') - String get baseUrl => 'https://very-good-blog-app.up.railway.app'; + String get baseUrl => const String.fromEnvironment('BASE_URL'); @Named('unAuthClient') @lazySingleton diff --git a/mobile/lib/login/view/login_view.dart b/mobile/lib/login/view/login_view.dart index b113738..e485525 100644 --- a/mobile/lib/login/view/login_view.dart +++ b/mobile/lib/login/view/login_view.dart @@ -1,4 +1,3 @@ -import 'package:authentication_repository/authentication_repository.dart'; import 'package:flutter/gestures.dart'; import 'package:flutter/material.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; @@ -19,7 +18,7 @@ class LoginView extends StatelessWidget { final l10n = context.l10n; return BlocListener( listener: (context, state) { - if (state.status == AuthenticationStatus.authenticated) { + if (state.status.isAuthenticated) { context.go(AppRoutes.home); } }, @@ -40,9 +39,7 @@ class LoginView extends StatelessWidget { ), ), ), - const SizedBox( - height: 24, - ), + const SizedBox(height: 24), SizedBox( height: context.screenHeight * 0.65, child: BlocProvider( diff --git a/mobile/packages/authentication_repository/lib/src/authentication_status.dart b/mobile/packages/authentication_repository/lib/src/authentication_status.dart index acb777d..782453a 100644 --- a/mobile/packages/authentication_repository/lib/src/authentication_status.dart +++ b/mobile/packages/authentication_repository/lib/src/authentication_status.dart @@ -22,4 +22,21 @@ enum AuthenticationStatus { /// A value that is used to indicate that the user /// is not successfully registered. unsuccessfullyRegistered; + + bool get isUnknown => this == AuthenticationStatus.unknown; + + bool get isAuthenticated => this == AuthenticationStatus.authenticated; + + bool get isAuthenticatedOffline => + this == AuthenticationStatus.authenticatedOffline; + + bool get isUnauthenticated => this == AuthenticationStatus.unauthenticated; + + bool get isSuccessfullyRegistered => + this == AuthenticationStatus.successfullyRegistered; + + bool get isExisted => this == AuthenticationStatus.existed; + + bool get isUnsuccessfullyRegistered => + this == AuthenticationStatus.unsuccessfullyRegistered; } From 4c9c1609048e4f4a05e6825c18ea3f100fbde9c7 Mon Sep 17 00:00:00 2001 From: dungngminh <63831488+dungngminh@users.noreply.github.com> Date: Wed, 14 Feb 2024 23:07:54 +0700 Subject: [PATCH 06/15] update dependabot for whole project --- .github/PULL_REQUEST_TEMPLATE.md | 9 +- .github/dependabot.yaml | 10 + .github/workflows/main.yaml | 18 - .vscode/configurationCache.log | 1 - .vscode/dryrun.log | 6 - .vscode/settings.json | 3 - .vscode/targets.log | 315 ------------------ mobile/.github/dependabot.yaml | 10 - .../cache_manager/app_cache_manager.dart | 1 + 9 files changed, 19 insertions(+), 354 deletions(-) create mode 100644 .github/dependabot.yaml delete mode 100644 .github/workflows/main.yaml delete mode 100644 .vscode/configurationCache.log delete mode 100644 .vscode/dryrun.log delete mode 100644 .vscode/settings.json delete mode 100644 .vscode/targets.log delete mode 100644 mobile/.github/dependabot.yaml diff --git a/.github/PULL_REQUEST_TEMPLATE.md b/.github/PULL_REQUEST_TEMPLATE.md index 6b9372e..b450227 100644 --- a/.github/PULL_REQUEST_TEMPLATE.md +++ b/.github/PULL_REQUEST_TEMPLATE.md @@ -1,5 +1,5 @@ +## Project + + + +- [ ] 📱 Mobile +- [ ] 📡 Backend + ## Type of Change diff --git a/.github/dependabot.yaml b/.github/dependabot.yaml new file mode 100644 index 0000000..e2db02c --- /dev/null +++ b/.github/dependabot.yaml @@ -0,0 +1,10 @@ +version: 2 +updates: + - package-ecosystem: "pub" + directory: "/backend" + schedule: + interval: "daily" + - package-ecosystem: "pub" + directory: "/mobile" + schedule: + interval: "daily" \ No newline at end of file diff --git a/.github/workflows/main.yaml b/.github/workflows/main.yaml deleted file mode 100644 index 3f2d44d..0000000 --- a/.github/workflows/main.yaml +++ /dev/null @@ -1,18 +0,0 @@ -name: very_good_blog_app - -on: - pull_request: - branches: - - master - - dev - -defaults: - run: - working-directory: ./mobile - -jobs: - build: - uses: VeryGoodOpenSource/very_good_workflows/.github/workflows/flutter_package.yml@v1 - with: - flutter_channel: stable - flutter_version: 3.0.0 diff --git a/.vscode/configurationCache.log b/.vscode/configurationCache.log deleted file mode 100644 index a27a703..0000000 --- a/.vscode/configurationCache.log +++ /dev/null @@ -1 +0,0 @@ -{"buildTargets":["make"],"launchTargets":[],"customConfigurationProvider":{"workspaceBrowse":{"browsePath":[],"compilerArgs":[]},"fileIndex":[]}} \ No newline at end of file diff --git a/.vscode/dryrun.log b/.vscode/dryrun.log deleted file mode 100644 index 5f064c7..0000000 --- a/.vscode/dryrun.log +++ /dev/null @@ -1,6 +0,0 @@ -make --dry-run --always-make --keep-going --print-directory -make: Entering directory '/home/thinhle/LeQuocThinh/very_good_blog_app' -make: Leaving directory '/home/thinhle/LeQuocThinh/very_good_blog_app' - -make: *** No targets specified and no makefile found. Stop. - diff --git a/.vscode/settings.json b/.vscode/settings.json deleted file mode 100644 index 65e1ec0..0000000 --- a/.vscode/settings.json +++ /dev/null @@ -1,3 +0,0 @@ -{ - "makefile.extensionOutputFolder": "./.vscode" -} \ No newline at end of file diff --git a/.vscode/targets.log b/.vscode/targets.log deleted file mode 100644 index c283005..0000000 --- a/.vscode/targets.log +++ /dev/null @@ -1,315 +0,0 @@ -make all --print-data-base --no-builtin-variables --no-builtin-rules --question -# GNU Make 4.2.1 -# Built for x86_64-pc-linux-gnu -# Copyright (C) 1988-2016 Free Software Foundation, Inc. -# License GPLv3+: GNU GPL version 3 or later -# This is free software: you are free to change and redistribute it. -# There is NO WARRANTY, to the extent permitted by law. - -# Make data base, printed on Sat Jun 18 19:27:13 2022 - -# Variables - -# 'override' directive -GNUMAKEFLAGS := -# automatic -()), ), ); + } From 4749a252f2ec0afcdb595df6ccdd235949fdd65d Mon Sep 17 00:00:00 2001 From: Dung Nguyen Minh <63831488+dungngminh@users.noreply.github.com> Date: Wed, 14 Feb 2024 23:09:54 +0700 Subject: [PATCH 07/15] Rename Readme.md to README.md --- backend/{Readme.md => README.md} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename backend/{Readme.md => README.md} (100%) diff --git a/backend/Readme.md b/backend/README.md similarity index 100% rename from backend/Readme.md rename to backend/README.md From 6a916400dcf55e63c8bfe2ba3067435aa5aa4fb9 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 14 Feb 2024 16:12:12 +0000 Subject: [PATCH 08/15] chore(deps): bump bloc_test from 9.1.5 to 9.1.6 in /mobile Bumps [bloc_test](https://github.com/felangel/bloc/tree/master/packages) from 9.1.5 to 9.1.6. - [Release notes](https://github.com/felangel/bloc/releases) - [Commits](https://github.com/felangel/bloc/commits/bloc_test-v9.1.6/packages) --- updated-dependencies: - dependency-name: bloc_test dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- mobile/pubspec.lock | 4 ++-- mobile/pubspec.yaml | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/mobile/pubspec.lock b/mobile/pubspec.lock index 01b4e44..db5f620 100644 --- a/mobile/pubspec.lock +++ b/mobile/pubspec.lock @@ -67,10 +67,10 @@ packages: dependency: "direct dev" description: name: bloc_test - sha256: "02f04270be5abae8df171143e61a0058a7acbce5dcac887612e89bb40cca4c33" + sha256: "55a48f69e0d480717067c5377c8485a3fcd41f1701a820deef72fa0f4ee7215f" url: "https://pub.dev" source: hosted - version: "9.1.5" + version: "9.1.6" blog_data_source: dependency: "direct main" description: diff --git a/mobile/pubspec.yaml b/mobile/pubspec.yaml index caff2b6..396adb7 100644 --- a/mobile/pubspec.yaml +++ b/mobile/pubspec.yaml @@ -73,7 +73,7 @@ dependencies: path: packages/user_repository dev_dependencies: - bloc_test: ^9.1.0 + bloc_test: ^9.1.6 build_runner: ^2.4.8 chopper_generator: ^7.1.1 flutter_test: From 8d0e7c1309e9229e707e589d582b4a9dba69caf6 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 14 Feb 2024 16:12:35 +0000 Subject: [PATCH 09/15] chore(deps): bump firebase_core from 2.24.2 to 2.25.4 in /mobile Bumps [firebase_core](https://github.com/firebase/flutterfire/tree/master/packages/firebase_core) from 2.24.2 to 2.25.4. - [Release notes](https://github.com/firebase/flutterfire/releases) - [Changelog](https://github.com/firebase/flutterfire/blob/master/CHANGELOG.md) - [Commits](https://github.com/firebase/flutterfire/commits/firebase_core-v2.25.4/packages/firebase_core) --- updated-dependencies: - dependency-name: firebase_core dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- mobile/pubspec.lock | 8 ++++---- mobile/pubspec.yaml | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/mobile/pubspec.lock b/mobile/pubspec.lock index 01b4e44..e20d948 100644 --- a/mobile/pubspec.lock +++ b/mobile/pubspec.lock @@ -462,10 +462,10 @@ packages: dependency: "direct main" description: name: firebase_core - sha256: "96607c0e829a581c2a483c658f04e8b159964c3bae2730f73297070bc85d40bb" + sha256: "7e049e32a9d347616edb39542cf92cd53fdb4a99fb6af0a0bff327c14cd76445" url: "https://pub.dev" source: hosted - version: "2.24.2" + version: "2.25.4" firebase_core_platform_interface: dependency: transitive description: @@ -478,10 +478,10 @@ packages: dependency: transitive description: name: firebase_core_web - sha256: d585bdf3c656c3f7821ba1bd44da5f13365d22fcecaf5eb75c4295246aaa83c0 + sha256: "57e61d6010e253b36d38191cefd6199d7849152cdcd234b61ca290cdb278a0ba" url: "https://pub.dev" source: hosted - version: "2.10.0" + version: "2.11.4" firebase_messaging: dependency: transitive description: diff --git a/mobile/pubspec.yaml b/mobile/pubspec.yaml index caff2b6..fa7b432 100644 --- a/mobile/pubspec.yaml +++ b/mobile/pubspec.yaml @@ -30,7 +30,7 @@ dependencies: draggable_home: ^1.0.5 easy_debounce: ^2.0.3 equatable: ^2.0.5 - firebase_core: ^2.4.1 + firebase_core: ^2.25.4 firebase_storage: ^11.0.10 firebase_storage_service: path: packages/firebase_storage_service From 3dfcb59f62ce7d1237f032e0a3b3db6c38e71738 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 19 Feb 2024 10:36:35 +0000 Subject: [PATCH 10/15] chore(deps): bump firebase_storage from 11.6.0 to 11.6.6 in /mobile Bumps [firebase_storage](https://github.com/firebase/flutterfire/tree/master/packages/firebase_storage) from 11.6.0 to 11.6.6. - [Release notes](https://github.com/firebase/flutterfire/releases) - [Changelog](https://github.com/firebase/flutterfire/blob/master/CHANGELOG.md) - [Commits](https://github.com/firebase/flutterfire/commits/firebase_storage-v11.6.6/packages/firebase_storage) --- updated-dependencies: - dependency-name: firebase_storage dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- mobile/pubspec.lock | 56 ++++++++++++++++++++++++++++++++------------- mobile/pubspec.yaml | 2 +- 2 files changed, 41 insertions(+), 17 deletions(-) diff --git a/mobile/pubspec.lock b/mobile/pubspec.lock index 3ef3957..85cc078 100644 --- a/mobile/pubspec.lock +++ b/mobile/pubspec.lock @@ -13,10 +13,10 @@ packages: dependency: transitive description: name: _flutterfire_internals - sha256: f5628cd9c92ed11083f425fd1f8f1bc60ecdda458c81d73b143aeda036c35fe7 + sha256: "737321f9be522620ed3794937298fb0027a48a402624fa2500f7532f94aea810" url: "https://pub.dev" source: hosted - version: "1.3.16" + version: "1.3.22" analyzer: dependency: transitive description: @@ -510,18 +510,18 @@ packages: dependency: "direct main" description: name: firebase_storage - sha256: "75e6cb6bed65138b5bbd86bfd7cf9bc9a175fb0c31aacc400e9203df117ffbe6" + sha256: a07433d3ffe948f7a10086e4b0bd3a940be4ed873cffd24746eed1896b568369 url: "https://pub.dev" source: hosted - version: "11.6.0" + version: "11.6.6" firebase_storage_platform_interface: dependency: transitive description: name: firebase_storage_platform_interface - sha256: "545a3a8edf337850403bb0fa03c8074a53deb87c0107d19755c77a82ce07919e" + sha256: af99d9fcf058d6f3a591cea899cad054ded7adb21fb1788dfe65c3e223196b15 url: "https://pub.dev" source: hosted - version: "5.1.3" + version: "5.1.9" firebase_storage_service: dependency: "direct main" description: @@ -533,10 +533,10 @@ packages: dependency: transitive description: name: firebase_storage_web - sha256: ee6870ff79aa304b8996ba18a4aefe1e8b3fc31fd385eab6574180267aa8d393 + sha256: "06a684016de9609928865798dece0f7d34782a15a76f5ac08bd3a8780035b0b2" url: "https://pub.dev" source: hosted - version: "3.6.17" + version: "3.7.0" fixnum: dependency: transitive description: @@ -1020,6 +1020,30 @@ packages: url: "https://pub.dev" source: hosted version: "1.1.0" + leak_tracker: + dependency: transitive + description: + name: leak_tracker + sha256: "78eb209deea09858f5269f5a5b02be4049535f568c07b275096836f01ea323fa" + url: "https://pub.dev" + source: hosted + version: "10.0.0" + leak_tracker_flutter_testing: + dependency: transitive + description: + name: leak_tracker_flutter_testing + sha256: b46c5e37c19120a8a01918cfaf293547f47269f7cb4b0058f21531c2465d6ef0 + url: "https://pub.dev" + source: hosted + version: "2.0.1" + leak_tracker_testing: + dependency: transitive + description: + name: leak_tracker_testing + sha256: a597f72a664dbd293f3bfc51f9ba69816f84dcd403cdac7066cb3f6003f3ab47 + url: "https://pub.dev" + source: hosted + version: "2.0.1" logger: dependency: transitive description: @@ -1048,26 +1072,26 @@ packages: dependency: transitive description: name: matcher - sha256: "1803e76e6653768d64ed8ff2e1e67bea3ad4b923eb5c56a295c3e634bad5960e" + sha256: d2323aa2060500f906aa31a895b4030b6da3ebdcc5619d14ce1aada65cd161cb url: "https://pub.dev" source: hosted - version: "0.12.16" + version: "0.12.16+1" material_color_utilities: dependency: transitive description: name: material_color_utilities - sha256: "9528f2f296073ff54cb9fee677df673ace1218163c3bc7628093e7eed5203d41" + sha256: "0e0a020085b65b6083975e499759762399b4475f766c21668c4ecca34ea74e5a" url: "https://pub.dev" source: hosted - version: "0.5.0" + version: "0.8.0" meta: dependency: transitive description: name: meta - sha256: a6e590c838b18133bb482a2745ad77c5bb7715fb0451209e1a7567d416678b8e + sha256: d584fa6707a52763a52446f02cc621b077888fb63b93bbcb1143a7be5a0c0c04 url: "https://pub.dev" source: hosted - version: "1.10.0" + version: "1.11.0" mime: dependency: transitive description: @@ -1135,10 +1159,10 @@ packages: dependency: transitive description: name: path - sha256: "8829d8a55c13fc0e37127c29fedf290c102f4e40ae94ada574091fe0ff96c917" + sha256: "087ce49c3f0dc39180befefc60fdb4acd8f8620e5682fe2476afd0b3688bb4af" url: "https://pub.dev" source: hosted - version: "1.8.3" + version: "1.9.0" path_parsing: dependency: transitive description: diff --git a/mobile/pubspec.yaml b/mobile/pubspec.yaml index 14b23d3..1f47d67 100644 --- a/mobile/pubspec.yaml +++ b/mobile/pubspec.yaml @@ -31,7 +31,7 @@ dependencies: easy_debounce: ^2.0.3 equatable: ^2.0.5 firebase_core: ^2.25.4 - firebase_storage: ^11.0.10 + firebase_storage: ^11.6.6 firebase_storage_service: path: packages/firebase_storage_service flutter: From 8957ace9efdeadace9ecdd859e057d7484684434 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 21 Feb 2024 10:47:15 +0000 Subject: [PATCH 11/15] chore(deps): bump flutter_svg from 2.0.9 to 2.0.10+1 in /mobile Bumps [flutter_svg](https://github.com/dnfield/flutter_svg/tree/master/packages) from 2.0.9 to 2.0.10+1. - [Release notes](https://github.com/dnfield/flutter_svg/releases) - [Commits](https://github.com/dnfield/flutter_svg/commits/HEAD/packages) --- updated-dependencies: - dependency-name: flutter_svg dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- mobile/pubspec.lock | 56 ++++++++++++++++++++++++++++++++------------- mobile/pubspec.yaml | 2 +- 2 files changed, 41 insertions(+), 17 deletions(-) diff --git a/mobile/pubspec.lock b/mobile/pubspec.lock index 3ef3957..ec87e76 100644 --- a/mobile/pubspec.lock +++ b/mobile/pubspec.lock @@ -735,10 +735,10 @@ packages: dependency: "direct main" description: name: flutter_svg - sha256: d39e7f95621fc84376bc0f7d504f05c3a41488c562f4a8ad410569127507402c + sha256: "7b4ca6cf3304575fe9c8ec64813c8d02ee41d2afe60bcfe0678bcb5375d596a2" url: "https://pub.dev" source: hosted - version: "2.0.9" + version: "2.0.10+1" flutter_test: dependency: "direct dev" description: flutter @@ -1020,6 +1020,30 @@ packages: url: "https://pub.dev" source: hosted version: "1.1.0" + leak_tracker: + dependency: transitive + description: + name: leak_tracker + sha256: "78eb209deea09858f5269f5a5b02be4049535f568c07b275096836f01ea323fa" + url: "https://pub.dev" + source: hosted + version: "10.0.0" + leak_tracker_flutter_testing: + dependency: transitive + description: + name: leak_tracker_flutter_testing + sha256: b46c5e37c19120a8a01918cfaf293547f47269f7cb4b0058f21531c2465d6ef0 + url: "https://pub.dev" + source: hosted + version: "2.0.1" + leak_tracker_testing: + dependency: transitive + description: + name: leak_tracker_testing + sha256: a597f72a664dbd293f3bfc51f9ba69816f84dcd403cdac7066cb3f6003f3ab47 + url: "https://pub.dev" + source: hosted + version: "2.0.1" logger: dependency: transitive description: @@ -1048,26 +1072,26 @@ packages: dependency: transitive description: name: matcher - sha256: "1803e76e6653768d64ed8ff2e1e67bea3ad4b923eb5c56a295c3e634bad5960e" + sha256: d2323aa2060500f906aa31a895b4030b6da3ebdcc5619d14ce1aada65cd161cb url: "https://pub.dev" source: hosted - version: "0.12.16" + version: "0.12.16+1" material_color_utilities: dependency: transitive description: name: material_color_utilities - sha256: "9528f2f296073ff54cb9fee677df673ace1218163c3bc7628093e7eed5203d41" + sha256: "0e0a020085b65b6083975e499759762399b4475f766c21668c4ecca34ea74e5a" url: "https://pub.dev" source: hosted - version: "0.5.0" + version: "0.8.0" meta: dependency: transitive description: name: meta - sha256: a6e590c838b18133bb482a2745ad77c5bb7715fb0451209e1a7567d416678b8e + sha256: d584fa6707a52763a52446f02cc621b077888fb63b93bbcb1143a7be5a0c0c04 url: "https://pub.dev" source: hosted - version: "1.10.0" + version: "1.11.0" mime: dependency: transitive description: @@ -1135,10 +1159,10 @@ packages: dependency: transitive description: name: path - sha256: "8829d8a55c13fc0e37127c29fedf290c102f4e40ae94ada574091fe0ff96c917" + sha256: "087ce49c3f0dc39180befefc60fdb4acd8f8620e5682fe2476afd0b3688bb4af" url: "https://pub.dev" source: hosted - version: "1.8.3" + version: "1.9.0" path_parsing: dependency: transitive description: @@ -1633,26 +1657,26 @@ packages: dependency: transitive description: name: vector_graphics - sha256: "18f6690295af52d081f6808f2f7c69f0eed6d7e23a71539d75f4aeb8f0062172" + sha256: "32c3c684e02f9bc0afb0ae0aa653337a2fe022e8ab064bcd7ffda27a74e288e3" url: "https://pub.dev" source: hosted - version: "1.1.9+2" + version: "1.1.11+1" vector_graphics_codec: dependency: transitive description: name: vector_graphics_codec - sha256: "531d20465c10dfac7f5cd90b60bbe4dd9921f1ec4ca54c83ebb176dbacb7bb2d" + sha256: c86987475f162fadff579e7320c7ddda04cd2fdeffbe1129227a85d9ac9e03da url: "https://pub.dev" source: hosted - version: "1.1.9+2" + version: "1.1.11+1" vector_graphics_compiler: dependency: transitive description: name: vector_graphics_compiler - sha256: "03012b0a33775c5530576b70240308080e1d5050f0faf000118c20e6463bc0ad" + sha256: "12faff3f73b1741a36ca7e31b292ddeb629af819ca9efe9953b70bd63fc8cd81" url: "https://pub.dev" source: hosted - version: "1.1.9+2" + version: "1.1.11+1" vector_math: dependency: transitive description: diff --git a/mobile/pubspec.yaml b/mobile/pubspec.yaml index 14b23d3..131d957 100644 --- a/mobile/pubspec.yaml +++ b/mobile/pubspec.yaml @@ -44,7 +44,7 @@ dependencies: flutter_quill: ^9.2.10 flutter_secure_storage: ^7.0.1 flutter_slidable: ^3.0.1 - flutter_svg: ^2.0.9 + flutter_svg: ^2.0.10+1 fluttertoast: ^8.1.2 formz: ^0.6.1 gap: ^3.0.1 From 807662ebb661c357399d3f6536d048a672370815 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 22 Feb 2024 11:08:58 +0000 Subject: [PATCH 12/15] chore(deps): bump formz from 0.6.1 to 0.7.0 in /mobile Bumps [formz](https://github.com/VeryGoodOpenSource/formz) from 0.6.1 to 0.7.0. - [Release notes](https://github.com/VeryGoodOpenSource/formz/releases) - [Changelog](https://github.com/VeryGoodOpenSource/formz/blob/main/CHANGELOG.md) - [Commits](https://github.com/VeryGoodOpenSource/formz/compare/v0.6.1...v0.7.0) --- updated-dependencies: - dependency-name: formz dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- mobile/pubspec.lock | 4 ++-- mobile/pubspec.yaml | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/mobile/pubspec.lock b/mobile/pubspec.lock index ec87e76..44a1012 100644 --- a/mobile/pubspec.lock +++ b/mobile/pubspec.lock @@ -761,10 +761,10 @@ packages: dependency: "direct main" description: name: formz - sha256: df8301299601139de7e653e68a07c332fd2db7cec65745eca1a1ea73fb711e06 + sha256: a58eb48d84685b7ffafac1d143bf47d585bf54c7db89fe81c175dfd6e53201c7 url: "https://pub.dev" source: hosted - version: "0.6.1" + version: "0.7.0" frontend_server_client: dependency: transitive description: diff --git a/mobile/pubspec.yaml b/mobile/pubspec.yaml index 131d957..fae4b18 100644 --- a/mobile/pubspec.yaml +++ b/mobile/pubspec.yaml @@ -46,7 +46,7 @@ dependencies: flutter_slidable: ^3.0.1 flutter_svg: ^2.0.10+1 fluttertoast: ^8.1.2 - formz: ^0.6.1 + formz: ^0.7.0 gap: ^3.0.1 get_it: ^7.2.0 go_router: ^13.0.1 From 2884ef1613bfc26fd5410c40dfb646398488c196 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 13 Mar 2024 11:09:36 +0000 Subject: [PATCH 13/15] chore(deps): bump firebase_storage from 11.6.6 to 11.6.10 in /mobile Bumps [firebase_storage](https://github.com/firebase/flutterfire/tree/master/packages/firebase_storage) from 11.6.6 to 11.6.10. - [Release notes](https://github.com/firebase/flutterfire/releases) - [Changelog](https://github.com/firebase/flutterfire/blob/master/CHANGELOG.md) - [Commits](https://github.com/firebase/flutterfire/commits/firebase_storage-v11.6.10/packages/firebase_storage) --- updated-dependencies: - dependency-name: firebase_storage dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- mobile/pubspec.lock | 40 ++++++++++++++++++++-------------------- mobile/pubspec.yaml | 2 +- 2 files changed, 21 insertions(+), 21 deletions(-) diff --git a/mobile/pubspec.lock b/mobile/pubspec.lock index aa5fe15..7adc8ba 100644 --- a/mobile/pubspec.lock +++ b/mobile/pubspec.lock @@ -13,10 +13,10 @@ packages: dependency: transitive description: name: _flutterfire_internals - sha256: "737321f9be522620ed3794937298fb0027a48a402624fa2500f7532f94aea810" + sha256: "554f148e71e9e016d9c04d4af6b103ca3f74a1ceed7d7307b70a0f41e991eb77" url: "https://pub.dev" source: hosted - version: "1.3.22" + version: "1.3.26" analyzer: dependency: transitive description: @@ -302,10 +302,10 @@ packages: dependency: transitive description: name: cross_file - sha256: fedaadfa3a6996f75211d835aaeb8fede285dae94262485698afd832371b9a5e + sha256: "55d7b444feb71301ef6b8838dbc1ae02e63dd48c8773f3810ff53bb1e2945b32" url: "https://pub.dev" source: hosted - version: "0.3.3+8" + version: "0.3.4+1" crypto: dependency: transitive description: @@ -462,10 +462,10 @@ packages: dependency: "direct main" description: name: firebase_core - sha256: "7e049e32a9d347616edb39542cf92cd53fdb4a99fb6af0a0bff327c14cd76445" + sha256: "67bf0d5fd78f12f51c6b54a72f6141314136a1a90e98b1b7c45e7fac883254ed" url: "https://pub.dev" source: hosted - version: "2.25.4" + version: "2.27.1" firebase_core_platform_interface: dependency: transitive description: @@ -478,10 +478,10 @@ packages: dependency: transitive description: name: firebase_core_web - sha256: "57e61d6010e253b36d38191cefd6199d7849152cdcd234b61ca290cdb278a0ba" + sha256: "5377eaac3b9fe8aaf22638d87f92b62784f23572e132dfc029195e84d6cb37de" url: "https://pub.dev" source: hosted - version: "2.11.4" + version: "2.12.0" firebase_messaging: dependency: transitive description: @@ -510,18 +510,18 @@ packages: dependency: "direct main" description: name: firebase_storage - sha256: a07433d3ffe948f7a10086e4b0bd3a940be4ed873cffd24746eed1896b568369 + sha256: "1f73deac05f02275c4d267eb3db3e9617f67f5cf011cdda1b483b6d91a0f895b" url: "https://pub.dev" source: hosted - version: "11.6.6" + version: "11.6.10" firebase_storage_platform_interface: dependency: transitive description: name: firebase_storage_platform_interface - sha256: af99d9fcf058d6f3a591cea899cad054ded7adb21fb1788dfe65c3e223196b15 + sha256: b7d6da9f3114a095632512fdd1f8eb346eff7f5107e3391c93826ba882684033 url: "https://pub.dev" source: hosted - version: "5.1.9" + version: "5.1.13" firebase_storage_service: dependency: "direct main" description: @@ -533,10 +533,10 @@ packages: dependency: transitive description: name: firebase_storage_web - sha256: "06a684016de9609928865798dece0f7d34782a15a76f5ac08bd3a8780035b0b2" + sha256: d02e7804a129538fe4ff256a4d1617bdaf86ad8971352c1b381ee2a43e6e38e7 url: "https://pub.dev" source: hosted - version: "3.7.0" + version: "3.8.0" fixnum: dependency: transitive description: @@ -849,10 +849,10 @@ packages: dependency: transitive description: name: http - sha256: a2bbf9d017fcced29139daa8ed2bba4ece450ab222871df93ca9eec6f80c34ba + sha256: "761a297c042deedc1ffbb156d6e2af13886bb305c2a343a4d972504cd67dd938" url: "https://pub.dev" source: hosted - version: "1.2.0" + version: "1.2.1" http_client_handler: dependency: "direct main" description: @@ -1619,10 +1619,10 @@ packages: dependency: transitive description: name: url_launcher_web - sha256: fff0932192afeedf63cdd50ecbb1bc825d31aed259f02bb8dba0f3b729a5e88b + sha256: "3692a459204a33e04bc94f5fb91158faf4f2c8903281ddd82915adecdb1a901d" url: "https://pub.dev" source: hosted - version: "2.2.3" + version: "2.3.0" url_launcher_windows: dependency: transitive description: @@ -1713,10 +1713,10 @@ packages: dependency: transitive description: name: web - sha256: afe077240a270dcfd2aafe77602b4113645af95d0ad31128cc02bce5ac5d5152 + sha256: "97da13628db363c635202ad97068d47c5b8aa555808e7a9411963c533b449b27" url: "https://pub.dev" source: hosted - version: "0.3.0" + version: "0.5.1" web_socket_channel: dependency: transitive description: diff --git a/mobile/pubspec.yaml b/mobile/pubspec.yaml index eb6393d..5cf8db6 100644 --- a/mobile/pubspec.yaml +++ b/mobile/pubspec.yaml @@ -31,7 +31,7 @@ dependencies: easy_debounce: ^2.0.3 equatable: ^2.0.5 firebase_core: ^2.25.4 - firebase_storage: ^11.6.6 + firebase_storage: ^11.6.10 firebase_storage_service: path: packages/firebase_storage_service flutter: From 259f4c14963296aee39f58517b13061328aabd65 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 14 Mar 2024 10:35:14 +0000 Subject: [PATCH 14/15] chore(deps): bump injectable from 2.3.2 to 2.3.5 in /mobile Bumps [injectable](https://github.com/Milad-Akarie/injectable) from 2.3.2 to 2.3.5. - [Commits](https://github.com/Milad-Akarie/injectable/commits) --- updated-dependencies: - dependency-name: injectable dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- mobile/pubspec.lock | 4 ++-- mobile/pubspec.yaml | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/mobile/pubspec.lock b/mobile/pubspec.lock index 7adc8ba..8fa42b0 100644 --- a/mobile/pubspec.lock +++ b/mobile/pubspec.lock @@ -944,10 +944,10 @@ packages: dependency: "direct main" description: name: injectable - sha256: cd3c422e13270c81f64ab73c80406b2b2ed563fe59d0ff2093eb7eee63d0bbeb + sha256: "44b4aa254816b23bf0a3285ff27da3ff0b516a6f00e0bbbea7b194f14fbb75a7" url: "https://pub.dev" source: hosted - version: "2.3.2" + version: "2.3.5" injectable_generator: dependency: "direct dev" description: diff --git a/mobile/pubspec.yaml b/mobile/pubspec.yaml index 5cf8db6..6da7685 100644 --- a/mobile/pubspec.yaml +++ b/mobile/pubspec.yaml @@ -55,7 +55,7 @@ dependencies: http_client_handler: path: packages/http_client_handler image_picker: ^1.0.4 - injectable: ^2.3.2 + injectable: ^2.3.5 intl: ^0.18.1 json_annotation: ^4.8.1 lazy_load_indexed_stack: ^1.0.1 From 2923a4475c705b4b9c3a39a5678a1ab3dbcfc2c1 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 25 Mar 2024 10:29:51 +0000 Subject: [PATCH 15/15] chore(deps): bump flutter_bloc from 8.1.3 to 8.1.5 in /mobile Bumps [flutter_bloc](https://github.com/felangel/bloc/tree/master/packages) from 8.1.3 to 8.1.5. - [Release notes](https://github.com/felangel/bloc/releases) - [Commits](https://github.com/felangel/bloc/commits/flutter_bloc-v8.1.5/packages) --- updated-dependencies: - dependency-name: flutter_bloc dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- mobile/pubspec.lock | 4 ++-- mobile/pubspec.yaml | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/mobile/pubspec.lock b/mobile/pubspec.lock index 8fa42b0..c15de9a 100644 --- a/mobile/pubspec.lock +++ b/mobile/pubspec.lock @@ -554,10 +554,10 @@ packages: dependency: "direct main" description: name: flutter_bloc - sha256: e74efb89ee6945bcbce74a5b3a5a3376b088e5f21f55c263fc38cbdc6237faae + sha256: f0ecf6e6eb955193ca60af2d5ca39565a86b8a142452c5b24d96fb477428f4d2 url: "https://pub.dev" source: hosted - version: "8.1.3" + version: "8.1.5" flutter_cache_manager: dependency: "direct main" description: diff --git a/mobile/pubspec.yaml b/mobile/pubspec.yaml index 6da7685..00ff4b6 100644 --- a/mobile/pubspec.yaml +++ b/mobile/pubspec.yaml @@ -36,7 +36,7 @@ dependencies: path: packages/firebase_storage_service flutter: sdk: flutter - flutter_bloc: ^8.1.1 + flutter_bloc: ^8.1.5 flutter_cache_manager: ^3.3.0 flutter_dotenv: ^5.0.2 flutter_localizations: