Browse Source

neon: Show suggestion to install NextPush if supported

pull/208/head
jld3103 2 years ago
parent
commit
6e75d850a4
No known key found for this signature in database
GPG Key ID: 9062417B9E8EB7B3
  1. 8
      packages/neon/integration_test/screenshot_test.dart
  2. 5
      packages/neon/lib/l10n/en.arb
  3. 30
      packages/neon/lib/l10n/localizations.dart
  4. 16
      packages/neon/lib/l10n/localizations_en.dart
  5. 4
      packages/neon/lib/main.dart
  6. 77
      packages/neon/lib/src/blocs/next_push.dart
  7. 1
      packages/neon/lib/src/neon.dart
  8. 32
      packages/neon/lib/src/pages/home.dart
  9. 4
      packages/neon/lib/src/utils/global_options.dart

8
packages/neon/integration_test/screenshot_test.dart

@ -132,6 +132,11 @@ Future pumpAppPage(
sharedPreferences, sharedPreferences,
disabled: true, disabled: true,
); );
final nextPushBloc = NextPushBloc(
accountsBloc,
globalOptions,
disabled: true,
);
// ignore: close_sinks // ignore: close_sinks
final userThemeStream = BehaviorSubject<NextcloudTheme?>(); final userThemeStream = BehaviorSubject<NextcloudTheme?>();
@ -163,6 +168,9 @@ Future pumpAppPage(
Provider<FirstLaunchBloc>( Provider<FirstLaunchBloc>(
create: (final _) => firstLaunchBloc, create: (final _) => firstLaunchBloc,
), ),
Provider<NextPushBloc>(
create: (final _) => nextPushBloc,
),
Provider<List<AppImplementation>>( Provider<List<AppImplementation>>(
create: (final _) => allAppImplementations, create: (final _) => allAppImplementations,
), ),

5
packages/neon/lib/l10n/en.arb

@ -51,6 +51,10 @@
"showSlashHide": "Show/Hide", "showSlashHide": "Show/Hide",
"exit": "Exit", "exit": "Exit",
"disabled": "Disabled", "disabled": "Disabled",
"firstLaunchGoToSettingsToEnablePushNotifications": "Go to the settings to enable push notifications",
"nextPushSupported": "NextPush is supported!",
"nextPushSupportedText": "NextPush is a FOSS way of receiving push notifications using the UnifiedPush protocol via a Nextcloud instance.\nYou can install NextPush from the F-Droid app store.",
"nextPushSupportedInstall": "Install NextPush",
"settings": "Settings", "settings": "Settings",
"settingsApps": "Apps", "settingsApps": "Apps",
"settingsExport": "Export settings", "settingsExport": "Export settings",
@ -65,7 +69,6 @@
} }
} }
}, },
"settingsGoToSettingsToEnablePushNotifications": "Go to the settings to enable push notifications",
"optionsCategoryGeneral": "General", "optionsCategoryGeneral": "General",
"optionsCategoryTheme": "Theme", "optionsCategoryTheme": "Theme",
"optionsCategoryPushNotifications": "Push notifications", "optionsCategoryPushNotifications": "Push notifications",

30
packages/neon/lib/l10n/localizations.dart

@ -269,6 +269,30 @@ abstract class AppLocalizations {
/// **'Disabled'** /// **'Disabled'**
String get disabled; String get disabled;
/// No description provided for @firstLaunchGoToSettingsToEnablePushNotifications.
///
/// In en, this message translates to:
/// **'Go to the settings to enable push notifications'**
String get firstLaunchGoToSettingsToEnablePushNotifications;
/// No description provided for @nextPushSupported.
///
/// In en, this message translates to:
/// **'NextPush is supported!'**
String get nextPushSupported;
/// No description provided for @nextPushSupportedText.
///
/// In en, this message translates to:
/// **'NextPush is a FOSS way of receiving push notifications using the UnifiedPush protocol via a Nextcloud instance.\nYou can install NextPush from the F-Droid app store.'**
String get nextPushSupportedText;
/// No description provided for @nextPushSupportedInstall.
///
/// In en, this message translates to:
/// **'Install NextPush'**
String get nextPushSupportedInstall;
/// No description provided for @settings. /// No description provided for @settings.
/// ///
/// In en, this message translates to: /// In en, this message translates to:
@ -311,12 +335,6 @@ abstract class AppLocalizations {
/// **'Do you want to reset all settings for {name}?'** /// **'Do you want to reset all settings for {name}?'**
String settingsResetForConfirmation(String name); String settingsResetForConfirmation(String name);
/// No description provided for @settingsGoToSettingsToEnablePushNotifications.
///
/// In en, this message translates to:
/// **'Go to the settings to enable push notifications'**
String get settingsGoToSettingsToEnablePushNotifications;
/// No description provided for @optionsCategoryGeneral. /// No description provided for @optionsCategoryGeneral.
/// ///
/// In en, this message translates to: /// In en, this message translates to:

16
packages/neon/lib/l10n/localizations_en.dart

@ -103,6 +103,19 @@ class AppLocalizationsEn extends AppLocalizations {
@override @override
String get disabled => 'Disabled'; String get disabled => 'Disabled';
@override
String get firstLaunchGoToSettingsToEnablePushNotifications => 'Go to the settings to enable push notifications';
@override
String get nextPushSupported => 'NextPush is supported!';
@override
String get nextPushSupportedText =>
'NextPush is a FOSS way of receiving push notifications using the UnifiedPush protocol via a Nextcloud instance.\nYou can install NextPush from the F-Droid app store.';
@override
String get nextPushSupportedInstall => 'Install NextPush';
@override @override
String get settings => 'Settings'; String get settings => 'Settings';
@ -126,9 +139,6 @@ class AppLocalizationsEn extends AppLocalizations {
return 'Do you want to reset all settings for $name?'; return 'Do you want to reset all settings for $name?';
} }
@override
String get settingsGoToSettingsToEnablePushNotifications => 'Go to the settings to enable push notifications';
@override @override
String get optionsCategoryGeneral => 'General'; String get optionsCategoryGeneral => 'General';

4
packages/neon/lib/main.dart

@ -55,6 +55,7 @@ Future main() async {
platform, platform,
); );
final firstLaunchBloc = FirstLaunchBloc(sharedPreferences); final firstLaunchBloc = FirstLaunchBloc(sharedPreferences);
final nextPushBloc = NextPushBloc(accountsBloc, globalOptions);
runApp( runApp(
MultiProvider( MultiProvider(
@ -83,6 +84,9 @@ Future main() async {
Provider<FirstLaunchBloc>( Provider<FirstLaunchBloc>(
create: (final _) => firstLaunchBloc, create: (final _) => firstLaunchBloc,
), ),
Provider<NextPushBloc>(
create: (final _) => nextPushBloc,
),
Provider<List<AppImplementation>>( Provider<List<AppImplementation>>(
create: (final _) => allAppImplementations, create: (final _) => allAppImplementations,
), ),

77
packages/neon/lib/src/blocs/next_push.dart

@ -0,0 +1,77 @@
part of '../neon.dart';
abstract class NextPushBlocEvents {}
abstract class NextPushBlocStates {
BehaviorSubject get onNextPushSupported;
}
class NextPushBloc extends Bloc implements NextPushBlocEvents, NextPushBlocStates {
NextPushBloc(
this._accountsBloc,
this._globalOptions, {
final bool disabled = false,
}) {
if (disabled) {
return;
}
Rx.merge([
_globalOptions.pushNotificationsEnabled.stream,
_globalOptions.pushNotificationsDistributor.stream,
_globalOptions.pushNotificationsDistributor.values,
_accountsBloc.accounts,
]).debounceTime(const Duration(milliseconds: 100)).listen((final _) async {
if (!_globalOptions.pushNotificationsEnabled.enabled.hasValue ||
!_globalOptions.pushNotificationsEnabled.enabled.value ||
!_globalOptions.pushNotificationsEnabled.hasValue ||
!_globalOptions.pushNotificationsEnabled.value) {
return;
}
if (_globalOptions.pushNotificationsDistributor.value != null) {
return;
}
if (_globalOptions.pushNotificationsDistributor.values.value.containsKey(unifiedPushNextPushID)) {
// NextPush is already installed
return;
}
var supported = false;
for (final account in _accountsBloc.accounts.value) {
if (!_supported.containsKey(account)) {
try {
_supported[account] = (await account.client.unifiedPushProvider.check()).success;
} catch (e, s) {
debugPrint(e.toString());
debugPrint(s.toString());
_supported[account] = false;
}
}
if (_supported[account]!) {
supported = true;
break;
}
}
if (!supported) {
return;
}
if (onNextPushSupported.hasValue) {
return;
}
onNextPushSupported.add(null);
});
}
final AccountsBloc _accountsBloc;
final GlobalOptions _globalOptions;
final _supported = <Account, bool>{};
@override
void dispose() {
unawaited(onNextPushSupported.close());
}
@override
BehaviorSubject onNextPushSupported = BehaviorSubject();
}

1
packages/neon/lib/src/neon.dart

@ -52,6 +52,7 @@ part 'blocs/apps.dart';
part 'blocs/capabilities.dart'; part 'blocs/capabilities.dart';
part 'blocs/first_launch.dart'; part 'blocs/first_launch.dart';
part 'blocs/login.dart'; part 'blocs/login.dart';
part 'blocs/next_push.dart';
part 'blocs/push_notifications.dart'; part 'blocs/push_notifications.dart';
part 'blocs/user_details.dart'; part 'blocs/user_details.dart';
part 'blocs/user_status.dart'; part 'blocs/user_status.dart';

32
packages/neon/lib/src/pages/home.dart

@ -25,6 +25,7 @@ class _HomePageState extends State<HomePage> {
late AppsBloc _appsBloc; late AppsBloc _appsBloc;
late CapabilitiesBloc _capabilitiesBloc; late CapabilitiesBloc _capabilitiesBloc;
late FirstLaunchBloc _firstLaunchBloc; late FirstLaunchBloc _firstLaunchBloc;
late NextPushBloc _nextPushBloc;
@override @override
void initState() { void initState() {
@ -35,6 +36,7 @@ class _HomePageState extends State<HomePage> {
_appsBloc = _accountsBloc.getAppsBloc(widget.account); _appsBloc = _accountsBloc.getAppsBloc(widget.account);
_capabilitiesBloc = _accountsBloc.getCapabilitiesBloc(widget.account); _capabilitiesBloc = _accountsBloc.getCapabilitiesBloc(widget.account);
_firstLaunchBloc = Provider.of<FirstLaunchBloc>(context, listen: false); _firstLaunchBloc = Provider.of<FirstLaunchBloc>(context, listen: false);
_nextPushBloc = Provider.of<NextPushBloc>(context, listen: false);
_appsBloc.openNotifications.listen((final _) async { _appsBloc.openNotifications.listen((final _) async {
final notificationsAppImplementation = _appsBloc.notificationsAppImplementation.valueOrNull; final notificationsAppImplementation = _appsBloc.notificationsAppImplementation.valueOrNull;
@ -101,7 +103,7 @@ class _HomePageState extends State<HomePage> {
_firstLaunchBloc.onFirstLaunch.listen((final _) { _firstLaunchBloc.onFirstLaunch.listen((final _) {
ScaffoldMessenger.of(context).showSnackBar( ScaffoldMessenger.of(context).showSnackBar(
SnackBar( SnackBar(
content: Text(AppLocalizations.of(context).settingsGoToSettingsToEnablePushNotifications), content: Text(AppLocalizations.of(context).firstLaunchGoToSettingsToEnablePushNotifications),
action: SnackBarAction( action: SnackBarAction(
label: AppLocalizations.of(context).settings, label: AppLocalizations.of(context).settings,
onPressed: () async { onPressed: () async {
@ -116,6 +118,34 @@ class _HomePageState extends State<HomePage> {
); );
}); });
_nextPushBloc.onNextPushSupported.listen((final _) async {
await showDialog(
context: context,
builder: (final context) => AlertDialog(
title: Text(AppLocalizations.of(context).nextPushSupported),
content: Text(AppLocalizations.of(context).nextPushSupportedText),
actions: [
OutlinedButton(
onPressed: () {
Navigator.of(context).pop();
},
child: Text(AppLocalizations.of(context).no),
),
ElevatedButton(
onPressed: () {
Navigator.of(context).pop();
launchUrlString(
'https://f-droid.org/packages/$unifiedPushNextPushID',
mode: LaunchMode.externalApplication,
);
},
child: Text(AppLocalizations.of(context).nextPushSupportedInstall),
),
],
),
);
});
unawaited(_checkMaintenanceMode()); unawaited(_checkMaintenanceMode());
} }

4
packages/neon/lib/src/utils/global_options.dart

@ -1,5 +1,7 @@
part of '../neon.dart'; part of '../neon.dart';
const unifiedPushNextPushID = 'org.unifiedpush.distributor.nextpush';
class GlobalOptions { class GlobalOptions {
GlobalOptions( GlobalOptions(
this._storage, this._storage,
@ -63,7 +65,7 @@ class GlobalOptions {
'io.heckel.ntfy': (final context) => AppLocalizations.of(context).globalOptionsPushNotificationsDistributorNtfy, 'io.heckel.ntfy': (final context) => AppLocalizations.of(context).globalOptionsPushNotificationsDistributorNtfy,
'org.unifiedpush.distributor.fcm': (final context) => 'org.unifiedpush.distributor.fcm': (final context) =>
AppLocalizations.of(context).globalOptionsPushNotificationsDistributorFCMUP, AppLocalizations.of(context).globalOptionsPushNotificationsDistributorFCMUP,
'org.unifiedpush.distributor.nextpush': (final context) => unifiedPushNextPushID: (final context) =>
AppLocalizations.of(context).globalOptionsPushNotificationsDistributorNextPush, AppLocalizations.of(context).globalOptionsPushNotificationsDistributorNextPush,
'org.unifiedpush.distributor.noprovider2push': (final context) => 'org.unifiedpush.distributor.noprovider2push': (final context) =>
AppLocalizations.of(context).globalOptionsPushNotificationsDistributorNoProvider2Push, AppLocalizations.of(context).globalOptionsPushNotificationsDistributorNoProvider2Push,

Loading…
Cancel
Save