feat: Improve notifications, add donation button, improved asn form field

This commit is contained in:
Anton Stubenbord
2023-03-06 22:21:14 +01:00
parent bd891a8658
commit 1172e54199
37 changed files with 985 additions and 305 deletions

View File

@@ -2,11 +2,16 @@ import 'dart:convert';
import 'dart:developer';
import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
import 'package:flutter_local_notifications/flutter_local_notifications.dart';
import 'package:open_filex/open_filex.dart';
import 'package:paperless_api/paperless_api.dart';
import 'package:paperless_mobile/features/notifications/services/models/notification_payloads/open_created_document_notification_payload.dart';
import 'package:paperless_mobile/features/notifications/services/notification_actions.dart';
import 'package:paperless_mobile/features/notifications/services/notification_channels.dart';
import 'package:paperless_mobile/features/notifications/converters/notification_tap_response_payload.dart';
import 'package:paperless_mobile/features/notifications/models/notification_payloads/notification_action/create_document_success_payload.dart';
import 'package:paperless_mobile/features/notifications/models/notification_payloads/notification_tap/open_downloaded_document_payload.dart';
import 'package:paperless_mobile/features/notifications/models/notification_actions.dart';
import 'package:paperless_mobile/features/notifications/models/notification_channels.dart';
import 'package:paperless_mobile/generated/l10n/app_localizations.dart';
class LocalNotificationService {
final FlutterLocalNotificationsPlugin _plugin =
@@ -16,7 +21,7 @@ class LocalNotificationService {
Future<void> initialize() async {
const AndroidInitializationSettings initializationSettingsAndroid =
AndroidInitializationSettings('ic_stat_paperless_logo_green');
AndroidInitializationSettings('paperless_logo_green');
final DarwinInitializationSettings initializationSettingsDarwin =
DarwinInitializationSettings(
requestSoundPermission: false,
@@ -32,6 +37,8 @@ class LocalNotificationService {
await _plugin.initialize(
initializationSettings,
onDidReceiveNotificationResponse: onDidReceiveNotificationResponse,
onDidReceiveBackgroundNotificationResponse:
onDidReceiveBackgroundNotificationResponse,
);
await _plugin
.resolvePlatformSpecificImplementation<
@@ -39,6 +46,51 @@ class LocalNotificationService {
?.requestPermission();
}
Future<void> notifyFileDownload({
required DocumentModel document,
required String filename,
required String filePath,
required bool finished,
required String locale,
}) async {
final tr = await S.delegate.load(Locale(locale));
int id = document.id;
await _plugin.show(
id,
filename,
finished
? tr.notificationDownloadComplete
: tr.notificationDownloadingDocument,
NotificationDetails(
android: AndroidNotificationDetails(
NotificationChannel.documentDownload.id + "_${document.id}",
NotificationChannel.documentDownload.name,
ongoing: !finished,
indeterminate: true,
importance: Importance.max,
priority: Priority.high,
showProgress: !finished,
when: DateTime.now().millisecondsSinceEpoch,
category: AndroidNotificationCategory.progress,
icon: finished ? 'file_download_done' : 'downloading',
),
iOS: DarwinNotificationDetails(
attachments: [
DarwinNotificationAttachment(
filePath,
),
],
),
),
payload: jsonEncode(
OpenDownloadedDocumentPayload(
filePath: filePath,
).toJson(),
),
); //TODO: INTL
}
//TODO: INTL
Future<void> notifyTaskChanged(Task task) {
log("[LocalNotificationService] notifyTaskChanged: ${task.toString()}");
@@ -49,20 +101,17 @@ class LocalNotificationService {
late int timestampMillis;
bool showProgress =
status == TaskStatus.started || status == TaskStatus.pending;
int progress = 0;
dynamic payload;
switch (status) {
case TaskStatus.started:
title = "Document received";
body = task.taskFileName;
timestampMillis = task.dateCreated.millisecondsSinceEpoch;
progress = 10;
break;
case TaskStatus.pending:
title = "Processing document...";
body = task.taskFileName;
timestampMillis = task.dateCreated.millisecondsSinceEpoch;
progress = 70;
break;
case TaskStatus.failure:
title = "Failed to process document";
@@ -73,7 +122,7 @@ class LocalNotificationService {
title = "Document successfully created";
body = task.taskFileName;
timestampMillis = task.dateDone!.millisecondsSinceEpoch;
payload = CreateDocumentSuccessNotificationResponsePayload(
payload = CreateDocumentSuccessPayload(
task.relatedDocument!,
);
break;
@@ -93,7 +142,7 @@ class LocalNotificationService {
showProgress: showProgress,
maxProgress: 100,
when: timestampMillis,
progress: progress,
indeterminate: true,
actions: status == TaskStatus.success
? [
//TODO: Implement once moved to new routing
@@ -109,6 +158,7 @@ class LocalNotificationService {
]
: [],
),
//TODO: Add darwin support
),
payload: jsonEncode(payload),
);
@@ -119,38 +169,68 @@ class LocalNotificationService {
String? title,
String? body,
String? payload,
) {}
void onDidReceiveNotificationResponse(NotificationResponse response) {
debugPrint("Received Notification: ${response.payload}");
if (response.notificationResponseType ==
NotificationResponseType.selectedNotificationAction) {
final action =
NotificationResponseAction.values.byName(response.actionId!);
_handleResponseAction(action, response);
}
// Non-actionable notification pressed, ignoring...
) {
debugPrint("onDidReceiveNotification!");
}
void _handleResponseAction(
NotificationResponseAction action,
void onDidReceiveNotificationResponse(NotificationResponse response) {
debugPrint(
"Received Notification ${response.id}: Action is ${response.actionId}): ${response.payload}",
);
switch (response.notificationResponseType) {
case NotificationResponseType.selectedNotification:
if (response.payload != null) {
final payload =
const NotificationTapResponsePayloadConverter().fromJson(
jsonDecode(response.payload!),
);
_handleResponseTapAction(payload.type, response);
}
break;
case NotificationResponseType.selectedNotificationAction:
final action =
NotificationResponseButtonAction.values.byName(response.actionId!);
_handleResponseButtonAction(action, response);
break;
}
}
void _handleResponseButtonAction(
NotificationResponseButtonAction action,
NotificationResponse response,
) {
switch (action) {
case NotificationResponseAction.openCreatedDocument:
final payload =
CreateDocumentSuccessNotificationResponsePayload.fromJson(
case NotificationResponseButtonAction.openCreatedDocument:
final payload = CreateDocumentSuccessPayload.fromJson(
jsonDecode(response.payload!),
);
log("Navigate to document ${payload.documentId}");
break;
case NotificationResponseAction.acknowledgeCreatedDocument:
final payload =
CreateDocumentSuccessNotificationResponsePayload.fromJson(
case NotificationResponseButtonAction.acknowledgeCreatedDocument:
final payload = CreateDocumentSuccessPayload.fromJson(
jsonDecode(response.payload!),
);
log("Acknowledge document ${payload.documentId}");
break;
}
}
void _handleResponseTapAction(
NotificationResponseOpenAction type,
NotificationResponse response,
) {
switch (type) {
case NotificationResponseOpenAction.openDownloadedDocumentPath:
final payload = OpenDownloadedDocumentPayload.fromJson(
jsonDecode(response.payload!));
OpenFilex.open(payload.filePath);
break;
}
}
}
void onDidReceiveBackgroundNotificationResponse(NotificationResponse response) {
//TODO: When periodic background inbox check is implemented, notification tap is handled here
debugPrint(response.toString());
}