feat: Add read marker

This commit is contained in:
Krille 2023-03-23 15:02:32 +01:00
parent 1a61ed5d85
commit 2e73051b81
No known key found for this signature in database
7 changed files with 29 additions and 6 deletions

View File

@ -2527,5 +2527,6 @@
"path": {} "path": {}
} }
}, },
"jumpToLastReadMessage": "Jump to last read message" "jumpToLastReadMessage": "Jump to last read message",
"readUpToHere": "Read up to here"
} }

View File

@ -53,6 +53,8 @@ class ChatController extends State<Chat> {
MatrixState? matrix; MatrixState? matrix;
String? readMarkerEventId;
String? get roomId => context.vRouter.pathParameters['roomid']; String? get roomId => context.vRouter.pathParameters['roomid'];
final AutoScrollController scrollController = AutoScrollController(); final AutoScrollController scrollController = AutoScrollController();

View File

@ -123,6 +123,8 @@ class ChatEventList extends StatelessWidget {
selected: controller.selectedEvents selected: controller.selectedEvents
.any((e) => e.eventId == event.eventId), .any((e) => e.eventId == event.eventId),
timeline: controller.timeline!, timeline: controller.timeline!,
displayReadMarker:
controller.readMarkerEventId == event.eventId,
nextEvent: i < controller.timeline!.events.length nextEvent: i < controller.timeline!.events.length
? controller.timeline!.events[i] ? controller.timeline!.events[i]
: null, : null,

View File

@ -143,6 +143,7 @@ class ChatView extends StatelessWidget {
final client = controller.matrix!.client; final client = controller.matrix!.client;
controller.sendingClient ??= client; controller.sendingClient ??= client;
controller.room = controller.sendingClient!.getRoomById(controller.roomId!); controller.room = controller.sendingClient!.getRoomById(controller.roomId!);
controller.readMarkerEventId ??= controller.room!.fullyRead;
if (controller.room == null) { if (controller.room == null) {
return Scaffold( return Scaffold(
appBar: AppBar( appBar: AppBar(

View File

@ -1,5 +1,6 @@
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter_gen/gen_l10n/l10n.dart';
import 'package:matrix/matrix.dart'; import 'package:matrix/matrix.dart';
import 'package:swipe_to_action/swipe_to_action.dart'; import 'package:swipe_to_action/swipe_to_action.dart';
@ -18,6 +19,7 @@ import 'verification_request_content.dart';
class Message extends StatelessWidget { class Message extends StatelessWidget {
final Event event; final Event event;
final Event? nextEvent; final Event? nextEvent;
final bool displayReadMarker;
final void Function(Event)? onSelect; final void Function(Event)? onSelect;
final void Function(Event)? onAvatarTab; final void Function(Event)? onAvatarTab;
final void Function(Event)? onInfoTab; final void Function(Event)? onInfoTab;
@ -30,6 +32,7 @@ class Message extends StatelessWidget {
const Message( const Message(
this.event, { this.event, {
this.nextEvent, this.nextEvent,
this.displayReadMarker = false,
this.longPressSelect = false, this.longPressSelect = false,
this.onSelect, this.onSelect,
this.onInfoTab, this.onInfoTab,
@ -303,7 +306,8 @@ class Message extends StatelessWidget {
Widget container; Widget container;
if (event.hasAggregatedEvents(timeline, RelationshipTypes.reaction) || if (event.hasAggregatedEvents(timeline, RelationshipTypes.reaction) ||
displayTime || displayTime ||
selected) { selected ||
displayReadMarker) {
container = Column( container = Column(
mainAxisSize: MainAxisSize.min, mainAxisSize: MainAxisSize.min,
crossAxisAlignment: crossAxisAlignment:
@ -347,6 +351,17 @@ class Message extends StatelessWidget {
), ),
child: MessageReactions(event, timeline), child: MessageReactions(event, timeline),
), ),
if (displayReadMarker)
Row(
children: [
const Expanded(child: Divider()),
Padding(
padding: const EdgeInsets.all(8.0),
child: Text(L10n.of(context)!.readUpToHere),
),
const Expanded(child: Divider()),
],
),
], ],
); );
} else { } else {

View File

@ -458,11 +458,12 @@ class InputBar extends StatelessWidget {
buildSuggestion(c, s, Matrix.of(context).client), buildSuggestion(c, s, Matrix.of(context).client),
onSuggestionSelected: (Map<String, String?> suggestion) => onSuggestionSelected: (Map<String, String?> suggestion) =>
insertSuggestion(context, suggestion), insertSuggestion(context, suggestion),
errorBuilder: (BuildContext context, Object? error) => const SizedBox.shrink(), errorBuilder: (BuildContext context, Object? error) =>
const SizedBox.shrink(),
loadingBuilder: (BuildContext context) => const SizedBox.shrink(), loadingBuilder: (BuildContext context) => const SizedBox.shrink(),
// fix loading briefly flickering a dark box // fix loading briefly flickering a dark box
noItemsFoundBuilder: (BuildContext context) => noItemsFoundBuilder: (BuildContext context) => const SizedBox
const SizedBox.shrink(), // fix loading briefly showing no suggestions .shrink(), // fix loading briefly showing no suggestions
), ),
), ),
); );

View File

@ -35,7 +35,8 @@ class MultipleEmotesSettingsView extends StatelessWidget {
final keys = packs.keys.toList(); final keys = packs.keys.toList();
keys.sort(); keys.sort();
return ListView.separated( return ListView.separated(
separatorBuilder: (BuildContext context, int i) => const SizedBox.shrink(), separatorBuilder: (BuildContext context, int i) =>
const SizedBox.shrink(),
itemCount: keys.length, itemCount: keys.length,
itemBuilder: (BuildContext context, int i) { itemBuilder: (BuildContext context, int i) {
final event = packs[keys[i]]; final event = packs[keys[i]];