Reduce diff with upstream somewhat

Rebase fixes

Rebase fixes
pull/2269/head
Steven Lageveen 4 weeks ago
parent a6d962f9ba
commit bf2f412de9

@ -1,26 +0,0 @@
pluginManagement {
def flutterSdkPath = {
def properties = new Properties()
file("local.properties").withInputStream { properties.load(it) }
def flutterSdkPath = properties.getProperty("flutter.sdk")
assert flutterSdkPath != null, "flutter.sdk not set in local.properties"
return flutterSdkPath
}()
includeBuild("$flutterSdkPath/packages/flutter_tools/gradle")
repositories {
google()
mavenCentral()
gradlePluginPortal()
}
}
plugins {
id "dev.flutter.flutter-plugin-loader" version "1.0.0"
id "com.android.application" version "8.7.3" apply false
id "org.jetbrains.kotlin.android" version "2.1.10" apply false
id "com.google.gms.google-services" version "4.3.8" apply false
}
include ":app"

@ -1,3 +0,0 @@
Hermes.AppDir
*.AppImage
*.AppImage.zsync

@ -1,4 +0,0 @@
#!/bin/sh
cd "$(dirname "$0")"
exec ./hermes

@ -1,9 +0,0 @@
[Desktop Entry]
Type=Application
Version=1.0
Name=Hermes
Comment=Matrix Client. Chat with your friends
Exec=AppRun
Icon=hermes
Terminal=false
Categories=Network;Chat;InstantMessaging;X-Matrix;

@ -1,24 +0,0 @@
# Hermes AppImage
Hermes is provided as AppImage too. To Download, visit hermes.im.
## Building
- Ensure you install `appimagetool`
```shell
flutter build linux
# copy binaries to appimage dir
cp -r build/linux/{x64,arm64}/release/bundle appimage/Hermes.AppDir
cd appimage
# prepare AppImage files
cp Hermes.desktop Hermes.AppDir/
mkdir -p Hermes.AppDir/usr/share/icons
cp ../assets/logo.svg Hermes.AppDir/hermes.svg
cp AppRun Hermes.AppDir
# build the AppImage
appimagetool Hermes.AppDir
```

@ -1,2 +1,2 @@
# im.hermes.Hermes # im.pantheon.Hermes
8b25b37b-f160-4350-b4f6-9a04554e8f9e 8b25b37b-f160-4350-b4f6-9a04554e8f9e

@ -104,7 +104,7 @@
> <img src="browser-badge.png" class="mb-2 inline w-36 pr-2 transition-transform hover:scale-105" /></a > <img src="browser-badge.png" class="mb-2 inline w-36 pr-2 transition-transform hover:scale-105" /></a
> <a href="https://snapcraft.io/hermes" > <a href="https://snapcraft.io/hermes"
><img src="snap-store-badge.svg" class="mb-2 inline w-36 pr-2 transition-transform hover:scale-105" /></a ><img src="snap-store-badge.svg" class="mb-2 inline w-36 pr-2 transition-transform hover:scale-105" /></a
> <a href="https://flathub.org/apps/details/im.hermes.Hermes" > <a href="https://flathub.org/apps/details/im.pantheon.Hermes"
><img src="flathub-badge-en.png" class="mb-2 inline w-36 pr-2 transition-transform hover:scale-105" /></a ><img src="flathub-badge-en.png" class="mb-2 inline w-36 pr-2 transition-transform hover:scale-105" /></a
> >
</div> </div>

@ -126,8 +126,9 @@ class ChatInputRow extends StatelessWidget {
AnimatedContainer( AnimatedContainer(
duration: PantheonThemes.animationDuration, duration: PantheonThemes.animationDuration,
curve: PantheonThemes.animationCurve, curve: PantheonThemes.animationCurve,
width: width: controller.sendController.text.isNotEmpty
controller.sendController.text.isNotEmpty ? 0 : height - 10, ? 0
: height - 10,
height: height, height: height,
alignment: Alignment.center, alignment: Alignment.center,
decoration: const BoxDecoration(), decoration: const BoxDecoration(),
@ -148,7 +149,8 @@ class ChatInputRow extends StatelessWidget {
theme.colorScheme.onPrimaryContainer, theme.colorScheme.onPrimaryContainer,
foregroundColor: foregroundColor:
theme.colorScheme.primaryContainer, theme.colorScheme.primaryContainer,
child: const Icon(Icons.gps_fixed_outlined), child: const Icon(Icons.gps_fixed_outlined,
),
), ),
title: Text(L10n.of(context).shareLocation), title: Text(L10n.of(context).shareLocation),
contentPadding: const EdgeInsets.all(0), contentPadding: const EdgeInsets.all(0),
@ -183,7 +185,7 @@ class ChatInputRow extends StatelessWidget {
contentPadding: const EdgeInsets.all(0), contentPadding: const EdgeInsets.all(0),
), ),
), ),
if (PlatformInfos.isMobile) if (PlatformInfos.isMobile)
PopupMenuItem<String>( PopupMenuItem<String>(
value: 'camera-video', value: 'camera-video',
child: ListTile( child: ListTile(

@ -1,255 +0,0 @@
import 'dart:async';
import 'package:flutter/cupertino.dart';
import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
import 'package:path/path.dart' as path_lib;
import 'package:path_provider/path_provider.dart';
import 'package:record/record.dart';
import 'package:wakelock_plus/wakelock_plus.dart';
import 'package:hermes/l10n/l10n.dart';
import 'package:hermes/config/app_config.dart';
import 'package:hermes/config/setting_keys.dart';
import 'package:hermes/utils/platform_infos.dart';
import 'package:hermes/widgets/matrix.dart';
import 'events/audio_player.dart';
class RecordingDialog extends StatefulWidget {
const RecordingDialog({
super.key,
});
@override
RecordingDialogState createState() => RecordingDialogState();
}
class RecordingDialogState extends State<RecordingDialog> {
Timer? _recorderSubscription;
Duration _duration = Duration.zero;
bool error = false;
final _audioRecorder = AudioRecorder();
final List<double> amplitudeTimeline = [];
String? fileName;
Future<void> startRecording() async {
final store = Matrix.of(context).store;
try {
final codec = kIsWeb
// Web seems to create webm instead of ogg when using opus encoder
// which does not play on iOS right now. So we use wav for now:
? AudioEncoder.wav
// Everywhere else we use opus if supported by the platform:
: await _audioRecorder.isEncoderSupported(AudioEncoder.opus)
? AudioEncoder.opus
: AudioEncoder.aacLc;
fileName =
'recording${DateTime.now().microsecondsSinceEpoch}.${codec.fileExtension}';
String? path;
if (!kIsWeb) {
final tempDir = await getTemporaryDirectory();
path = path_lib.join(tempDir.path, fileName);
}
final result = await _audioRecorder.hasPermission();
if (result != true) {
setState(() => error = true);
return;
}
await WakelockPlus.enable();
await _audioRecorder.start(
RecordConfig(
bitRate: AppSettings.audioRecordingBitRate.getItem(store),
sampleRate: AppSettings.audioRecordingSamplingRate.getItem(store),
numChannels: AppSettings.audioRecordingNumChannels.getItem(store),
autoGain: AppSettings.audioRecordingAutoGain.getItem(store),
echoCancel: AppSettings.audioRecordingEchoCancel.getItem(store),
noiseSuppress: AppSettings.audioRecordingNoiseSuppress.getItem(store),
encoder: codec,
),
path: path ?? '',
);
setState(() => _duration = Duration.zero);
_recorderSubscription?.cancel();
_recorderSubscription =
Timer.periodic(const Duration(milliseconds: 100), (_) async {
final amplitude = await _audioRecorder.getAmplitude();
var value = 100 + amplitude.current * 2;
value = value < 1 ? 1 : value;
amplitudeTimeline.add(value);
setState(() {
_duration += const Duration(milliseconds: 100);
});
});
} catch (_) {
setState(() => error = true);
rethrow;
}
}
@override
void initState() {
super.initState();
startRecording();
}
@override
void dispose() {
WakelockPlus.disable();
_recorderSubscription?.cancel();
_audioRecorder.stop();
super.dispose();
}
void _stopAndSend() async {
_recorderSubscription?.cancel();
final path = await _audioRecorder.stop();
if (path == null) throw ('Recording failed!');
const waveCount = AudioPlayerWidget.wavesCount;
final step = amplitudeTimeline.length < waveCount
? 1
: (amplitudeTimeline.length / waveCount).round();
final waveform = <int>[];
for (var i = 0; i < amplitudeTimeline.length; i += step) {
waveform.add((amplitudeTimeline[i] / 100 * 1024).round());
}
Navigator.of(context, rootNavigator: false).pop<RecordingResult>(
RecordingResult(
path: path,
duration: _duration.inMilliseconds,
waveform: waveform,
fileName: fileName,
),
);
}
@override
Widget build(BuildContext context) {
final theme = Theme.of(context);
const maxDecibalWidth = 64.0;
final time =
'${_duration.inMinutes.toString().padLeft(2, '0')}:${(_duration.inSeconds % 60).toString().padLeft(2, '0')}';
final content = error
? Text(L10n.of(context).oopsSomethingWentWrong)
: Row(
children: [
Container(
width: 16,
height: 16,
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(32),
color: Colors.red,
),
),
Expanded(
child: Row(
mainAxisSize: MainAxisSize.min,
mainAxisAlignment: MainAxisAlignment.end,
children: amplitudeTimeline.reversed
.take(26)
.toList()
.reversed
.map(
(amplitude) => Container(
margin: const EdgeInsets.only(left: 2),
width: 4,
decoration: BoxDecoration(
color: theme.colorScheme.primary,
borderRadius:
BorderRadius.circular(AppConfig.borderRadius),
),
height: maxDecibalWidth * (amplitude / 100),
),
)
.toList(),
),
),
const SizedBox(width: 8),
SizedBox(
width: 48,
child: Text(time),
),
],
);
if (PlatformInfos.isCupertinoStyle) {
return CupertinoAlertDialog(
content: content,
actions: [
CupertinoDialogAction(
onPressed: () => Navigator.of(context, rootNavigator: false).pop(),
child: Text(
L10n.of(context).cancel,
style: TextStyle(
color: theme.textTheme.bodyMedium?.color?.withAlpha(150),
),
),
),
if (error != true)
CupertinoDialogAction(
onPressed: _stopAndSend,
child: Text(L10n.of(context).send),
),
],
);
}
return AlertDialog(
content: content,
actions: [
TextButton(
onPressed: () => Navigator.of(context, rootNavigator: false).pop(),
child: Text(
L10n.of(context).cancel,
style: TextStyle(
color: theme.colorScheme.error,
),
),
),
if (error != true)
TextButton(
onPressed: _stopAndSend,
child: Text(L10n.of(context).send),
),
],
);
}
}
class RecordingResult {
final String path;
final int duration;
final List<int> waveform;
final String? fileName;
const RecordingResult({
required this.path,
required this.duration,
required this.waveform,
required this.fileName,
});
}
extension on AudioEncoder {
String get fileExtension {
switch (this) {
case AudioEncoder.aacLc:
case AudioEncoder.aacEld:
case AudioEncoder.aacHe:
return 'm4a';
case AudioEncoder.opus:
return 'ogg';
case AudioEncoder.wav:
return 'wav';
case AudioEncoder.amrNb:
case AudioEncoder.amrWb:
case AudioEncoder.flac:
case AudioEncoder.pcm16bits:
throw UnsupportedError('Not yet used');
}
}
}

@ -95,18 +95,19 @@ class ChatListController extends State<ChatList>
late ActiveFilter activeFilter; late ActiveFilter activeFilter;
String? get activeSpaceId => Matrix.of(context).activeSpaceId; String? _activeSpaceId;
String? get activeSpaceId => _activeSpaceId;
void setActiveSpace(String spaceId) async { void setActiveSpace(String spaceId) async {
await Matrix.of(context).client.getRoomById(spaceId)!.postLoad(); await Matrix.of(context).client.getRoomById(spaceId)!.postLoad();
setState(() { setState(() {
Matrix.of(context).activeSpaceId = spaceId; _activeSpaceId = spaceId;
}); });
} }
void clearActiveSpace() => setState(() { void clearActiveSpace() => setState(() {
Matrix.of(context).activeSpaceId = null; _activeSpaceId = null;
}); });
void onChatTap(Room room) async { void onChatTap(Room room) async {
@ -816,7 +817,7 @@ class ChatListController extends State<ChatList>
context.go('/rooms'); context.go('/rooms');
setState(() { setState(() {
activeFilter = ActiveFilter.allChats; activeFilter = ActiveFilter.allChats;
Matrix.of(context).activeSpaceId = null; _activeSpaceId = null;
Matrix.of(context).setActiveClient(client); Matrix.of(context).setActiveClient(client);
}); });
_clientStream.add(client); _clientStream.add(client);
@ -825,7 +826,7 @@ class ChatListController extends State<ChatList>
void setActiveBundle(String bundle) { void setActiveBundle(String bundle) {
context.go('/rooms'); context.go('/rooms');
setState(() { setState(() {
Matrix.of(context).activeSpaceId = null; _activeSpaceId = null;
Matrix.of(context).activeBundle = bundle; Matrix.of(context).activeBundle = bundle;
if (!Matrix.of(context) if (!Matrix.of(context)
.currentBundle! .currentBundle!

@ -57,10 +57,10 @@ class ImageViewerController extends State<ImageViewer> {
void onKeyEvent(KeyEvent event) { void onKeyEvent(KeyEvent event) {
switch (event.logicalKey) { switch (event.logicalKey) {
case LogicalKeyboardKey.arrowUp: case LogicalKeyboardKey.arrowUp:
case LogicalKeyboardKey.keyH: case LogicalKeyboardKey.keyK:
if (canGoBack) prevImage(); if (canGoBack) prevImage();
break; break;
case LogicalKeyboardKey.keyL: case LogicalKeyboardKey.keyJ:
case LogicalKeyboardKey.arrowDown: case LogicalKeyboardKey.arrowDown:
if (canGoNext) nextImage(); if (canGoNext) nextImage();
break; break;

@ -92,7 +92,7 @@ class BackgroundPush {
await notificationTap( await notificationTap(
NotificationResponseJson.fromJsonString(message), NotificationResponseJson.fromJsonString(message),
client: client, client: client,
router: FluffyChatApp.router, router: HermesApp.router,
l10n: l10n, l10n: l10n,
); );
} catch (e, s) { } catch (e, s) {
@ -110,7 +110,7 @@ class BackgroundPush {
onDidReceiveNotificationResponse: (response) => notificationTap( onDidReceiveNotificationResponse: (response) => notificationTap(
response, response,
client: client, client: client,
router: FluffyChatApp.router, router: HermesApp.router,
l10n: l10n, l10n: l10n,
), ),
onDidReceiveBackgroundNotificationResponse: notificationTapBackground, onDidReceiveBackgroundNotificationResponse: notificationTapBackground,
@ -329,7 +329,7 @@ class BackgroundPush {
notificationTap( notificationTap(
response, response,
client: client, client: client,
router: FluffyChatApp.router, router: HermesApp.router,
l10n: l10n, l10n: l10n,
); );
} }

@ -6,15 +6,14 @@ import 'package:flutter_local_notifications/flutter_local_notifications.dart';
import 'package:flutter_vodozemac/flutter_vodozemac.dart' as vod; import 'package:flutter_vodozemac/flutter_vodozemac.dart' as vod;
import 'package:go_router/go_router.dart'; import 'package:go_router/go_router.dart';
import 'package:matrix/matrix.dart'; import 'package:matrix/matrix.dart';
import 'package:fluffychat/l10n/l10n.dart';
import 'package:fluffychat/utils/client_download_content_extension.dart'; import 'package:fluffychat/utils/client_download_content_extension.dart';
import 'package:fluffychat/utils/client_manager.dart'; import 'package:hermes/l10n/l10n.dart';
import 'package:fluffychat/utils/matrix_sdk_extensions/matrix_locals.dart'; import 'package:hermes/utils/matrix_sdk_extensions/matrix_locals.dart';
import 'package:fluffychat/utils/platform_infos.dart'; import 'package:hermes/utils/platform_infos.dart';
import 'package:fluffychat/utils/push_helper.dart'; import 'package:hermes/utils/push_helper.dart';
import '../config/app_config.dart'; import '../config/app_config.dart';
import '../config/setting_keys.dart'; import '../config/setting_keys.dart';
import 'package:hermes/utils/client_manager.dart';
bool _vodInitialized = false; bool _vodInitialized = false;
@ -92,7 +91,7 @@ Future<void> notificationTap(
notificationResponse.notificationResponseType.name, notificationResponse.notificationResponseType.name,
); );
final payload = final payload =
FluffyChatPushPayload.fromString(notificationResponse.payload ?? ''); HermesPushPayload.fromString(notificationResponse.payload ?? '');
switch (notificationResponse.notificationResponseType) { switch (notificationResponse.notificationResponseType) {
case NotificationResponseType.selectedNotification: case NotificationResponseType.selectedNotification:
final roomId = payload.roomId; final roomId = payload.roomId;
@ -116,7 +115,7 @@ Future<void> notificationTap(
: '/rooms/$roomId', : '/rooms/$roomId',
); );
case NotificationResponseType.selectedNotificationAction: case NotificationResponseType.selectedNotificationAction:
final actionType = FluffyChatNotificationActions.values.singleWhereOrNull( final actionType = HermesNotificationActions.values.singleWhereOrNull(
(action) => action.name == notificationResponse.actionId, (action) => action.name == notificationResponse.actionId,
); );
if (actionType == null) { if (actionType == null) {
@ -136,13 +135,13 @@ Future<void> notificationTap(
); );
} }
switch (actionType) { switch (actionType) {
case FluffyChatNotificationActions.markAsRead: case HermesNotificationActions.markAsRead:
await room.setReadMarker( await room.setReadMarker(
payload.eventId ?? room.lastEvent!.eventId, payload.eventId ?? room.lastEvent!.eventId,
mRead: payload.eventId ?? room.lastEvent!.eventId, mRead: payload.eventId ?? room.lastEvent!.eventId,
public: AppSettings.sendPublicReadReceipts.value, public: AppSettings.sendPublicReadReceipts.value,
); );
case FluffyChatNotificationActions.reply: case HermesNotificationActions.reply:
final input = notificationResponse.input; final input = notificationResponse.input;
if (input == null || input.isEmpty) { if (input == null || input.isEmpty) {
throw Exception( throw Exception(
@ -207,7 +206,7 @@ Future<void> notificationTap(
enableVibration: false, enableVibration: false,
actions: <AndroidNotificationAction>[ actions: <AndroidNotificationAction>[
AndroidNotificationAction( AndroidNotificationAction(
FluffyChatNotificationActions.reply.name, HermesNotificationActions.reply.name,
l10n.reply, l10n.reply,
inputs: [ inputs: [
AndroidNotificationActionInput( AndroidNotificationActionInput(
@ -219,14 +218,14 @@ Future<void> notificationTap(
semanticAction: SemanticAction.reply, semanticAction: SemanticAction.reply,
), ),
AndroidNotificationAction( AndroidNotificationAction(
FluffyChatNotificationActions.markAsRead.name, HermesNotificationActions.markAsRead.name,
l10n.markAsRead, l10n.markAsRead,
semanticAction: SemanticAction.markAsRead, semanticAction: SemanticAction.markAsRead,
), ),
], ],
), ),
), ),
payload: FluffyChatPushPayload( payload: HermesPushPayload(
client.clientName, client.clientName,
room.id, room.id,
eventId, eventId,
@ -237,4 +236,4 @@ Future<void> notificationTap(
} }
} }
enum FluffyChatNotificationActions { markAsRead, reply } enum HermesNotificationActions { markAsRead, reply }

@ -317,24 +317,23 @@ Future<void> _tryPushHelper(
title, title,
body, body,
platformChannelSpecifics, platformChannelSpecifics,
payload: payload: HermesPushPayload(client.clientName, event.room.id, event.eventId)
FluffyChatPushPayload(client.clientName, event.room.id, event.eventId) .toString(),
.toString(),
); );
Logs().v('Push helper has been completed!'); Logs().v('Push helper has been completed!');
} }
class FluffyChatPushPayload { class HermesPushPayload {
final String? clientName, roomId, eventId; final String? clientName, roomId, eventId;
FluffyChatPushPayload(this.clientName, this.roomId, this.eventId); HermesPushPayload(this.clientName, this.roomId, this.eventId);
factory FluffyChatPushPayload.fromString(String payload) { factory HermesPushPayload.fromString(String payload) {
final parts = payload.split('|'); final parts = payload.split('|');
if (parts.length != 3) { if (parts.length != 3) {
return FluffyChatPushPayload(null, null, null); return HermesPushPayload(null, null, null);
} }
return FluffyChatPushPayload(parts[0], parts[1], parts[2]); return HermesPushPayload(parts[0], parts[1], parts[2]);
} }
@override @override

@ -13,8 +13,7 @@ extension UiaRequestManager on MatrixState {
Future uiaRequestHandler(UiaRequest uiaRequest) async { Future uiaRequestHandler(UiaRequest uiaRequest) async {
final l10n = L10n.of(context); final l10n = L10n.of(context);
final navigatorContext = final navigatorContext =
HermesApp.router.routerDelegate.navigatorKey.currentContext ?? HermesApp.router.routerDelegate.navigatorKey.currentContext ?? context;
context;
try { try {
if (uiaRequest.state != UiaRequestState.waitForUser || if (uiaRequest.state != UiaRequestState.waitForUser ||
uiaRequest.nextStages.isEmpty) { uiaRequest.nextStages.isEmpty) {

@ -1,47 +1,22 @@
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:go_router/go_router.dart';
import 'package:hermes/config/setting_keys.dart';
import 'package:fluffychat/config/setting_keys.dart';
import 'package:flutter/material.dart';
import 'package:go_router/go_router.dart';
import 'package:matrix/matrix.dart'; import 'package:matrix/matrix.dart';
import 'package:shared_preferences/shared_preferences.dart'; import 'package:shared_preferences/shared_preferences.dart';
import 'package:fluffychat/config/setting_keys.dart';
import 'package:hermes/l10n/l10n.dart';
import 'package:hermes/config/routes.dart'; import 'package:hermes/config/routes.dart';
import 'package:hermes/config/themes.dart'; import 'package:hermes/config/themes.dart';
import 'package:hermes/l10n/l10n.dart';
import 'package:hermes/widgets/app_lock.dart'; import 'package:hermes/widgets/app_lock.dart';
import 'package:hermes/widgets/theme_builder.dart'; import 'package:hermes/widgets/theme_builder.dart';
import '../config/app_config.dart';
import 'package:hermes/config/setting_keys.dart';
import '../utils/custom_scroll_behaviour.dart'; import '../utils/custom_scroll_behaviour.dart';
import 'matrix.dart'; import 'matrix.dart';
class BackIntent extends Intent {
const BackIntent();
}
class BackAction extends Action<BackIntent> {
@override
Object? invoke(covariant BackIntent intent) {
// Use a very obvious print statement
final currentContext =
primaryFocus?.context; // Try to get context from focus
if (currentContext != null) {
Navigator.maybePop(currentContext);
}
return null; // Action handled
}
}
class HermesApp extends StatelessWidget { class HermesApp extends StatelessWidget {
final Widget? testWidget; final Widget? testWidget;
final List<Client> clients; final List<Client> clients;
@ -70,12 +45,6 @@ class HermesApp extends StatelessWidget {
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
final globalShortcuts = <ShortcutActivator, Intent>{
const SingleActivator(LogicalKeyboardKey.escape): const BackIntent(),
};
final globalActions = <Type, Action<Intent>>{
BackIntent: BackAction(),
};
return ThemeBuilder( return ThemeBuilder(
builder: (context, themeMode, primaryColor) => MaterialApp.router( builder: (context, themeMode, primaryColor) => MaterialApp.router(
title: AppSettings.applicationName.value, title: AppSettings.applicationName.value,
@ -88,21 +57,15 @@ class HermesApp extends StatelessWidget {
localizationsDelegates: L10n.localizationsDelegates, localizationsDelegates: L10n.localizationsDelegates,
supportedLocales: L10n.supportedLocales, supportedLocales: L10n.supportedLocales,
routerConfig: router, routerConfig: router,
builder: (context, child) => Shortcuts( builder: (context, child) => AppLockWidget(
shortcuts: globalShortcuts, pincode: pincode,
child: Actions( clients: clients,
actions: globalActions, // Need a navigator above the Matrix widget for
child: AppLockWidget( // displaying dialogs
pincode: pincode, child: Matrix(
clients: clients, clients: clients,
// Need a navigator above the Matrix widget for store: store,
// displaying dialogs child: testWidget ?? child,
child: Matrix(
clients: clients,
store: store,
child: testWidget ?? child,
),
),
), ),
), ),
), ),

@ -1,144 +0,0 @@
diff --git a/android/app/build.gradle b/android/app/build.gradle
index bb8e015cd..3ff4a7579 100644
--- a/android/app/build.gradle
+++ b/android/app/build.gradle
@@ -2,7 +2,7 @@ plugins {
id "com.android.application"
id "kotlin-android"
id "dev.flutter.flutter-gradle-plugin"
- //id "com.google.gms.google-services"
+ id "com.google.gms.google-services"
}
def localProperties = new Properties()
@@ -97,11 +97,12 @@ flutter {
}
dependencies {
- //implementation 'com.google.firebase:firebase-messaging:19.0.1' // Workaround for https://github.com/microg/android_packages_apps_GmsCore/issues/313#issuecomment-617651698
+ implementation 'com.google.firebase:firebase-messaging:19.0.1'
+ // Workaround for https://github.com/microg/android_packages_apps_GmsCore/issues/313#issuecomment-617651698
implementation 'androidx.multidex:multidex:2.0.1'
coreLibraryDesugaring("com.android.tools:desugar_jdk_libs:2.1.4")
}
configurations.all {
- exclude group: 'com.google.android.gms'
+ //exclude group: 'com.google.android.gms'
}
\ No newline at end of file
diff --git a/android/app/proguard-rules.pro b/android/app/proguard-rules.pro
index d0e0fbc9..0a546da0 100644
--- a/android/app/proguard-rules.pro
+++ b/android/app/proguard-rules.pro
@@ -1 +1,42 @@
--keep class net.sqlcipher.** { *; }
\ No newline at end of file
+-optimizationpasses 5
+## Flutter wrapper
+-keep class net.sqlcipher.** { *; }
+-keep class io.flutter.app.** { *; }
+-keep class io.flutter.plugin.** { *; }
+-keep class io.flutter.util.** { *; }
+-keep class io.flutter.view.** { *; }
+-keep class io.flutter.** { *; }
+-keep class io.flutter.plugins.** { *; }
+-dontwarn io.flutter.embedding.**
+
+##---------------Begin: proguard configuration for Gson (Needed for flutter_local_notifications) ----------
+# Gson uses generic type information stored in a class file when working with fields. Proguard
+# removes such information by default, so configure it to keep all of it.
+-keepattributes Signature
+
+# For using GSON @Expose annotation
+-keepattributes *Annotation*
+
+# Gson specific classes
+-dontwarn sun.misc.**
+
+# Application classes that will be serialized/deserialized over Gson
+-keep class com.google.gson.examples.android.model.** { <fields>; }
+
+# Prevent proguard from stripping interface information from TypeAdapter, TypeAdapterFactory,
+# JsonSerializer, JsonDeserializer instances (so they can be used in @JsonAdapter)
+-keep class * extends com.google.gson.TypeAdapter
+-keep class * implements com.google.gson.TypeAdapterFactory
+-keep class * implements com.google.gson.JsonSerializer
+-keep class * implements com.google.gson.JsonDeserializer
+
+# Prevent R8 from leaving Data object members always null
+-keepclassmembers,allowobfuscation class * {
+ @com.google.gson.annotations.SerializedName <fields>;
+}
+
+# Retain generic signatures of TypeToken and its subclasses with R8 version 3.0 and higher.
+-keep,allowobfuscation,allowshrinking class com.google.gson.reflect.TypeToken
+-keep,allowobfuscation,allowshrinking class * extends com.google.gson.reflect.TypeToken
+
+##---------------End: proguard configuration for Gson (Needed for flutter_local_notifications) ----------
\ No newline at end of file
diff --git a/android/app/src/main/kotlin/chat/pantheon/hermes/FcmPushService.kt b/android/app/src/main/kotlin/chat/pantheon/hermes/FcmPushService.kt
index d9930f55..510e9845 100644
--- a/android/app/src/main/kotlin/chat/pantheon/hermes/FcmPushService.kt
+++ b/android/app/src/main/kotlin/chat/pantheon/hermes/FcmPushService.kt
@@ -1,4 +1,4 @@
-/*package chat.pantheon.hermes
+package chat.pantheon.hermes
import com.famedly.fcm_shared_isolate.FcmSharedIsolateService
@@ -33,4 +33,3 @@ class FcmPushService : FcmSharedIsolateService() {
}
}
}
-*/
\ No newline at end of file
diff --git a/android/settings.gradle b/android/settings.gradle
index b2fd960a..fdb01a4d 100644
--- a/android/settings.gradle
+++ b/android/settings.gradle
@@ -20,7 +20,7 @@ plugins {
id "dev.flutter.flutter-plugin-loader" version "1.0.0"
id "com.android.application" version "8.7.3" apply false
id "org.jetbrains.kotlin.android" version "2.1.10" apply false
- // id "com.google.gms.google-services" version "4.3.8" apply false
+ id "com.google.gms.google-services" version "4.3.8" apply false
}
include ":app"
\ No newline at end of file
diff --git a/lib/utils/background_push.dart b/lib/utils/background_push.dart
index 1ba2659a..989f458e 100644
--- a/lib/utils/background_push.dart
+++ b/lib/utils/background_push.dart
@@ -39,7 +39,7 @@ import '../config/setting_keys.dart';
import '../widgets/matrix.dart';
import 'platform_infos.dart';
-//import 'package:fcm_shared_isolate/fcm_shared_isolate.dart';
+import 'package:fcm_shared_isolate/fcm_shared_isolate.dart';
class NoTokenException implements Exception {
String get cause => 'Cannot get firebase token';
@@ -64,7 +64,7 @@ class BackgroundPush {
final pendingTests = <String, Completer<void>>{};
- final dynamic firebase = null; //FcmSharedIsolate();
+ final dynamic firebase = FcmSharedIsolate();
DateTime? lastReceivedPush;
diff --git a/pubspec.yaml b/pubspec.yaml
index fb3e3ca4..039b2ccc 100644
--- a/pubspec.yaml
+++ b/pubspec.yaml
@@ -25,7 +25,7 @@ dependencies:
dynamic_color: ^1.7.0
emoji_picker_flutter: ^4.3.0
emojis: ^0.9.9
- #fcm_shared_isolate: ^0.2.0
+ fcm_shared_isolate: ^0.2.0
file_picker: ^8.1.2
file_selector: ^1.0.3
flutter:
Loading…
Cancel
Save