mirror of
https://gitlab.com/famedly/fluffychat.git
synced 2024-11-23 20:49:26 +01:00
feat: Add read marker
This commit is contained in:
parent
1a61ed5d85
commit
2e73051b81
@ -2527,5 +2527,6 @@
|
|||||||
"path": {}
|
"path": {}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"jumpToLastReadMessage": "Jump to last read message"
|
"jumpToLastReadMessage": "Jump to last read message",
|
||||||
|
"readUpToHere": "Read up to here"
|
||||||
}
|
}
|
||||||
|
@ -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();
|
||||||
|
@ -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,
|
||||||
|
@ -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(
|
||||||
|
@ -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 {
|
||||||
|
@ -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
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
|
@ -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]];
|
||||||
|
Loading…
Reference in New Issue
Block a user