Skip to content

Commit 32febd4

Browse files
committed
Use a common HTTP Client.
1 parent a4ec196 commit 32febd4

File tree

10 files changed

+91
-51
lines changed

10 files changed

+91
-51
lines changed

example/lib/main.dart

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -94,7 +94,7 @@ class _MyAppState extends State<MyApp> {
9494
name: 'Pricing Card',
9595
builder: (context) {
9696
return CodelesslyWidget(
97-
layoutID: '0RZGVlSiIb7yITaXrIxo',
97+
layoutID: '0RbIfjMG9TmGHNt4FmNI',
9898
loadingBuilder: (context) {
9999
return const CupertinoActivityIndicator();
100100
},

lib/src/auth/codelessly_auth_manager.dart

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ import 'dart:io';
44

55
import 'package:firebase_auth/firebase_auth.dart';
66
import 'package:flutter/foundation.dart';
7-
import 'package:http/http.dart';
7+
import 'package:http/http.dart' as http;
88
import 'package:jwt_decoder/jwt_decoder.dart';
99

1010
import '../../codelessly_sdk.dart';
@@ -16,6 +16,9 @@ class CodelesslyAuthManager extends AuthManager {
1616
/// The configuration used to authenticate the token.
1717
final CodelesslyConfig config;
1818

19+
/// The client used to make HTTP requests.
20+
final http.Client client;
21+
1922
/// The cache manager used to store the auth data after authentication.
2023
final CacheManager cacheManager;
2124

@@ -63,6 +66,7 @@ class CodelesslyAuthManager extends AuthManager {
6366
required this.cacheManager,
6467
required this.firebaseAuth,
6568
required this.errorHandler,
69+
required this.client,
6670
AuthData? authData,
6771
}) : _authData = authData {
6872
if (_authData != null) {
@@ -305,6 +309,7 @@ class CodelesslyAuthManager extends AuthManager {
305309
final AuthData? authData = await verifyProjectAuthToken(
306310
userToken: _idTokenResult!.token!,
307311
config: config,
312+
client: client,
308313
postSuccess: postAuthSuccess,
309314
);
310315

@@ -358,6 +363,7 @@ class CodelesslyAuthManager extends AuthManager {
358363
static Future<AuthData?> verifyProjectAuthToken({
359364
required String userToken,
360365
required CodelesslyConfig config,
366+
required http.Client client,
361367
required Future<void> Function(AuthData authData) postSuccess,
362368
}) async {
363369
const String label = 'verifyProjectAuthToken';
@@ -371,9 +377,8 @@ class CodelesslyAuthManager extends AuthManager {
371377
);
372378

373379
try {
374-
// TODO(Saad): Use an HTTP client.
375380
// Make a POST request to the server to verify the token.
376-
final Response result = await post(
381+
final http.Response result = await client.post(
377382
Uri.parse(
378383
'${config.firebaseCloudFunctionsBaseURL}/api/verifyProjectAuthToken'),
379384
headers: <String, String>{

lib/src/codelessly.dart

Lines changed: 16 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -6,9 +6,11 @@ import 'package:collection/collection.dart';
66
import 'package:firebase_auth/firebase_auth.dart';
77
import 'package:firebase_core/firebase_core.dart';
88
import 'package:flutter/widgets.dart';
9+
import 'package:http/http.dart';
910

1011
import '../codelessly_sdk.dart';
1112
import 'logging/reporter.dart';
13+
import 'utils/codelessly_http_client.dart';
1214

1315
typedef NavigationListener = void Function(BuildContext context);
1416
typedef BreakpointsListener = void Function(
@@ -34,6 +36,11 @@ class Codelessly {
3436
/// Initialization is needed before usage.
3537
static Codelessly get instance => _instance;
3638

39+
final Client _client = CodelesslyHttpClient();
40+
41+
/// Returns the HTTP client used by this SDK instance.
42+
Client get client => _client;
43+
3744
CodelesslyConfig? _config;
3845

3946
/// Returns the configuration options provided to this SDK.
@@ -126,7 +133,7 @@ class Codelessly {
126133
final StreamController<CStatus> _statusStreamController =
127134
StreamController.broadcast()..add(CStatus.empty());
128135

129-
final StatTracker _tracker = CodelesslyStatTracker();
136+
late final StatTracker _tracker = CodelesslyStatTracker(client: _client);
130137

131138
/// Tracks statistics of various operations in the SDK.
132139
StatTracker get tracker => _tracker;
@@ -229,6 +236,7 @@ class Codelessly {
229236
_previewDataManager = null;
230237
_config = null;
231238
_navigationListeners.clear();
239+
_client.close();
232240
}
233241

234242
/// Resets the state of the SDK. This is useful for resetting the data without
@@ -549,6 +557,7 @@ class Codelessly {
549557
config: _config!,
550558
cacheManager: _cacheManager!,
551559
firebaseAuth: _firebaseAuth!,
560+
client: _client,
552561
errorHandler: errorHandler,
553562
);
554563

@@ -561,15 +570,15 @@ class Codelessly {
561570
authManager: _authManager!,
562571
networkDataRepository: FirebaseDataRepository(
563572
firestore: firebaseFirestore,
564-
tracker: tracker,
573+
tracker: _tracker,
565574
config: _config!,
566575
),
567576
localDataRepository: LocalDataRepository(
568577
cacheManager: _cacheManager!,
569578
),
570579
firebaseFirestore: firebaseFirestore,
571580
errorHandler: errorHandler,
572-
tracker: tracker,
581+
tracker: _tracker,
573582
);
574583

575584
// Create the preview data manager.
@@ -582,14 +591,14 @@ class Codelessly {
582591
networkDataRepository: FirebaseDataRepository(
583592
firestore: firebaseFirestore,
584593
config: _config!,
585-
tracker: tracker,
594+
tracker: _tracker,
586595
),
587596
localDataRepository: LocalDataRepository(
588597
cacheManager: _cacheManager!,
589598
),
590599
firebaseFirestore: firebaseFirestore,
591600
errorHandler: errorHandler,
592-
tracker: tracker,
601+
tracker: _tracker,
593602
);
594603

595604
// Create the template data manager. This is always automatically
@@ -606,14 +615,14 @@ class Codelessly {
606615
networkDataRepository: FirebaseDataRepository(
607616
firestore: firebaseFirestore,
608617
config: _config!,
609-
tracker: tracker,
618+
tracker: _tracker,
610619
),
611620
localDataRepository: LocalDataRepository(
612621
cacheManager: _cacheManager!,
613622
),
614623
firebaseFirestore: firebaseFirestore,
615624
errorHandler: errorHandler,
616-
tracker: tracker,
625+
tracker: _tracker,
617626
);
618627

619628
_updateStatus(CStatus.loading(CLoadingState.createdManagers));

lib/src/constants.dart

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,7 @@ const String templatesPath = 'templates';
5858
/// STAT TRACKING
5959
const String statsCollection = 'stats';
6060
const String lostStatsDoc = '_lost';
61-
const String loadsField = 'loads';
61+
const String viewsField = 'views';
6262
const String writesField = 'writes';
6363
const String readsField = 'reads';
6464
const String bundleDownloadsField = 'bundle_downloads';

lib/src/data/firebase_data_repository.dart

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -53,13 +53,17 @@ class FirebaseDataRepository extends NetworkDataRepository {
5353
.doc(layoutID);
5454

5555
return layoutDoc.get().then((value) {
56+
if (!value.exists) {
57+
throw CodelesslyException('Layout [$layoutID] does not exist.');
58+
}
5659
tracker.trackRead('${source.serverPath}/downloadLayoutModel');
5760

5861
final Map<String, dynamic> data = value.data() ?? {};
5962

6063
// Layout does not exist or there's a network error.
6164
if (data.isEmpty) {
62-
throw CodelesslyException('Failed to download layout [$layoutID].');
65+
throw CodelesslyException(
66+
'Failed to download layout [$layoutID], no data found.');
6367
}
6468

6569
final SDKPublishLayout layout = SDKPublishLayout.fromJson(

lib/src/data/web_data_repository.dart

Lines changed: 10 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -2,30 +2,29 @@ import 'dart:async';
22
import 'dart:convert';
33
import 'dart:developer';
44

5-
import 'package:http/http.dart';
5+
import 'package:http/http.dart' as http;
66

77
import '../../codelessly_sdk.dart';
88

99
/// A [NetworkDataRepository] implementation that utilizes the Firebase Cloud
1010
/// Functions to retrieve the relevant data.
11-
///
12-
/// Since Firedart is not compatible with Flutter Web, this implementation
13-
/// utilizes the http package instead.
1411
@Deprecated('Use [FirebaseDataRepository] instead.')
1512
class WebDataRepository extends NetworkDataRepository {
13+
final http.Client client;
14+
1615
/// Creates a [WebDataRepository] instance.
1716
WebDataRepository({
1817
required super.config,
1918
required super.tracker,
19+
required this.client,
2020
});
2121

2222
@override
2323
Stream<SDKPublishModel?> streamPublishModel({
2424
required String projectID,
2525
required PublishSource source,
2626
}) async* {
27-
// TODO(Saad): Use an HTTP client.
28-
final Response result = await post(
27+
final http.Response result = await client.post(
2928
Uri.parse(
3029
'${config.firebaseCloudFunctionsBaseURL}/api/getPublishModelRequest'),
3130
headers: <String, String>{'Content-Type': 'application/json'},
@@ -57,8 +56,7 @@ class WebDataRepository extends NetworkDataRepository {
5756
required String layoutID,
5857
required PublishSource source,
5958
}) async {
60-
// TODO(Saad): Use an HTTP client.
61-
final Response result = await post(
59+
final http.Response result = await client.post(
6260
Uri.parse(
6361
'${config.firebaseCloudFunctionsBaseURL}/api/getLayoutModelRequest'),
6462
headers: <String, String>{'Content-Type': 'application/json'},
@@ -94,8 +92,7 @@ class WebDataRepository extends NetworkDataRepository {
9492
required PublishSource source,
9593
}) async {
9694
try {
97-
// TODO(Saad): Use an HTTP client.
98-
final Response result = await post(
95+
final http.Response result = await client.post(
9996
Uri.parse(
10097
'${config.firebaseCloudFunctionsBaseURL}/api/getFontModelRequest'),
10198
headers: <String, String>{'Content-Type': 'application/json'},
@@ -132,8 +129,7 @@ class WebDataRepository extends NetworkDataRepository {
132129
required PublishSource source,
133130
}) async {
134131
try {
135-
// TODO(Saad): Use an HTTP client.
136-
final Response result = await post(
132+
final http.Response result = await client.post(
137133
Uri.parse(
138134
'${config.firebaseCloudFunctionsBaseURL}/api/getPublishedApiRequest'),
139135
headers: <String, String>{'Content-Type': 'application/json'},
@@ -172,8 +168,7 @@ class WebDataRepository extends NetworkDataRepository {
172168
required PublishSource source,
173169
}) async {
174170
try {
175-
// TODO(Saad): Use an HTTP client.
176-
final Response result = await post(
171+
final http.Response result = await client.post(
177172
Uri.parse(
178173
'${config.firebaseCloudFunctionsBaseURL}/api/getPublishedLayoutVariablesRequest'),
179174
headers: <String, String>{'Content-Type': 'application/json'},
@@ -214,8 +209,7 @@ class WebDataRepository extends NetworkDataRepository {
214209
}) async {
215210
log('[WebDataRepo] Downloading conditions for $layoutID');
216211
try {
217-
// TODO(Saad): Use an HTTP client.
218-
final Response result = await post(
212+
final http.Response result = await client.post(
219213
Uri.parse(
220214
'${config.firebaseCloudFunctionsBaseURL}/api/getPublishedLayoutConditionsRequest'),
221215
headers: <String, String>{'Content-Type': 'application/json'},

lib/src/functions/functions_repository.dart

Lines changed: 13 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -403,14 +403,17 @@ class FunctionsRepository {
403403
try {
404404
final http.Response response;
405405
if (kIsWeb && useCloudFunctionForWeb) {
406+
final codelessly = context.read<Codelessly>();
407+
final client = codelessly.client;
406408
final String cloudFunctionsURL =
407-
context.read<Codelessly>().config!.firebaseCloudFunctionsBaseURL;
409+
codelessly.config!.firebaseCloudFunctionsBaseURL;
408410
final receivedResponse = await makeApiRequestWeb(
409411
method: method,
410412
url: url,
411413
headers: headers,
412414
body: body,
413415
cloudFunctionsURL: cloudFunctionsURL,
416+
client: client,
414417
);
415418

416419
// cloud function returns actual response in body.
@@ -422,14 +425,16 @@ class FunctionsRepository {
422425
reasonPhrase: actualResponse['reasonPhrase']?.toString(),
423426
);
424427
} else {
425-
// TODO(Saad): Use an HTTP client.
428+
final codelessly = context.read<Codelessly>();
429+
final client = codelessly.client;
426430
final Uri uri = Uri.parse(url);
427431
response = switch (method) {
428-
HttpMethod.get => await http.get(uri, headers: headers),
429-
HttpMethod.post => await http.post(uri, headers: headers, body: body),
432+
HttpMethod.get => await client.get(uri, headers: headers),
433+
HttpMethod.post =>
434+
await client.post(uri, headers: headers, body: body),
430435
HttpMethod.delete =>
431-
await http.delete(uri, headers: headers, body: body),
432-
HttpMethod.put => await http.put(uri, headers: headers, body: body)
436+
await client.delete(uri, headers: headers, body: body),
437+
HttpMethod.put => await client.put(uri, headers: headers, body: body)
433438
};
434439
}
435440

@@ -522,9 +527,9 @@ ${response.body.contains('{') ? const JsonEncoder.withIndent(' ').convert(json.
522527
required Map<String, dynamic> headers,
523528
required Object? body,
524529
required String cloudFunctionsURL,
530+
required http.Client client,
525531
}) async {
526-
// TODO(Saad): Use an HTTP client.
527-
return http.post(
532+
return client.post(
528533
Uri.parse('$cloudFunctionsURL/makeApiRequest'),
529534
headers: {'content-type': 'application/json'},
530535
body: jsonEncode({

0 commit comments

Comments
 (0)