Add localization for 'Received a GIF' in multiple languages and update chat UI

This commit is contained in:
Zach
2026-07-08 20:38:06 -07:00
parent c683dbd8f1
commit 8765d0f4cc
26 changed files with 107 additions and 12 deletions
+1
View File
@@ -734,6 +734,7 @@
} }
}, },
"chat_sendGif": "Send GIF", "chat_sendGif": "Send GIF",
"chat_receivedGif": "Received a GIF",
"chat_reply": "Reply", "chat_reply": "Reply",
"chat_addReaction": "Add Reaction", "chat_addReaction": "Add Reaction",
"chat_me": "Me", "chat_me": "Me",
+6
View File
@@ -2692,6 +2692,12 @@ abstract class AppLocalizations {
/// **'Send GIF'** /// **'Send GIF'**
String get chat_sendGif; String get chat_sendGif;
/// No description provided for @chat_receivedGif.
///
/// In en, this message translates to:
/// **'Received a GIF'**
String get chat_receivedGif;
/// No description provided for @chat_reply. /// No description provided for @chat_reply.
/// ///
/// In en, this message translates to: /// In en, this message translates to:
+4 -1
View File
@@ -1468,6 +1468,9 @@ class AppLocalizationsBg extends AppLocalizations {
@override @override
String get chat_sendGif => 'Изпрати GIF'; String get chat_sendGif => 'Изпрати GIF';
@override
String get chat_receivedGif => 'Received a GIF';
@override @override
String get chat_reply => 'Отговори'; String get chat_reply => 'Отговори';
@@ -2706,7 +2709,6 @@ class AppLocalizationsBg extends AppLocalizations {
'Байтовете, използвани за кодиране на идентификатора на този повторител в таговете за откриване на потоци/цикли, са: 0=1 байт (256 идентификатора, до 64 скока), 1=2 байта (65 000 идентификатора, до 32 скока), 2=3 байта (16 милиона идентификатора, до 21 скока). Версиите 1.13 и по-старите фърмуери използват многобайтови пътища - само след като мрежата е актуализирана до версия 1.14 или по-нова.'; 'Байтовете, използвани за кодиране на идентификатора на този повторител в таговете за откриване на потоци/цикли, са: 0=1 байт (256 идентификатора, до 64 скока), 1=2 байта (65 000 идентификатора, до 32 скока), 2=3 байта (16 милиона идентификатора, до 21 скока). Версиите 1.13 и по-старите фърмуери използват многобайтови пътища - само след като мрежата е актуализирана до версия 1.14 или по-нова.';
@override @override
String get repeater_txDelay => 'Забавяне на Flood TX';
String get repeater_keySettings => 'Change Identity Keys'; String get repeater_keySettings => 'Change Identity Keys';
@override @override
@@ -2742,6 +2744,7 @@ class AppLocalizationsBg extends AppLocalizations {
} }
@override @override
String get repeater_txDelay => 'Забавяне на Flood TX';
@override @override
String get repeater_txDelayHelper => String get repeater_txDelayHelper =>
+3
View File
@@ -1469,6 +1469,9 @@ class AppLocalizationsDe extends AppLocalizations {
@override @override
String get chat_sendGif => 'GIF senden'; String get chat_sendGif => 'GIF senden';
@override
String get chat_receivedGif => 'Received a GIF';
@override @override
String get chat_reply => 'Antworten'; String get chat_reply => 'Antworten';
+3
View File
@@ -1438,6 +1438,9 @@ class AppLocalizationsEn extends AppLocalizations {
@override @override
String get chat_sendGif => 'Send GIF'; String get chat_sendGif => 'Send GIF';
@override
String get chat_receivedGif => 'Received a GIF';
@override @override
String get chat_reply => 'Reply'; String get chat_reply => 'Reply';
+3
View File
@@ -1465,6 +1465,9 @@ class AppLocalizationsEs extends AppLocalizations {
@override @override
String get chat_sendGif => 'Enviar GIF'; String get chat_sendGif => 'Enviar GIF';
@override
String get chat_receivedGif => 'Received a GIF';
@override @override
String get chat_reply => 'Responder'; String get chat_reply => 'Responder';
+3
View File
@@ -1467,6 +1467,9 @@ class AppLocalizationsFr extends AppLocalizations {
@override @override
String get chat_sendGif => 'Envoyer un GIF'; String get chat_sendGif => 'Envoyer un GIF';
@override
String get chat_receivedGif => 'Received a GIF';
@override @override
String get chat_reply => 'Répondre'; String get chat_reply => 'Répondre';
+3
View File
@@ -1460,6 +1460,9 @@ class AppLocalizationsHu extends AppLocalizations {
@override @override
String get chat_sendGif => 'GIF küldése'; String get chat_sendGif => 'GIF küldése';
@override
String get chat_receivedGif => 'Received a GIF';
@override @override
String get chat_reply => 'Válasz'; String get chat_reply => 'Válasz';
+3
View File
@@ -1466,6 +1466,9 @@ class AppLocalizationsIt extends AppLocalizations {
@override @override
String get chat_sendGif => 'Invia GIF'; String get chat_sendGif => 'Invia GIF';
@override
String get chat_receivedGif => 'Received a GIF';
@override @override
String get chat_reply => 'Rispondi'; String get chat_reply => 'Rispondi';
+3
View File
@@ -1395,6 +1395,9 @@ class AppLocalizationsJa extends AppLocalizations {
@override @override
String get chat_sendGif => 'GIF を送信'; String get chat_sendGif => 'GIF を送信';
@override
String get chat_receivedGif => 'Received a GIF';
@override @override
String get chat_reply => '返信'; String get chat_reply => '返信';
+3
View File
@@ -1398,6 +1398,9 @@ class AppLocalizationsKo extends AppLocalizations {
@override @override
String get chat_sendGif => 'GIF 보내기'; String get chat_sendGif => 'GIF 보내기';
@override
String get chat_receivedGif => 'Received a GIF';
@override @override
String get chat_reply => '답변'; String get chat_reply => '답변';
+3
View File
@@ -1454,6 +1454,9 @@ class AppLocalizationsNl extends AppLocalizations {
@override @override
String get chat_sendGif => 'GIF verzenden'; String get chat_sendGif => 'GIF verzenden';
@override
String get chat_receivedGif => 'Received a GIF';
@override @override
String get chat_reply => 'Reageren'; String get chat_reply => 'Reageren';
+3
View File
@@ -1477,6 +1477,9 @@ class AppLocalizationsPl extends AppLocalizations {
@override @override
String get chat_sendGif => 'Wyślij GIF'; String get chat_sendGif => 'Wyślij GIF';
@override
String get chat_receivedGif => 'Received a GIF';
@override @override
String get chat_reply => 'Odpowiedz'; String get chat_reply => 'Odpowiedz';
+3
View File
@@ -1464,6 +1464,9 @@ class AppLocalizationsPt extends AppLocalizations {
@override @override
String get chat_sendGif => 'Enviar GIF'; String get chat_sendGif => 'Enviar GIF';
@override
String get chat_receivedGif => 'Received a GIF';
@override @override
String get chat_reply => 'Responder'; String get chat_reply => 'Responder';
+3
View File
@@ -1465,6 +1465,9 @@ class AppLocalizationsRu extends AppLocalizations {
@override @override
String get chat_sendGif => 'Отправить GIF'; String get chat_sendGif => 'Отправить GIF';
@override
String get chat_receivedGif => 'Received a GIF';
@override @override
String get chat_reply => 'Ответить'; String get chat_reply => 'Ответить';
+3
View File
@@ -1454,6 +1454,9 @@ class AppLocalizationsSk extends AppLocalizations {
@override @override
String get chat_sendGif => 'Odoslať GIF'; String get chat_sendGif => 'Odoslať GIF';
@override
String get chat_receivedGif => 'Received a GIF';
@override @override
String get chat_reply => 'Odpovedať'; String get chat_reply => 'Odpovedať';
+3
View File
@@ -1453,6 +1453,9 @@ class AppLocalizationsSl extends AppLocalizations {
@override @override
String get chat_sendGif => 'Pošlji GIF'; String get chat_sendGif => 'Pošlji GIF';
@override
String get chat_receivedGif => 'Received a GIF';
@override @override
String get chat_reply => 'Odgovori'; String get chat_reply => 'Odgovori';
+3
View File
@@ -1446,6 +1446,9 @@ class AppLocalizationsSv extends AppLocalizations {
@override @override
String get chat_sendGif => 'Skicka GIF'; String get chat_sendGif => 'Skicka GIF';
@override
String get chat_receivedGif => 'Received a GIF';
@override @override
String get chat_reply => 'Svara'; String get chat_reply => 'Svara';
+3
View File
@@ -1459,6 +1459,9 @@ class AppLocalizationsUk extends AppLocalizations {
@override @override
String get chat_sendGif => 'Надіслати GIF'; String get chat_sendGif => 'Надіслати GIF';
@override
String get chat_receivedGif => 'Received a GIF';
@override @override
String get chat_reply => 'Відповісти'; String get chat_reply => 'Відповісти';
+3
View File
@@ -1381,6 +1381,9 @@ class AppLocalizationsZh extends AppLocalizations {
@override @override
String get chat_sendGif => '发送 GIF'; String get chat_sendGif => '发送 GIF';
@override
String get chat_receivedGif => 'Received a GIF';
@override @override
String get chat_reply => '回复'; String get chat_reply => '回复';
+2
View File
@@ -1579,6 +1579,8 @@ class _ChannelChatScreenState extends State<ChannelChatScreen> {
} }
String _formatPathPrefixes(Uint8List pathBytes) { String _formatPathPrefixes(Uint8List pathBytes) {
// Join with ", " (not bare ",") so long paths have soft-wrap break points
// and stay confined to the message bubble instead of overflowing right.
return pathBytes return pathBytes
.map((b) => b.toRadixString(16).padLeft(2, '0').toUpperCase()) .map((b) => b.toRadixString(16).padLeft(2, '0').toUpperCase())
.join(', '); .join(', ');
+11 -3
View File
@@ -27,6 +27,7 @@ import '../widgets/qr_code_display.dart';
import '../widgets/quick_switch_bar.dart'; import '../widgets/quick_switch_bar.dart';
import '../widgets/sync_progress_overlay.dart'; import '../widgets/sync_progress_overlay.dart';
import '../widgets/unread_badge.dart'; import '../widgets/unread_badge.dart';
import '../helpers/gif_helper.dart';
import '../helpers/snack_bar_builder.dart'; import '../helpers/snack_bar_builder.dart';
import 'channel_chat_screen.dart'; import 'channel_chat_screen.dart';
import 'community_qr_scanner_screen.dart'; import 'community_qr_scanner_screen.dart';
@@ -410,7 +411,11 @@ class _ChannelsScreenState extends State<ChannelsScreen>
// Last message preview // Last message preview
final messages = connector.getChannelMessages(channel); final messages = connector.getChannelMessages(channel);
final lastMessage = messages.isNotEmpty ? messages.last : null; final lastMessage = messages.isNotEmpty ? messages.last : null;
final lastPreview = lastMessage?.text ?? ''; final lastMessageText = lastMessage?.text ?? '';
final lastPreview = lastMessageText.isNotEmpty &&
GifHelper.parseGif(lastMessageText) != null
? context.l10n.chat_receivedGif
: lastMessageText;
final lastTime = lastMessage?.timestamp; final lastTime = lastMessage?.timestamp;
final channelLabel = channel.name.isEmpty final channelLabel = channel.name.isEmpty
@@ -453,7 +458,7 @@ class _ChannelsScreenState extends State<ChannelsScreen>
) )
: null, : null,
child: Row( child: Row(
crossAxisAlignment: CrossAxisAlignment.center, crossAxisAlignment: CrossAxisAlignment.start,
children: [ children: [
// Leading avatar with optional community badge // Leading avatar with optional community badge
Stack( Stack(
@@ -581,10 +586,13 @@ class _ChannelsScreenState extends State<ChannelsScreen>
const SizedBox(width: 4), const SizedBox(width: 4),
ReorderableDragStartListener( ReorderableDragStartListener(
index: dragIndex, index: dragIndex,
// Top-aligned with the "CH n" / time line. Bottom padding keeps
// a comfortable drag target without pushing the icon down.
child: Padding( child: Padding(
padding: const EdgeInsets.all(8), padding: const EdgeInsets.only(left: 8, right: 8, bottom: 16),
child: Icon( child: Icon(
Icons.drag_handle, Icons.drag_handle,
size: 18,
color: scheme.onSurfaceVariant, color: scheme.onSurfaceVariant,
), ),
), ),
+2 -2
View File
@@ -276,7 +276,7 @@ class _NeighborsScreenState extends State<NeighborsScreen> {
return Scaffold( return Scaffold(
appBar: AppBar( appBar: AppBar(
title: Column( title: Column(
crossAxisAlignment: CrossAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.center,
mainAxisSize: MainAxisSize.min, mainAxisSize: MainAxisSize.min,
children: [ children: [
Text( Text(
@@ -296,7 +296,7 @@ class _NeighborsScreenState extends State<NeighborsScreen> {
), ),
], ],
), ),
centerTitle: false, centerTitle: true,
actions: [ actions: [
IconButton( IconButton(
icon: Icon(isFloodMode ? Icons.waves : Icons.route), icon: Icon(isFloodMode ? Icons.waves : Icons.route),
+2 -2
View File
@@ -334,7 +334,7 @@ class _TelemetryScreenState extends State<TelemetryScreen> {
return Scaffold( return Scaffold(
appBar: AppBar( appBar: AppBar(
title: Column( title: Column(
crossAxisAlignment: CrossAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.center,
mainAxisSize: MainAxisSize.min, mainAxisSize: MainAxisSize.min,
children: [ children: [
Text( Text(
@@ -350,7 +350,7 @@ class _TelemetryScreenState extends State<TelemetryScreen> {
), ),
], ],
), ),
centerTitle: false, centerTitle: true,
bottom: const SyncProgressAppBarBottom(), bottom: const SyncProgressAppBarBottom(),
actions: [ actions: [
IconButton( IconButton(
+10 -3
View File
@@ -26,9 +26,16 @@ class QuickSwitchBar extends StatelessWidget {
final colorScheme = theme.colorScheme; final colorScheme = theme.colorScheme;
final labelStyle = theme.textTheme.labelMedium ?? const TextStyle(); final labelStyle = theme.textTheme.labelMedium ?? const TextStyle();
final background = highContrast ? MapPalette.panelDark : Colors.transparent; final background = highContrast ? MapPalette.panelDark : Colors.transparent;
final selectedColor = highContrast // The selected icon sits on the primary indicator pill, so it uses
// onPrimary. The label sits below on the bar background, so it must use a
// foreground color that contrasts with the surface (not onPrimary, which
// is white-on-white in the light theme).
final selectedIconColor = highContrast
? MapPalette.textPrimary ? MapPalette.textPrimary
: colorScheme.onPrimary; : colorScheme.onPrimary;
final selectedLabelColor = highContrast
? MapPalette.textPrimary
: colorScheme.onSurface;
final unselectedColor = highContrast final unselectedColor = highContrast
? MapPalette.textSecondary ? MapPalette.textSecondary
: colorScheme.onSurfaceVariant; : colorScheme.onSurfaceVariant;
@@ -59,13 +66,13 @@ class QuickSwitchBar extends StatelessWidget {
final isSelected = states.contains(WidgetState.selected); final isSelected = states.contains(WidgetState.selected);
return labelStyle.copyWith( return labelStyle.copyWith(
fontWeight: isSelected ? FontWeight.w700 : FontWeight.w500, fontWeight: isSelected ? FontWeight.w700 : FontWeight.w500,
color: isSelected ? selectedColor : unselectedColor, color: isSelected ? selectedLabelColor : unselectedColor,
); );
}), }),
iconTheme: WidgetStateProperty.resolveWith((states) { iconTheme: WidgetStateProperty.resolveWith((states) {
final isSelected = states.contains(WidgetState.selected); final isSelected = states.contains(WidgetState.selected);
return IconThemeData( return IconThemeData(
color: isSelected ? selectedColor : unselectedColor, color: isSelected ? selectedIconColor : unselectedColor,
); );
}), }),
), ),
+17
View File
@@ -16,6 +16,7 @@
"channels_regionNotSet", "channels_regionNotSet",
"channels_regionSelect_Title", "channels_regionSelect_Title",
"channels_clearRegion", "channels_clearRegion",
"chat_receivedGif",
"repeater_keySettings", "repeater_keySettings",
"repeater_keySettingsSubtitle", "repeater_keySettingsSubtitle",
"repeater_prvKey", "repeater_prvKey",
@@ -32,6 +33,7 @@
"settings_regionFetchRegions", "settings_regionFetchRegions",
"settings_regionFetchRegionsFail", "settings_regionFetchRegionsFail",
"settings_regionFetchRegionsAlreadyExists", "settings_regionFetchRegionsAlreadyExists",
"chat_receivedGif",
"repeater_keySettings", "repeater_keySettings",
"repeater_keySettingsSubtitle", "repeater_keySettingsSubtitle",
"repeater_prvKey", "repeater_prvKey",
@@ -61,6 +63,7 @@
"channels_regionNotSet", "channels_regionNotSet",
"channels_regionSelect_Title", "channels_regionSelect_Title",
"channels_clearRegion", "channels_clearRegion",
"chat_receivedGif",
"repeater_keySettings", "repeater_keySettings",
"repeater_keySettingsSubtitle", "repeater_keySettingsSubtitle",
"repeater_prvKey", "repeater_prvKey",
@@ -90,6 +93,7 @@
"channels_regionNotSet", "channels_regionNotSet",
"channels_regionSelect_Title", "channels_regionSelect_Title",
"channels_clearRegion", "channels_clearRegion",
"chat_receivedGif",
"repeater_keySettings", "repeater_keySettings",
"repeater_keySettingsSubtitle", "repeater_keySettingsSubtitle",
"repeater_prvKey", "repeater_prvKey",
@@ -119,6 +123,7 @@
"channels_regionNotSet", "channels_regionNotSet",
"channels_regionSelect_Title", "channels_regionSelect_Title",
"channels_clearRegion", "channels_clearRegion",
"chat_receivedGif",
"repeater_keySettings", "repeater_keySettings",
"repeater_keySettingsSubtitle", "repeater_keySettingsSubtitle",
"repeater_prvKey", "repeater_prvKey",
@@ -148,6 +153,7 @@
"channels_regionNotSet", "channels_regionNotSet",
"channels_regionSelect_Title", "channels_regionSelect_Title",
"channels_clearRegion", "channels_clearRegion",
"chat_receivedGif",
"repeater_keySettings", "repeater_keySettings",
"repeater_keySettingsSubtitle", "repeater_keySettingsSubtitle",
"repeater_prvKey", "repeater_prvKey",
@@ -177,6 +183,7 @@
"channels_regionNotSet", "channels_regionNotSet",
"channels_regionSelect_Title", "channels_regionSelect_Title",
"channels_clearRegion", "channels_clearRegion",
"chat_receivedGif",
"repeater_keySettings", "repeater_keySettings",
"repeater_keySettingsSubtitle", "repeater_keySettingsSubtitle",
"repeater_prvKey", "repeater_prvKey",
@@ -206,6 +213,7 @@
"channels_regionNotSet", "channels_regionNotSet",
"channels_regionSelect_Title", "channels_regionSelect_Title",
"channels_clearRegion", "channels_clearRegion",
"chat_receivedGif",
"repeater_keySettings", "repeater_keySettings",
"repeater_keySettingsSubtitle", "repeater_keySettingsSubtitle",
"repeater_prvKey", "repeater_prvKey",
@@ -235,6 +243,7 @@
"channels_regionNotSet", "channels_regionNotSet",
"channels_regionSelect_Title", "channels_regionSelect_Title",
"channels_clearRegion", "channels_clearRegion",
"chat_receivedGif",
"repeater_keySettings", "repeater_keySettings",
"repeater_keySettingsSubtitle", "repeater_keySettingsSubtitle",
"repeater_prvKey", "repeater_prvKey",
@@ -264,6 +273,7 @@
"channels_regionNotSet", "channels_regionNotSet",
"channels_regionSelect_Title", "channels_regionSelect_Title",
"channels_clearRegion", "channels_clearRegion",
"chat_receivedGif",
"repeater_keySettings", "repeater_keySettings",
"repeater_keySettingsSubtitle", "repeater_keySettingsSubtitle",
"repeater_prvKey", "repeater_prvKey",
@@ -293,6 +303,7 @@
"channels_regionNotSet", "channels_regionNotSet",
"channels_regionSelect_Title", "channels_regionSelect_Title",
"channels_clearRegion", "channels_clearRegion",
"chat_receivedGif",
"repeater_keySettings", "repeater_keySettings",
"repeater_keySettingsSubtitle", "repeater_keySettingsSubtitle",
"repeater_prvKey", "repeater_prvKey",
@@ -322,6 +333,7 @@
"channels_regionNotSet", "channels_regionNotSet",
"channels_regionSelect_Title", "channels_regionSelect_Title",
"channels_clearRegion", "channels_clearRegion",
"chat_receivedGif",
"repeater_keySettings", "repeater_keySettings",
"repeater_keySettingsSubtitle", "repeater_keySettingsSubtitle",
"repeater_prvKey", "repeater_prvKey",
@@ -351,6 +363,7 @@
"channels_regionNotSet", "channels_regionNotSet",
"channels_regionSelect_Title", "channels_regionSelect_Title",
"channels_clearRegion", "channels_clearRegion",
"chat_receivedGif",
"repeater_keySettings", "repeater_keySettings",
"repeater_keySettingsSubtitle", "repeater_keySettingsSubtitle",
"repeater_prvKey", "repeater_prvKey",
@@ -380,6 +393,7 @@
"channels_regionNotSet", "channels_regionNotSet",
"channels_regionSelect_Title", "channels_regionSelect_Title",
"channels_clearRegion", "channels_clearRegion",
"chat_receivedGif",
"repeater_keySettings", "repeater_keySettings",
"repeater_keySettingsSubtitle", "repeater_keySettingsSubtitle",
"repeater_prvKey", "repeater_prvKey",
@@ -409,6 +423,7 @@
"channels_regionNotSet", "channels_regionNotSet",
"channels_regionSelect_Title", "channels_regionSelect_Title",
"channels_clearRegion", "channels_clearRegion",
"chat_receivedGif",
"repeater_keySettings", "repeater_keySettings",
"repeater_keySettingsSubtitle", "repeater_keySettingsSubtitle",
"repeater_prvKey", "repeater_prvKey",
@@ -438,6 +453,7 @@
"channels_regionNotSet", "channels_regionNotSet",
"channels_regionSelect_Title", "channels_regionSelect_Title",
"channels_clearRegion", "channels_clearRegion",
"chat_receivedGif",
"repeater_keySettings", "repeater_keySettings",
"repeater_keySettingsSubtitle", "repeater_keySettingsSubtitle",
"repeater_prvKey", "repeater_prvKey",
@@ -467,6 +483,7 @@
"channels_regionNotSet", "channels_regionNotSet",
"channels_regionSelect_Title", "channels_regionSelect_Title",
"channels_clearRegion", "channels_clearRegion",
"chat_receivedGif",
"repeater_keySettings", "repeater_keySettings",
"repeater_keySettingsSubtitle", "repeater_keySettingsSubtitle",
"repeater_prvKey", "repeater_prvKey",