diff --git a/android/app/src/main/res/xml/locale_config.xml b/android/app/src/main/res/xml/locale_config.xml
index b3bb1ff7a..a37191e79 100644
--- a/android/app/src/main/res/xml/locale_config.xml
+++ b/android/app/src/main/res/xml/locale_config.xml
@@ -6,6 +6,7 @@
+
@@ -50,6 +51,7 @@
+
diff --git a/assets/l10n/intl_de.arb b/assets/l10n/intl_de.arb
index e65dc2135..77735f142 100644
--- a/assets/l10n/intl_de.arb
+++ b/assets/l10n/intl_de.arb
@@ -3274,7 +3274,7 @@
"@notificationRuleJitsi": {},
"allDevices": "Alle Geräte",
"@allDevices": {},
- "enterNewChat": "Neuen Chat starten",
+ "enterNewChat": "Neuen Chat betreten",
"@enterNewChat": {},
"shareKeysWith": "Schlüssel teilen mit...",
"@shareKeysWith": {},
diff --git a/assets/l10n/intl_nl.arb b/assets/l10n/intl_nl.arb
index 399822c16..c41f9ba75 100644
--- a/assets/l10n/intl_nl.arb
+++ b/assets/l10n/intl_nl.arb
@@ -3354,5 +3354,28 @@
"approve": "Goedkeuren",
"@approve": {},
"youHaveKnocked": "Je hebt geklopt",
- "@youHaveKnocked": {}
+ "@youHaveKnocked": {},
+ "sentVoiceMessage": "🎙️ {duration} - {sender}",
+ "@sentVoiceMessage": {
+ "type": "String",
+ "placeholders": {
+ "sender": {
+ "type": "String"
+ },
+ "duration": {
+ "type": "String"
+ }
+ }
+ },
+ "countInvited": "{count} uitgenodigd",
+ "@countInvited": {
+ "type": "String",
+ "placeholders": {
+ "count": {
+ "type": "int"
+ }
+ }
+ },
+ "checkList": "Checklist",
+ "@checkList": {}
}
diff --git a/assets/l10n/intl_yue_HK.arb b/assets/l10n/intl_yue_HK.arb
deleted file mode 100644
index 0967ef424..000000000
--- a/assets/l10n/intl_yue_HK.arb
+++ /dev/null
@@ -1 +0,0 @@
-{}
diff --git a/assets/l10n/intl_yue_Hant.arb b/assets/l10n/intl_yue_Hant.arb
index 3f76be695..cce50f372 100644
--- a/assets/l10n/intl_yue_Hant.arb
+++ b/assets/l10n/intl_yue_Hant.arb
@@ -1,4 +1,5 @@
{
+ "@@locale": "yue",
"normalUser": "正常用家",
"@normalUser": {},
"areYouSureYouWantToLogout": "係咪確定要 log out?",
diff --git a/lib/pages/chat/chat.dart b/lib/pages/chat/chat.dart
index db309551b..804537810 100644
--- a/lib/pages/chat/chat.dart
+++ b/lib/pages/chat/chat.dart
@@ -1674,13 +1674,18 @@ class ChatController extends State
}
void goToNewRoomAction() async {
+ final newRoomId = room
+ .getState(EventTypes.RoomTombstone)!
+ .parsedTombstoneContent
+ .replacementRoom;
final result = await showFutureLoadingDialog(
context: context,
- future: () => room.client.joinRoomById(
+ future: () => room.client.joinRoom(
room
.getState(EventTypes.RoomTombstone)!
.parsedTombstoneContent
.replacementRoom,
+ via: [newRoomId.domain!],
),
);
if (result.error != null) return;
diff --git a/lib/utils/client_download_content_extension.dart b/lib/utils/client_download_content_extension.dart
index 9fff1eccd..f93d522f0 100644
--- a/lib/utils/client_download_content_extension.dart
+++ b/lib/utils/client_download_content_extension.dart
@@ -1,5 +1,6 @@
import 'dart:typed_data';
+import 'package:image/image.dart';
import 'package:matrix/matrix.dart';
extension ClientDownloadContentExtension on Client {
@@ -10,6 +11,7 @@ extension ClientDownloadContentExtension on Client {
bool isThumbnail = false,
bool? animated,
ThumbnailMethod? thumbnailMethod,
+ bool rounded = false,
}) async {
// To stay compatible with previous storeKeys:
final cacheKey = isThumbnail
@@ -44,10 +46,17 @@ extension ClientDownloadContentExtension on Client {
if (response.statusCode != 200) {
throw Exception();
}
- final remoteData = response.bodyBytes;
+ var imageData = response.bodyBytes;
- await database?.storeFile(cacheKey, remoteData, 0);
+ if (rounded) {
+ final image = decodeImage(imageData);
+ if (image != null) {
+ imageData = copyCropCircle(image).toUint8List();
+ }
+ }
- return remoteData;
+ await database?.storeFile(cacheKey, imageData, 0);
+
+ return imageData;
}
}
diff --git a/lib/utils/push_helper.dart b/lib/utils/push_helper.dart
index 538ad77d5..91b23e479 100644
--- a/lib/utils/push_helper.dart
+++ b/lib/utils/push_helper.dart
@@ -1,3 +1,4 @@
+import 'dart:convert';
import 'dart:ui';
import 'package:flutter/foundation.dart';
@@ -16,7 +17,6 @@ import 'package:fluffychat/utils/client_download_content_extension.dart';
import 'package:fluffychat/utils/client_manager.dart';
import 'package:fluffychat/utils/matrix_sdk_extensions/matrix_locals.dart';
import 'package:fluffychat/utils/platform_infos.dart';
-import 'package:fluffychat/utils/shortcut_memory_icon.dart';
Future pushHelper(
PushNotification notification, {
@@ -165,11 +165,12 @@ Future _tryPushHelper(
: await client
.downloadMxcCached(
avatar,
- thumbnailMethod: ThumbnailMethod.scale,
- width: 256,
- height: 256,
+ thumbnailMethod: ThumbnailMethod.crop,
+ width: 128,
+ height: 128,
animated: false,
isThumbnail: true,
+ rounded: true,
)
.timeout(const Duration(seconds: 3));
} catch (e, s) {
@@ -186,11 +187,12 @@ Future _tryPushHelper(
: await client
.downloadMxcCached(
senderAvatar,
- thumbnailMethod: ThumbnailMethod.scale,
- width: 256,
- height: 256,
+ thumbnailMethod: ThumbnailMethod.crop,
+ width: 128,
+ height: 128,
animated: false,
isThumbnail: true,
+ rounded: true,
)
.timeout(const Duration(seconds: 3));
} catch (e, s) {
@@ -320,10 +322,7 @@ Future _setShortcut(
action: AppConfig.inviteLinkPrefix + event.room.id,
shortLabel: title,
conversationShortcut: true,
- icon: await avatarFile?.toShortcutMemoryIcon(
- event.room.id,
- event.room.client.database,
- ),
+ icon: avatarFile == null ? null : base64Encode(avatarFile),
shortcutIconAsset: avatarFile == null
? ShortcutIconAsset.androidAsset
: ShortcutIconAsset.memoryAsset,
diff --git a/lib/utils/shortcut_memory_icon.dart b/lib/utils/shortcut_memory_icon.dart
deleted file mode 100644
index c1557e44a..000000000
--- a/lib/utils/shortcut_memory_icon.dart
+++ /dev/null
@@ -1,36 +0,0 @@
-import 'dart:convert';
-import 'dart:typed_data';
-
-import 'package:image/image.dart';
-import 'package:matrix/matrix.dart';
-
-extension ShortcutMemoryIcon on Uint8List {
- Future toShortcutMemoryIcon(
- String roomId,
- DatabaseApi? database,
- ) async {
- final cacheKey = Uri.parse('im.fluffychat://shortcuts/$roomId');
- final cachedFile = await database?.getFile(cacheKey);
- if (cachedFile != null) return base64Encode(cachedFile);
-
- final image = decodeImage(this);
- if (image == null) return null;
-
- final size = image.width < image.height ? image.width : image.height;
- final x = (image.width - size) ~/ 2;
- final y = (image.height - size) ~/ 2;
-
- final croppedImage = copyCrop(
- image,
- x: x,
- y: y,
- width: size,
- height: size,
- );
-
- final bytes = croppedImage.toUint8List();
- await database?.storeFile(cacheKey, bytes, 0);
-
- return base64Encode(croppedImage.toUint8List());
- }
-}