Skip to content

Commit 3408a67

Browse files
authored
Merge pull request #17 from CoderJava/feature/kirimkan-versi-app-yang-digunakan-oleh-user-ke-api
Feature - Kirimkan versi app yang digunakan ke API
2 parents a9e29cb + 49e64c5 commit 3408a67

File tree

17 files changed

+509
-10
lines changed

17 files changed

+509
-10
lines changed

lib/feature/data/datasource/user/user_remote_data_source.dart

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import 'package:dipantau_desktop_client/config/flavor_config.dart';
44
import 'package:dipantau_desktop_client/feature/data/model/update_user/update_user_body.dart';
55
import 'package:dipantau_desktop_client/feature/data/model/user_profile/list_user_profile_response.dart';
66
import 'package:dipantau_desktop_client/feature/data/model/user_profile/user_profile_response.dart';
7+
import 'package:dipantau_desktop_client/feature/domain/usecase/user_version/user_version_body.dart';
78

89
abstract class UserRemoteDataSource {
910
/// Panggil endpoint [host]/profile
@@ -26,6 +27,11 @@ abstract class UserRemoteDataSource {
2627
late String pathUpdateUser;
2728

2829
Future<bool> updateUser(UpdateUserBody body, int id);
30+
31+
/// Panggil endpoint [host]/version
32+
late String pathSendAppVersion;
33+
34+
Future<bool> sendAppVersion(UserVersionBody body);
2935
}
3036

3137
class UserRemoteDataSourceImpl implements UserRemoteDataSource {
@@ -101,4 +107,26 @@ class UserRemoteDataSourceImpl implements UserRemoteDataSource {
101107
throw DioException(requestOptions: RequestOptions(path: pathUpdateUser));
102108
}
103109
}
110+
111+
@override
112+
String pathSendAppVersion = '';
113+
114+
@override
115+
Future<bool> sendAppVersion(UserVersionBody body) async {
116+
pathSendAppVersion = '$baseUrl/version';
117+
final response = await dio.post(
118+
pathSendAppVersion,
119+
data: body.toJson(),
120+
options: Options(
121+
headers: {
122+
baseUrlConfig.requiredToken: true,
123+
},
124+
),
125+
);
126+
if (response.statusCode.toString().startsWith('2')) {
127+
return true;
128+
} else {
129+
throw DioException(requestOptions: RequestOptions(path: pathSendAppVersion));
130+
}
131+
}
104132
}

lib/feature/data/repository/user/user_repository_impl.dart

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ import 'package:dipantau_desktop_client/feature/data/model/update_user/update_us
77
import 'package:dipantau_desktop_client/feature/data/model/user_profile/list_user_profile_response.dart';
88
import 'package:dipantau_desktop_client/feature/data/model/user_profile/user_profile_response.dart';
99
import 'package:dipantau_desktop_client/feature/domain/repository/user/user_repository.dart';
10+
import 'package:dipantau_desktop_client/feature/domain/usecase/user_version/user_version_body.dart';
1011

1112
class UserRepositoryImpl implements UserRepository {
1213
final UserRemoteDataSource remoteDataSource;
@@ -113,4 +114,34 @@ class UserRepositoryImpl implements UserRepository {
113114
}
114115
return (failure: failure, response: response);
115116
}
117+
118+
@override
119+
Future<({Failure? failure, bool? response})> sendAppVersion(UserVersionBody body) async {
120+
Failure? failure;
121+
bool? response;
122+
final isConnected = await networkInfo.isConnected;
123+
if (isConnected) {
124+
try {
125+
response = await remoteDataSource.sendAppVersion(body);
126+
} on DioException catch (error) {
127+
final message = error.message ?? error.toString();
128+
if (error.response == null) {
129+
failure = ServerFailure(message);
130+
} else {
131+
final errorMessage = getErrorMessageFromEndpoint(
132+
error.response?.data,
133+
message,
134+
error.response?.statusCode,
135+
);
136+
failure = ServerFailure(errorMessage);
137+
}
138+
} on TypeError catch (error) {
139+
final errorMessage = error.toString();
140+
failure = ParsingFailure(errorMessage);
141+
}
142+
} else {
143+
failure = ConnectionFailure();
144+
}
145+
return (failure: failure, response: response);
146+
}
116147
}

lib/feature/domain/repository/user/user_repository.dart

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,11 +3,14 @@ import 'package:dipantau_desktop_client/core/error/failure.dart';
33
import 'package:dipantau_desktop_client/feature/data/model/update_user/update_user_body.dart';
44
import 'package:dipantau_desktop_client/feature/data/model/user_profile/list_user_profile_response.dart';
55
import 'package:dipantau_desktop_client/feature/data/model/user_profile/user_profile_response.dart';
6+
import 'package:dipantau_desktop_client/feature/domain/usecase/user_version/user_version_body.dart';
67

78
abstract class UserRepository {
89
Future<Either<Failure, UserProfileResponse>> getProfile();
910

1011
Future<({Failure? failure, ListUserProfileResponse? response})> getAllMembers();
1112

1213
Future<({Failure? failure, bool? response})> updateUser(UpdateUserBody body, int id);
14+
15+
Future<({Failure? failure, bool? response})> sendAppVersion(UserVersionBody body);
1316
}
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
import 'package:dipantau_desktop_client/core/error/failure.dart';
2+
import 'package:dipantau_desktop_client/core/usecase/usecase.dart';
3+
import 'package:dipantau_desktop_client/feature/domain/repository/user/user_repository.dart';
4+
import 'package:dipantau_desktop_client/feature/domain/usecase/user_version/user_version_body.dart';
5+
import 'package:equatable/equatable.dart';
6+
7+
class SendAppVersion implements UseCaseRecords<bool?, ParamsSendAppVersion> {
8+
final UserRepository repository;
9+
10+
SendAppVersion({required this.repository});
11+
12+
@override
13+
Future<({Failure? failure, bool? response})> call(ParamsSendAppVersion params) {
14+
return repository.sendAppVersion(params.body);
15+
}
16+
}
17+
18+
class ParamsSendAppVersion extends Equatable {
19+
final UserVersionBody body;
20+
21+
ParamsSendAppVersion({required this.body});
22+
23+
@override
24+
List<Object?> get props => [
25+
body,
26+
];
27+
28+
@override
29+
String toString() {
30+
return 'ParamsSendAppVersion{body: $body}';
31+
}
32+
}
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
import 'package:equatable/equatable.dart';
2+
import 'package:json_annotation/json_annotation.dart';
3+
4+
part 'user_version_body.g.dart';
5+
6+
@JsonSerializable()
7+
class UserVersionBody extends Equatable {
8+
@JsonKey(name: 'code')
9+
final String code;
10+
@JsonKey(name: 'name')
11+
final String name;
12+
@JsonKey(name: 'user_id')
13+
final int userId;
14+
15+
UserVersionBody({
16+
required this.code,
17+
required this.name,
18+
required this.userId,
19+
});
20+
21+
factory UserVersionBody.fromJson(Map<String, dynamic> json) => _$UserVersionBodyFromJson(json);
22+
23+
Map<String, dynamic> toJson() => _$UserVersionBodyToJson(this);
24+
25+
@override
26+
List<Object?> get props => [
27+
code,
28+
name,
29+
userId,
30+
];
31+
32+
@override
33+
String toString() {
34+
return 'UserVersionBody{code: $code, name: $name, userId: $userId}';
35+
}
36+
}

lib/feature/presentation/bloc/home/home_bloc.dart

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,8 @@ import 'package:bloc/bloc.dart';
44
import 'package:dipantau_desktop_client/core/error/failure.dart';
55
import 'package:dipantau_desktop_client/feature/data/model/track_user_lite/track_user_lite_response.dart';
66
import 'package:dipantau_desktop_client/feature/domain/usecase/get_track_user_lite/get_track_user_lite.dart';
7+
import 'package:dipantau_desktop_client/feature/domain/usecase/send_app_version/send_app_version.dart';
8+
import 'package:dipantau_desktop_client/feature/domain/usecase/user_version/user_version_body.dart';
79
import 'package:equatable/equatable.dart';
810

911
part 'home_event.dart';
@@ -12,15 +14,31 @@ part 'home_state.dart';
1214

1315
class HomeBloc extends Bloc<HomeEvent, HomeState> {
1416
final GetTrackUserLite getTrackUserLite;
17+
final SendAppVersion sendAppVersion;
1518

1619
HomeBloc({
1720
required this.getTrackUserLite,
21+
required this.sendAppVersion,
1822
}) : super(InitialHomeState()) {
1923
on<LoadDataHomeEvent>(_onLoadDataHomeEvent);
2024
}
2125

2226
FutureOr<void> _onLoadDataHomeEvent(LoadDataHomeEvent event, Emitter<HomeState> emit) async {
2327
emit(LoadingHomeState());
28+
29+
final userVersionBody = event.userVersionBody;
30+
if (userVersionBody != null) {
31+
await sendAppVersion(
32+
ParamsSendAppVersion(
33+
body: UserVersionBody(
34+
code: userVersionBody.code,
35+
name: userVersionBody.name,
36+
userId: userVersionBody.userId,
37+
),
38+
),
39+
);
40+
}
41+
2442
final result = await getTrackUserLite(
2543
ParamsGetTrackUserLite(
2644
date: event.date,

lib/feature/presentation/bloc/home/home_event.dart

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,22 +8,26 @@ class LoadDataHomeEvent extends HomeEvent {
88
final String date;
99
final String projectId;
1010
final bool isAutoStart;
11+
final UserVersionBody? userVersionBody;
1112

1213
LoadDataHomeEvent({
1314
required this.date,
1415
required this.projectId,
1516
required this.isAutoStart,
17+
this.userVersionBody,
1618
});
1719

1820
@override
1921
List<Object?> get props => [
2022
date,
2123
projectId,
2224
isAutoStart,
25+
userVersionBody,
2326
];
2427

2528
@override
2629
String toString() {
27-
return 'LoadDataHomeEvent{date: $date, projectId: $projectId, isAutoStart: $isAutoStart}';
30+
return 'LoadDataHomeEvent{date: $date, projectId: $projectId, isAutoStart: $isAutoStart, '
31+
'userVersionBody: $userVersionBody}';
2832
}
2933
}

lib/feature/presentation/page/home/home_page.dart

Lines changed: 20 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ import 'package:dipantau_desktop_client/feature/data/model/track_task/track_task
1717
import 'package:dipantau_desktop_client/feature/data/model/track_user_lite/track_user_lite_response.dart';
1818
import 'package:dipantau_desktop_client/feature/database/app_database.dart';
1919
import 'package:dipantau_desktop_client/feature/database/entity/track/track.dart';
20+
import 'package:dipantau_desktop_client/feature/domain/usecase/user_version/user_version_body.dart';
2021
import 'package:dipantau_desktop_client/feature/presentation/bloc/cron_tracking/cron_tracking_bloc.dart';
2122
import 'package:dipantau_desktop_client/feature/presentation/bloc/home/home_bloc.dart';
2223
import 'package:dipantau_desktop_client/feature/presentation/bloc/tracking/tracking_bloc.dart';
@@ -125,7 +126,7 @@ class _HomePageState extends State<HomePage> with TrayListener, WindowListener {
125126
widgetHelper.showSnackBar(context, 'error: $error');
126127
}
127128
setupCronTimer();
128-
doLoadData();
129+
doLoadDataTask();
129130
});
130131
super.initState();
131132
}
@@ -555,7 +556,7 @@ class _HomePageState extends State<HomePage> with TrayListener, WindowListener {
555556
return WidgetError(
556557
title: 'oops'.tr(),
557558
message: errorMessage,
558-
onTryAgain: doLoadData,
559+
onTryAgain: doLoadDataTask,
559560
);
560561
}
561562
return buildWidgetListTrack();
@@ -765,7 +766,7 @@ class _HomePageState extends State<HomePage> with TrayListener, WindowListener {
765766
now.day,
766767
);
767768
setState(() {});
768-
doLoadData();
769+
doLoadDataTask();
769770
}
770771
},
771772
child: Container(
@@ -919,7 +920,7 @@ class _HomePageState extends State<HomePage> with TrayListener, WindowListener {
919920
);
920921
}
921922

922-
Future<void> doLoadData({bool isAutoStart = false}) async {
923+
Future<void> doLoadDataTask({bool isAutoStart = false}) async {
923924
listTrackTask.clear();
924925
final now = DateTime.now();
925926
final formattedNow = helper.setDateFormat('yyyy-MM-dd').format(now);
@@ -932,11 +933,25 @@ class _HomePageState extends State<HomePage> with TrayListener, WindowListener {
932933
final newListTrackLocal = await trackDao.findAllTrackLikeDate('$formattedNow%');
933934
listTrackLocal.addAll(newListTrackLocal);
934935

936+
UserVersionBody? userVersionBody;
937+
final versionCode = packageInfo.buildNumber;
938+
final versionName = packageInfo.version;
939+
final strUserId = sharedPreferencesManager.getString(SharedPreferencesManager.keyUserId) ?? '';
940+
final userId = int.tryParse(strUserId);
941+
if (strUserId.isNotEmpty && userId != null) {
942+
userVersionBody = UserVersionBody(
943+
code: versionCode,
944+
name: versionName,
945+
userId: userId,
946+
);
947+
}
948+
935949
homeBloc.add(
936950
LoadDataHomeEvent(
937951
date: formattedNow,
938952
projectId: selectedProjectId.toString(),
939953
isAutoStart: isAutoStart,
954+
userVersionBody: userVersionBody,
940955
),
941956
);
942957
}
@@ -1152,7 +1167,7 @@ class _HomePageState extends State<HomePage> with TrayListener, WindowListener {
11521167
await sharedPreferencesManager.clearKey(SharedPreferencesManager.keySleepTime);
11531168
networkInfo.isConnected.then((isConnected) {
11541169
if (isConnected) {
1155-
doLoadData(isAutoStart: true);
1170+
doLoadDataTask(isAutoStart: true);
11561171
} else {
11571172
autoStartFromSleep();
11581173
}

lib/injection_container.dart

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@ import 'package:dipantau_desktop_client/feature/domain/usecase/get_track_user/ge
3333
import 'package:dipantau_desktop_client/feature/domain/usecase/get_track_user_lite/get_track_user_lite.dart';
3434
import 'package:dipantau_desktop_client/feature/domain/usecase/login/login.dart';
3535
import 'package:dipantau_desktop_client/feature/domain/usecase/refresh_token/refresh_token.dart';
36+
import 'package:dipantau_desktop_client/feature/domain/usecase/send_app_version/send_app_version.dart';
3637
import 'package:dipantau_desktop_client/feature/domain/usecase/set_kv_setting/set_kv_setting.dart';
3738
import 'package:dipantau_desktop_client/feature/domain/usecase/sign_up/sign_up.dart';
3839
import 'package:dipantau_desktop_client/feature/domain/usecase/update_user/update_user.dart';
@@ -62,6 +63,7 @@ void init() {
6263
sl.registerFactory(
6364
() => HomeBloc(
6465
getTrackUserLite: sl(),
66+
sendAppVersion: sl(),
6567
),
6668
);
6769
sl.registerFactory(
@@ -147,6 +149,7 @@ void init() {
147149
sl.registerLazySingleton(() => GetTrackUser(repository: sl()));
148150
sl.registerLazySingleton(() => GetKvSetting(repository: sl()));
149151
sl.registerLazySingleton(() => SetKvSetting(repository: sl()));
152+
sl.registerLazySingleton(() => SendAppVersion(repository: sl()));
150153

151154
// repository
152155
sl.registerLazySingleton<AuthRepository>(

0 commit comments

Comments
 (0)