Skip to content

Commit a0c6dcd

Browse files
authored
Merge pull request #4 from hoc081098/deps
deps and refactor
2 parents 6dd7ac1 + af4f7fe commit a0c6dcd

24 files changed

+555
-446
lines changed

analysis_options.yaml

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,4 @@
11
include: package:pedantic/analysis_options.1.9.0.yaml
2-
analyzer:
3-
exclude:
4-
- "lib/src/generated/*.dart"
5-
- "lib/generated/*.dart"
62
linter:
73
rules:
84
- prefer_final_locals

lib/app.dart

Lines changed: 23 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ import 'package:flutter/material.dart';
22
import 'package:flutter_bloc_pattern/flutter_bloc_pattern.dart';
33
import 'package:flutter_provider/flutter_provider.dart';
44
import 'package:node_auth/domain/models/auth_state.dart';
5+
import 'package:node_auth/domain/repositories/user_repository.dart';
56
import 'package:node_auth/domain/usecases/get_auth_state_stream_use_case.dart';
67
import 'package:node_auth/domain/usecases/get_auth_state_use_case.dart';
78
import 'package:node_auth/domain/usecases/login_use_case.dart';
@@ -19,33 +20,38 @@ class MyApp extends StatelessWidget {
1920
@override
2021
Widget build(BuildContext context) {
2122
final routes = <String, WidgetBuilder>{
22-
'/': (context) => const Home(),
23+
Navigator.defaultRouteName: (context) {
24+
return Provider<GetAuthStateUseCase>.factory(
25+
(context) => GetAuthStateUseCase(context.get()),
26+
child: const Home(),
27+
);
28+
},
2329
RegisterPage.routeName: (context) {
24-
final registerUser = Provider.of<RegisterUseCase>(context);
25-
2630
return BlocProvider<RegisterBloc>(
2731
child: const RegisterPage(),
28-
initBloc: () => RegisterBloc(registerUser),
32+
initBloc: (context) => RegisterBloc(
33+
RegisterUseCase(context.get()),
34+
),
2935
);
3036
},
3137
HomePage.routeName: (context) {
32-
final logout = Provider.of<LogoutUseCase>(context);
33-
final getAuthState = Provider.of<GetAuthStateStreamUseCase>(context);
34-
final uploadImage = Provider.of<UploadImageUseCase>(context);
35-
3638
return BlocProvider<HomeBloc>(
3739
child: const HomePage(),
38-
initBloc: () => HomeBloc(
39-
logout,
40-
getAuthState,
41-
uploadImage,
42-
),
40+
initBloc: (context) {
41+
final userRepository = context.get<UserRepository>();
42+
return HomeBloc(
43+
LogoutUseCase(userRepository),
44+
GetAuthStateStreamUseCase(userRepository),
45+
UploadImageUseCase(userRepository),
46+
);
47+
},
4348
);
4449
},
4550
LoginPage.routeName: (context) {
46-
final login = Provider.of<LoginUseCase>(context);
4751
return BlocProvider<LoginBloc>(
48-
initBloc: () => LoginBloc(login),
52+
initBloc: (context) => LoginBloc(
53+
LoginUseCase(context.get()),
54+
),
4955
child: const LoginPage(),
5056
);
5157
},
@@ -54,15 +60,14 @@ class MyApp extends StatelessWidget {
5460
},
5561
};
5662

57-
return Provider<Map<String, WidgetBuilder>>(
58-
value: routes,
63+
return Provider<Map<String, WidgetBuilder>>.value(
64+
routes,
5965
child: MaterialApp(
6066
title: 'Flutter Demo',
6167
theme: ThemeData(
6268
brightness: Brightness.dark,
6369
accentColor: const Color(0xFF00e676),
6470
),
65-
initialRoute: '/',
6671
routes: routes,
6772
),
6873
);

lib/data/local/entities/user_entity.dart

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ abstract class UserEntity implements Built<UserEntity, UserEntityBuilder> {
1414
@BuiltValueField(wireName: 'created_at')
1515
DateTime get createdAt;
1616

17+
@nullable
1718
@BuiltValueField(wireName: 'image_url')
1819
String get imageUrl;
1920

lib/data/local/entities/user_entity.g.dart

Lines changed: 6 additions & 7 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

lib/data/remote/api_service.dart

Lines changed: 9 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -2,11 +2,7 @@ import 'dart:async';
22
import 'dart:convert';
33
import 'dart:io';
44

5-
import 'package:flutter/foundation.dart' show debugPrint;
6-
import 'package:http/http.dart' as http;
7-
import 'package:path/path.dart' as path;
85
import 'package:node_auth/data/constants.dart';
9-
import 'package:node_auth/data/exception/remote_data_source_exception.dart';
106
import 'package:node_auth/data/remote/network_utils.dart';
117
import 'package:node_auth/data/remote/remote_data_source.dart';
128
import 'package:node_auth/data/remote/response/token_response.dart';
@@ -80,7 +76,7 @@ class ApiService implements RemoteDataSource {
8076
String newPassword,
8177
String token,
8278
) async {
83-
final url = Uri.http(baseUrl, '/users/$email/password');
79+
final url = Uri.https(baseUrl, '/users/$email/password');
8480
final body = {'password': password, 'new_password': newPassword};
8581
final json = await NetworkUtils.put(
8682
url,
@@ -121,30 +117,16 @@ class ApiService implements RemoteDataSource {
121117
Future<UserResponse> uploadImage(
122118
File file,
123119
String email,
120+
String token,
124121
) async {
125122
final url = Uri.https(baseUrl, '/users/upload');
126-
final stream = http.ByteStream(file.openRead());
127-
final length = await file.length();
128-
final request = http.MultipartRequest('POST', url)
129-
..fields['user'] = email
130-
..files.add(
131-
http.MultipartFile(
132-
'my_image',
133-
stream,
134-
length,
135-
filename: path.basename(file.path),
136-
),
137-
);
138-
final streamedResponse = await request.send();
139-
final statusCode = streamedResponse.statusCode;
140-
final decoded = json.decode(await streamedResponse.stream.bytesToString());
141-
142-
debugPrint('decoded: $decoded');
143-
144-
if (statusCode < 200 || statusCode >= 300) {
145-
throw RemoteDataSourceException(statusCode, decoded['message']);
146-
}
147-
123+
final decoded = await NetworkUtils.multipartPost(
124+
url,
125+
file,
126+
'my_image',
127+
fields: {'user': email},
128+
headers: {xAccessToken: token},
129+
);
148130
return UserResponse.fromJson(decoded);
149131
}
150132
}

lib/data/remote/network_utils.dart

Lines changed: 88 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,66 @@
11
import 'dart:convert';
2+
import 'dart:io';
23

4+
import 'package:flutter/foundation.dart';
35
import 'package:http/http.dart' as http;
46
import 'package:node_auth/data/exception/remote_data_source_exception.dart';
7+
import 'package:path/path.dart' as path;
8+
9+
final _indent = ' ' * 11;
10+
11+
void _logRequest(
12+
Uri url,
13+
String method, {
14+
Map<String, String> headers,
15+
Map<String, String> body,
16+
Map<String, String> multipartFields,
17+
List<http.MultipartFile> multipartFiles,
18+
}) {
19+
debugPrint('[http] --> ${method} ${url}');
20+
debugPrint('${_indent}headers: $headers');
21+
22+
if (method == 'POST' || method == 'PUT') {
23+
debugPrint('${_indent}body: $body');
24+
25+
if (method == 'POST') {
26+
if (multipartFields != null) {
27+
debugPrint('${_indent}multipartFields: ${multipartFields}');
28+
}
29+
if (multipartFields != null) {
30+
debugPrint('${_indent}multipartFiles: ${multipartFiles}');
31+
}
32+
}
33+
}
34+
}
35+
36+
void _logResponse(http.Response response) {
37+
debugPrint('[http] <-- ${response.statusCode} ${response.request}');
38+
debugPrint('${_indent}bodyBytes: ${response.bodyBytes?.length}');
39+
try {
40+
debugPrint('${_indent}body: ' + response.body);
41+
} catch (_) {}
42+
}
543

644
class NetworkUtils {
745
static Future get(
846
Uri url, {
947
Map<String, String> headers,
1048
}) async {
49+
_logRequest(url, 'GET', headers: headers);
50+
1151
final response = await http.get(url, headers: headers);
52+
_logResponse(response);
53+
return _parse(response);
54+
}
55+
56+
static dynamic _parse(http.Response response) {
1257
final body = response.body;
1358
final statusCode = response.statusCode;
59+
1460
if (body == null) {
1561
throw RemoteDataSourceException(statusCode, 'Response body is null');
1662
}
63+
1764
final decoded = json.decode(body);
1865
if (statusCode < 200 || statusCode >= 300) {
1966
throw RemoteDataSourceException(statusCode, decoded['message']);
@@ -39,6 +86,8 @@ class NetworkUtils {
3986
Map<String, String> headers,
4087
Map<String, String> body,
4188
}) async {
89+
_logRequest(url, method, headers: headers, body: body);
90+
4291
final request = http.Request(method, url);
4392
if (body != null) {
4493
request.bodyFields = body;
@@ -48,25 +97,55 @@ class NetworkUtils {
4897
}
4998
final streamedResponse = await request.send();
5099

51-
final statusCode = streamedResponse.statusCode;
52-
final decoded = json.decode(await streamedResponse.stream.bytesToString());
53-
54-
if (statusCode < 200 || statusCode >= 300) {
55-
throw RemoteDataSourceException(statusCode, decoded['message']);
56-
}
57-
58-
return decoded;
100+
final response = await http.Response.fromStream(streamedResponse);
101+
_logResponse(response);
102+
return _parse(response);
59103
}
60104

61105
static Future put(
62106
Uri url, {
63107
Map<String, String> headers,
64-
body,
108+
Map<String, String> body,
65109
}) =>
66110
_helper(
67111
'PUT',
68112
url,
69113
headers: headers,
70114
body: body,
71115
);
116+
117+
static Future multipartPost(
118+
Uri url,
119+
File file,
120+
String field, {
121+
Map<String, String> headers,
122+
Map<String, String> fields,
123+
}) async {
124+
final stream = http.ByteStream(file.openRead());
125+
final length = await file.length();
126+
127+
final request = http.MultipartRequest('POST', url)
128+
..fields.addAll(fields ?? {})
129+
..files.add(
130+
http.MultipartFile(
131+
field,
132+
stream,
133+
length,
134+
filename: path.basename(file.path),
135+
),
136+
)
137+
..headers.addAll(headers ?? {});
138+
_logRequest(
139+
url,
140+
'POST',
141+
headers: headers,
142+
multipartFields: request.fields,
143+
multipartFiles: request.files,
144+
);
145+
final streamedResponse = await request.send();
146+
147+
final response = await http.Response.fromStream(streamedResponse);
148+
_logResponse(response);
149+
return _parse(response);
150+
}
72151
}

lib/data/remote/remote_data_source.dart

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,5 +27,9 @@ abstract class RemoteDataSource {
2727

2828
Future<UserResponse> getUserProfile(String email, String token);
2929

30-
Future<UserResponse> uploadImage(File file, String email);
30+
Future<UserResponse> uploadImage(
31+
File file,
32+
String email,
33+
String token,
34+
);
3135
}

lib/data/remote/response/user_response.dart

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ abstract class UserResponse
1515
@BuiltValueField(wireName: 'created_at')
1616
DateTime get createdAt;
1717

18+
@nullable
1819
@BuiltValueField(wireName: 'image_url')
1920
String get imageUrl;
2021

lib/data/remote/response/user_response.g.dart

Lines changed: 6 additions & 7 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

lib/data/user_repository_imp.dart

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -103,6 +103,7 @@ class UserRepositoryImpl implements UserRepository {
103103
() => _remoteDataSource.uploadImage(
104104
image,
105105
userAndToken.user.email,
106+
userAndToken.token,
106107
),
107108
).flatMapResult(
108109
(user) => _execute(

0 commit comments

Comments
 (0)