diff --git a/packages/neon/lib/main.dart b/packages/neon/lib/main.dart index ea796107..2a29a73d 100644 --- a/packages/neon/lib/main.dart +++ b/packages/neon/lib/main.dart @@ -6,6 +6,7 @@ import 'package:neon/app.dart'; import 'package:neon/src/blocs/accounts.dart'; import 'package:neon/src/blocs/push_notifications.dart'; import 'package:neon/src/neon.dart'; +import 'package:package_info_plus/package_info_plus.dart'; import 'package:provider/provider.dart'; import 'package:shared_preferences/shared_preferences.dart'; @@ -25,16 +26,17 @@ Future main() async { FlutterNativeSplash.preserve(widgetsBinding: WidgetsBinding.instance); - await Global.init(); - final sharedPreferences = await SharedPreferences.getInstance(); final platform = await getNeonPlatform(); final requestManager = await getRequestManager(platform); final allAppImplementations = getAppImplementations(sharedPreferences, requestManager, platform); + final packageInfo = await PackageInfo.fromPlatform(); + final globalOptions = GlobalOptions( Storage('global', sharedPreferences), + packageInfo, ); final accountsBloc = AccountsBloc( @@ -42,6 +44,7 @@ Future main() async { Storage('accounts', sharedPreferences), sharedPreferences, globalOptions, + packageInfo, ); final pushNotificationsBloc = PushNotificationsBloc( accountsBloc, @@ -78,6 +81,9 @@ Future main() async { Provider>( create: (final _) => allAppImplementations, ), + Provider( + create: (final _) => packageInfo, + ), ], child: NeonApp( accountsBloc: accountsBloc, diff --git a/packages/neon/lib/src/blocs/accounts.dart b/packages/neon/lib/src/blocs/accounts.dart index 87c157c9..1ba28b1b 100644 --- a/packages/neon/lib/src/blocs/accounts.dart +++ b/packages/neon/lib/src/blocs/accounts.dart @@ -4,6 +4,7 @@ import 'package:neon/src/blocs/user_details.dart'; import 'package:neon/src/blocs/user_status.dart'; import 'package:neon/src/models/account.dart'; import 'package:neon/src/neon.dart'; +import 'package:package_info_plus/package_info_plus.dart'; import 'package:rx_bloc/rx_bloc.dart'; import 'package:rxdart/rxdart.dart'; import 'package:shared_preferences/shared_preferences.dart'; @@ -29,6 +30,7 @@ class AccountsBloc extends $AccountsBloc { this._storage, this._sharedPreferences, this._globalOptions, + this._packageInfo, ) { _accountsSubject.listen((final accounts) async { _globalOptions.updateAccounts(accounts); @@ -53,6 +55,7 @@ class AccountsBloc extends $AccountsBloc { }); _$addAccountEvent.listen((final account) async { + account.setupClient(_packageInfo); if (_activeAccountSubject.valueOrNull == null) { setActiveAccount(account); } @@ -71,6 +74,7 @@ class AccountsBloc extends $AccountsBloc { }); _$updateAccountEvent.listen((final account) async { + account.setupClient(_packageInfo); final accounts = _accountsSubject.value; final index = accounts.indexWhere((final a) => a.id == account.id); if (index == -1) { @@ -92,7 +96,7 @@ class AccountsBloc extends $AccountsBloc { _accountsSubject.add( _storage .getStringList(_keyAccounts)! - .map((final a) => Account.fromJson(json.decode(a) as Map)) + .map((final a) => (Account.fromJson(json.decode(a) as Map))..setupClient(_packageInfo)) .toList(), ); } @@ -126,13 +130,14 @@ class AccountsBloc extends $AccountsBloc { return null; } + final RequestManager _requestManager; final Storage _storage; final SharedPreferences _sharedPreferences; final GlobalOptions _globalOptions; + final PackageInfo _packageInfo; final _keyAccounts = 'accounts'; final _keyLastUsedAccount = 'last-used-account'; - final RequestManager _requestManager; final _accountsOptions = {}; late final _activeAccountSubject = BehaviorSubject.seeded(null); late final _accountsSubject = BehaviorSubject>.seeded([]); diff --git a/packages/neon/lib/src/blocs/login.dart b/packages/neon/lib/src/blocs/login.dart index 81e2e785..6a976279 100644 --- a/packages/neon/lib/src/blocs/login.dart +++ b/packages/neon/lib/src/blocs/login.dart @@ -3,6 +3,7 @@ import 'dart:async'; import 'package:flutter/foundation.dart'; import 'package:neon/src/models/account.dart'; import 'package:nextcloud/nextcloud.dart'; +import 'package:package_info_plus/package_info_plus.dart'; import 'package:rx_bloc/rx_bloc.dart'; import 'package:rxdart/rxdart.dart'; @@ -24,7 +25,7 @@ abstract class LoginBlocStates { @RxBloc() class LoginBloc extends $LoginBloc { - LoginBloc() { + LoginBloc(this._packageInfo) { _$setServerURLEvent.listen((final url) async { _serverURLSubject.add(url); _loginFlowInitSubject.add(null); @@ -35,7 +36,7 @@ class LoginBloc extends $LoginBloc { try { final client = NextcloudClient( url, - userAgentOverride: userAgentOverride(), + userAgentOverride: userAgent(_packageInfo), ); final status = (await client.core.getStatus())!; @@ -74,6 +75,8 @@ class LoginBloc extends $LoginBloc { } } + final PackageInfo _packageInfo; + final _serverURLSubject = BehaviorSubject.seeded(null); final _serverConnectionStateSubject = BehaviorSubject.seeded(null); final _loginFlowInitSubject = BehaviorSubject.seeded(null); diff --git a/packages/neon/lib/src/models/account.dart b/packages/neon/lib/src/models/account.dart index bd9389a7..3d628c96 100644 --- a/packages/neon/lib/src/models/account.dart +++ b/packages/neon/lib/src/models/account.dart @@ -5,12 +5,13 @@ import 'package:json_annotation/json_annotation.dart'; import 'package:neon/l10n/localizations.dart'; import 'package:neon/src/neon.dart'; import 'package:nextcloud/nextcloud.dart'; +import 'package:package_info_plus/package_info_plus.dart'; import 'package:rxdart/rxdart.dart'; import 'package:settings/settings.dart'; part 'account.g.dart'; -String userAgentOverride() => 'Neon ${Global.packageInfo.version}+${Global.packageInfo.buildNumber}'; +String userAgent(PackageInfo packageInfo) => 'Neon ${packageInfo.version}+${packageInfo.buildNumber}'; @JsonSerializable() class Account { @@ -49,12 +50,22 @@ class Account { NextcloudClient? _client; - NextcloudClient get client => _client ??= NextcloudClient( - serverURL, - username: username, - password: password ?? appPassword, - userAgentOverride: userAgentOverride(), - ); + void setupClient(PackageInfo packageInfo) { + _client ??= NextcloudClient( + serverURL, + username: username, + password: password ?? appPassword, + userAgentOverride: userAgent(packageInfo), + ); + } + + NextcloudClient get client { + if (_client == null) { + throw Exception('You need to call setupClient() first'); + } + + return _client!; + } } Map _idCache = {}; diff --git a/packages/neon/lib/src/pages/login/login.dart b/packages/neon/lib/src/pages/login/login.dart index f7a182dd..8428b3f8 100644 --- a/packages/neon/lib/src/pages/login/login.dart +++ b/packages/neon/lib/src/pages/login/login.dart @@ -16,12 +16,16 @@ class _LoginPageState extends State { WebViewController? _webViewController; final _formKey = GlobalKey(); final _focusNode = FocusNode(); - final _loginBloc = LoginBloc(); + late final PackageInfo _packageInfo; + late final LoginBloc _loginBloc; @override void initState() { super.initState(); + _packageInfo = Provider.of(context, listen: false); + _loginBloc = LoginBloc(_packageInfo); + if (widget.serverURL != null) { _loginBloc.setServerURL(widget.serverURL!); } @@ -73,7 +77,7 @@ class _LoginPageState extends State { final Env? env, ) => { - HttpHeaders.userAgentHeader: userAgentOverride(), + HttpHeaders.userAgentHeader: userAgent(_packageInfo), if (env != null) ...{ HttpHeaders.authorizationHeader: 'Basic ${base64.encode(utf8.encode('${env.testUsername}:${env.testPassword}'))}', @@ -137,7 +141,7 @@ class _LoginPageState extends State { ? WebView( javascriptMode: JavascriptMode.unrestricted, zoomEnabled: false, - userAgent: userAgentOverride(), + userAgent: userAgent(_packageInfo), onWebViewCreated: (final controller) async { _webViewController = controller; final url = diff --git a/packages/neon/lib/src/pages/settings/settings.dart b/packages/neon/lib/src/pages/settings/settings.dart index 11a5c243..65f4c00e 100644 --- a/packages/neon/lib/src/pages/settings/settings.dart +++ b/packages/neon/lib/src/pages/settings/settings.dart @@ -249,7 +249,7 @@ class _SettingsPageState extends State { withoutText: true, ), applicationLegalese: await rootBundle.loadString('assets/LEGALESE.txt'), - applicationVersion: (await PackageInfo.fromPlatform()).version, + applicationVersion: Provider.of(context, listen: false).version, ); }, ), diff --git a/packages/neon/lib/src/utils/global.dart b/packages/neon/lib/src/utils/global.dart index 67d87b96..b38951dd 100644 --- a/packages/neon/lib/src/utils/global.dart +++ b/packages/neon/lib/src/utils/global.dart @@ -1,11 +1,6 @@ part of '../neon.dart'; class Global { - static Future init() async { - packageInfo = await PackageInfo.fromPlatform(); - } - - static late PackageInfo packageInfo; static Function()? onPushNotificationReceived; static Function(String? payload)? onPushNotificationClicked; static Future Function(NotificationsNotification notification)? handleNotificationOpening; diff --git a/packages/neon/lib/src/utils/global_options.dart b/packages/neon/lib/src/utils/global_options.dart index 9f39184a..714bc5c4 100644 --- a/packages/neon/lib/src/utils/global_options.dart +++ b/packages/neon/lib/src/utils/global_options.dart @@ -1,7 +1,10 @@ part of '../neon.dart'; class GlobalOptions { - GlobalOptions(this._storage) { + GlobalOptions( + this._storage, + this._packageInfo, + ) { themeMode.stream.listen((final value) { _themeOLEDAsDarkEnabledSubject.add(value != ThemeMode.light); }); @@ -29,13 +32,14 @@ class GlobalOptions { } final Storage _storage; + final PackageInfo _packageInfo; final _accountsIDsSubject = BehaviorSubject>(); final _themeOLEDAsDarkEnabledSubject = BehaviorSubject(); final _pushNotificationsEnabledSubject = BehaviorSubject(); final _pushNotificationsDistributorsSubject = BehaviorSubject>(); - final _distributorsMap = { - Global.packageInfo.packageName: (final context) => + late final _distributorsMap = { + _packageInfo.packageName: (final context) => AppLocalizations.of(context).globalOptionsPushNotificationsDistributorFirebaseEmbedded, 'com.github.gotify.up': (final context) => AppLocalizations.of(context).globalOptionsPushNotificationsDistributorGotifyUP,