Skip to content

Commit 31eb33c

Browse files
authored
http_client_hoc081098, cancellation_token_hoc081098, Future to Single (#73)
* draft http_client_hoc081098 * further refactor * further refactor * further refactor * further refactor * further refactor * rxdart_ext: ^0.2.6 * deps * fix * fix
1 parent 27385fa commit 31eb33c

27 files changed

+539
-474
lines changed

.github/workflows/flutter.yml

+4-3
Original file line numberDiff line numberDiff line change
@@ -46,12 +46,13 @@ jobs:
4646
- name: Gen code
4747
run: flutter packages pub run build_runner build --delete-conflicting-outputs
4848

49-
- name: Build APK
50-
run: flutter build apk --no-shrink
49+
- name: Build Debug APK
50+
run: flutter build apk --debug --no-shrink
5151

5252
- name: Upload APK
53+
if: ${{ matrix.flutter-channel == 'stable' }}
5354
uses: actions/upload-artifact@v3
5455
with:
5556
name: app-${{ matrix.flutter-channel }}
56-
path: build/app/outputs/apk/release/app-release.apk
57+
path: build/app/outputs/apk/debug/app-debug.apk
5758

analysis_options.yaml

+2-1
Original file line numberDiff line numberDiff line change
@@ -7,4 +7,5 @@ linter:
77
- always_declare_return_types
88
- prefer_single_quotes
99
- unawaited_futures
10-
- unsafe_html
10+
- unsafe_html
11+
- avoid_slow_async_io

ios/Podfile.lock

+6
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
PODS:
22
- CryptoSwift (1.2.0)
3+
- cupertino_http (0.0.1):
4+
- Flutter
35
- Flutter (1.0.0)
46
- image_picker_ios (0.0.1):
57
- Flutter
@@ -8,6 +10,7 @@ PODS:
810

911
DEPENDENCIES:
1012
- CryptoSwift (~> 1.2.0)
13+
- cupertino_http (from `.symlinks/plugins/cupertino_http/ios`)
1114
- Flutter (from `Flutter`)
1215
- image_picker_ios (from `.symlinks/plugins/image_picker_ios/ios`)
1316
- shared_preferences_ios (from `.symlinks/plugins/shared_preferences_ios/ios`)
@@ -17,6 +20,8 @@ SPEC REPOS:
1720
- CryptoSwift
1821

1922
EXTERNAL SOURCES:
23+
cupertino_http:
24+
:path: ".symlinks/plugins/cupertino_http/ios"
2025
Flutter:
2126
:path: Flutter
2227
image_picker_ios:
@@ -26,6 +31,7 @@ EXTERNAL SOURCES:
2631

2732
SPEC CHECKSUMS:
2833
CryptoSwift: 40e374e45291d8dceedcb0d6184da94533eaabdf
34+
cupertino_http: 5f8b1161107fe6c8d94a0c618735a033d93fa7db
2935
Flutter: 50d75fe2f02b26cc09d224853bb45737f8b3214a
3036
image_picker_ios: b786a5dcf033a8336a657191401bfdf12017dabb
3137
shared_preferences_ios: 548a61f8053b9b8a49ac19c1ffbc8b92c50d68ad

lib/data/exception/local_data_source_exception.dart

+1-1
Original file line numberDiff line numberDiff line change
@@ -7,5 +7,5 @@ class LocalDataSourceException implements Exception {
77

88
@override
99
String toString() =>
10-
'LocalDataSourceException{message=$message, error=$error}';
10+
'LocalDataSourceException{message=$message, error=$error, stackTrace=$stackTrace}';
1111
}
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,11 @@
1-
import 'dart:io';
1+
class RemoteDataSourceException implements Exception {
2+
final String message;
3+
final Object error;
4+
final StackTrace stackTrace;
25

3-
class RemoteDataSourceException extends HttpException {
4-
final int statusCode;
5-
6-
RemoteDataSourceException(this.statusCode, String message) : super(message);
6+
const RemoteDataSourceException(this.message, this.error, this.stackTrace);
77

88
@override
99
String toString() =>
10-
'RemoteDataSourceException{statusCode=$statusCode, message=$message}';
10+
'RemoteDataSourceException{message=$message, error=$error, stackTrace=$stackTrace}';
1111
}

lib/data/local/local_data_source.dart

+4-3
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,20 @@
11
import 'package:node_auth/data/local/entities/user_and_token_entity.dart';
2+
import 'package:node_auth/domain/models/app_error.dart';
23

34
abstract class LocalDataSource {
45
/// Returns a single-subscription stream that emits [UserAndTokenEntity] or null
56
Stream<UserAndTokenEntity?> get userAndToken$;
67

78
/// Returns a future that completes with a [UserAndTokenEntity] value or null
8-
Future<UserAndTokenEntity?> get userAndToken;
9+
Single<UserAndTokenEntity?> get userAndToken;
910

1011
/// Save [userAndToken] into local storage.
1112
/// Throws [LocalDataSourceException] if saving is failed
12-
Future<void> saveUserAndToken(UserAndTokenEntity userAndToken);
13+
Single<void> saveUserAndToken(UserAndTokenEntity userAndToken);
1314

1415
/// Remove user and token from local storage.
1516
/// Throws [LocalDataSourceException] if removing is failed
16-
Future<void> removeUserAndToken();
17+
Single<void> removeUserAndToken();
1718
}
1819

1920
abstract class Crypto {

lib/data/local/shared_pref_util.dart

+19-14
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ import 'package:node_auth/data/exception/local_data_source_exception.dart';
55
import 'package:node_auth/data/local/entities/user_and_token_entity.dart';
66
import 'package:node_auth/data/local/local_data_source.dart';
77
import 'package:rx_shared_preferences/rx_shared_preferences.dart';
8-
import 'package:rxdart/rxdart.dart';
8+
import 'package:rxdart_ext/rxdart_ext.dart';
99

1010
class SharedPrefUtil implements LocalDataSource {
1111
static const _kUserTokenKey = 'com.hoc.node_auth_flutter.user_and_token';
@@ -15,23 +15,28 @@ class SharedPrefUtil implements LocalDataSource {
1515
const SharedPrefUtil(this._rxPrefs, this._crypto);
1616

1717
@override
18-
Future<void> removeUserAndToken() =>
19-
_rxPrefs.remove(_kUserTokenKey).onError<Object>((e, s) =>
20-
throw LocalDataSourceException('Cannot delete user and token', e, s));
18+
Single<void> removeUserAndToken() => Single.fromCallable(
19+
() => _rxPrefs.remove(_kUserTokenKey).onError<Object>((e, s) =>
20+
throw LocalDataSourceException(
21+
'Cannot delete user and token', e, s)),
22+
);
2123

2224
@override
23-
Future<void> saveUserAndToken(UserAndTokenEntity userAndToken) {
24-
return _rxPrefs
25-
.write<UserAndTokenEntity>(_kUserTokenKey, userAndToken, _toString)
26-
.onError<Object>((e, s) =>
27-
throw LocalDataSourceException('Cannot save user and token', e, s));
28-
}
25+
Single<void> saveUserAndToken(UserAndTokenEntity userAndToken) =>
26+
Single.fromCallable(
27+
() => _rxPrefs
28+
.write<UserAndTokenEntity>(_kUserTokenKey, userAndToken, _toString)
29+
.onError<Object>((e, s) => throw LocalDataSourceException(
30+
'Cannot save user and token', e, s)),
31+
);
2932

3033
@override
31-
Future<UserAndTokenEntity?> get userAndToken => _rxPrefs
32-
.read<UserAndTokenEntity>(_kUserTokenKey, _toEntity)
33-
.onError<Object>((e, s) =>
34-
throw LocalDataSourceException('Cannot read user and token', e, s));
34+
Single<UserAndTokenEntity?> get userAndToken => Single.fromCallable(
35+
() => _rxPrefs
36+
.read<UserAndTokenEntity>(_kUserTokenKey, _toEntity)
37+
.onError<Object>((e, s) => throw LocalDataSourceException(
38+
'Cannot read user and token', e, s)),
39+
);
3540

3641
@override
3742
Stream<UserAndTokenEntity?> get userAndToken$ => _rxPrefs

lib/data/mappers.dart

+37
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,43 @@
11
part of 'user_repository_imp.dart';
22

33
abstract class _Mappers {
4+
///
5+
/// Convert error to [Failure]
6+
///
7+
static AppError errorToAppError(Object e, StackTrace s) {
8+
if (e is CancellationException) {
9+
return const AppCancellationError();
10+
}
11+
12+
if (e is RemoteDataSourceException) {
13+
if (e.error is CancellationException) {
14+
return const AppCancellationError();
15+
}
16+
return AppError(
17+
message: e.message,
18+
error: e,
19+
stackTrace: s,
20+
);
21+
}
22+
23+
if (e is LocalDataSourceException) {
24+
if (e.error is CancellationException) {
25+
return const AppCancellationError();
26+
}
27+
return AppError(
28+
message: e.message,
29+
error: e,
30+
stackTrace: s,
31+
);
32+
}
33+
34+
return AppError(
35+
message: e.toString(),
36+
error: e,
37+
stackTrace: s,
38+
);
39+
}
40+
441
/// Entity -> Domain
542
static AuthenticationState userAndTokenEntityToDomainAuthState(
643
UserAndTokenEntity? entity) {

0 commit comments

Comments
 (0)