windows fixes: especially new version of win toast

This commit is contained in:
Dan Ballard 2023-05-22 12:54:40 -07:00
parent 2c0e0e16f2
commit 471ab96743
4 changed files with 109 additions and 36 deletions

View File

@ -44,6 +44,8 @@ Future<void> main() async {
print("Cwtch version: ${EnvironmentConfig.BUILD_VER} built on: ${EnvironmentConfig.BUILD_DATE}");
LicenseRegistry.addLicense(() => licenses());
WidgetsFlutterBinding.ensureInitialized();
// window_manager requires (await recommended but probably not required if not using immediately)
windowManager.ensureInitialized();
print("runApp()");
return runApp(Flwtch());
}
@ -104,9 +106,10 @@ class FlwtchState extends State<Flwtch> with WindowListener {
new CwtchNotifier(profs, globalSettings, globalErrorHandler, globalTorStatus, newDesktopNotificationsManager(_notificationSelectConvo), globalAppState, globalServersList, this);
cwtch = CwtchFfi(cwtchNotifier);
}
startConnectivityListener();
print("initState: invoking cwtch.Start()");
cwtch.Start();
print("initState: starting connectivityListener");
startConnectivityListener();
print("initState: done!");
super.initState();
}
@ -288,7 +291,8 @@ class FlwtchState extends State<Flwtch> with WindowListener {
);
// On Gnome follows up a clicked notification with a "Cwtch is ready" notification that takes you to the app. AFAICT just because Gnome is bad
// https://askubuntu.com/questions/1286206/how-to-skip-the-is-ready-notification-and-directly-open-apps-in-ubuntu-20-4
windowManager.focus();
await windowManager.show();
await windowManager.focus();
}
// using windowManager flutter plugin until proper lifecycle management lands in desktop
@ -303,6 +307,9 @@ class FlwtchState extends State<Flwtch> with WindowListener {
globalAppState.focus = false;
}
void onWindowClose() {
}
@override
void dispose() {
globalAppState.SetModalState(ModalState.shutdown);

View File

@ -23,7 +23,8 @@ abstract class NotificationsManager {
// NullNotificationsManager ignores all notification requests
class NullNotificationsManager implements NotificationsManager {
@override
Future<void> notify(String message, String profile, int conversationId) async {}
Future<void> notify(
String message, String profile, int conversationId) async {}
}
// Windows Notification Manager uses https://pub.dev/packages/desktoasts to implement
@ -31,11 +32,32 @@ class NullNotificationsManager implements NotificationsManager {
class WindowsNotificationManager implements NotificationsManager {
bool active = false;
bool initialized = false;
late Future<void> Function(String, int) notificationSelectConvo;
// TODO This needs testing and redefining...
WindowsNotificationManager() {
WindowsNotificationManager(Future<void> Function(String, int) notificationSelectConvo) {
this.notificationSelectConvo = notificationSelectConvo;
scheduleMicrotask(() async {
initialized = await WinToast.instance().initialize(clsid: 'cwtch', displayName: 'Cwtch', aumId: 'Open Privacy Research Society', iconPath: '');
//initialized = await WinToast.instance().initialize(clsid: 'cwtch', displayName: 'Cwtch', aumId: 'Open Privacy Research Society', iconPath: '');
// initialize toast with you aumId, displayName and iconPath
var init = await WinToast.instance().initialize(
aumId: 'OpenPrivacyResearchSociety.Cwtch',
displayName: 'Cwtch',
iconPath: '', // TODO NEED ICON
clsid: 'cwtch',
);
WinToast.instance().setActivatedCallback((event) {
if (event.argument != "close") {
try {
Map<String, dynamic> payloadMap = jsonDecode(event.argument);
var payload = NotificationPayload.fromJson(payloadMap);
notificationSelectConvo(payload.profileOnion, payload.convoId);
} catch (e) {
/* it failed, is ok, may have been 'close'? */
}
}
});
initialized = true;
});
}
@ -43,14 +65,31 @@ class WindowsNotificationManager implements NotificationsManager {
if (initialized && !globalAppState.focus) {
if (!active) {
active = true;
// WinToast.instance().clear();
//final toast = await WinToast.instance().showToast(toast: Toast(children: ,type: ToastType.text01, title: message));
//toast?.eventStream.listen((event) {
// if (event is ActivatedEvent) {
// WinToast.instance().bringWindowToFront();
// }
active = false;
// });
WinToast.instance().clear();
await WinToast.instance().showToast(
toast: Toast(
duration: ToastDuration.short,
children: [
ToastChildAudio(source: ToastAudioSource.im),
ToastChildVisual(
binding: ToastVisualBinding(children: [
ToastVisualBindingChildText(
text: message,
id: 1,
),
])),
ToastChildActions(children: [
ToastAction(
content: "Open",
arguments: jsonEncode(NotificationPayload(profile, conversationId)),
),
ToastAction(
content: "Close",
arguments: "close",
),
]),
]));
active = false;
}
}
}
@ -87,7 +126,8 @@ class NixNotificationManager implements NotificationsManager {
Future<String> detectLinuxAssetsPath() async {
var devStat = FileStat.stat("assets");
var localStat = FileStat.stat("data/flutter_assets");
var homeStat = FileStat.stat((Platform.environment["HOME"] ?? "") + "/.local/share/cwtch/data/flutter_assets");
var homeStat = FileStat.stat((Platform.environment["HOME"] ?? "") +
"/.local/share/cwtch/data/flutter_assets");
var rootStat = FileStat.stat("/usr/share/cwtch/data/flutter_assets");
if ((await devStat).type == FileSystemEntityType.directory) {
@ -95,14 +135,16 @@ class NixNotificationManager implements NotificationsManager {
} else if ((await localStat).type == FileSystemEntityType.directory) {
return path.join(Directory.current.path, "data/flutter_assets/");
} else if ((await homeStat).type == FileSystemEntityType.directory) {
return (Platform.environment["HOME"] ?? "") + "/.local/share/cwtch/data/flutter_assets/";
return (Platform.environment["HOME"] ?? "") +
"/.local/share/cwtch/data/flutter_assets/";
} else if ((await rootStat).type == FileSystemEntityType.directory) {
return "/usr/share/cwtch/data/flutter_assets/";
}
return "";
}
NixNotificationManager(Future<void> Function(String, int) notificationSelectConvo) {
NixNotificationManager(
Future<void> Function(String, int) notificationSelectConvo) {
this.notificationSelectConvo = notificationSelectConvo;
flutterLocalNotificationsPlugin = FlutterLocalNotificationsPlugin();
@ -113,24 +155,39 @@ class NixNotificationManager implements NotificationsManager {
linuxAssetsPath = "";
}
var linuxIcon =
FilePathLinuxIcon(path.join(linuxAssetsPath, 'assets/knott.png'));
var linuxIcon = FilePathLinuxIcon(path.join(linuxAssetsPath, 'assets/knott.png'));
final LinuxInitializationSettings initializationSettingsLinux =
LinuxInitializationSettings(
defaultActionName: 'Open notification',
defaultIcon: linuxIcon,
defaultSuppressSound: true);
final LinuxInitializationSettings initializationSettingsLinux = LinuxInitializationSettings(defaultActionName: 'Open notification', defaultIcon: linuxIcon, defaultSuppressSound: true);
final InitializationSettings initializationSettings =
InitializationSettings(
android: null,
iOS: null,
macOS: DarwinInitializationSettings(defaultPresentSound: false),
linux: initializationSettingsLinux);
final InitializationSettings initializationSettings = InitializationSettings(android: null, iOS: null, macOS: DarwinInitializationSettings(defaultPresentSound: false), linux: initializationSettingsLinux);
flutterLocalNotificationsPlugin.resolvePlatformSpecificImplementation<MacOSFlutterLocalNotificationsPlugin>()?.requestPermissions(
flutterLocalNotificationsPlugin
.resolvePlatformSpecificImplementation<
MacOSFlutterLocalNotificationsPlugin>()
?.requestPermissions(
alert: true,
badge: false,
sound: false,
);
await flutterLocalNotificationsPlugin.initialize(initializationSettings, );
await flutterLocalNotificationsPlugin.initialize(
initializationSettings,
);
});
}
Future<void> notify(String message, String profile, int conversationId) async {
Future<void> notify(
String message, String profile, int conversationId) async {
if (!globalAppState.focus) {
// Warning: Only use title field on Linux, body field will render links as clickable
await flutterLocalNotificationsPlugin.show(
@ -138,7 +195,11 @@ class NixNotificationManager implements NotificationsManager {
message,
'',
NotificationDetails(
linux: LinuxNotificationDetails(suppressSound: true, category: LinuxNotificationCategory.imReceived, icon: FilePathLinuxIcon(path.join(linuxAssetsPath, 'assets/knott.png')))),
linux: LinuxNotificationDetails(
suppressSound: true,
category: LinuxNotificationCategory.imReceived,
icon: FilePathLinuxIcon(
path.join(linuxAssetsPath, 'assets/knott.png')))),
payload: jsonEncode(NotificationPayload(profile, conversationId)));
}
}
@ -153,7 +214,9 @@ class NixNotificationManager implements NotificationsManager {
}
}
NotificationsManager newDesktopNotificationsManager(Future<void> Function(String profileOnion, int convoId) notificationSelectConvo) {
NotificationsManager newDesktopNotificationsManager(
Future<void> Function(String profileOnion, int convoId)
notificationSelectConvo) {
// We don't want notifications in Dev Mode
if (EnvironmentConfig.TEST_MODE) {
return NullNotificationsManager();
@ -163,19 +226,22 @@ NotificationsManager newDesktopNotificationsManager(Future<void> Function(String
try {
return NixNotificationManager(notificationSelectConvo);
} catch (e) {
EnvironmentConfig.debugLog("Failed to create LinuxNotificationManager. Switching off notifications.");
EnvironmentConfig.debugLog(
"Failed to create LinuxNotificationManager. Switching off notifications.");
}
} else if (Platform.isMacOS) {
try {
return NixNotificationManager(notificationSelectConvo);
} catch (e) {
EnvironmentConfig.debugLog("Failed to create NixNotificationManager. Switching off notifications.");
EnvironmentConfig.debugLog(
"Failed to create NixNotificationManager. Switching off notifications.");
}
} else if (Platform.isWindows) {
try {
return WindowsNotificationManager();
return WindowsNotificationManager(notificationSelectConvo);
} catch (e) {
EnvironmentConfig.debugLog("Failed to create Windows desktoasts notification manager");
EnvironmentConfig.debugLog(
"Failed to create Windows desktoasts notification manager");
}
}

View File

@ -81,7 +81,7 @@ ShowInstDetails show
Section
# define the output path for this file
SetOutPath $INSTDIR
SetOutPath "$INSTDIR"
# define what to install and place it in the output path
# Filler for .sh to populate with contents of deploy/windows

View File

@ -69,14 +69,14 @@ IDI_APP_ICON_16 ICON "resources\\knot_16.ico"
// Version
//
#ifdef FLUTTER_BUILD_NUMBER
#define VERSION_AS_NUMBER FLUTTER_BUILD_NUMBER
#if defined(FLUTTER_VERSION_MAJOR) && defined(FLUTTER_VERSION_MINOR) && defined(FLUTTER_VERSION_PATCH) && defined(FLUTTER_VERSION_BUILD)
#define VERSION_AS_NUMBER FLUTTER_VERSION_MAJOR,FLUTTER_VERSION_MINOR,FLUTTER_VERSION_PATCH,FLUTTER_VERSION_BUILD
#else
#define VERSION_AS_NUMBER 1,0,0
#define VERSION_AS_NUMBER 1,0,0,0
#endif
#ifdef FLUTTER_BUILD_NAME
#define VERSION_AS_STRING #FLUTTER_BUILD_NAME
#if defined(FLUTTER_VERSION)
#define VERSION_AS_STRING FLUTTER_VERSION
#else
#define VERSION_AS_STRING "1.0.0"
#endif