mirror of
https://gitlab.com/famedly/fluffychat.git
synced 2024-11-06 03:59:28 +01:00
feat: Jump to last read event
This commit is contained in:
parent
a4a852ede8
commit
c2768ae40a
@ -2526,5 +2526,6 @@
|
|||||||
"placeholders": {
|
"placeholders": {
|
||||||
"path": {}
|
"path": {}
|
||||||
}
|
}
|
||||||
}
|
},
|
||||||
|
"jumpToLastReadMessage": "Jump to last read message"
|
||||||
}
|
}
|
||||||
|
@ -132,6 +132,11 @@ class ChatController extends State<Chat> {
|
|||||||
|
|
||||||
bool showEmojiPicker = false;
|
bool showEmojiPicker = false;
|
||||||
|
|
||||||
|
bool get lastReadEventVisible =>
|
||||||
|
timeline == null ||
|
||||||
|
room!.fullyRead.isEmpty ||
|
||||||
|
timeline!.events.any((event) => event.eventId == room!.fullyRead);
|
||||||
|
|
||||||
void recreateChat() async {
|
void recreateChat() async {
|
||||||
final room = this.room;
|
final room = this.room;
|
||||||
final userId = room?.directChatMatrixID;
|
final userId = room?.directChatMatrixID;
|
||||||
@ -190,9 +195,13 @@ class ChatController extends State<Chat> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void requestFuture() async {
|
void requestFuture() async {
|
||||||
if (!timeline!.canRequestFuture) return;
|
final timeline = this.timeline;
|
||||||
|
if (timeline == null) return;
|
||||||
|
if (!timeline.canRequestFuture) return;
|
||||||
try {
|
try {
|
||||||
await timeline!.requestFuture(historyCount: _loadHistoryCount);
|
final mostRecentEventId = timeline.events.first.eventId;
|
||||||
|
await timeline.requestFuture(historyCount: _loadHistoryCount);
|
||||||
|
setReadMarker(eventId: mostRecentEventId);
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
ScaffoldMessenger.of(context).showSnackBar(
|
ScaffoldMessenger.of(context).showSnackBar(
|
||||||
SnackBar(
|
SnackBar(
|
||||||
@ -280,20 +289,30 @@ class ChatController extends State<Chat> {
|
|||||||
|
|
||||||
Future<void>? _setReadMarkerFuture;
|
Future<void>? _setReadMarkerFuture;
|
||||||
|
|
||||||
void setReadMarker([_]) {
|
void setReadMarker({String? eventId}) {
|
||||||
if (_setReadMarkerFuture == null &&
|
if (_setReadMarkerFuture != null) return;
|
||||||
(room!.hasNewMessages || room!.notificationCount > 0) &&
|
if (lastReadEventVisible &&
|
||||||
timeline != null &&
|
!room!.hasNewMessages &&
|
||||||
timeline!.events.isNotEmpty &&
|
room!.notificationCount == 0) {
|
||||||
Matrix.of(context).webHasFocus) {
|
return;
|
||||||
Logs().v('Set read marker...');
|
}
|
||||||
|
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
|
// ignore: unawaited_futures
|
||||||
_setReadMarkerFuture = timeline!.setReadMarker().then((_) {
|
_setReadMarkerFuture = timeline.setReadMarker(eventId).then((_) {
|
||||||
_setReadMarkerFuture = null;
|
_setReadMarkerFuture = null;
|
||||||
});
|
});
|
||||||
room!.client.updateIosBadge();
|
room!.client.updateIosBadge();
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
@override
|
@override
|
||||||
void dispose() {
|
void dispose() {
|
||||||
@ -759,6 +778,7 @@ class ChatController extends State<Chat> {
|
|||||||
timeline = null;
|
timeline = null;
|
||||||
});
|
});
|
||||||
await getTimeline();
|
await getTimeline();
|
||||||
|
setReadMarker(eventId: timeline!.events.first.eventId);
|
||||||
}
|
}
|
||||||
scrollController.jumpTo(0);
|
scrollController.jumpTo(0);
|
||||||
}
|
}
|
||||||
|
@ -174,7 +174,7 @@ class ChatView extends StatelessWidget {
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
child: GestureDetector(
|
child: GestureDetector(
|
||||||
onTapDown: controller.setReadMarker,
|
onTapDown: (_) => controller.setReadMarker(),
|
||||||
behavior: HitTestBehavior.opaque,
|
behavior: HitTestBehavior.opaque,
|
||||||
child: StreamBuilder(
|
child: StreamBuilder(
|
||||||
stream: controller.room!.onUpdate.stream
|
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)
|
if (controller.dragging)
|
||||||
Container(
|
Container(
|
||||||
color: Theme.of(context)
|
color: Theme.of(context)
|
||||||
|
Loading…
Reference in New Issue
Block a user