* chore: Nicer invite selection view
* chore: Do not request thousands of users on invite page
* build(deps): bump rexml from 3.3.6 to 3.3.9 in /ios
Bumps [rexml](https://github.com/ruby/rexml) from 3.3.6 to 3.3.9.
- [Release notes](https://github.com/ruby/rexml/releases)
- [Changelog](https://github.com/ruby/rexml/blob/master/NEWS.md)
- [Commits](https://github.com/ruby/rexml/compare/v3.3.6...v3.3.9)
---
updated-dependencies:
- dependency-name: rexml
dependency-type: indirect
...
Signed-off-by: dependabot[bot] <support@github.com>
* design: Highlight emoji only messages
* chore: Follow up emoji only messages
* Translated using Weblate (Galician)
Currently translated at 100.0% (672 of 672 strings)
Translation: FluffyChat/Translations
Translate-URL: https://hosted.weblate.org/projects/fluffychat/translations/gl/
* Translated using Weblate (Russian)
Currently translated at 99.7% (670 of 672 strings)
Translation: FluffyChat/Translations
Translate-URL: https://hosted.weblate.org/projects/fluffychat/translations/ru/
* design: New login design
* chore: Improve spaces design
* chore: Improve spaces design
* chore: Improved UX for creating groups and spaces
* Translated using Weblate (German)
Currently translated at 100.0% (672 of 672 strings)
Translation: FluffyChat/Translations
Translate-URL: https://hosted.weblate.org/projects/fluffychat/translations/de/
* feat: Better wallpapers with blur and opacity sliders and improved styles page
* chore: Follow up wallpaper configs
* chore: Add max length to state messages
* chore: Follow up wallpaper design
* feat: Open account manage url when using MAS
* chore: follow up wellknown fetch
* Translated using Weblate (Arabic)
Currently translated at 100.0% (674 of 674 strings)
Translation: FluffyChat/Translations
Translate-URL: https://hosted.weblate.org/projects/fluffychat/translations/ar/
* Translated using Weblate (Estonian)
Currently translated at 100.0% (674 of 674 strings)
Translation: FluffyChat/Translations
Translate-URL: https://hosted.weblate.org/projects/fluffychat/translations/et/
* Translated using Weblate (Chinese (Simplified Han script))
Currently translated at 100.0% (674 of 674 strings)
Translation: FluffyChat/Translations
Translate-URL: https://hosted.weblate.org/projects/fluffychat/translations/zh_Hans/
* Translated using Weblate (Indonesian)
Currently translated at 100.0% (674 of 674 strings)
Translation: FluffyChat/Translations
Translate-URL: https://hosted.weblate.org/projects/fluffychat/translations/id/
* Translated using Weblate (Finnish)
Currently translated at 79.0% (533 of 674 strings)
Translation: FluffyChat/Translations
Translate-URL: https://hosted.weblate.org/projects/fluffychat/translations/fi/
* Translated using Weblate (Latvian)
Currently translated at 100.0% (674 of 674 strings)
Translation: FluffyChat/Translations
Translate-URL: https://hosted.weblate.org/projects/fluffychat/translations/lv/
* build: Add links to snapcraft.yaml file
* chore: Nicer empty page
* chore: Polish chat bubble colors
* chore: Follow up chat bubble design
* refactor: Remove unnecessary builder widget
* chore: Design adjustments
* chore: Follow up design
* refactor: Display two lines on new messages
* chore: Design follow up
* Translated using Weblate (Arabic)
Currently translated at 100.0% (678 of 678 strings)
Translation: FluffyChat/Translations
Translate-URL: https://hosted.weblate.org/projects/fluffychat/translations/ar/
* Translated using Weblate (German)
Currently translated at 100.0% (678 of 678 strings)
Translation: FluffyChat/Translations
Translate-URL: https://hosted.weblate.org/projects/fluffychat/translations/de/
* Translated using Weblate (Estonian)
Currently translated at 99.7% (676 of 678 strings)
Translation: FluffyChat/Translations
Translate-URL: https://hosted.weblate.org/projects/fluffychat/translations/et/
* Translated using Weblate (Basque)
Currently translated at 100.0% (678 of 678 strings)
Translation: FluffyChat/Translations
Translate-URL: https://hosted.weblate.org/projects/fluffychat/translations/eu/
* Translated using Weblate (Ukrainian)
Currently translated at 100.0% (678 of 678 strings)
Translation: FluffyChat/Translations
Translate-URL: https://hosted.weblate.org/projects/fluffychat/translations/uk/
* Translated using Weblate (Chinese (Simplified Han script))
Currently translated at 100.0% (678 of 678 strings)
Translation: FluffyChat/Translations
Translate-URL: https://hosted.weblate.org/projects/fluffychat/translations/zh_Hans/
* chore: Follow up message bubbles
* chore: Follow up design
* chore: Follow up design
* chore: Follow up colors
* chore: Follow up homeserverpicker UX
* chore: Design follow up
* feat: Add about server page
* chore: Follow up update snackbar
* chore: Polish login design
* chore: Follow up login page
* chore: Follow up homeserver picker
* chore: Follow up appbar shadow
* refactor: Performance boost for avatar widget
* Revert "refactor: Performance boost for avatar widget"
This reverts commit 58577bb9e8.
* Translated using Weblate (Estonian)
Currently translated at 100.0% (678 of 678 strings)
Translation: FluffyChat/Translations
Translate-URL: https://hosted.weblate.org/projects/fluffychat/translations/et/
* Translated using Weblate (Ukrainian)
Currently translated at 100.0% (678 of 678 strings)
Translation: FluffyChat/Translations
Translate-URL: https://hosted.weblate.org/projects/fluffychat/translations/uk/
* Translated using Weblate (Latvian)
Currently translated at 100.0% (678 of 678 strings)
Translation: FluffyChat/Translations
Translate-URL: https://hosted.weblate.org/projects/fluffychat/translations/lv/
* Translated using Weblate (Arabic)
Currently translated at 100.0% (687 of 687 strings)
Translation: FluffyChat/Translations
Translate-URL: https://hosted.weblate.org/projects/fluffychat/translations/ar/
* Translated using Weblate (Estonian)
Currently translated at 100.0% (687 of 687 strings)
Translation: FluffyChat/Translations
Translate-URL: https://hosted.weblate.org/projects/fluffychat/translations/et/
* Translated using Weblate (Basque)
Currently translated at 100.0% (687 of 687 strings)
Translation: FluffyChat/Translations
Translate-URL: https://hosted.weblate.org/projects/fluffychat/translations/eu/
* Translated using Weblate (Galician)
Currently translated at 100.0% (687 of 687 strings)
Translation: FluffyChat/Translations
Translate-URL: https://hosted.weblate.org/projects/fluffychat/translations/gl/
* Translated using Weblate (Chinese (Simplified Han script))
Currently translated at 100.0% (687 of 687 strings)
Translation: FluffyChat/Translations
Translate-URL: https://hosted.weblate.org/projects/fluffychat/translations/zh_Hans/
* Translated using Weblate (Indonesian)
Currently translated at 100.0% (687 of 687 strings)
Translation: FluffyChat/Translations
Translate-URL: https://hosted.weblate.org/projects/fluffychat/translations/id/
* Translated using Weblate (Latvian)
Currently translated at 100.0% (687 of 687 strings)
Translation: FluffyChat/Translations
Translate-URL: https://hosted.weblate.org/projects/fluffychat/translations/lv/
* Translated using Weblate (Ukrainian)
Currently translated at 100.0% (687 of 687 strings)
Translation: FluffyChat/Translations
Translate-URL: https://hosted.weblate.org/projects/fluffychat/translations/uk/
* Translated using Weblate (Korean)
Currently translated at 100.0% (687 of 687 strings)
Translation: FluffyChat/Translations
Translate-URL: https://hosted.weblate.org/projects/fluffychat/translations/ko/
* chore: Follow up homeserver input field
* refactor: Move to upstream geolocator
* chore: Follow up send file dialog
* Translated using Weblate (Spanish)
Currently translated at 74.6% (513 of 687 strings)
Translation: FluffyChat/Translations
Translate-URL: https://hosted.weblate.org/projects/fluffychat/translations/es/
* refactor: Migrate to newer keyboard shortcuts package
* refactor: Remove keyboard shortcuts
This package right now
makes the web app
nearly unusable as it
throws multiple errors on
every key press. The
package seems to be
unmaintained. I tried
two other packages
and none of them worked.
* build: Update matrix dart sdk to 0.35.0
* chore: Better FluffyChat Logo for PWA
* build: (deps): bump samuelmeuli/action-snapcraft from 2 to 3
Bumps [samuelmeuli/action-snapcraft](https://github.com/samuelmeuli/action-snapcraft) from 2 to 3.
- [Release notes](https://github.com/samuelmeuli/action-snapcraft/releases)
- [Commits](https://github.com/samuelmeuli/action-snapcraft/compare/v2...v3)
---
updated-dependencies:
- dependency-name: samuelmeuli/action-snapcraft
dependency-type: direct:production
update-type: version-update:semver-major
...
Signed-off-by: dependabot[bot] <support@github.com>
* chore: Follow up send file dialog
* feat: Add markdown context actions for text input
* build: Update flutter to 3.24.5
* build: Remove snapcraft build workaround
* chore: Better error message when join room failed
* chore: Follow up join room
* chore: Make error dialog show full error
* chore: Follow up loading dialog
* chore: Follow up loading dialog
* build: Snapcraft from local build file
* chore: Follow up build snap
* chore: Follow up snapcraft in ci
* build: Revert build snapcraft changes
* build: Try downgrading flutter web auth
* chore: add hint in pubspec.yaml regarding flutter_web_auth_2
* Translated using Weblate (Estonian)
Currently translated at 100.0% (688 of 688 strings)
Translation: FluffyChat/Translations
Translate-URL: https://hosted.weblate.org/projects/fluffychat/translations/et/
* Translated using Weblate (Galician)
Currently translated at 100.0% (688 of 688 strings)
Translation: FluffyChat/Translations
Translate-URL: https://hosted.weblate.org/projects/fluffychat/translations/gl/
* Translated using Weblate (Chinese (Simplified Han script))
Currently translated at 100.0% (688 of 688 strings)
Translation: FluffyChat/Translations
Translate-URL: https://hosted.weblate.org/projects/fluffychat/translations/zh_Hans/
* Translated using Weblate (Indonesian)
Currently translated at 100.0% (688 of 688 strings)
Translation: FluffyChat/Translations
Translate-URL: https://hosted.weblate.org/projects/fluffychat/translations/id/
* Translated using Weblate (Irish)
Currently translated at 100.0% (688 of 688 strings)
Translation: FluffyChat/Translations
Translate-URL: https://hosted.weblate.org/projects/fluffychat/translations/ga/
* Translated using Weblate (Arabic)
Currently translated at 100.0% (688 of 688 strings)
Translation: FluffyChat/Translations
Translate-URL: https://hosted.weblate.org/projects/fluffychat/translations/ar/
* Translated using Weblate (Basque)
Currently translated at 100.0% (688 of 688 strings)
Translation: FluffyChat/Translations
Translate-URL: https://hosted.weblate.org/projects/fluffychat/translations/eu/
* Translated using Weblate (Ukrainian)
Currently translated at 100.0% (688 of 688 strings)
Translation: FluffyChat/Translations
Translate-URL: https://hosted.weblate.org/projects/fluffychat/translations/uk/
* Translated using Weblate (Latvian)
Currently translated at 100.0% (688 of 688 strings)
Translation: FluffyChat/Translations
Translate-URL: https://hosted.weblate.org/projects/fluffychat/translations/lv/
* Translated using Weblate (Italian)
Currently translated at 100.0% (688 of 688 strings)
Translation: FluffyChat/Translations
Translate-URL: https://hosted.weblate.org/projects/fluffychat/translations/it/
* Translated using Weblate (Estonian)
Currently translated at 100.0% (694 of 694 strings)
Translation: FluffyChat/Translations
Translate-URL: https://hosted.weblate.org/projects/fluffychat/translations/et/
* Translated using Weblate (Chinese (Simplified Han script))
Currently translated at 100.0% (694 of 694 strings)
Translation: FluffyChat/Translations
Translate-URL: https://hosted.weblate.org/projects/fluffychat/translations/zh_Hans/
* Translated using Weblate (Arabic)
Currently translated at 100.0% (694 of 694 strings)
Translation: FluffyChat/Translations
Translate-URL: https://hosted.weblate.org/projects/fluffychat/translations/ar/
* Translated using Weblate (Basque)
Currently translated at 100.0% (694 of 694 strings)
Translation: FluffyChat/Translations
Translate-URL: https://hosted.weblate.org/projects/fluffychat/translations/eu/
* Translated using Weblate (Irish)
Currently translated at 100.0% (694 of 694 strings)
Translation: FluffyChat/Translations
Translate-URL: https://hosted.weblate.org/projects/fluffychat/translations/ga/
* Translated using Weblate (Indonesian)
Currently translated at 100.0% (694 of 694 strings)
Translation: FluffyChat/Translations
Translate-URL: https://hosted.weblate.org/projects/fluffychat/translations/id/
* Translated using Weblate (Latvian)
Currently translated at 100.0% (694 of 694 strings)
Translation: FluffyChat/Translations
Translate-URL: https://hosted.weblate.org/projects/fluffychat/translations/lv/
* Translated using Weblate (Arabic)
Currently translated at 100.0% (695 of 695 strings)
Translation: FluffyChat/Translations
Translate-URL: https://hosted.weblate.org/projects/fluffychat/translations/ar/
* Translated using Weblate (Estonian)
Currently translated at 100.0% (695 of 695 strings)
Translation: FluffyChat/Translations
Translate-URL: https://hosted.weblate.org/projects/fluffychat/translations/et/
* Translated using Weblate (Chinese (Simplified Han script))
Currently translated at 100.0% (695 of 695 strings)
Translation: FluffyChat/Translations
Translate-URL: https://hosted.weblate.org/projects/fluffychat/translations/zh_Hans/
* Translated using Weblate (Irish)
Currently translated at 99.8% (694 of 695 strings)
Translation: FluffyChat/Translations
Translate-URL: https://hosted.weblate.org/projects/fluffychat/translations/ga/
* Translated using Weblate (German)
Currently translated at 99.5% (692 of 695 strings)
Translation: FluffyChat/Translations
Translate-URL: https://hosted.weblate.org/projects/fluffychat/translations/de/
* fix: dont use thumbnails for emoticons
* chore: Improve presence performance
* Translated using Weblate (Basque)
Currently translated at 100.0% (695 of 695 strings)
Translation: FluffyChat/Translations
Translate-URL: https://hosted.weblate.org/projects/fluffychat/translations/eu/
* Translated using Weblate (Galician)
Currently translated at 100.0% (695 of 695 strings)
Translation: FluffyChat/Translations
Translate-URL: https://hosted.weblate.org/projects/fluffychat/translations/gl/
* Translated using Weblate (Italian)
Currently translated at 100.0% (695 of 695 strings)
Translation: FluffyChat/Translations
Translate-URL: https://hosted.weblate.org/projects/fluffychat/translations/it/
* Translated using Weblate (Irish)
Currently translated at 100.0% (695 of 695 strings)
Translation: FluffyChat/Translations
Translate-URL: https://hosted.weblate.org/projects/fluffychat/translations/ga/
* Translated using Weblate (Russian)
Currently translated at 100.0% (695 of 695 strings)
Translation: FluffyChat/Translations
Translate-URL: https://hosted.weblate.org/projects/fluffychat/translations/ru/
* Translated using Weblate (Ukrainian)
Currently translated at 100.0% (695 of 695 strings)
Translation: FluffyChat/Translations
Translate-URL: https://hosted.weblate.org/projects/fluffychat/translations/uk/
* Translated using Weblate (Catalan)
Currently translated at 95.1% (661 of 695 strings)
Translation: FluffyChat/Translations
Translate-URL: https://hosted.weblate.org/projects/fluffychat/translations/ca/
* build: Bump version
* chore: Follow up send file dialog for images
* chore: Follow up send multiple images
* build: Add android build workaround for new flutter version
* build: Use file selector to save files
* chore: Follow up save file on desktop
* chore: Adjust default linux window height
* refactor: Update to new receive sharing intent package
* fluffychat merge
* fluffychat merge
* fluffychat merge
* fix android build
* fluffychat merge
* fluffychat merge
---------
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: Krille <c.kussowski@famedly.com>
Co-authored-by: Krille-chan <christian-kussowski@posteo.de>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: josé m <correoxm@disroot.org>
Co-authored-by: v1s7 <v1s7@users.noreply.hosted.weblate.org>
Co-authored-by: Christian <christian-pauly@posteo.de>
Co-authored-by: Rex_sa <rex.sa@pm.me>
Co-authored-by: Priit Jõerüüt <hwlate@joeruut.com>
Co-authored-by: 大王叫我来巡山 <hamburger2048@users.noreply.hosted.weblate.org>
Co-authored-by: Linerly <linerly@proton.me>
Co-authored-by: Edgars Andersons <Edgars+Weblate@gaitenis.id.lv>
Co-authored-by: xabirequejo <xabi.rn@gmail.com>
Co-authored-by: Bezruchenko Simon <worcposj44@gmail.com>
Co-authored-by: Ihor Hordiichuk <igor_ck@outlook.com>
Co-authored-by: Bruno Roh <kane.roh429@gmail.com>
Co-authored-by: Kimby <kimisaes@naver.com>
Co-authored-by: Aindriú Mac Giolla Eoin <aindriu80@gmail.com>
Co-authored-by: Angelo Schirinzi <muten619@hotmail.it>
Co-authored-by: Marek Vospěl <marek@vospel.cz>
Co-authored-by: Александр (Alexandr1995) <stupino19951406@gmail.com>
523 lines
16 KiB
Dart
523 lines
16 KiB
Dart
/*
|
|
* Famedly
|
|
* Copyright (C) 2020, 2021 Famedly GmbH
|
|
* Copyright (C) 2021 Fluffychat
|
|
*
|
|
* This program is free software: you can redistribute it and/or modify
|
|
* it under the terms of the GNU Affero General Public License as
|
|
* published by the Free Software Foundation, either version 3 of the
|
|
* License, or (at your option) any later version.
|
|
*
|
|
* This program is distributed in the hope that it will be useful,
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
* GNU Affero General Public License for more details.
|
|
*
|
|
* You should have received a copy of the GNU Affero General Public License
|
|
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
|
*/
|
|
|
|
import 'dart:async';
|
|
import 'dart:convert';
|
|
import 'dart:io';
|
|
|
|
import 'package:fcm_shared_isolate/fcm_shared_isolate.dart';
|
|
import 'package:firebase_core/firebase_core.dart';
|
|
import 'package:firebase_messaging/firebase_messaging.dart';
|
|
import 'package:fluffychat/pangea/constants/language_constants.dart';
|
|
import 'package:fluffychat/pangea/utils/error_handler.dart';
|
|
import 'package:fluffychat/utils/push_helper.dart';
|
|
import 'package:fluffychat/widgets/fluffy_chat_app.dart';
|
|
import 'package:flutter/foundation.dart';
|
|
import 'package:flutter/material.dart';
|
|
import 'package:flutter_app_badger/flutter_app_badger.dart';
|
|
import 'package:flutter_gen/gen_l10n/l10n.dart';
|
|
import 'package:flutter_local_notifications/flutter_local_notifications.dart';
|
|
import 'package:http/http.dart' as http;
|
|
import 'package:matrix/matrix.dart';
|
|
import 'package:unifiedpush/unifiedpush.dart';
|
|
import 'package:unifiedpush_ui/unifiedpush_ui.dart';
|
|
|
|
import '../config/app_config.dart';
|
|
import '../config/setting_keys.dart';
|
|
import '../widgets/matrix.dart';
|
|
import 'platform_infos.dart';
|
|
|
|
//import 'package:fcm_shared_isolate/fcm_shared_isolate.dart';
|
|
|
|
class NoTokenException implements Exception {
|
|
String get cause => 'Cannot get firebase token';
|
|
}
|
|
|
|
class BackgroundPush {
|
|
static BackgroundPush? _instance;
|
|
final FlutterLocalNotificationsPlugin _flutterLocalNotificationsPlugin =
|
|
FlutterLocalNotificationsPlugin();
|
|
Client client;
|
|
MatrixState? matrix;
|
|
String? _fcmToken;
|
|
void Function(String errorMsg, {Uri? link})? onFcmError;
|
|
L10n? l10n;
|
|
|
|
Future<void> loadLocale() async {
|
|
final context = matrix?.context;
|
|
// inspired by _lookupL10n in .dart_tool/flutter_gen/gen_l10n/l10n.dart
|
|
l10n ??= (context != null ? L10n.of(context) : null) ??
|
|
(await L10n.delegate.load(PlatformDispatcher.instance.locale));
|
|
}
|
|
|
|
final pendingTests = <String, Completer<void>>{};
|
|
|
|
// final dynamic firebase = null; //FcmSharedIsolate();
|
|
// #Pangea
|
|
// uncommented to enable notifications on IOS
|
|
final FcmSharedIsolate? firebase = FcmSharedIsolate();
|
|
// Pangea#
|
|
|
|
DateTime? lastReceivedPush;
|
|
|
|
bool upAction = false;
|
|
|
|
void _init() async {
|
|
try {
|
|
// #Pangea
|
|
onLogin ??=
|
|
client.onLoginStateChanged.stream.listen(handleLoginStateChanged);
|
|
// Pangea#
|
|
await _flutterLocalNotificationsPlugin.initialize(
|
|
const InitializationSettings(
|
|
android: AndroidInitializationSettings('notifications_icon'),
|
|
iOS: DarwinInitializationSettings(),
|
|
),
|
|
onDidReceiveNotificationResponse: goToRoom,
|
|
);
|
|
Logs().v('Flutter Local Notifications initialized');
|
|
firebase?.setListeners(
|
|
onMessage: (message) => pushHelper(
|
|
PushNotification.fromJson(
|
|
Map<String, dynamic>.from(message['data'] ?? message),
|
|
),
|
|
client: client,
|
|
l10n: l10n,
|
|
activeRoomId: matrix?.activeRoomId,
|
|
flutterLocalNotificationsPlugin: _flutterLocalNotificationsPlugin,
|
|
),
|
|
// #Pangea
|
|
onNewToken: _newFcmToken,
|
|
// Pangea#
|
|
);
|
|
if (Platform.isAndroid) {
|
|
await UnifiedPush.initialize(
|
|
onNewEndpoint: _newUpEndpoint,
|
|
onRegistrationFailed: _upUnregistered,
|
|
onUnregistered: _upUnregistered,
|
|
onMessage: _onUpMessage,
|
|
);
|
|
}
|
|
} catch (e, s) {
|
|
Logs().e('Unable to initialize Flutter local notifications', e, s);
|
|
}
|
|
}
|
|
|
|
BackgroundPush._(this.client) {
|
|
_init();
|
|
}
|
|
|
|
factory BackgroundPush.clientOnly(Client client) {
|
|
return _instance ??= BackgroundPush._(client);
|
|
}
|
|
|
|
factory BackgroundPush(
|
|
MatrixState matrix, {
|
|
final void Function(String errorMsg, {Uri? link})? onFcmError,
|
|
}) {
|
|
final instance = BackgroundPush.clientOnly(matrix.client);
|
|
instance.matrix = matrix;
|
|
// ignore: prefer_initializing_formals
|
|
instance.onFcmError = onFcmError;
|
|
// #Pangea
|
|
instance.fullInit();
|
|
// Pangea#
|
|
return instance;
|
|
}
|
|
|
|
// #Pangea
|
|
Future<void> fullInit() => setupPush();
|
|
|
|
void handleLoginStateChanged(_) => setupPush();
|
|
|
|
StreamSubscription<LoginState>? onLogin;
|
|
|
|
void _newFcmToken(String token) {
|
|
_fcmToken = token;
|
|
debugPrint('Fcm foken $_fcmToken');
|
|
setupPush();
|
|
}
|
|
// Pangea#
|
|
|
|
Future<void> cancelNotification(String roomId) async {
|
|
Logs().v('Cancel notification for room', roomId);
|
|
await _flutterLocalNotificationsPlugin.cancel(roomId.hashCode);
|
|
|
|
// Workaround for app icon badge not updating
|
|
if (Platform.isIOS) {
|
|
final unreadCount = client.rooms
|
|
.where((room) => room.isUnreadOrInvited && room.id != roomId)
|
|
.length;
|
|
if (unreadCount == 0) {
|
|
FlutterAppBadger.removeBadge();
|
|
} else {
|
|
FlutterAppBadger.updateBadgeCount(unreadCount);
|
|
}
|
|
return;
|
|
}
|
|
}
|
|
|
|
Future<void> setupPusher({
|
|
String? gatewayUrl,
|
|
String? token,
|
|
Set<String?>? oldTokens,
|
|
bool useDeviceSpecificAppId = false,
|
|
}) async {
|
|
// #Pangea
|
|
try {
|
|
// Pangea#
|
|
if (PlatformInfos.isIOS) {
|
|
await firebase?.requestPermission();
|
|
} else if (PlatformInfos.isAndroid) {
|
|
_flutterLocalNotificationsPlugin
|
|
.resolvePlatformSpecificImplementation<
|
|
AndroidFlutterLocalNotificationsPlugin>()
|
|
?.requestNotificationsPermission();
|
|
}
|
|
// #Pangea
|
|
} catch (err, s) {
|
|
ErrorHandler.logError(
|
|
e: "Error requesting notifications permission: $err",
|
|
s: s,
|
|
);
|
|
}
|
|
// Pangea#
|
|
|
|
final clientName = PlatformInfos.clientName;
|
|
oldTokens ??= <String>{};
|
|
final pushers = await (client.getPushers().catchError((e) {
|
|
Logs().w('[Push] Unable to request pushers', e);
|
|
return <Pusher>[];
|
|
})) ??
|
|
[];
|
|
var setNewPusher = false;
|
|
// Just the plain app id, we add the .data_message suffix later
|
|
var appId = AppConfig.pushNotificationsAppId;
|
|
// we need the deviceAppId to remove potential legacy UP pusher
|
|
var deviceAppId = '$appId.${client.deviceID}';
|
|
// appId may only be up to 64 chars as per spec
|
|
if (deviceAppId.length > 64) {
|
|
deviceAppId = deviceAppId.substring(0, 64);
|
|
}
|
|
if (!useDeviceSpecificAppId && PlatformInfos.isAndroid) {
|
|
appId += '.data_message';
|
|
}
|
|
final thisAppId = useDeviceSpecificAppId ? deviceAppId : appId;
|
|
if (gatewayUrl != null && token != null) {
|
|
final currentPushers = pushers.where((pusher) => pusher.pushkey == token);
|
|
if (currentPushers.length == 1 &&
|
|
currentPushers.first.kind == 'http' &&
|
|
currentPushers.first.appId == thisAppId &&
|
|
currentPushers.first.appDisplayName == clientName &&
|
|
currentPushers.first.deviceDisplayName == client.deviceName &&
|
|
currentPushers.first.lang == 'en' &&
|
|
// #Pangea
|
|
currentPushers.first.lang == LanguageKeys.defaultLanguage &&
|
|
// Pangea#
|
|
currentPushers.first.data.url.toString() == gatewayUrl &&
|
|
currentPushers.first.data.format ==
|
|
AppConfig.pushNotificationsPusherFormat &&
|
|
mapEquals(
|
|
currentPushers.single.data.additionalProperties,
|
|
{"data_message": pusherDataMessageFormat},
|
|
)) {
|
|
Logs().i('[Push] Pusher already set');
|
|
} else {
|
|
Logs().i('Need to set new pusher');
|
|
oldTokens.add(token);
|
|
if (client.isLogged()) {
|
|
setNewPusher = true;
|
|
}
|
|
}
|
|
} else {
|
|
Logs().w('[Push] Missing required push credentials');
|
|
}
|
|
for (final pusher in pushers) {
|
|
if ((token != null &&
|
|
pusher.pushkey != token &&
|
|
deviceAppId == pusher.appId) ||
|
|
oldTokens.contains(pusher.pushkey)) {
|
|
try {
|
|
await client.deletePusher(pusher);
|
|
Logs().i('[Push] Removed legacy pusher for this device');
|
|
} catch (err) {
|
|
Logs().w('[Push] Failed to remove old pusher', err);
|
|
}
|
|
}
|
|
}
|
|
if (setNewPusher) {
|
|
try {
|
|
await client.postPusher(
|
|
Pusher(
|
|
pushkey: token!,
|
|
appId: thisAppId,
|
|
appDisplayName: clientName,
|
|
deviceDisplayName: client.deviceName!,
|
|
//#Pangea
|
|
// lang: 'en',
|
|
lang: LanguageKeys.defaultLanguage,
|
|
// Pangea#
|
|
data: PusherData(
|
|
url: Uri.parse(gatewayUrl!),
|
|
format: AppConfig.pushNotificationsPusherFormat,
|
|
additionalProperties: {"data_message": pusherDataMessageFormat},
|
|
),
|
|
kind: 'http',
|
|
),
|
|
append: false,
|
|
);
|
|
} catch (e, s) {
|
|
Logs().e('[Push] Unable to set pushers', e, s);
|
|
// #Pangea
|
|
ErrorHandler.logError(e: e, s: s);
|
|
// Pangea#
|
|
}
|
|
}
|
|
}
|
|
|
|
final pusherDataMessageFormat = Platform.isAndroid
|
|
? 'android'
|
|
: Platform.isIOS
|
|
? 'ios'
|
|
: null;
|
|
|
|
static bool _wentToRoomOnStartup = false;
|
|
|
|
Future<void> setupPush() async {
|
|
Logs().d("SetupPush");
|
|
if (client.onLoginStateChanged.value != LoginState.loggedIn ||
|
|
!PlatformInfos.isMobile ||
|
|
matrix == null) {
|
|
return;
|
|
}
|
|
// Do not setup unifiedpush if this has been initialized by
|
|
// an unifiedpush action
|
|
if (upAction) {
|
|
return;
|
|
}
|
|
if (!PlatformInfos.isIOS &&
|
|
(await UnifiedPush.getDistributors()).isNotEmpty) {
|
|
await setupUp();
|
|
} else {
|
|
await setupFirebase();
|
|
}
|
|
|
|
// ignore: unawaited_futures
|
|
_flutterLocalNotificationsPlugin
|
|
.getNotificationAppLaunchDetails()
|
|
.then((details) {
|
|
if (details == null ||
|
|
!details.didNotificationLaunchApp ||
|
|
_wentToRoomOnStartup) {
|
|
return;
|
|
}
|
|
_wentToRoomOnStartup = true;
|
|
goToRoom(details.notificationResponse);
|
|
});
|
|
}
|
|
|
|
Future<void> _noFcmWarning() async {
|
|
if (matrix == null) {
|
|
return;
|
|
}
|
|
if ((matrix?.store.getBool(SettingKeys.showNoGoogle) ?? false) == true) {
|
|
return;
|
|
}
|
|
await loadLocale();
|
|
WidgetsBinding.instance.addPostFrameCallback((_) {
|
|
if (PlatformInfos.isAndroid) {
|
|
onFcmError?.call(
|
|
l10n!.noGoogleServicesWarning,
|
|
link: Uri.parse(
|
|
AppConfig.enablePushTutorial,
|
|
),
|
|
);
|
|
return;
|
|
}
|
|
onFcmError?.call(l10n!.oopsPushError);
|
|
});
|
|
}
|
|
|
|
Future<void> setupFirebase() async {
|
|
Logs().v('Setup firebase');
|
|
if (_fcmToken?.isEmpty ?? true) {
|
|
try {
|
|
// #Pangea
|
|
// _fcmToken = await firebase?.getToken();
|
|
_fcmToken = await _getToken();
|
|
// Pangea#
|
|
if (_fcmToken == null) throw ('PushToken is null');
|
|
} catch (e, s) {
|
|
Logs().w('[Push] cannot get token', e, e is String ? null : s);
|
|
await _noFcmWarning();
|
|
return;
|
|
}
|
|
}
|
|
await setupPusher(
|
|
gatewayUrl: AppConfig.pushNotificationsGatewayUrl,
|
|
token: _fcmToken,
|
|
);
|
|
}
|
|
|
|
Future<void> goToRoom(NotificationResponse? response) async {
|
|
try {
|
|
final roomId = response?.payload;
|
|
Logs().v('[Push] Attempting to go to room $roomId...');
|
|
if (roomId == null) {
|
|
return;
|
|
}
|
|
await client.roomsLoading;
|
|
await client.accountDataLoading;
|
|
if (client.getRoomById(roomId) == null) {
|
|
await client
|
|
.waitForRoomInSync(roomId)
|
|
.timeout(const Duration(seconds: 30));
|
|
}
|
|
FluffyChatApp.router.go(
|
|
client.getRoomById(roomId)?.membership == Membership.invite
|
|
? '/rooms'
|
|
: '/rooms/$roomId',
|
|
);
|
|
} catch (e, s) {
|
|
Logs().e('[Push] Failed to open room', e, s);
|
|
// #Pangea
|
|
ErrorHandler.logError(e: e, s: s);
|
|
// Pangea#
|
|
}
|
|
}
|
|
|
|
Future<void> setupUp() async {
|
|
await UnifiedPushUi(matrix!.context, ["default"], UPFunctions())
|
|
.registerAppWithDialog();
|
|
}
|
|
|
|
Future<void> _newUpEndpoint(String newEndpoint, String i) async {
|
|
upAction = true;
|
|
if (newEndpoint.isEmpty) {
|
|
await _upUnregistered(i);
|
|
return;
|
|
}
|
|
var endpoint =
|
|
'https://matrix.gateway.unifiedpush.org/_matrix/push/v1/notify';
|
|
try {
|
|
final url = Uri.parse(newEndpoint)
|
|
.replace(
|
|
path: '/_matrix/push/v1/notify',
|
|
query: '',
|
|
)
|
|
.toString()
|
|
.split('?')
|
|
.first;
|
|
final res =
|
|
json.decode(utf8.decode((await http.get(Uri.parse(url))).bodyBytes));
|
|
if (res['gateway'] == 'matrix' ||
|
|
(res['unifiedpush'] is Map &&
|
|
res['unifiedpush']['gateway'] == 'matrix')) {
|
|
endpoint = url;
|
|
}
|
|
} catch (e) {
|
|
Logs().i(
|
|
'[Push] No self-hosted unified push gateway present: $newEndpoint',
|
|
);
|
|
}
|
|
Logs().i('[Push] UnifiedPush using endpoint $endpoint');
|
|
final oldTokens = <String?>{};
|
|
try {
|
|
// #Pangea
|
|
// final fcmToken = await firebase?.getToken();
|
|
final fcmToken = await _getToken();
|
|
// Pangea#
|
|
oldTokens.add(fcmToken);
|
|
} catch (_) {}
|
|
await setupPusher(
|
|
gatewayUrl: endpoint,
|
|
token: newEndpoint,
|
|
oldTokens: oldTokens,
|
|
useDeviceSpecificAppId: true,
|
|
);
|
|
await matrix?.store.setString(SettingKeys.unifiedPushEndpoint, newEndpoint);
|
|
await matrix?.store.setBool(SettingKeys.unifiedPushRegistered, true);
|
|
}
|
|
|
|
Future<void> _upUnregistered(String i) async {
|
|
upAction = true;
|
|
Logs().i('[Push] Removing UnifiedPush endpoint...');
|
|
final oldEndpoint =
|
|
matrix?.store.getString(SettingKeys.unifiedPushEndpoint);
|
|
await matrix?.store.setBool(SettingKeys.unifiedPushRegistered, false);
|
|
await matrix?.store.remove(SettingKeys.unifiedPushEndpoint);
|
|
if (oldEndpoint?.isNotEmpty ?? false) {
|
|
// remove the old pusher
|
|
await setupPusher(
|
|
oldTokens: {oldEndpoint},
|
|
);
|
|
}
|
|
}
|
|
|
|
Future<void> _onUpMessage(Uint8List message, String i) async {
|
|
upAction = true;
|
|
final data = Map<String, dynamic>.from(
|
|
json.decode(utf8.decode(message))['notification'],
|
|
);
|
|
// UP may strip the devices list
|
|
data['devices'] ??= [];
|
|
await pushHelper(
|
|
PushNotification.fromJson(data),
|
|
client: client,
|
|
l10n: l10n,
|
|
activeRoomId: matrix?.activeRoomId,
|
|
flutterLocalNotificationsPlugin: _flutterLocalNotificationsPlugin,
|
|
);
|
|
}
|
|
|
|
// #Pangea
|
|
Future<String?> _getToken() async {
|
|
if (Platform.isAndroid) {
|
|
await Firebase.initializeApp(
|
|
// options: DefaultFirebaseOptions.currentPlatform,
|
|
);
|
|
return (await FirebaseMessaging.instance.getToken());
|
|
}
|
|
return await firebase?.getToken();
|
|
}
|
|
// Pangea#
|
|
}
|
|
|
|
class UPFunctions extends UnifiedPushFunctions {
|
|
final List<String> features = [/*list of features*/];
|
|
@override
|
|
Future<String?> getDistributor() async {
|
|
return await UnifiedPush.getDistributor();
|
|
}
|
|
|
|
@override
|
|
Future<List<String>> getDistributors() async {
|
|
return await UnifiedPush.getDistributors(features);
|
|
}
|
|
|
|
@override
|
|
Future<void> registerApp(String instance) async {
|
|
await UnifiedPush.registerApp(instance, features);
|
|
}
|
|
|
|
@override
|
|
Future<void> saveDistributor(String distributor) async {
|
|
await UnifiedPush.saveDistributor(distributor);
|
|
}
|
|
}
|