mirror of
https://github.com/krille-chan/fluffychat
synced 2024-09-10 13:05:11 +00:00
feat: Jump to last read event
This commit is contained in:
parent
c00a6e3d00
commit
5c70dd39bc
3 changed files with 62 additions and 16 deletions
|
@ -2526,5 +2526,6 @@
|
|||
"placeholders": {
|
||||
"path": {}
|
||||
}
|
||||
}
|
||||
},
|
||||
"jumpToLastReadMessage": "Jump to last read message"
|
||||
}
|
||||
|
|
|
@ -132,6 +132,11 @@ class ChatController extends State<Chat> {
|
|||
|
||||
bool showEmojiPicker = false;
|
||||
|
||||
bool get lastReadEventVisible =>
|
||||
timeline == null ||
|
||||
room!.fullyRead.isEmpty ||
|
||||
timeline!.events.any((event) => event.eventId == room!.fullyRead);
|
||||
|
||||
void recreateChat() async {
|
||||
final room = this.room;
|
||||
final userId = room?.directChatMatrixID;
|
||||
|
@ -190,9 +195,13 @@ class ChatController extends State<Chat> {
|
|||
}
|
||||
|
||||
void requestFuture() async {
|
||||
if (!timeline!.canRequestFuture) return;
|
||||
final timeline = this.timeline;
|
||||
if (timeline == null) return;
|
||||
if (!timeline.canRequestFuture) return;
|
||||
try {
|
||||
await timeline!.requestFuture(historyCount: _loadHistoryCount);
|
||||
final mostRecentEventId = timeline.events.first.eventId;
|
||||
await timeline.requestFuture(historyCount: _loadHistoryCount);
|
||||
setReadMarker(eventId: mostRecentEventId);
|
||||
} catch (err) {
|
||||
ScaffoldMessenger.of(context).showSnackBar(
|
||||
SnackBar(
|
||||
|
@ -280,19 +289,29 @@ class ChatController extends State<Chat> {
|
|||
|
||||
Future<void>? _setReadMarkerFuture;
|
||||
|
||||
void setReadMarker([_]) {
|
||||
if (_setReadMarkerFuture == null &&
|
||||
(room!.hasNewMessages || room!.notificationCount > 0) &&
|
||||
timeline != null &&
|
||||
timeline!.events.isNotEmpty &&
|
||||
Matrix.of(context).webHasFocus) {
|
||||
Logs().v('Set read marker...');
|
||||
// ignore: unawaited_futures
|
||||
_setReadMarkerFuture = timeline!.setReadMarker().then((_) {
|
||||
_setReadMarkerFuture = null;
|
||||
});
|
||||
room!.client.updateIosBadge();
|
||||
void setReadMarker({String? eventId}) {
|
||||
if (_setReadMarkerFuture != null) return;
|
||||
if (lastReadEventVisible &&
|
||||
!room!.hasNewMessages &&
|
||||
room!.notificationCount == 0) {
|
||||
return;
|
||||
}
|
||||
if (!Matrix.of(context).webHasFocus) return;
|
||||
|
||||
final timeline = this.timeline;
|
||||
if (timeline == null || timeline.events.isEmpty) return;
|
||||
|
||||
if (eventId == null && !lastReadEventVisible) {
|
||||
return;
|
||||
}
|
||||
|
||||
eventId ??= timeline.events.first.eventId;
|
||||
Logs().v('Set read marker...', eventId);
|
||||
// ignore: unawaited_futures
|
||||
_setReadMarkerFuture = timeline.setReadMarker(eventId).then((_) {
|
||||
_setReadMarkerFuture = null;
|
||||
});
|
||||
room!.client.updateIosBadge();
|
||||
}
|
||||
|
||||
@override
|
||||
|
@ -759,6 +778,7 @@ class ChatController extends State<Chat> {
|
|||
timeline = null;
|
||||
});
|
||||
await getTimeline();
|
||||
setReadMarker(eventId: timeline!.events.first.eventId);
|
||||
}
|
||||
scrollController.jumpTo(0);
|
||||
}
|
||||
|
|
|
@ -174,7 +174,7 @@ class ChatView extends StatelessWidget {
|
|||
}
|
||||
},
|
||||
child: GestureDetector(
|
||||
onTapDown: controller.setReadMarker,
|
||||
onTapDown: (_) => controller.setReadMarker(),
|
||||
behavior: HitTestBehavior.opaque,
|
||||
child: StreamBuilder(
|
||||
stream: controller.room!.onUpdate.stream
|
||||
|
@ -351,6 +351,31 @@ class ChatView extends StatelessWidget {
|
|||
],
|
||||
),
|
||||
),
|
||||
if (!controller.lastReadEventVisible)
|
||||
Positioned(
|
||||
top: 16,
|
||||
left: 0,
|
||||
right: 0,
|
||||
child: Center(
|
||||
child: FloatingActionButton.extended(
|
||||
icon: const Icon(Icons.arrow_upward_outlined),
|
||||
onPressed: () => controller
|
||||
.scrollToEventId(controller.room!.fullyRead),
|
||||
label: Row(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: [
|
||||
Text(L10n.of(context)!.jumpToLastReadMessage),
|
||||
IconButton(
|
||||
onPressed: () => controller.setReadMarker(
|
||||
eventId: controller.room!.fullyRead,
|
||||
),
|
||||
icon: const Icon(Icons.close),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
if (controller.dragging)
|
||||
Container(
|
||||
color: Theme.of(context)
|
||||
|
|
Loading…
Reference in a new issue