Merge pull request 'add window_manager plug in to get desktop active state to gate windows notifications; also add spam prevention to windows notifications' (#338) from winFocus into trunk
continuous-integration/drone/push Build is passing Details

Reviewed-on: #338
This commit is contained in:
Sarah Jamie Lewis 2022-01-26 21:41:37 +00:00
commit 2bff77983b
5 changed files with 64 additions and 8 deletions

View File

@ -12,6 +12,7 @@ import 'package:cwtch/settings.dart';
import 'package:cwtch/torstatus.dart'; import 'package:cwtch/torstatus.dart';
import 'package:flutter/services.dart'; import 'package:flutter/services.dart';
import 'package:provider/provider.dart'; import 'package:provider/provider.dart';
import 'package:window_manager/window_manager.dart';
import 'cwtch/cwtch.dart'; import 'cwtch/cwtch.dart';
import 'cwtch/cwtchNotifier.dart'; import 'cwtch/cwtchNotifier.dart';
import 'licenses.dart'; import 'licenses.dart';
@ -45,7 +46,7 @@ class Flwtch extends StatefulWidget {
FlwtchState createState() => FlwtchState(); FlwtchState createState() => FlwtchState();
} }
class FlwtchState extends State<Flwtch> { class FlwtchState extends State<Flwtch> with WindowListener {
final TextStyle biggerFont = const TextStyle(fontSize: 18); final TextStyle biggerFont = const TextStyle(fontSize: 18);
late Cwtch cwtch; late Cwtch cwtch;
late ProfileListState profs; late ProfileListState profs;
@ -56,6 +57,7 @@ class FlwtchState extends State<Flwtch> {
@override @override
initState() { initState() {
print("initState: running..."); print("initState: running...");
windowManager.addListener(this);
super.initState(); super.initState();
print("initState: registering notification, shutdown handlers..."); print("initState: registering notification, shutdown handlers...");
@ -203,8 +205,21 @@ class FlwtchState extends State<Flwtch> {
} }
} }
// using windowManager flutter plugin until proper lifecycle management lands in desktop
@override
void onWindowFocus() {
globalAppState.focus = true;
}
@override
void onWindowBlur() {
globalAppState.focus = false;
}
@override @override
void dispose() { void dispose() {
windowManager.removeListener(this);
cwtch.dispose(); cwtch.dispose();
super.dispose(); super.dispose();
} }

View File

@ -14,6 +14,7 @@ class AppState extends ChangeNotifier {
int? _selectedIndex; int? _selectedIndex;
bool _unreadMessagesBelow = false; bool _unreadMessagesBelow = false;
bool _disableFilePicker = false; bool _disableFilePicker = false;
bool _focus = true;
void SetCwtchInit() { void SetCwtchInit() {
cwtchInit = true; cwtchInit = true;
@ -74,5 +75,11 @@ class AppState extends ChangeNotifier {
notifyListeners(); notifyListeners();
} }
bool get focus => _focus;
set focus(bool newVal) {
_focus = newVal;
notifyListeners();
}
bool isLandscape(BuildContext c) => MediaQuery.of(c).size.width > MediaQuery.of(c).size.height; bool isLandscape(BuildContext c) => MediaQuery.of(c).size.width > MediaQuery.of(c).size.height;
} }

View File

@ -1,5 +1,6 @@
import 'dart:io'; import 'dart:io';
import 'package:cwtch/main.dart';
import 'package:desktoasts/desktoasts.dart'; import 'package:desktoasts/desktoasts.dart';
import 'package:desktop_notifications/desktop_notifications.dart'; import 'package:desktop_notifications/desktop_notifications.dart';
import 'package:path/path.dart' as path; import 'package:path/path.dart' as path;
@ -22,9 +23,11 @@ class NullNotificationsManager implements NotificationsManager {
class LinuxNotificationsManager implements NotificationsManager { class LinuxNotificationsManager implements NotificationsManager {
int previous_id = 0; int previous_id = 0;
late NotificationsClient client; late NotificationsClient client;
LinuxNotificationsManager(NotificationsClient client) { LinuxNotificationsManager(NotificationsClient client) {
this.client = client; this.client = client;
} }
Future<void> notify(String message) async { Future<void> notify(String message) async {
var iconPath = Uri.file(path.join(path.current, "cwtch.png")); var iconPath = Uri.file(path.join(path.current, "cwtch.png"));
client.notify(message, appName: "cwtch", appIcon: iconPath.toString(), replacesId: this.previous_id).then((Notification value) => previous_id = value.id); client.notify(message, appName: "cwtch", appIcon: iconPath.toString(), replacesId: this.previous_id).then((Notification value) => previous_id = value.id);
@ -35,22 +38,45 @@ class LinuxNotificationsManager implements NotificationsManager {
// windows notifications // windows notifications
class WindowsNotificationManager implements NotificationsManager { class WindowsNotificationManager implements NotificationsManager {
late ToastService service; late ToastService service;
bool active = false;
WindowsNotificationManager() { WindowsNotificationManager() {
service = new ToastService( service = new ToastService(
appName: 'Cwtch', appName: 'cwtch',
companyName: 'Open Privacy Research Society', companyName: 'Open Privacy Research Society',
productName: 'Cwtch', productName: 'Cwtch',
); );
service.stream.listen((event) {
// the user closed the notification of the OS timed it out
if (event is ToastDismissed) {
active = false;
}
// clicked
if (event is ToastActivated) {
active = false;
}
// if a supplied action was clicked
if (event is ToastInteracted) {
active = false;
}
});
} }
Future<void> notify(String message) async { Future<void> notify(String message) async {
Toast toast = new Toast( if (!globalAppState.focus) {
type: ToastType.text01, if (!active) {
title: 'Cwtch', // One string of bold text on the first line (title),
subtitle: message, // one string (subtitle) of regular text wrapped across the second and third lines.
); Toast toast = new Toast(
service.show(toast); type: ToastType.text02,
title: 'Cwtch',
subtitle: message,
);
service.show(toast);
active = true;
}
}
} }
} }

View File

@ -474,6 +474,13 @@ packages:
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "2.2.4" version: "2.2.4"
window_manager:
dependency: "direct main"
description:
name: window_manager
url: "https://pub.dartlang.org"
source: hosted
version: "0.1.4"
xdg_directories: xdg_directories:
dependency: transitive dependency: transitive
description: description:

View File

@ -45,6 +45,7 @@ dependencies:
file_picker_desktop: ^1.1.0 file_picker_desktop: ^1.1.0
url_launcher: ^6.0.12 url_launcher: ^6.0.12
desktoasts: ^0.0.2 desktoasts: ^0.0.2
window_manager: ^0.1.4
dev_dependencies: dev_dependencies:
msix: ^2.1.3 msix: ^2.1.3