refactor: Use local notifications for linux

pull/2988/head
krille-chan 3 days ago committed by Christian Kußowski
parent b100913c7a
commit 1d38928ad6
No known key found for this signature in database

@ -1966,8 +1966,6 @@
"@start": {},
"reportUser": "التبيلغ عن المستخدم",
"@reportUser": {},
"openChat": "فتح المحادثة",
"@openChat": {},
"pinMessage": "تثبيت في الغرفة",
"@pinMessage": {},
"confirmEventUnpin": "هل أنت متأكد من إلغاء تثبيت الحدث بشكل دائم؟",

@ -1473,7 +1473,6 @@
"removeFromSpace": "Выдаліць з прасторы",
"start": "Пачаць",
"pleaseEnterRecoveryKeyDescription": "Каб разблакіраваць вашы мінулыя паведамленні, калі ласка, увядзіце ключ аднаўлення, што быў згенерыраваны ў мінулай сесіі. Ключ аднаўлення гэта НЕ ваш пароль.",
"openChat": "Адкрыць чат",
"markAsRead": "Адзначыць як прачытанае",
"reportUser": "Паскардзіцца на карыстальніка",
"dismiss": "Адхіліць",

@ -1801,7 +1801,6 @@
"placeholders": {}
},
"@storeInSecureStorageDescription": {},
"@openChat": {},
"@kickUserDescription": {},
"@sendAMessage": {
"type": "String",

@ -2169,7 +2169,6 @@
"custom": "Personalitzat",
"noBackupWarning": "Compte! Si no actives la còpia de seguretat dels xats, perdràs accés als teus missatges xifrats. És molt recomanable activar-ho abans de tancar la sessió.",
"storeInSecureStorageDescription": "Desa la clau de recuperació en l'emmagatzematge segur d'aquest dispositiu.",
"openChat": "Obre el xat",
"kickUserDescription": "Li usuàrïi ha estat expulsadi però no vetadi. Als xats públics, pot tornar-hi a entrar en qualsevol moment.",
"importNow": "Importa-ho ara",
"pinMessage": "Fixa a la sala",

@ -1913,7 +1913,6 @@
},
"markAsRead": "Označit jako přečtené",
"reportUser": "Nahlásit uživatele",
"openChat": "Otevřete chat",
"dismiss": "Zavrhnout",
"reactedWith": "{sender} reagoval s {reaction}",
"@reactedWith": {

@ -1937,7 +1937,6 @@
},
"markAsRead": "Als gelesen markiert",
"reportUser": "Benutzer melden",
"openChat": "Chat öffnen",
"confirmEventUnpin": "Möchtest du das Ereignis wirklich dauerhaft lösen?",
"dismiss": "Verwerfen",
"youKicked": "👞 Du hast {user} rausgeworfen",

@ -2063,7 +2063,6 @@
"removeFromSpace": "Remove from space",
"start": "Start",
"pleaseEnterRecoveryKeyDescription": "To unlock your old messages, please enter your recovery key that has been generated in a previous session. Your recovery key is NOT your password.",
"openChat": "Open Chat",
"markAsRead": "Mark as read",
"reportUser": "Report user",
"dismiss": "Dismiss",

@ -1968,7 +1968,6 @@
"replace": "Reemplazar",
"unsupportedAndroidVersionLong": "Esta característica requiere una versión más reciente de Android. Por favor, compruebe las actualizaciones o la compatibilidad de LineageOS.",
"storeSecurlyOnThisDevice": "Almacenar de forma segura en este dispositivo",
"openChat": "Abrir chat",
"screenSharingDetail": "Usted está compartiendo su pantalla en FluffyChat",
"dismiss": "Descartar",
"unsupportedAndroidVersion": "Versión de Android no compatible",

@ -1913,7 +1913,6 @@
},
"markAsRead": "Märgi loetuks",
"reportUser": "Teata kasutajast",
"openChat": "Ava vestlus",
"dismiss": "Loobu",
"reactedWith": "{sender} reageeris nii {reaction}",
"@reactedWith": {

@ -1935,7 +1935,6 @@
"removeFromSpace": "Kendu gunetik",
"start": "Hasi",
"reportUser": "Salatu erabiltzailea",
"openChat": "Ireki txata",
"youJoinedTheChat": "Txatera batu zara",
"youAcceptedTheInvitation": "👍 Gonbidapena onartu duzu",
"youBannedUser": "{user}(r)i debekua ezarri diozu",

@ -1904,7 +1904,6 @@
"type": "String",
"placeholders": {}
},
"openChat": "باز کردن چت",
"dismiss": "رد کردن",
"unsupportedAndroidVersion": "نسخه اندروید پشتیبانی‌نشده",
"youUnbannedUser": "شما محرومیت {user} را برداشتید",

@ -1962,8 +1962,6 @@
}
}
},
"openChat": "Avaa Keskustelu",
"@openChat": {},
"pinMessage": "Kiinnitä huoneeseen",
"@pinMessage": {},
"confirmEventUnpin": "Haluatko varmasti irrottaa tapahtuman pysyvästi?",

@ -1940,8 +1940,6 @@
"@markAsRead": {},
"reportUser": "Signaler l'utilisateur/trice",
"@reportUser": {},
"openChat": "Ouvrir la discussion",
"@openChat": {},
"reactedWith": "{sender} a réagi avec {reaction}",
"@reactedWith": {
"type": "String",

@ -2024,7 +2024,6 @@
"messageInfo": "Eolas teachtaireachta",
"messageType": "Cineál Teachtaireachta",
"pleaseEnterRecoveryKeyDescription": "Chun do sheanteachtaireachtaí a dhíghlasáil, cuir isteach d'eochair athshlánaithe a gineadh i seisiún eile. NÍ do phasfhocal í d'eochair athshlánaithe.",
"openChat": "Oscail Comhrá",
"unsupportedAndroidVersionLong": "Éilíonn an ghné seo leagan Android níos nuaí. Seiceáil le haghaidh nuashonruithe nó tacaíocht Lineage OS.",
"experimentalVideoCalls": "Glaonna físe turgnamhacha",
"invitedBy": "📩 Cuireadh ó {user}",

@ -1910,7 +1910,6 @@
"dismiss": "Desbotar",
"markAsRead": "Marcar como lido",
"reportUser": "Denunciar usuaria",
"openChat": "Abrir Conversa",
"voiceCall": "Chamada de voz",
"emojis": "Emojis",
"placeCall": "Chamar",

@ -1908,7 +1908,6 @@
},
"markAsRead": "Označi kao pročitano",
"reportUser": "Prijavi korisnika",
"openChat": "Otvori chat",
"dismiss": "Odbaci",
"unsupportedAndroidVersion": "Nepodržana Android verzija",
"unsupportedAndroidVersionLong": "Ova funkcija zahtijeva noviju verziju Androida. Provjeri, postoje li nove verzije ili podrška za Lineage OS.",

@ -2279,8 +2279,6 @@
"@noBackupWarning": {},
"storeInSecureStorageDescription": "Tárolja a visszaállítási kulcsot az eszköz biztonsági tárjában.",
"@storeInSecureStorageDescription": {},
"openChat": "Csevegés megnyitása",
"@openChat": {},
"kickUserDescription": "A felhasználó kirúgásra került a csevegésből, de nincs kitiltva. Publikus csevegés esetén a felhasználó bármikor visszatérhet.",
"@kickUserDescription": {},
"importNow": "Importálás most",

@ -1913,7 +1913,6 @@
"dismiss": "Abaikan",
"markAsRead": "Tandai sebagai dibaca",
"reportUser": "Laporkan pengguna",
"openChat": "Buka Chat",
"reactedWith": "{sender} bereaksi dengan {reaction}",
"@reactedWith": {
"type": "String",

@ -578,8 +578,6 @@
"type": "String",
"placeholders": {}
},
"openChat": "Aperter li conversation",
"@openChat": {},
"reportMessage": "Raportar li missage",
"@reportMessage": {
"type": "String",

@ -2278,8 +2278,6 @@
"@noBackupWarning": {},
"storeInSecureStorageDescription": "Salva la chiave di recupero nell'archivio sicuro di questo dispositivo.",
"@storeInSecureStorageDescription": {},
"openChat": "Apri la Chat",
"@openChat": {},
"kickUserDescription": "L'utente è stato rimosso, ma non bannato. Nelle chat pubbliche, l'utente potrà rientrare quando vuole.",
"@kickUserDescription": {},
"importNow": "Importa ora",

@ -1841,7 +1841,6 @@
"openGallery": "ギャラリーを開く",
"removeFromSpace": "スペースから削除",
"pleaseEnterRecoveryKeyDescription": "古いメッセージを解除するには、以前のセッションで生成されたリカバリーキーを入力してください。リカバリーキーはパスワードではありません。",
"openChat": "チャットを開く",
"experimentalVideoCalls": "実験的なビデオ通話",
"youAcceptedTheInvitation": "👍 招待を承諾しました",
"youUnbannedUser": "{user} の禁止を解除しました",

@ -1183,7 +1183,6 @@
"openGallery": "Ldi timidelt",
"removeFromSpace": "Kkes seg tallunt",
"start": "Senker",
"openChat": "Ldi Adiwenni",
"markAsRead": "Creḍ amzun yettwaɣṛa",
"reportUser": "Cetki aseqdac",
"dismiss": "Agi",

@ -1939,8 +1939,6 @@
"@markAsRead": {},
"reportUser": "유저 신고",
"@reportUser": {},
"openChat": "채팅 열기",
"@openChat": {},
"reactedWith": "{sender}가 {reaction}로 반응함",
"@reactedWith": {
"type": "String",

@ -1391,8 +1391,6 @@
}
}
},
"openChat": "Atverti pokalbį",
"@openChat": {},
"reportUser": "Pranešti apie vartotoją",
"@reportUser": {},
"dismiss": "Atsisakyti",

@ -2117,7 +2117,6 @@
"placeholders": {}
},
"storeInSecureStorageDescription": "Glabāt atkopes atslēgu šīs ierīces drošajā krātuvē.",
"openChat": "Atvērt tērzēšanu",
"kickUserDescription": "Lietotājs ir izmests no tērzēšanas, bet piekļuve nav liegta. Publiskās tērzēšanās lietotājs var atkārtoti pievienoties jebkurā laikā.",
"sendAMessage": "Nosūtīt ziņu",
"@sendAMessage": {

@ -1694,7 +1694,6 @@
"placeholders": {}
},
"dismiss": "Avvis",
"openChat": "Åpne chat",
"reopenChat": "Gjenåpne chat",
"changeTheDescriptionOfTheGroup": "Endre beskrivelsen til chatten",
"inviteOtherUsers": "Inviter andre brukere til denne chatten",

@ -1913,7 +1913,6 @@
"dismiss": "Sluiten",
"markAsRead": "Markeer als gelezen",
"reportUser": "Persoon rapporteren",
"openChat": "Chat openen",
"reactedWith": "{sender} reageerde met {reaction}",
"@reactedWith": {
"type": "String",

@ -1909,7 +1909,6 @@
"type": "String",
"placeholders": {}
},
"openChat": "Otwórz czat",
"supposedMxid": "To powinno być {mxid}",
"@supposedMxid": {
"type": "String",

@ -1912,7 +1912,6 @@
"openGallery": "Abrir galeria",
"markAsRead": "Marcar como lido",
"dismiss": "Descartar",
"openChat": "Abrir conversa",
"reportUser": "Denunciar usuário",
"emojis": "Emojis",
"placeCall": "Chamar",

@ -540,8 +540,6 @@
}
}
},
"openChat": "Deschideți Chat",
"@openChat": {},
"youBannedUser": "Ați interzis pe {user}",
"@youBannedUser": {
"placeholders": {

@ -1905,7 +1905,6 @@
"dismiss": "Отклонить",
"markAsRead": "Отметить как прочитанное",
"reportUser": "Сообщить о пользователе",
"openChat": "Открыть чат",
"reactedWith": "{sender} реагирует с {reaction}",
"@reactedWith": {
"type": "String",

@ -1908,7 +1908,6 @@
},
"link": "Länk",
"reportUser": "Rapportera användare",
"openChat": "Öppna Chatt",
"sendOnEnter": "Skicka med Enter",
"scanQrCode": "Skanna QR-kod",
"yourChatBackupHasBeenSetUp": "Din chatt-backup har konfigurerats.",

@ -820,7 +820,6 @@
"placeholders": {}
},
"time": "நேரம்",
"openChat": "திறந்த அரட்டை",
"markAsRead": "படித்தபடி குறி",
"reportUser": "பயனர் புகாரளிக்கவும்",
"dismiss": "தள்ளுபடி",

@ -1859,7 +1859,6 @@
"placeholders": {}
},
"@storeInSecureStorageDescription": {},
"@openChat": {},
"@kickUserDescription": {},
"@sendAMessage": {
"type": "String",

@ -1940,8 +1940,6 @@
"@markAsRead": {},
"reportUser": "Kullanıcıyı bildir",
"@reportUser": {},
"openChat": "Sohbeti Aç",
"@openChat": {},
"reactedWith": "{sender}, {reaction} ile tepki verdi",
"@reactedWith": {
"type": "String",

@ -1914,7 +1914,6 @@
"dismiss": "Відхилити",
"markAsRead": "Позначити прочитаним",
"reportUser": "Поскаржився на користувача",
"openChat": "Відкрити бесіду",
"reactedWith": "{sender} реагує з {reaction}",
"@reactedWith": {
"type": "String",

@ -2093,7 +2093,6 @@
}
},
"newSpaceDescription": "Maydonlar sizga suhbatlaringizni birlashtirish va shaxsiy yoki ommaviy hamjamiyatlarni yaratish imkonini beradi.",
"openChat": "Suhbatni ochish",
"youJoinedTheChat": "Siz suhbatga qoʻshildingiz",
"encryptThisChat": "Bu suhbatni shifrlash",
"disableEncryptionWarning": "Xavfsizlik nuqtai nazaridan, agar u ilgari yoqilgan boʻlsa, suhbatda shifrlashni oʻchirib qoʻyolmaysiz.",

@ -1914,7 +1914,6 @@
"dismiss": "忽略",
"markAsRead": "标为已读",
"reportUser": "举报用户",
"openChat": "打开聊天",
"reactedWith": "{sender} 回应了 {reaction}",
"@reactedWith": {
"type": "String",

@ -2564,8 +2564,6 @@
"@spaces": {},
"start": "開始",
"@start": {},
"openChat": "開啟聊天室",
"@openChat": {},
"unreadChatsInApp": "{appname}{unread} 未讀聊天室",
"@unreadChatsInApp": {
"type": "String",

@ -3,10 +3,7 @@
//
// SPDX-License-Identifier: AGPL-3.0-or-later
import 'dart:io';
import 'package:collection/collection.dart';
import 'package:desktop_notifications/desktop_notifications.dart';
import 'package:fluffychat/config/setting_keys.dart';
import 'package:fluffychat/l10n/l10n.dart';
import 'package:fluffychat/utils/custom_http_client.dart';
@ -158,15 +155,6 @@ abstract class ClientManager {
html.Notification(title, body: body);
return;
}
if (Platform.isLinux) {
await NotificationsClient().notify(
title,
body: body,
appName: AppSettings.applicationName.value,
hints: [NotificationHint.soundName('message-new-instant')],
);
return;
}
final flutterLocalNotificationsPlugin = FlutterLocalNotificationsPlugin();

@ -191,8 +191,14 @@ Future<void> notificationTap(
);
case FluffyChatNotificationActions.mute:
await room.setPushRuleState(PushRuleState.mentionsOnly);
case FluffyChatNotificationActions.open:
router?.go(
client.getRoomById(roomId)?.membership == Membership.invite
? '/rooms?client=${client.clientName}'
: '/rooms/$roomId?client=${client.clientName}',
);
}
}
}
enum FluffyChatNotificationActions { markAsRead, reply, mute }
enum FluffyChatNotificationActions { markAsRead, reply, mute, open }

@ -3,20 +3,16 @@
//
// SPDX-License-Identifier: AGPL-3.0-or-later
import 'dart:io';
import 'package:collection/collection.dart';
import 'package:desktop_notifications/desktop_notifications.dart';
import 'package:fluffychat/config/setting_keys.dart';
import 'package:fluffychat/l10n/l10n.dart';
import 'package:fluffychat/utils/client_download_content_extension.dart';
import 'package:fluffychat/utils/matrix_sdk_extensions/matrix_locals.dart';
import 'package:fluffychat/utils/notification_background_handler.dart';
import 'package:fluffychat/utils/push_helper.dart';
import 'package:fluffychat/widgets/fluffy_chat_app.dart';
import 'package:fluffychat/widgets/matrix.dart';
import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
import 'package:image/image.dart';
import 'package:flutter_local_notifications/flutter_local_notifications.dart';
import 'package:matrix/matrix.dart';
import 'package:universal_html/html.dart' as html;
@ -47,54 +43,15 @@ extension LocalNotificationsExtension on MatrixState {
hideEdit: true,
removeMarkdown: true,
);
final avatarUrl = event.room.avatar;
if (kIsWeb) {
final avatarUrl = event.senderFromMemoryOrFallback.avatarUrl;
Uri? thumbnailUri;
if (avatarUrl != null) {
const size = 128;
const thumbnailMethod = ThumbnailMethod.crop;
// Pre-cache so that we can later just set the thumbnail uri as icon:
try {
await client.downloadMxcCached(
avatarUrl,
width: size,
height: size,
thumbnailMethod: thumbnailMethod,
isThumbnail: true,
rounded: true,
);
} catch (e, s) {
Logs().d('Unable to pre-download avatar for web notification', e, s);
}
thumbnailUri = await event.senderFromMemoryOrFallback.avatarUrl
?.getThumbnailUri(
client,
width: size,
height: size,
method: thumbnailMethod,
);
}
const size = 128;
const thumbnailMethod = ThumbnailMethod.crop;
if (AppSettings.webNotificationSound.value) _audioPlayer.play();
html.Notification(
title,
body: body,
icon: thumbnailUri?.toString(),
tag: event.room.id,
);
} else if (Platform.isLinux) {
final avatarUrl = event.room.avatar;
final hints = [NotificationHint.soundName('message-new-instant')];
if (avatarUrl != null) {
const size = notificationAvatarDimension;
const thumbnailMethod = ThumbnailMethod.crop;
// Pre-cache so that we can later just set the thumbnail uri as icon:
final data = await client.downloadMxcCached(
if (avatarUrl != null) {
// Pre-cache so that we can later just set the thumbnail uri as icon:
try {
await client.downloadMxcCached(
avatarUrl,
width: size,
height: size,
@ -102,66 +59,54 @@ extension LocalNotificationsExtension on MatrixState {
isThumbnail: true,
rounded: true,
);
final image = decodeImage(data);
if (image != null) {
final realData = image.getBytes(order: ChannelOrder.rgba);
hints.add(
NotificationHint.imageData(
image.width,
image.height,
realData,
hasAlpha: true,
channels: 4,
),
);
}
} catch (e, s) {
Logs().d('Unable to pre-download avatar for web notification', e, s);
}
final notification = await linuxNotifications!.notify(
}
if (kIsWeb) {
final thumbnailUri = await avatarUrl?.getThumbnailUri(
client,
width: size,
height: size,
method: thumbnailMethod,
);
if (AppSettings.webNotificationSound.value) _audioPlayer.play();
html.Notification(
title,
body: body,
replacesId: linuxNotificationIds[roomId] ?? 0,
appName: AppSettings.applicationName.value,
appIcon: 'fluffychat',
actions: [
NotificationAction(
DesktopNotificationActions.openChat.name,
l10n.openChat,
),
NotificationAction(
DesktopNotificationActions.seen.name,
l10n.markAsRead,
),
],
hints: hints,
icon: thumbnailUri?.toString(),
tag: event.room.id,
);
notification.action.then((actionStr) {
var action = DesktopNotificationActions.values.singleWhereOrNull(
(a) => a.name == actionStr,
);
if (action == null && actionStr == 'default') {
action = DesktopNotificationActions.openChat;
}
switch (action!) {
case DesktopNotificationActions.seen:
event.room.setReadMarker(
event.eventId,
mRead: event.eventId,
public: AppSettings.sendPublicReadReceipts.value,
);
break;
case DesktopNotificationActions.openChat:
setActiveClient(event.room.client);
FluffyChatApp.router.go(
'/rooms/${event.room.id}?client=${event.room.client.clientName}',
);
break;
}
});
linuxNotificationIds[roomId] = notification.id;
return;
}
FlutterLocalNotificationsPlugin().show(
id: event.room.id.hashCode,
title: title,
body: body,
notificationDetails: NotificationDetails(
linux: LinuxNotificationDetails(
sound: ThemeLinuxSound('message-new-instant'),
actions: [
LinuxNotificationAction(
key: FluffyChatNotificationActions.markAsRead.name,
label: l10n.markAsRead,
),
LinuxNotificationAction(
key: FluffyChatNotificationActions.mute.name,
label: l10n.mute,
),
],
),
),
payload: FluffyChatPushPayload(
client.clientName,
event.room.id,
event.eventId,
).toString(),
);
}
}
enum DesktopNotificationActions { seen, openChat }

@ -7,11 +7,11 @@ import 'dart:async';
import 'dart:convert';
import 'package:collection/collection.dart';
import 'package:desktop_notifications/desktop_notifications.dart';
import 'package:fluffychat/l10n/l10n.dart';
import 'package:fluffychat/utils/client_manager.dart';
import 'package:fluffychat/utils/init_with_restore.dart';
import 'package:fluffychat/utils/matrix_sdk_extensions/matrix_file_extension.dart';
import 'package:fluffychat/utils/notification_background_handler.dart';
import 'package:fluffychat/utils/platform_infos.dart';
import 'package:fluffychat/utils/uia_request_manager.dart';
import 'package:fluffychat/utils/voip_plugin.dart';
@ -20,6 +20,7 @@ import 'package:fluffychat/widgets/fluffy_chat_app.dart';
import 'package:fluffychat/widgets/future_loading_dialog.dart';
import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
import 'package:flutter_local_notifications/flutter_local_notifications.dart';
import 'package:image_picker/image_picker.dart';
import 'package:intl/intl.dart';
import 'package:just_audio/just_audio.dart';
@ -205,11 +206,6 @@ class MatrixState extends State<Matrix> with WidgetsBindingObserver {
return route.split('/')[2];
}
final linuxNotifications = PlatformInfos.isLinux
? NotificationsClient()
: null;
final Map<String, int> linuxNotificationIds = {};
@override
void initState() {
super.initState();
@ -289,6 +285,19 @@ class MatrixState extends State<Matrix> with WidgetsBindingObserver {
});
onUiaRequest[name] ??= c.onUiaRequest.stream.listen(uiaRequestHandler);
if (PlatformInfos.isWeb || PlatformInfos.isLinux) {
FlutterLocalNotificationsPlugin().initialize(
settings: InitializationSettings(
linux: LinuxInitializationSettings(
defaultActionName: FluffyChatNotificationActions.open.name,
),
),
onDidReceiveNotificationResponse: (response) => notificationTap(
response,
clients: widget.clients,
router: FluffyChatApp.router,
l10n: null,
),
);
c.onSync.stream.first.then((s) {
html.Notification.requestPermission();
onNotification[name] ??= c.onNotification.stream.listen(
@ -381,8 +390,6 @@ class MatrixState extends State<Matrix> with WidgetsBindingObserver {
onLogoutSub.values.map((s) => s.cancel());
onNotification.values.map((s) => s.cancel());
linuxNotifications?.close();
super.dispose();
}

@ -305,14 +305,6 @@ packages:
url: "https://pub.dev"
source: hosted
version: "0.7.1"
desktop_notifications:
dependency: "direct main"
description:
name: desktop_notifications
sha256: "6d92694ad6e9297a862c5ff7dd6b8ff64c819972557754769f819d2209612927"
url: "https://pub.dev"
source: hosted
version: "0.6.3"
desktop_webview_window:
dependency: transitive
description:

@ -23,7 +23,6 @@ dependencies:
collection: ^1.18.0
cross_file: ^0.3.5
desktop_drop: ^0.7.1
desktop_notifications: ^0.6.3
device_info_plus: ^12.4.0
dynamic_color: ^1.8.1
emoji_picker_flutter: ^4.4.0

Loading…
Cancel
Save