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()); - } -}