TF-34 Add data layer login for fix bug mock data user
This commit is contained in:
@@ -1,5 +1,5 @@
|
|||||||
import 'package:model/model.dart';
|
import 'package:model/model.dart';
|
||||||
|
|
||||||
abstract class AuthenticationDataSource {
|
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:model/model.dart';
|
||||||
import 'package:tmail_ui_user/features/login/data/datasource/atuthentitcation_datasource.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/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';
|
import 'package:tmail_ui_user/features/login/data/network/login_api.dart';
|
||||||
|
|
||||||
class AuthenticationDataSourceImpl extends AuthenticationDataSource {
|
class AuthenticationDataSourceImpl extends AuthenticationDataSource {
|
||||||
@@ -11,10 +11,10 @@ class AuthenticationDataSourceImpl extends AuthenticationDataSource {
|
|||||||
AuthenticationDataSourceImpl(this.loginAPI);
|
AuthenticationDataSourceImpl(this.loginAPI);
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Future<User> authenticationUser(Uri baseUrl, UserName userName, Password password) {
|
Future<UserProfile> authenticationUser(Uri baseUrl, UserName userName, Password password) {
|
||||||
return Future.sync(() async {
|
return Future.sync(() async {
|
||||||
final userResponse = await loginAPI.authenticationUser(baseUrl, AccountRequest(userName, password));
|
final userProfileResponse = await loginAPI.authenticationUser(baseUrl, AccountRequest(userName, password));
|
||||||
return userResponse.toUser();
|
return userProfileResponse.toUserProfile();
|
||||||
}).catchError((error) {
|
}).catchError((error) {
|
||||||
throw 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:json_annotation/json_annotation.dart';
|
||||||
import 'package:model/model.dart';
|
import 'package:model/model.dart';
|
||||||
|
|
||||||
@@ -10,5 +8,5 @@ class UserIdConverter implements JsonConverter<UserId, String> {
|
|||||||
UserId fromJson(String json) => UserId(json);
|
UserId fromJson(String json) => UserId(json);
|
||||||
|
|
||||||
@override
|
@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:core/core.dart';
|
||||||
import 'package:dio/dio.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/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 {
|
class LoginAPI {
|
||||||
final DioClient _dioClient;
|
final DioClient _dioClient;
|
||||||
|
|
||||||
LoginAPI(this._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 basicAuth = 'Basic ' + base64Encode(utf8.encode('${accountRequest.userName.userName}:${accountRequest.password.value}'));
|
||||||
final resultJson = await _dioClient.post(
|
final resultJson = await _dioClient.post(
|
||||||
Endpoint.authentication.generateAuthenticationUrl(baseUrl),
|
Endpoint.authentication.generateAuthenticationUrl(baseUrl),
|
||||||
options: Options(headers: _buildHeaderRequestParam(basicAuth)),
|
options: Options(headers: _buildHeaderRequestParam(basicAuth)),
|
||||||
data: accountRequest.toJson());
|
data: accountRequest.toJson());
|
||||||
return UserResponse.fromJson(resultJson);
|
return UserProfileResponse.fromJson(resultJson);
|
||||||
}
|
}
|
||||||
|
|
||||||
Map<String, dynamic> _buildHeaderRequestParam(String authorizationHeader) {
|
Map<String, dynamic> _buildHeaderRequestParam(String authorizationHeader) {
|
||||||
|
|||||||
@@ -8,7 +8,7 @@ class AuthenticationRepositoryImpl extends AuthenticationRepository {
|
|||||||
AuthenticationRepositoryImpl(this.loginDataSource);
|
AuthenticationRepositoryImpl(this.loginDataSource);
|
||||||
|
|
||||||
@override
|
@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);
|
return loginDataSource.authenticationUser(baseUrl, userName, password);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1,6 +1,10 @@
|
|||||||
|
import 'dart:convert';
|
||||||
|
|
||||||
import 'package:model/model.dart';
|
import 'package:model/model.dart';
|
||||||
import 'package:shared_preferences/shared_preferences.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/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';
|
import 'package:tmail_ui_user/features/login/domain/repository/credential_repository.dart';
|
||||||
|
|
||||||
class CredentialRepositoryImpl extends CredentialRepository {
|
class CredentialRepositoryImpl extends CredentialRepository {
|
||||||
@@ -53,4 +57,23 @@ class CredentialRepositoryImpl extends CredentialRepository {
|
|||||||
Future saveUserName(UserName userName) async {
|
Future saveUserName(UserName userName) async {
|
||||||
await sharedPreferences.setString(LoginConstant.keyUserName, userName.userName);
|
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 keyBaseUrl = 'KEY_BASE_URL';
|
||||||
static const keyUserName = 'KEY_USER_NAME';
|
static const keyUserName = 'KEY_USER_NAME';
|
||||||
static const keyPassword = 'KEY_PASSWORD';
|
static const keyPassword = 'KEY_PASSWORD';
|
||||||
|
static const keyUserProfile = 'KEY_USER_PROFILE';
|
||||||
}
|
}
|
||||||
Reference in New Issue
Block a user