Browse Source

Merge pull request #258 from provokateurin/feature/improve-push-notifications

Improve push notifications
pull/261/head
Kate 2 years ago committed by GitHub
parent
commit
ebd29fb270
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. BIN
      packages/app/android/app/src/main/res/mipmap-hdpi/app_files.png
  2. BIN
      packages/app/android/app/src/main/res/mipmap-hdpi/app_news.png
  3. BIN
      packages/app/android/app/src/main/res/mipmap-hdpi/app_notes.png
  4. BIN
      packages/app/android/app/src/main/res/mipmap-hdpi/app_notifications.png
  5. BIN
      packages/app/android/app/src/main/res/mipmap-mdpi/app_files.png
  6. BIN
      packages/app/android/app/src/main/res/mipmap-mdpi/app_news.png
  7. BIN
      packages/app/android/app/src/main/res/mipmap-mdpi/app_notes.png
  8. BIN
      packages/app/android/app/src/main/res/mipmap-mdpi/app_notifications.png
  9. BIN
      packages/app/android/app/src/main/res/mipmap-xhdpi/app_files.png
  10. BIN
      packages/app/android/app/src/main/res/mipmap-xhdpi/app_news.png
  11. BIN
      packages/app/android/app/src/main/res/mipmap-xhdpi/app_notes.png
  12. BIN
      packages/app/android/app/src/main/res/mipmap-xhdpi/app_notifications.png
  13. BIN
      packages/app/android/app/src/main/res/mipmap-xxhdpi/app_files.png
  14. BIN
      packages/app/android/app/src/main/res/mipmap-xxhdpi/app_news.png
  15. BIN
      packages/app/android/app/src/main/res/mipmap-xxhdpi/app_notes.png
  16. BIN
      packages/app/android/app/src/main/res/mipmap-xxhdpi/app_notifications.png
  17. BIN
      packages/app/android/app/src/main/res/mipmap-xxxhdpi/app_files.png
  18. BIN
      packages/app/android/app/src/main/res/mipmap-xxxhdpi/app_news.png
  19. BIN
      packages/app/android/app/src/main/res/mipmap-xxxhdpi/app_notes.png
  20. BIN
      packages/app/android/app/src/main/res/mipmap-xxxhdpi/app_notifications.png
  21. 2
      packages/neon/neon/lib/l10n/en.arb
  22. 1
      packages/neon/neon/lib/neon.dart
  23. 26
      packages/neon/neon/lib/src/blocs/accounts.dart
  24. 72
      packages/neon/neon/lib/src/utils/push_utils.dart
  25. 4
      tool/generate-neon.sh

BIN
packages/app/android/app/src/main/res/mipmap-hdpi/app_files.png

Binary file not shown.

Before

Width:  |  Height:  |  Size: 499 B

BIN
packages/app/android/app/src/main/res/mipmap-hdpi/app_news.png

Binary file not shown.

Before

Width:  |  Height:  |  Size: 602 B

BIN
packages/app/android/app/src/main/res/mipmap-hdpi/app_notes.png

Binary file not shown.

Before

Width:  |  Height:  |  Size: 859 B

BIN
packages/app/android/app/src/main/res/mipmap-hdpi/app_notifications.png

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.1 KiB

BIN
packages/app/android/app/src/main/res/mipmap-mdpi/app_files.png

Binary file not shown.

Before

Width:  |  Height:  |  Size: 337 B

BIN
packages/app/android/app/src/main/res/mipmap-mdpi/app_news.png

Binary file not shown.

Before

Width:  |  Height:  |  Size: 377 B

BIN
packages/app/android/app/src/main/res/mipmap-mdpi/app_notes.png

Binary file not shown.

Before

Width:  |  Height:  |  Size: 687 B

BIN
packages/app/android/app/src/main/res/mipmap-mdpi/app_notifications.png

Binary file not shown.

Before

Width:  |  Height:  |  Size: 724 B

BIN
packages/app/android/app/src/main/res/mipmap-xhdpi/app_files.png

Binary file not shown.

Before

Width:  |  Height:  |  Size: 583 B

BIN
packages/app/android/app/src/main/res/mipmap-xhdpi/app_news.png

Binary file not shown.

Before

Width:  |  Height:  |  Size: 624 B

BIN
packages/app/android/app/src/main/res/mipmap-xhdpi/app_notes.png

Binary file not shown.

Before

Width:  |  Height:  |  Size: 995 B

BIN
packages/app/android/app/src/main/res/mipmap-xhdpi/app_notifications.png

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.4 KiB

BIN
packages/app/android/app/src/main/res/mipmap-xxhdpi/app_files.png

Binary file not shown.

Before

Width:  |  Height:  |  Size: 843 B

BIN
packages/app/android/app/src/main/res/mipmap-xxhdpi/app_news.png

Binary file not shown.

Before

Width:  |  Height:  |  Size: 910 B

BIN
packages/app/android/app/src/main/res/mipmap-xxhdpi/app_notes.png

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.4 KiB

BIN
packages/app/android/app/src/main/res/mipmap-xxhdpi/app_notifications.png

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.0 KiB

BIN
packages/app/android/app/src/main/res/mipmap-xxxhdpi/app_files.png

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.1 KiB

BIN
packages/app/android/app/src/main/res/mipmap-xxxhdpi/app_news.png

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.6 KiB

BIN
packages/app/android/app/src/main/res/mipmap-xxxhdpi/app_notes.png

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.7 KiB

BIN
packages/app/android/app/src/main/res/mipmap-xxxhdpi/app_notifications.png

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.7 KiB

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

@ -1,6 +1,6 @@
{ {
"@@locale": "en", "@@locale": "en",
"appImplementationName": "{app, select, core{Server} files{Files} news{News} notes{Notes} notifications{Notifications} other{}}", "appImplementationName": "{app, select, nextcloud{Nextcloud} core{Server} files{Files} news{News} notes{Notes} notifications{Notifications} other{}}",
"@appImplementationName": { "@appImplementationName": {
"placeholders": { "placeholders": {
"app": {} "app": {}

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

@ -5,7 +5,6 @@ import 'dart:convert';
import 'dart:io'; import 'dart:io';
import 'dart:math'; import 'dart:math';
import 'package:collection/collection.dart';
import 'package:crypto/crypto.dart'; import 'package:crypto/crypto.dart';
import 'package:file_picker/file_picker.dart'; import 'package:file_picker/file_picker.dart';
import 'package:filesize/filesize.dart'; import 'package:filesize/filesize.dart';

26
packages/neon/neon/lib/src/blocs/accounts.dart

@ -1,5 +1,7 @@
part of '../../neon.dart'; part of '../../neon.dart';
const _keyAccounts = 'accounts';
abstract class AccountsBlocEvents { abstract class AccountsBlocEvents {
void addAccount(final Account account); void addAccount(final Account account);
void removeAccount(final Account account); void removeAccount(final Account account);
@ -20,20 +22,13 @@ class AccountsBloc extends Bloc implements AccountsBlocEvents, AccountsBlocState
this._globalOptions, this._globalOptions,
this._allAppImplementations, this._allAppImplementations,
) { ) {
accounts.listen((final as) async { accounts
..add(loadAccounts(_storage))
..listen((final as) async {
_globalOptions.updateAccounts(as); _globalOptions.updateAccounts(as);
await _storage.setStringList(_keyAccounts, as.map((final a) => json.encode(a.toJson())).toList()); await _storage.setStringList(_keyAccounts, as.map((final a) => json.encode(a.toJson())).toList());
}); });
if (_storage.containsKey(_keyAccounts)) {
accounts.add(
_storage
.getStringList(_keyAccounts)!
.map((final a) => Account.fromJson(json.decode(a) as Map<String, dynamic>))
.toList(),
);
}
final as = accounts.value; final as = accounts.value;
if (_globalOptions.rememberLastUsedAccount.value && _storage.containsKey(_keyLastUsedAccount)) { if (_globalOptions.rememberLastUsedAccount.value && _storage.containsKey(_keyLastUsedAccount)) {
final lastUsedAccountID = _storage.getString(_keyLastUsedAccount); final lastUsedAccountID = _storage.getString(_keyLastUsedAccount);
@ -56,7 +51,6 @@ class AccountsBloc extends Bloc implements AccountsBlocEvents, AccountsBlocState
final SharedPreferences _sharedPreferences; final SharedPreferences _sharedPreferences;
final GlobalOptions _globalOptions; final GlobalOptions _globalOptions;
final List<AppImplementation> _allAppImplementations; final List<AppImplementation> _allAppImplementations;
final _keyAccounts = 'accounts';
final _keyLastUsedAccount = 'last-used-account'; final _keyLastUsedAccount = 'last-used-account';
final _accountsOptions = <String, AccountSpecificOptions>{}; final _accountsOptions = <String, AccountSpecificOptions>{};
@ -194,3 +188,13 @@ class AccountsBloc extends Bloc implements AccountsBlocEvents, AccountsBlocState
); );
} }
} }
List<Account> loadAccounts(final AppStorage storage) {
if (storage.containsKey(_keyAccounts)) {
return storage
.getStringList(_keyAccounts)!
.map((final a) => Account.fromJson(json.decode(a) as Map<String, dynamic>))
.toList();
}
return [];
}

72
packages/neon/neon/lib/src/utils/push_utils.dart

@ -55,71 +55,71 @@ class PushUtils {
for (final message in Uri(query: utf8.decode(messages)).queryParameters.values) { for (final message in Uri(query: utf8.decode(messages)).queryParameters.values) {
final data = json.decode(message) as Map<String, dynamic>; final data = json.decode(message) as Map<String, dynamic>;
final notification = PushNotification( final pushNotification = PushNotification(
accountID: instance, accountID: instance,
priority: data['priority']! as String, priority: data['priority']! as String,
type: data['type']! as String, type: data['type']! as String,
subject: decryptPushNotificationSubject(keypair.privateKey, data['subject']! as String), subject: decryptPushNotificationSubject(keypair.privateKey, data['subject']! as String),
); );
if (notification.subject.delete ?? false) { if (pushNotification.subject.delete ?? false) {
await localNotificationsPlugin.cancel(_getNotificationID(instance, notification)); await localNotificationsPlugin.cancel(_getNotificationID(instance, pushNotification));
} else if (notification.subject.deleteAll ?? false) { } else if (pushNotification.subject.deleteAll ?? false) {
await localNotificationsPlugin.cancelAll(); await localNotificationsPlugin.cancelAll();
Global.onPushNotificationReceived?.call(instance); Global.onPushNotificationReceived?.call(instance);
} else if (notification.type == 'background') { } else if (pushNotification.type == 'background') {
debugPrint('Got unknown background notification ${json.encode(notification.toJson())}'); debugPrint('Got unknown background notification ${json.encode(pushNotification.toJson())}');
} else { } else {
final localizations = await appLocalizationsFromSystem(); final localizations = await appLocalizationsFromSystem();
final platform = await getNeonPlatform(); final platform = await getNeonPlatform();
final cache = Cache(platform); final cache = Cache(platform);
await cache.init(); await cache.init();
//final requestManager = RequestManager(cache);
//final allAppImplementations = getAppImplementations(sharedPreferences, requestManager, platform);
final allAppImplementations = <AppImplementation>[];
final matchingAppImplementations = NextcloudNotificationsNotification? notification;
allAppImplementations.where((final a) => a.id == notification.subject.app).toList(); var accounts = <Account>[];
AppImplementation? app; Account? account;
if (matchingAppImplementations.isNotEmpty) { try {
app = matchingAppImplementations.single; accounts = loadAccounts(AppStorage('accounts', sharedPreferences));
} else { account = accounts.find(instance);
app = allAppImplementations.firstWhereOrNull((final a) => a.id == 'notifications'); if (account != null) {
notification =
(await account.client.notifications.getNotification(id: pushNotification.subject.nid!)).ocs.data;
}
} catch (e, s) {
debugPrint(e.toString());
debugPrint(s.toString());
} }
final appID = app?.id ?? notification.subject.app; final appID = notification?.app ?? pushNotification.subject.app ?? 'nextcloud';
var appName = localizations.appImplementationName(appID ?? ''); var appName = localizations.appImplementationName(appID);
if (appName == '') { if (appName == '') {
appName = appID ?? 'Nextcloud'; debugPrint('Missing app name for $appID');
appName = appID;
} }
final title = notification?.subject ?? pushNotification.subject.subject;
final message = notification != null && notification.message != '' ? notification.message : null;
await localNotificationsPlugin.show( await localNotificationsPlugin.show(
_getNotificationID(instance, notification), _getNotificationID(instance, pushNotification),
appName, message != null ? '$appName: $title' : appName,
notification.subject.subject, message ?? title,
NotificationDetails( NotificationDetails(
android: AndroidNotificationDetails( android: AndroidNotificationDetails(
notification.subject.app ?? 'nextcloud', appID,
appName, appName,
groupKey: notification.subject.app != null ? 'app_${notification.subject.app}' : 'nextcloud', subText: accounts.length > 1 && account != null ? account.client.humanReadableID : null,
icon: '@mipmap/${app != null ? 'app_${app.id}' : 'ic_launcher'}', groupKey: 'app_$appID',
icon: '@mipmap/ic_launcher',
color: themePrimaryColor, color: themePrimaryColor,
category: notification.type == 'voip' ? AndroidNotificationCategory.call : null, category: pushNotification.type == 'voip' ? AndroidNotificationCategory.call : null,
importance: Importance.max, importance: Importance.max,
priority: notification.priority == 'high' priority: pushNotification.priority == 'high'
? (notification.type == 'voip' ? Priority.max : Priority.high) ? (pushNotification.type == 'voip' ? Priority.max : Priority.high)
: Priority.defaultPriority, : Priority.defaultPriority,
), ),
), ),
payload: json.encode( payload: json.encode(pushNotification.toJson()),
PushNotification(
accountID: instance,
priority: notification.priority,
type: notification.type,
subject: notification.subject,
).toJson(),
),
); );
} }

4
tool/generate-neon.sh

@ -70,10 +70,6 @@ copy_nextcloud_app_svg notifications external/nextcloud-notifications
# Android launcher icons # Android launcher icons
export_mipmap_icon_all "assets/logo.svg" "ic_launcher" & export_mipmap_icon_all "assets/logo.svg" "ic_launcher" &
for id in files news notes notifications; do
export_mipmap_icon_all "../neon/neon_$id/assets/app.svg" "app_$id" &
done
wait
fvm dart run flutter_native_splash:create fvm dart run flutter_native_splash:create
) )

Loading…
Cancel
Save