Skip to content

Commit 800461c

Browse files
committed
wip
1 parent 7b324af commit 800461c

File tree

5 files changed

+76
-4
lines changed

5 files changed

+76
-4
lines changed

assets/l10n/app_en.arb

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,10 @@
4747
"@actionSheetOptionCopy": {
4848
"description": "Label for copy message text button on action sheet."
4949
},
50+
"actionSheetMarkAsUnread": "Mark as unread from here",
51+
"@actionSheetMarkAsUnread": {
52+
"description": "Label for mark as unread button on action sheet."
53+
},
5054
"actionSheetOptionShare": "Share",
5155
"@actionSheetOptionShare": {
5256
"description": "Label for share button on action sheet."

lib/api/model/model.dart

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -504,6 +504,18 @@ sealed class Message {
504504
return list.map((raw) => MessageFlag.fromRawString(raw as String)).toList();
505505
}
506506

507+
bool isOnSameNarrowAs(Message other) {
508+
if (this is StreamMessage) {
509+
return other is StreamMessage
510+
&& other.streamId == (this as StreamMessage).streamId
511+
&& other.topic == topic;
512+
} else if (this is DmMessage) {
513+
return other is DmMessage
514+
&& other.recipientId == recipientId;
515+
}
516+
return false;
517+
}
518+
507519
Message({
508520
required this.client,
509521
required this.content,

lib/model/message_list.dart

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -238,6 +238,25 @@ mixin _MessageSequence {
238238
}
239239
_updateEndMarkers();
240240
}
241+
242+
/// Returns a list of messages that are sent after the given [message].
243+
List<Message> getMessagesAfter(Message message) {
244+
final messageIndex = _findMessageWithId(message.id);
245+
if (messageIndex == -1) {
246+
// Message not found in the list, return an empty list.
247+
return [];
248+
}
249+
250+
// Return the list of messages after the given message.
251+
return messages.sublist(messageIndex + 1);
252+
}
253+
254+
/// Returns a list of messages that are sent after the given [message] on same narrow.
255+
List<Message> getNarrowMessagesAfter(Message message) {
256+
return getMessagesAfter(message)
257+
.where((element) => element.isOnSameNarrowAs(message))
258+
.toList();
259+
}
241260
}
242261

243262
@visibleForTesting

lib/widgets/action_sheet.dart

Lines changed: 34 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ import 'package:share_plus/share_plus.dart';
66
import '../api/exception.dart';
77
import '../api/model/model.dart';
88
import '../api/route/messages.dart';
9+
import '../model/message_list.dart';
910
import 'clipboard.dart';
1011
import 'compose_box.dart';
1112
import 'dialog.dart';
@@ -17,7 +18,7 @@ import 'store.dart';
1718
/// Show a sheet of actions you can take on a message in the message list.
1819
///
1920
/// Must have a [MessageListPage] ancestor.
20-
void showMessageActionSheet({required BuildContext context, required Message message}) {
21+
void showMessageActionSheet({required BuildContext context, required Message message, required MessageListView model}) {
2122
final store = PerAccountStoreWidget.of(context);
2223

2324
// The UI that's conditioned on this won't live-update during this appearance
@@ -45,6 +46,7 @@ void showMessageActionSheet({required BuildContext context, required Message mes
4546
messageListContext: context,
4647
),
4748
CopyButton(message: message, messageListContext: context),
49+
MarkAsUnread(message: message, messageListContext: context, model: model),
4850
]);
4951
});
5052
}
@@ -366,3 +368,34 @@ class CopyButton extends MessageActionSheetMenuItemButton {
366368
data: ClipboardData(text: rawContent));
367369
}
368370
}
371+
372+
class MarkAsUnread extends MessageActionSheetMenuItemButton {
373+
MarkAsUnread({
374+
super.key,
375+
required super.message,
376+
required super.messageListContext,
377+
required this.model,
378+
});
379+
380+
final MessageListView model;
381+
382+
@override IconData get icon => Icons.mark_chat_unread_outlined;
383+
384+
@override
385+
String label(ZulipLocalizations zulipLocalizations) {
386+
return zulipLocalizations.actionSheetMarkAsUnread;
387+
}
388+
389+
@override void onPressed(BuildContext context) async {
390+
Navigator.of(context).pop();
391+
final ids = [
392+
message.id,
393+
...model.getNarrowMessagesAfter(message).map((e) => e.id)];
394+
395+
try {
396+
final connection = PerAccountStoreWidget.of(messageListContext).connection;
397+
await updateMessageFlags(connection, messages: ids,
398+
op: UpdateMessageFlagsOp.remove, flag: MessageFlag.read);
399+
} catch (e) {}
400+
}
401+
}

lib/widgets/message_list.dart

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -397,6 +397,7 @@ class _MessageListState extends State<MessageList> with PerAccountStoreAwareStat
397397
case MessageListMessageItem():
398398
final header = RecipientHeader(message: data.message, narrow: widget.narrow);
399399
return MessageItem(
400+
model: model!,
400401
key: ValueKey(data.message.id),
401402
header: header,
402403
trailingWhitespace: i == 1 ? 8 : 11,
@@ -571,12 +572,14 @@ class MessageItem extends StatelessWidget {
571572
super.key,
572573
required this.item,
573574
required this.header,
575+
required this.model,
574576
this.trailingWhitespace,
575577
});
576578

577579
final MessageListMessageItem item;
578580
final Widget header;
579581
final double? trailingWhitespace;
582+
final MessageListView model;
580583

581584
@override
582585
Widget build(BuildContext context) {
@@ -589,7 +592,7 @@ class MessageItem extends StatelessWidget {
589592
child: ColoredBox(
590593
color: Colors.white,
591594
child: Column(children: [
592-
MessageWithPossibleSender(item: item),
595+
MessageWithPossibleSender(item: item, model: model,),
593596
if (trailingWhitespace != null && item.isLastInBlock) SizedBox(height: trailingWhitespace!),
594597
]))));
595598
}
@@ -892,9 +895,10 @@ String formatHeaderDate(
892895
// - https://github.com/zulip/zulip-mobile/issues/5511
893896
// - https://www.figma.com/file/1JTNtYo9memgW7vV6d0ygq/Zulip-Mobile?node-id=538%3A20849&mode=dev
894897
class MessageWithPossibleSender extends StatelessWidget {
895-
const MessageWithPossibleSender({super.key, required this.item});
898+
const MessageWithPossibleSender({super.key, required this.item, required this.model});
896899

897900
final MessageListMessageItem item;
901+
final MessageListView model;
898902

899903
// TODO(#95) unchanged in dark theme?
900904
static final _starColor = const HSLColor.fromAHSL(0.5, 47, 1, 0.41).toColor();
@@ -957,7 +961,7 @@ class MessageWithPossibleSender extends StatelessWidget {
957961

958962
return GestureDetector(
959963
behavior: HitTestBehavior.translucent,
960-
onLongPress: () => showMessageActionSheet(context: context, message: message),
964+
onLongPress: () => showMessageActionSheet(context: context, message: message, model: model),
961965
child: Padding(
962966
padding: const EdgeInsets.symmetric(vertical: 4),
963967
child: Column(children: [

0 commit comments

Comments
 (0)