From cae1252fc891edad8d2c323ad6c6a40a4c47368a Mon Sep 17 00:00:00 2001 From: dab246 Date: Wed, 25 Aug 2021 13:12:17 +0700 Subject: [PATCH] TF-34 Add data layer login for fix bug mock data user --- .../atuthentitcation_datasource.dart | 2 +- .../authentication_datasource_impl.dart | 8 +- .../presentation_account_extension.dart | 8 ++ .../extensions/user_profile_extension.dart | 22 +++++ .../model/converter/avatar_id_converter.dart | 12 +++ .../avatar_id_nullable_converter.dart | 12 +++ .../presentation_email_address_converter.dart | 12 +++ .../model/converter/user_id_converter.dart | 4 +- .../presentation_account_response.dart | 30 +++++++ .../model/response/user_profile_response.dart | 88 +++++++++++++++++++ .../data/model/response/user_response.dart | 46 ---------- .../login/data/network/login_api.dart | 6 +- .../authentication_repository_impl.dart | 2 +- .../credential_repository_impl.dart | 23 +++++ lib/features/login/data/utils/attribute.dart | 9 ++ .../login/data/utils/login_constant.dart | 1 + 16 files changed, 227 insertions(+), 58 deletions(-) create mode 100644 lib/features/login/data/extensions/presentation_account_extension.dart create mode 100644 lib/features/login/data/extensions/user_profile_extension.dart create mode 100644 lib/features/login/data/model/converter/avatar_id_converter.dart create mode 100644 lib/features/login/data/model/converter/avatar_id_nullable_converter.dart create mode 100644 lib/features/login/data/model/converter/presentation_email_address_converter.dart create mode 100644 lib/features/login/data/model/response/presentation_account_response.dart create mode 100644 lib/features/login/data/model/response/user_profile_response.dart delete mode 100644 lib/features/login/data/model/response/user_response.dart create mode 100644 lib/features/login/data/utils/attribute.dart diff --git a/lib/features/login/data/datasource/atuthentitcation_datasource.dart b/lib/features/login/data/datasource/atuthentitcation_datasource.dart index ff2092bae..e5ae2a6a6 100644 --- a/lib/features/login/data/datasource/atuthentitcation_datasource.dart +++ b/lib/features/login/data/datasource/atuthentitcation_datasource.dart @@ -1,5 +1,5 @@ import 'package:model/model.dart'; abstract class AuthenticationDataSource { - Future authenticationUser(Uri baseUrl, UserName userName, Password password); + Future authenticationUser(Uri baseUrl, UserName userName, Password password); } \ No newline at end of file diff --git a/lib/features/login/data/datasource_impl/authentication_datasource_impl.dart b/lib/features/login/data/datasource_impl/authentication_datasource_impl.dart index 9b0235c0d..0f82f6719 100644 --- a/lib/features/login/data/datasource_impl/authentication_datasource_impl.dart +++ b/lib/features/login/data/datasource_impl/authentication_datasource_impl.dart @@ -1,7 +1,7 @@ import 'package:model/model.dart'; import 'package:tmail_ui_user/features/login/data/datasource/atuthentitcation_datasource.dart'; import 'package:tmail_ui_user/features/login/data/model/request/account_request.dart'; -import 'package:tmail_ui_user/features/login/data/model/response/user_response.dart'; +import 'package:tmail_ui_user/features/login/data/model/response/user_profile_response.dart'; import 'package:tmail_ui_user/features/login/data/network/login_api.dart'; class AuthenticationDataSourceImpl extends AuthenticationDataSource { @@ -11,10 +11,10 @@ class AuthenticationDataSourceImpl extends AuthenticationDataSource { AuthenticationDataSourceImpl(this.loginAPI); @override - Future authenticationUser(Uri baseUrl, UserName userName, Password password) { + Future authenticationUser(Uri baseUrl, UserName userName, Password password) { return Future.sync(() async { - final userResponse = await loginAPI.authenticationUser(baseUrl, AccountRequest(userName, password)); - return userResponse.toUser(); + final userProfileResponse = await loginAPI.authenticationUser(baseUrl, AccountRequest(userName, password)); + return userProfileResponse.toUserProfile(); }).catchError((error) { throw error; }); diff --git a/lib/features/login/data/extensions/presentation_account_extension.dart b/lib/features/login/data/extensions/presentation_account_extension.dart new file mode 100644 index 000000000..1fd71cd57 --- /dev/null +++ b/lib/features/login/data/extensions/presentation_account_extension.dart @@ -0,0 +1,8 @@ +import 'package:model/model.dart'; +import 'package:tmail_ui_user/features/login/data/model/response/presentation_account_response.dart'; + +extension PresentationAccountExtension on PresentationAccount { + PresentationAccountResponse toPresentationAccountResponse() { + return PresentationAccountResponse(emails, preferredEmailIndex, type); + } +} \ No newline at end of file diff --git a/lib/features/login/data/extensions/user_profile_extension.dart b/lib/features/login/data/extensions/user_profile_extension.dart new file mode 100644 index 000000000..11e1eb6bb --- /dev/null +++ b/lib/features/login/data/extensions/user_profile_extension.dart @@ -0,0 +1,22 @@ +import 'package:model/model.dart'; +import 'package:tmail_ui_user/features/login/data/model/response/user_profile_response.dart'; +import 'package:tmail_ui_user/features/login/data/extensions/presentation_account_extension.dart'; + +extension UserProfileExtension on UserProfile { + UserProfileResponse toUserProfileResponse() { + return UserProfileResponse( + id, + firstName, + lastName, + jobTitle, + service, + buildingLocation, + officeLocation, + mainPhone, + description, + currentAvatar, + avatars, + accounts.map((account) => account.toPresentationAccountResponse()).toList() + ); + } +} \ No newline at end of file diff --git a/lib/features/login/data/model/converter/avatar_id_converter.dart b/lib/features/login/data/model/converter/avatar_id_converter.dart new file mode 100644 index 000000000..6ffa0e262 --- /dev/null +++ b/lib/features/login/data/model/converter/avatar_id_converter.dart @@ -0,0 +1,12 @@ +import 'package:json_annotation/json_annotation.dart'; +import 'package:model/model.dart'; + +class AvatarIdConverter implements JsonConverter { + const AvatarIdConverter(); + + @override + AvatarId fromJson(String json) => AvatarId(json); + + @override + String toJson(AvatarId object) => object.id; +} diff --git a/lib/features/login/data/model/converter/avatar_id_nullable_converter.dart b/lib/features/login/data/model/converter/avatar_id_nullable_converter.dart new file mode 100644 index 000000000..7f250e44a --- /dev/null +++ b/lib/features/login/data/model/converter/avatar_id_nullable_converter.dart @@ -0,0 +1,12 @@ +import 'package:json_annotation/json_annotation.dart'; +import 'package:model/model.dart'; + +class AvatarIdNullableConverter implements JsonConverter { + const AvatarIdNullableConverter(); + + @override + AvatarId? fromJson(String? json) => json != null ? AvatarId(json) : AvatarId.initial(); + + @override + String? toJson(AvatarId? object) => object?.id; +} diff --git a/lib/features/login/data/model/converter/presentation_email_address_converter.dart b/lib/features/login/data/model/converter/presentation_email_address_converter.dart new file mode 100644 index 000000000..ec595aed0 --- /dev/null +++ b/lib/features/login/data/model/converter/presentation_email_address_converter.dart @@ -0,0 +1,12 @@ +import 'package:json_annotation/json_annotation.dart'; +import 'package:model/model.dart'; + +class PresentationEmailAddressConverter implements JsonConverter { + const PresentationEmailAddressConverter(); + + @override + PresentationEmailAddress fromJson(String json) => PresentationEmailAddress(json); + + @override + String toJson(PresentationEmailAddress object) => object.email; +} diff --git a/lib/features/login/data/model/converter/user_id_converter.dart b/lib/features/login/data/model/converter/user_id_converter.dart index 7ead95f0e..7eb5cd5ab 100644 --- a/lib/features/login/data/model/converter/user_id_converter.dart +++ b/lib/features/login/data/model/converter/user_id_converter.dart @@ -1,5 +1,3 @@ -import 'dart:convert'; - import 'package:json_annotation/json_annotation.dart'; import 'package:model/model.dart'; @@ -10,5 +8,5 @@ class UserIdConverter implements JsonConverter { UserId fromJson(String json) => UserId(json); @override - String toJson(UserId object) => jsonEncode(object.id); + String toJson(UserId object) => object.id; } diff --git a/lib/features/login/data/model/response/presentation_account_response.dart b/lib/features/login/data/model/response/presentation_account_response.dart new file mode 100644 index 000000000..823c9f226 --- /dev/null +++ b/lib/features/login/data/model/response/presentation_account_response.dart @@ -0,0 +1,30 @@ + +import 'package:equatable/equatable.dart'; +import 'package:json_annotation/json_annotation.dart'; +import 'package:model/model.dart'; +import 'package:tmail_ui_user/features/login/data/model/converter/presentation_email_address_converter.dart'; + +part 'presentation_account_response.g.dart'; + +@PresentationEmailAddressConverter() +@JsonSerializable() +class PresentationAccountResponse with EquatableMixin { + final List? emails; + final int preferredEmailIndex; + final AccountType type; + + PresentationAccountResponse(this.emails, this.preferredEmailIndex, this.type); + + factory PresentationAccountResponse.fromJson(Map json) => _$PresentationAccountResponseFromJson(json); + + Map toJson() => _$PresentationAccountResponseToJson(this); + + @override + List get props => [emails, preferredEmailIndex, type]; +} + +extension PresentationAccountResponseExtension on PresentationAccountResponse { + PresentationAccount toPresentationAccount() { + return PresentationAccount(emails ?? [], preferredEmailIndex, type); + } +} \ No newline at end of file diff --git a/lib/features/login/data/model/response/user_profile_response.dart b/lib/features/login/data/model/response/user_profile_response.dart new file mode 100644 index 000000000..45c7191b8 --- /dev/null +++ b/lib/features/login/data/model/response/user_profile_response.dart @@ -0,0 +1,88 @@ +import 'package:equatable/equatable.dart'; +import 'package:json_annotation/json_annotation.dart'; +import 'package:model/model.dart'; +import 'package:tmail_ui_user/features/login/data/model/converter/avatar_id_converter.dart'; +import 'package:tmail_ui_user/features/login/data/model/converter/avatar_id_nullable_converter.dart'; +import 'package:tmail_ui_user/features/login/data/model/converter/user_id_converter.dart'; +import 'package:tmail_ui_user/features/login/data/model/response/presentation_account_response.dart'; +import 'package:tmail_ui_user/features/login/data/utils/attribute.dart'; + +part 'user_profile_response.g.dart'; + +@AvatarIdNullableConverter() +@AvatarIdConverter() +@UserIdConverter() +@JsonSerializable() +class UserProfileResponse with EquatableMixin { + + @JsonKey(name: Attribute.id, includeIfNull: false) + final UserId id; + @JsonKey(name: Attribute.firstname, includeIfNull: false) + final String? firstName; + @JsonKey(name: Attribute.lastname, includeIfNull: false) + final String? lastName; + @JsonKey(name: Attribute.job_title, includeIfNull: false) + final String? jobTitle; + @JsonKey(includeIfNull: false) + final String? service; + @JsonKey(name: Attribute.building_location, includeIfNull: false) + final String? buildingLocation; + @JsonKey(name: Attribute.office_location, includeIfNull: false) + final String? officeLocation; + @JsonKey(name: Attribute.main_phone, includeIfNull: false) + final String? mainPhone; + @JsonKey(includeIfNull: false) + final String? description; + @JsonKey(includeIfNull: false) + final AvatarId? currentAvatar; + @JsonKey(includeIfNull: false) + final List? avatars; + @JsonKey(includeIfNull: false) + final List? accounts; + + UserProfileResponse( + this.id, + this.firstName, + this.lastName, + this.jobTitle, + this.service, + this.buildingLocation, + this.officeLocation, + this.mainPhone, + this.description, + this.currentAvatar, + this.avatars, + this.accounts + ); + + factory UserProfileResponse.fromJson(Map json) => _$UserProfileResponseFromJson(json); + + Map toJson() => _$UserProfileResponseToJson(this); + + @override + List get props => [ + id, + firstName, + lastName, + accounts, + ]; +} + +extension UserProfileResponseExtension on UserProfileResponse { + UserProfile toUserProfile() { + return UserProfile( + id, + firstName ?? '', + lastName ?? '', + jobTitle ?? '', + service ?? '', + buildingLocation ?? '', + officeLocation ?? '', + mainPhone ?? '', + description ?? '', + currentAvatar ?? AvatarId.initial(), + avatars ?? [], + accounts != null ? accounts!.map((account) => account.toPresentationAccount()).toList() : [] + ); + } +} \ No newline at end of file diff --git a/lib/features/login/data/model/response/user_response.dart b/lib/features/login/data/model/response/user_response.dart deleted file mode 100644 index c9c8e02d5..000000000 --- a/lib/features/login/data/model/response/user_response.dart +++ /dev/null @@ -1,46 +0,0 @@ -import 'package:core/data/constants/constant.dart'; -import 'package:equatable/equatable.dart'; -import 'package:json_annotation/json_annotation.dart'; -import 'package:model/model.dart'; -import 'package:tmail_ui_user/features/login/data/model/converter/user_id_converter.dart'; - -part 'user_response.g.dart'; - -@UserIdConverter() -@JsonSerializable() -class UserResponse with EquatableMixin { - - @JsonKey(name: Constant.userId) - final UserId userId; - @JsonKey(name: Constant.firstName) - final String firstName; - @JsonKey(name: Constant.lastName) - final String lastName; - - UserResponse( - this.userId, - this.firstName, - this.lastName - ); - - factory UserResponse.fromJson(Map json) => _$UserResponseFromJson(json); - - Map toJson() => _$UserResponseToJson(this); - - @override - List get props => [ - userId, - firstName, - lastName, - ]; -} - -extension UserResponseExtension on UserResponse { - User toUser() { - return User( - userId, - firstName, - lastName, - ); - } -} \ No newline at end of file diff --git a/lib/features/login/data/network/login_api.dart b/lib/features/login/data/network/login_api.dart index 526888fe2..0a58c7be7 100644 --- a/lib/features/login/data/network/login_api.dart +++ b/lib/features/login/data/network/login_api.dart @@ -5,20 +5,20 @@ import 'dart:io'; import 'package:core/core.dart'; import 'package:dio/dio.dart'; import 'package:tmail_ui_user/features/login/data/model/request/account_request.dart'; -import 'package:tmail_ui_user/features/login/data/model/response/user_response.dart'; +import 'package:tmail_ui_user/features/login/data/model/response/user_profile_response.dart'; class LoginAPI { final DioClient _dioClient; LoginAPI(this._dioClient); - Future authenticationUser(Uri baseUrl, AccountRequest accountRequest) async { + Future authenticationUser(Uri baseUrl, AccountRequest accountRequest) async { final basicAuth = 'Basic ' + base64Encode(utf8.encode('${accountRequest.userName.userName}:${accountRequest.password.value}')); final resultJson = await _dioClient.post( Endpoint.authentication.generateAuthenticationUrl(baseUrl), options: Options(headers: _buildHeaderRequestParam(basicAuth)), data: accountRequest.toJson()); - return UserResponse.fromJson(resultJson); + return UserProfileResponse.fromJson(resultJson); } Map _buildHeaderRequestParam(String authorizationHeader) { diff --git a/lib/features/login/data/repository/authentication_repository_impl.dart b/lib/features/login/data/repository/authentication_repository_impl.dart index a61e2d404..298239da8 100644 --- a/lib/features/login/data/repository/authentication_repository_impl.dart +++ b/lib/features/login/data/repository/authentication_repository_impl.dart @@ -8,7 +8,7 @@ class AuthenticationRepositoryImpl extends AuthenticationRepository { AuthenticationRepositoryImpl(this.loginDataSource); @override - Future authenticationUser(Uri baseUrl, UserName userName, Password password) { + Future authenticationUser(Uri baseUrl, UserName userName, Password password) { return loginDataSource.authenticationUser(baseUrl, userName, password); } } \ No newline at end of file diff --git a/lib/features/login/data/repository/credential_repository_impl.dart b/lib/features/login/data/repository/credential_repository_impl.dart index 5466436a4..4d16634af 100644 --- a/lib/features/login/data/repository/credential_repository_impl.dart +++ b/lib/features/login/data/repository/credential_repository_impl.dart @@ -1,6 +1,10 @@ +import 'dart:convert'; + import 'package:model/model.dart'; import 'package:shared_preferences/shared_preferences.dart'; +import 'package:tmail_ui_user/features/login/data/model/response/user_profile_response.dart'; import 'package:tmail_ui_user/features/login/data/utils/login_constant.dart'; +import 'package:tmail_ui_user/features/login/data/extensions/user_profile_extension.dart'; import 'package:tmail_ui_user/features/login/domain/repository/credential_repository.dart'; class CredentialRepositoryImpl extends CredentialRepository { @@ -53,4 +57,23 @@ class CredentialRepositoryImpl extends CredentialRepository { Future saveUserName(UserName userName) async { await sharedPreferences.setString(LoginConstant.keyUserName, userName.userName); } + + @override + Future getUserProfile() async { + final json = sharedPreferences.getString(LoginConstant.keyUserProfile) ?? ''; + Map mapObject = jsonDecode(json); + return UserProfileResponse.fromJson(mapObject).toUserProfile(); + } + + @override + Future removeUserProfile() async { + await sharedPreferences.remove(LoginConstant.keyUserProfile); + } + + @override + Future saveUserProfile(UserProfile userProfile) async { + final userProfileResponse = userProfile.toUserProfileResponse(); + final json = jsonEncode(userProfileResponse.toJson()); + await sharedPreferences.setString(LoginConstant.keyUserProfile, json); + } } \ No newline at end of file diff --git a/lib/features/login/data/utils/attribute.dart b/lib/features/login/data/utils/attribute.dart new file mode 100644 index 000000000..84587132f --- /dev/null +++ b/lib/features/login/data/utils/attribute.dart @@ -0,0 +1,9 @@ +class Attribute { + static const id = '_id'; + static const firstname = 'firstname'; + static const lastname = 'lastname'; + static const job_title = 'job_title'; + static const building_location = 'building_location'; + static const office_location = 'office_location'; + static const main_phone = 'main_phone'; +} diff --git a/lib/features/login/data/utils/login_constant.dart b/lib/features/login/data/utils/login_constant.dart index ac9eb86ae..bd3637feb 100644 --- a/lib/features/login/data/utils/login_constant.dart +++ b/lib/features/login/data/utils/login_constant.dart @@ -2,4 +2,5 @@ class LoginConstant { static const keyBaseUrl = 'KEY_BASE_URL'; static const keyUserName = 'KEY_USER_NAME'; static const keyPassword = 'KEY_PASSWORD'; + static const keyUserProfile = 'KEY_USER_PROFILE'; } \ No newline at end of file