TF-34 Add data layer login for fix bug mock data user

This commit is contained in:
dab246
2021-08-25 13:12:17 +07:00
committed by Dat H. Pham
parent b3e1534de3
commit cae1252fc8
16 changed files with 227 additions and 58 deletions
@@ -1,5 +1,5 @@
import 'package:model/model.dart';
abstract class AuthenticationDataSource {
Future<User> authenticationUser(Uri baseUrl, UserName userName, Password password);
Future<UserProfile> authenticationUser(Uri baseUrl, UserName userName, Password password);
}
@@ -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<User> authenticationUser(Uri baseUrl, UserName userName, Password password) {
Future<UserProfile> 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;
});
@@ -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);
}
}
@@ -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()
);
}
}
@@ -0,0 +1,12 @@
import 'package:json_annotation/json_annotation.dart';
import 'package:model/model.dart';
class AvatarIdConverter implements JsonConverter<AvatarId, String> {
const AvatarIdConverter();
@override
AvatarId fromJson(String json) => AvatarId(json);
@override
String toJson(AvatarId object) => object.id;
}
@@ -0,0 +1,12 @@
import 'package:json_annotation/json_annotation.dart';
import 'package:model/model.dart';
class AvatarIdNullableConverter implements JsonConverter<AvatarId?, String?> {
const AvatarIdNullableConverter();
@override
AvatarId? fromJson(String? json) => json != null ? AvatarId(json) : AvatarId.initial();
@override
String? toJson(AvatarId? object) => object?.id;
}
@@ -0,0 +1,12 @@
import 'package:json_annotation/json_annotation.dart';
import 'package:model/model.dart';
class PresentationEmailAddressConverter implements JsonConverter<PresentationEmailAddress, String> {
const PresentationEmailAddressConverter();
@override
PresentationEmailAddress fromJson(String json) => PresentationEmailAddress(json);
@override
String toJson(PresentationEmailAddress object) => object.email;
}
@@ -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, String> {
UserId fromJson(String json) => UserId(json);
@override
String toJson(UserId object) => jsonEncode(object.id);
String toJson(UserId object) => object.id;
}
@@ -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<PresentationEmailAddress>? emails;
final int preferredEmailIndex;
final AccountType type;
PresentationAccountResponse(this.emails, this.preferredEmailIndex, this.type);
factory PresentationAccountResponse.fromJson(Map<String, dynamic> json) => _$PresentationAccountResponseFromJson(json);
Map<String, dynamic> toJson() => _$PresentationAccountResponseToJson(this);
@override
List<Object?> get props => [emails, preferredEmailIndex, type];
}
extension PresentationAccountResponseExtension on PresentationAccountResponse {
PresentationAccount toPresentationAccount() {
return PresentationAccount(emails ?? [], preferredEmailIndex, type);
}
}
@@ -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<AvatarId>? avatars;
@JsonKey(includeIfNull: false)
final List<PresentationAccountResponse>? 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<String, dynamic> json) => _$UserProfileResponseFromJson(json);
Map<String, dynamic> toJson() => _$UserProfileResponseToJson(this);
@override
List<Object?> 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() : []
);
}
}
@@ -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<String, dynamic> json) => _$UserResponseFromJson(json);
Map<String, dynamic> toJson() => _$UserResponseToJson(this);
@override
List<Object?> get props => [
userId,
firstName,
lastName,
];
}
extension UserResponseExtension on UserResponse {
User toUser() {
return User(
userId,
firstName,
lastName,
);
}
}
@@ -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<UserResponse> authenticationUser(Uri baseUrl, AccountRequest accountRequest) async {
Future<UserProfileResponse> 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<String, dynamic> _buildHeaderRequestParam(String authorizationHeader) {
@@ -8,7 +8,7 @@ class AuthenticationRepositoryImpl extends AuthenticationRepository {
AuthenticationRepositoryImpl(this.loginDataSource);
@override
Future<User> authenticationUser(Uri baseUrl, UserName userName, Password password) {
Future<UserProfile> authenticationUser(Uri baseUrl, UserName userName, Password password) {
return loginDataSource.authenticationUser(baseUrl, userName, password);
}
}
@@ -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<UserProfile> getUserProfile() async {
final json = sharedPreferences.getString(LoginConstant.keyUserProfile) ?? '';
Map<String, dynamic> 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);
}
}
@@ -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';
}
@@ -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';
}