Skip to content

Commit 311964e

Browse files
committed
msglist: Support retrieving failed outbox message content
1 parent d0379eb commit 311964e

13 files changed

+279
-23
lines changed

assets/l10n/app_en.arb

+4
Original file line numberDiff line numberDiff line change
@@ -801,6 +801,10 @@
801801
"@messageIsMovedLabel": {
802802
"description": "Label for a moved message. (Use ALL CAPS for cased alphabets: Latin, Greek, Cyrillic, etc.)"
803803
},
804+
"messageIsntSentLabel": "MESSAGE ISN'T SENT. CHECK YOUR CONNECTION.",
805+
"@messageIsntSentLabel": {
806+
"description": "Label for a message that isn't sent. (Use ALL CAPS for cased alphabets: Latin, Greek, Cyrillic, etc.)"
807+
},
804808
"pollVoterNames": "({voterNames})",
805809
"@pollVoterNames": {
806810
"description": "The list of people who voted for a poll option, wrapped in parentheses.",

lib/generated/l10n/zulip_localizations.dart

+6
Original file line numberDiff line numberDiff line change
@@ -1184,6 +1184,12 @@ abstract class ZulipLocalizations {
11841184
/// **'MOVED'**
11851185
String get messageIsMovedLabel;
11861186

1187+
/// Label for a message that isn't sent. (Use ALL CAPS for cased alphabets: Latin, Greek, Cyrillic, etc.)
1188+
///
1189+
/// In en, this message translates to:
1190+
/// **'MESSAGE ISN\'T SENT. CHECK YOUR CONNECTION.'**
1191+
String get messageIsntSentLabel;
1192+
11871193
/// The list of people who voted for a poll option, wrapped in parentheses.
11881194
///
11891195
/// In en, this message translates to:

lib/generated/l10n/zulip_localizations_ar.dart

+4
Original file line numberDiff line numberDiff line change
@@ -654,6 +654,10 @@ class ZulipLocalizationsAr extends ZulipLocalizations {
654654
@override
655655
String get messageIsMovedLabel => 'MOVED';
656656

657+
@override
658+
String get messageIsntSentLabel =>
659+
'MESSAGE ISN\'T SENT. CHECK YOUR CONNECTION.';
660+
657661
@override
658662
String pollVoterNames(String voterNames) {
659663
return '($voterNames)';

lib/generated/l10n/zulip_localizations_en.dart

+4
Original file line numberDiff line numberDiff line change
@@ -654,6 +654,10 @@ class ZulipLocalizationsEn extends ZulipLocalizations {
654654
@override
655655
String get messageIsMovedLabel => 'MOVED';
656656

657+
@override
658+
String get messageIsntSentLabel =>
659+
'MESSAGE ISN\'T SENT. CHECK YOUR CONNECTION.';
660+
657661
@override
658662
String pollVoterNames(String voterNames) {
659663
return '($voterNames)';

lib/generated/l10n/zulip_localizations_ja.dart

+4
Original file line numberDiff line numberDiff line change
@@ -654,6 +654,10 @@ class ZulipLocalizationsJa extends ZulipLocalizations {
654654
@override
655655
String get messageIsMovedLabel => 'MOVED';
656656

657+
@override
658+
String get messageIsntSentLabel =>
659+
'MESSAGE ISN\'T SENT. CHECK YOUR CONNECTION.';
660+
657661
@override
658662
String pollVoterNames(String voterNames) {
659663
return '($voterNames)';

lib/generated/l10n/zulip_localizations_nb.dart

+4
Original file line numberDiff line numberDiff line change
@@ -654,6 +654,10 @@ class ZulipLocalizationsNb extends ZulipLocalizations {
654654
@override
655655
String get messageIsMovedLabel => 'MOVED';
656656

657+
@override
658+
String get messageIsntSentLabel =>
659+
'MESSAGE ISN\'T SENT. CHECK YOUR CONNECTION.';
660+
657661
@override
658662
String pollVoterNames(String voterNames) {
659663
return '($voterNames)';

lib/generated/l10n/zulip_localizations_pl.dart

+4
Original file line numberDiff line numberDiff line change
@@ -663,6 +663,10 @@ class ZulipLocalizationsPl extends ZulipLocalizations {
663663
@override
664664
String get messageIsMovedLabel => 'PRZENIESIONO';
665665

666+
@override
667+
String get messageIsntSentLabel =>
668+
'MESSAGE ISN\'T SENT. CHECK YOUR CONNECTION.';
669+
666670
@override
667671
String pollVoterNames(String voterNames) {
668672
return '($voterNames)';

lib/generated/l10n/zulip_localizations_ru.dart

+4
Original file line numberDiff line numberDiff line change
@@ -667,6 +667,10 @@ class ZulipLocalizationsRu extends ZulipLocalizations {
667667
@override
668668
String get messageIsMovedLabel => 'ПЕРЕМЕЩЕНО';
669669

670+
@override
671+
String get messageIsntSentLabel =>
672+
'MESSAGE ISN\'T SENT. CHECK YOUR CONNECTION.';
673+
670674
@override
671675
String pollVoterNames(String voterNames) {
672676
return '($voterNames)';

lib/generated/l10n/zulip_localizations_sk.dart

+4
Original file line numberDiff line numberDiff line change
@@ -656,6 +656,10 @@ class ZulipLocalizationsSk extends ZulipLocalizations {
656656
@override
657657
String get messageIsMovedLabel => 'PRESUNUTÉ';
658658

659+
@override
660+
String get messageIsntSentLabel =>
661+
'MESSAGE ISN\'T SENT. CHECK YOUR CONNECTION.';
662+
659663
@override
660664
String pollVoterNames(String voterNames) {
661665
return '($voterNames)';

lib/generated/l10n/zulip_localizations_uk.dart

+4
Original file line numberDiff line numberDiff line change
@@ -666,6 +666,10 @@ class ZulipLocalizationsUk extends ZulipLocalizations {
666666
@override
667667
String get messageIsMovedLabel => 'ПЕРЕМІЩЕНО';
668668

669+
@override
670+
String get messageIsntSentLabel =>
671+
'MESSAGE ISN\'T SENT. CHECK YOUR CONNECTION.';
672+
669673
@override
670674
String pollVoterNames(String voterNames) {
671675
return '($voterNames)';

lib/model/message.dart

+2-3
Original file line numberDiff line numberDiff line change
@@ -275,9 +275,8 @@ mixin _OutboxMessageStore on PerAccountStoreBase {
275275
void _handleMessageEventOutbox(MessageEvent event) {
276276
if (event.localMessageId != null) {
277277
final localMessageId = int.parse(event.localMessageId!, radix: 10);
278-
// The outbox message can be missing if the user removes it (to be
279-
// implemented in #1441) before the event arrives.
280-
// Nothing to do in that case.
278+
// The outbox message can be missing if the user removes it before the
279+
// event arrives. Nothing to do in that case.
281280
_outboxMessages.remove(localMessageId);
282281
_outboxMessageDebounceTimers.remove(localMessageId)?.cancel();
283282
_outboxMessageWaitPeriodTimers.remove(localMessageId)?.cancel();

lib/widgets/message_list.dart

+80-15
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ import 'package:intl/intl.dart' hide TextDirection;
55

66
import '../api/model/model.dart';
77
import '../generated/l10n/zulip_localizations.dart';
8+
import '../model/message.dart';
89
import '../model/message_list.dart';
910
import '../model/narrow.dart';
1011
import '../model/store.dart';
@@ -1515,22 +1516,86 @@ class OutboxMessageWithPossibleSender extends StatelessWidget {
15151516

15161517
final MessageListOutboxMessageItem item;
15171518

1519+
// TODO should we restore the topic as well?
1520+
void _handlePress(BuildContext context) {
1521+
final content = item.message.content.endsWith('\n')
1522+
? item.message.content : '${item.message.content}\n';
1523+
1524+
final composeBoxController =
1525+
MessageListPage.ancestorOf(context).composeBoxState!.controller;
1526+
composeBoxController.content.insertPadded(content);
1527+
if (!composeBoxController.contentFocusNode.hasFocus) {
1528+
composeBoxController.contentFocusNode.requestFocus();
1529+
}
1530+
1531+
final store = PerAccountStoreWidget.of(context);
1532+
assert(store.outboxMessages.containsKey(item.message.localMessageId));
1533+
store.removeOutboxMessage(item.message.localMessageId);
1534+
}
1535+
15181536
@override
15191537
Widget build(BuildContext context) {
1520-
final message = item.message;
1521-
return Padding(
1522-
padding: const EdgeInsets.symmetric(vertical: 4),
1523-
child: Column(children: [
1524-
if (item.showSender)
1525-
_SenderRow(message: message, showTimestamp: false),
1526-
Padding(
1527-
padding: const EdgeInsets.symmetric(horizontal: 16),
1528-
// This is adapated from [MessageContent].
1529-
// TODO(#576): Offer InheritedMessage ancestor once we are ready
1530-
// to support local echoing images and lightbox.
1531-
child: DefaultTextStyle(
1532-
style: ContentTheme.of(context).textStylePlainParagraph,
1533-
child: BlockContentList(nodes: item.content.nodes))),
1534-
]));
1538+
final designVariables = DesignVariables.of(context);
1539+
final zulipLocalizations = ZulipLocalizations.of(context);
1540+
final isComposeBoxOffered =
1541+
MessageListPage.ancestorOf(context).composeBoxState != null;
1542+
1543+
final GestureTapCallback? handleTap;
1544+
final double opacity;
1545+
final Widget bottom;
1546+
switch (item.message.state) {
1547+
case OutboxMessageState.hidden:
1548+
assert(false,
1549+
'Hidden OutboxMessage messages should not appear in message lists');
1550+
handleTap = null;
1551+
opacity = 1.0;
1552+
bottom = SizedBox.shrink();
1553+
1554+
case OutboxMessageState.waiting:
1555+
handleTap = null;
1556+
opacity = 1.0;
1557+
bottom = LinearProgressIndicator(
1558+
minHeight: 2,
1559+
color: designVariables.foreground.withFadedAlpha(0.5),
1560+
backgroundColor: designVariables.foreground.withFadedAlpha(0.2));
1561+
1562+
case OutboxMessageState.failed:
1563+
case OutboxMessageState.waitPeriodExpired:
1564+
handleTap = isComposeBoxOffered ? () => _handlePress(context) : null;
1565+
opacity = 0.6;
1566+
bottom = Text(
1567+
zulipLocalizations.messageIsntSentLabel,
1568+
textAlign: TextAlign.end,
1569+
style: TextStyle(
1570+
color: designVariables.btnLabelAttLowIntDanger,
1571+
fontSize: 12,
1572+
height: 12 / 12,
1573+
letterSpacing: proportionalLetterSpacing(
1574+
context, 0.006, baseFontSize: 12),
1575+
).merge(weightVariableTextStyle(context, wght: 400)));
1576+
}
1577+
1578+
return GestureDetector(
1579+
onTap: handleTap,
1580+
behavior: HitTestBehavior.opaque,
1581+
child: Opacity(opacity: opacity, child: Padding(
1582+
padding: const EdgeInsets.symmetric(vertical: 4),
1583+
child: Column(children: [
1584+
if (item.showSender)
1585+
_SenderRow(message: item.message, showTimestamp: false),
1586+
Padding(
1587+
padding: const EdgeInsets.symmetric(horizontal: 16),
1588+
child: Column(crossAxisAlignment: CrossAxisAlignment.stretch,
1589+
children: [
1590+
// This is adapated from [MessageContent].
1591+
// TODO(#576): Offer InheritedMessage ancestor once we are ready
1592+
// to support local echoing images and lightbox.
1593+
DefaultTextStyle(
1594+
style: ContentTheme.of(context).textStylePlainParagraph,
1595+
child: BlockContentList(nodes: item.content.nodes)),
1596+
1597+
bottom,
1598+
])),
1599+
]))));
15351600
}
15361601
}

0 commit comments

Comments
 (0)