diff --git a/packages/dynamite/lib/src/openapi_builder.dart b/packages/dynamite/lib/src/openapi_builder.dart index 633589b1..9f8e41b9 100644 --- a/packages/dynamite/lib/src/openapi_builder.dart +++ b/packages/dynamite/lib/src/openapi_builder.dart @@ -34,13 +34,45 @@ class OpenAPIBuilder implements Builder { final registeredJsonObjects = []; final output = [ "import 'dart:convert';", + "import 'dart:io';", "import 'dart:typed_data';", '', - "import 'package:http/http.dart' as http;", + "import 'package:cookie_jar/cookie_jar.dart';", "import 'package:json_annotation/json_annotation.dart';", '', + "export 'package:cookie_jar/cookie_jar.dart';", + '', "part '${p.basename(outputId.changeExtension('.g.dart').path)}';", '', + Extension( + (final b) => b + ..name = 'HttpClientResponseBody' + ..on = refer('HttpClientResponse') + ..methods.addAll([ + Method( + (final b) => b + ..name = 'bodyBytes' + ..returns = refer('Future') + ..type = MethodType.getter + ..modifier = MethodModifier.async + ..lambda = true + ..body = const Code( + 'Uint8List.fromList((await toList()).reduce((final value, final element) => [...value, ...element]))', + ), + ), + Method( + (final b) => b + ..name = 'body' + ..returns = refer('Future') + ..type = MethodType.getter + ..modifier = MethodModifier.async + ..lambda = true + ..body = const Code( + 'utf8.decode(await bodyBytes)', + ), + ), + ]), + ).accept(emitter).toString(), Class( (final b) => b ..name = 'Response' @@ -707,6 +739,19 @@ class OpenAPIBuilder implements Builder { ..modifier = FieldModifier.final$ ..late = true, ), + Field( + (final b) => b + ..name = 'httpClient' + ..type = refer('HttpClient') + ..modifier = FieldModifier.final$ + ..late = true, + ), + Field( + (final b) => b + ..name = 'cookieJar' + ..type = refer('CookieJar?') + ..modifier = FieldModifier.final$, + ), if (hasAnySecurity) ...[ Field( (final b) => b @@ -733,6 +778,18 @@ class OpenAPIBuilder implements Builder { ..type = refer('Map?') ..named = true, ), + Parameter( + (final b) => b + ..name = 'httpClient' + ..type = refer('HttpClient?') + ..named = true, + ), + Parameter( + (final b) => b + ..name = 'cookieJar' + ..toThis = true + ..named = true, + ), if (hasAnySecurity) ...[ Parameter( (final b) => b @@ -753,6 +810,7 @@ class OpenAPIBuilder implements Builder { }, ''' : ''} }; + this.httpClient = httpClient ?? HttpClient(); '''), ), ) @@ -797,18 +855,30 @@ class OpenAPIBuilder implements Builder { ), ]) ..body = const Code(r''' - final request = http.Request(method, Uri.parse('$baseURL$path')); - request.headers.addAll(baseHeaders); - request.headers.addAll(headers); + final uri = Uri.parse('$baseURL$path'); + final request = await httpClient.openUrl(method, uri); + for (final header in {...baseHeaders, ...headers}.entries) { + request.headers.add(header.key, header.value); + } if (body != null) { - request.bodyBytes = body.toList(); + request.add(body.toList()); + } + if (cookieJar != null) { + request.cookies.addAll(await cookieJar!.loadForRequest(uri)); + } + + final response = await request.close(); + if (cookieJar != null) { + await cookieJar!.saveFromResponse(uri, response.cookies); } - - final response = await http.Response.fromStream(await request.send()); + final responseHeaders = {}; + response.headers.forEach((final name, final values) { + responseHeaders[name] = values.last; + }); return Response( response.statusCode, - response.headers, - response.bodyBytes, + responseHeaders, + await response.bodyBytes, ); '''), ), diff --git a/packages/neon/integration_test/screenshot_test.dart b/packages/neon/integration_test/screenshot_test.dart index 483092c6..ee81c5a4 100644 --- a/packages/neon/integration_test/screenshot_test.dart +++ b/packages/neon/integration_test/screenshot_test.dart @@ -108,7 +108,7 @@ Future pumpAppPage( final allAppImplementations = getAppImplementations(sharedPreferences, requestManager, platform); final globalOptions = GlobalOptions( - Storage('global', sharedPreferences), + AppStorage('global', sharedPreferences), packageInfo, ); await globalOptions.pushNotificationsEnabled.set(false); @@ -116,7 +116,7 @@ Future pumpAppPage( final accountsBloc = AccountsBloc( requestManager, platform, - Storage('accounts', sharedPreferences), + AppStorage('accounts', sharedPreferences), sharedPreferences, globalOptions, packageInfo, diff --git a/packages/neon/lib/main.dart b/packages/neon/lib/main.dart index 4549514b..0032f061 100644 --- a/packages/neon/lib/main.dart +++ b/packages/neon/lib/main.dart @@ -36,14 +36,14 @@ Future main() async { final packageInfo = await PackageInfo.fromPlatform(); final globalOptions = GlobalOptions( - Storage('global', sharedPreferences), + AppStorage('global', sharedPreferences), packageInfo, ); final accountsBloc = AccountsBloc( requestManager, platform, - Storage('accounts', sharedPreferences), + AppStorage('accounts', sharedPreferences), sharedPreferences, globalOptions, packageInfo, diff --git a/packages/neon/lib/src/apps/files/app.dart b/packages/neon/lib/src/apps/files/app.dart index 2915de6f..1ad08e08 100644 --- a/packages/neon/lib/src/apps/files/app.dart +++ b/packages/neon/lib/src/apps/files/app.dart @@ -48,7 +48,7 @@ class FilesApp extends AppImplementation { String nameFromLocalization(final AppLocalizations localizations) => localizations.filesName; @override - FilesAppSpecificOptions buildOptions(final Storage storage) => FilesAppSpecificOptions(storage); + FilesAppSpecificOptions buildOptions(final AppStorage storage) => FilesAppSpecificOptions(storage); @override FilesBloc buildBloc(final NextcloudClient client) => FilesBloc( diff --git a/packages/neon/lib/src/apps/news/app.dart b/packages/neon/lib/src/apps/news/app.dart index f822727c..8e8b16a8 100644 --- a/packages/neon/lib/src/apps/news/app.dart +++ b/packages/neon/lib/src/apps/news/app.dart @@ -56,7 +56,7 @@ class NewsApp extends AppImplementation { String nameFromLocalization(final AppLocalizations localizations) => localizations.newsName; @override - NewsAppSpecificOptions buildOptions(final Storage storage) => NewsAppSpecificOptions(storage, platform); + NewsAppSpecificOptions buildOptions(final AppStorage storage) => NewsAppSpecificOptions(storage, platform); @override NewsBloc buildBloc(final NextcloudClient client) => NewsBloc( diff --git a/packages/neon/lib/src/apps/notes/app.dart b/packages/neon/lib/src/apps/notes/app.dart index fd7b30d8..a4132af5 100644 --- a/packages/neon/lib/src/apps/notes/app.dart +++ b/packages/neon/lib/src/apps/notes/app.dart @@ -45,7 +45,7 @@ class NotesApp extends AppImplementation { String nameFromLocalization(final AppLocalizations localizations) => localizations.notesName; @override - NotesAppSpecificOptions buildOptions(final Storage storage) => NotesAppSpecificOptions(storage); + NotesAppSpecificOptions buildOptions(final AppStorage storage) => NotesAppSpecificOptions(storage); @override NotesBloc buildBloc(final NextcloudClient client) => NotesBloc( diff --git a/packages/neon/lib/src/apps/notifications/app.dart b/packages/neon/lib/src/apps/notifications/app.dart index 2a3cb8cb..c0a8d94f 100644 --- a/packages/neon/lib/src/apps/notifications/app.dart +++ b/packages/neon/lib/src/apps/notifications/app.dart @@ -25,7 +25,7 @@ class NotificationsApp extends AppImplementation localizations.notificationsName; @override - NotificationsAppSpecificOptions buildOptions(final Storage storage) => NotificationsAppSpecificOptions(storage); + NotificationsAppSpecificOptions buildOptions(final AppStorage storage) => NotificationsAppSpecificOptions(storage); @override NotificationsBloc buildBloc(final NextcloudClient client) => NotificationsBloc( diff --git a/packages/neon/lib/src/blocs/accounts.dart b/packages/neon/lib/src/blocs/accounts.dart index a2b8d3f1..88c73c71 100644 --- a/packages/neon/lib/src/blocs/accounts.dart +++ b/packages/neon/lib/src/blocs/accounts.dart @@ -123,7 +123,7 @@ class AccountsBloc extends $AccountsBloc { } AccountSpecificOptions getOptions(final Account account) => _accountsOptions[account.id] ??= AccountSpecificOptions( - Storage('accounts-${account.id}', _sharedPreferences), + AppStorage('accounts-${account.id}', _sharedPreferences), getAppsBloc(account), ); @@ -177,7 +177,7 @@ class AccountsBloc extends $AccountsBloc { final RequestManager _requestManager; final NeonPlatform _platform; - final Storage _storage; + final AppStorage _storage; final SharedPreferences _sharedPreferences; final GlobalOptions _globalOptions; final List _allAppImplementations; diff --git a/packages/neon/lib/src/blocs/push_notifications.dart b/packages/neon/lib/src/blocs/push_notifications.dart index b5b72580..030dd204 100644 --- a/packages/neon/lib/src/blocs/push_notifications.dart +++ b/packages/neon/lib/src/blocs/push_notifications.dart @@ -126,7 +126,7 @@ class PushNotificationsBloc extends $PushNotificationsBloc { final AccountsBloc _accountsBloc; final NeonPlatform _platform; final SharedPreferences _sharedPreferences; - late final _storage = Storage('notifications', _sharedPreferences); + late final _storage = AppStorage('notifications', _sharedPreferences); final GlobalOptions _globalOptions; final Env? _env; RSAKeypair? _keypair; diff --git a/packages/neon/lib/src/utils/account_options.dart b/packages/neon/lib/src/utils/account_options.dart index b1f41d03..c5b2b35d 100644 --- a/packages/neon/lib/src/utils/account_options.dart +++ b/packages/neon/lib/src/utils/account_options.dart @@ -17,7 +17,7 @@ class AccountSpecificOptions { }); } - final Storage _storage; + final AppStorage _storage; final AppsBloc _appsBloc; final _appIDsSubject = BehaviorSubject>(); diff --git a/packages/neon/lib/src/utils/app_implementation.dart b/packages/neon/lib/src/utils/app_implementation.dart index 9bbb63b5..cc8b3eb4 100644 --- a/packages/neon/lib/src/utils/app_implementation.dart +++ b/packages/neon/lib/src/utils/app_implementation.dart @@ -18,7 +18,7 @@ abstract class AppImplementation nameFromLocalization(AppLocalizations.of(context)); late final R options; - R buildOptions(final Storage storage); + R buildOptions(final AppStorage storage); T buildBloc(final NextcloudClient client); diff --git a/packages/neon/lib/src/utils/global_options.dart b/packages/neon/lib/src/utils/global_options.dart index bf5b3969..529b410f 100644 --- a/packages/neon/lib/src/utils/global_options.dart +++ b/packages/neon/lib/src/utils/global_options.dart @@ -35,7 +35,7 @@ class GlobalOptions { }); } - final Storage _storage; + final AppStorage _storage; final PackageInfo _packageInfo; final _themeOLEDAsDarkEnabledSubject = BehaviorSubject(); final _pushNotificationsEnabledEnabledSubject = BehaviorSubject(); diff --git a/packages/neon/lib/src/utils/nextcloud_app_specific_options.dart b/packages/neon/lib/src/utils/nextcloud_app_specific_options.dart index cb55a9f7..93c47157 100644 --- a/packages/neon/lib/src/utils/nextcloud_app_specific_options.dart +++ b/packages/neon/lib/src/utils/nextcloud_app_specific_options.dart @@ -3,7 +3,7 @@ part of '../neon.dart'; abstract class NextcloudAppSpecificOptions { NextcloudAppSpecificOptions(this.storage); - final Storage storage; + final AppStorage storage; late final List categories; late final List