fix: Scrolling in fragmented timeline

This commit is contained in:
Christian Kußowski 2025-12-06 10:19:57 +01:00
parent 53af09227f
commit cacb944918
No known key found for this signature in database
GPG key ID: E067ECD60F1A0652
4 changed files with 45 additions and 43 deletions

View file

@ -224,9 +224,14 @@ class ChatController extends State<ChatPageWithRoom>
final timeline = this.timeline;
if (timeline == null) return;
Logs().v('Requesting future...');
final mostRecentEventId = timeline.events.first.eventId;
final mostRecentEvent = timeline.events.filterByVisibleInGui().firstOrNull;
await timeline.requestFuture(historyCount: _loadHistoryCount);
setReadMarker(eventId: mostRecentEventId);
if (mostRecentEvent != null) {
setReadMarker(eventId: mostRecentEvent.eventId);
}
}
void _updateScrollController() {
@ -241,11 +246,6 @@ class ChatController extends State<ChatPageWithRoom>
setState(() => _scrolledUp = false);
setReadMarker();
}
if (scrollController.position.pixels == 0 ||
scrollController.position.pixels == 64) {
requestFuture();
}
}
void _loadDraft() async {
@ -458,7 +458,7 @@ class ChatController extends State<ChatPageWithRoom>
void onInsert(int i) {
// setState will be called by updateView() anyway
animateInEventIndex = i;
if (i <= 5) animateInEventIndex = i;
}
Future<void> _getTimeline({String? eventContextId}) async {

View file

@ -5,6 +5,7 @@ import 'package:collection/collection.dart';
import 'package:scroll_to_index/scroll_to_index.dart';
import 'package:fluffychat/config/themes.dart';
import 'package:fluffychat/l10n/l10n.dart';
import 'package:fluffychat/pages/chat/chat.dart';
import 'package:fluffychat/pages/chat/events/message.dart';
import 'package:fluffychat/pages/chat/seen_by_row.dart';
@ -63,16 +64,16 @@ class ChatEventList extends StatelessWidget {
(BuildContext context, int i) {
// Footer to display typing indicator and read receipts:
if (i == 0) {
if (timeline.isRequestingFuture) {
return const Center(
child: CircularProgressIndicator.adaptive(strokeWidth: 2),
);
}
if (timeline.canRequestFuture) {
return Center(
child: IconButton(
onPressed: controller.requestFuture,
icon: const Icon(Icons.refresh_outlined),
child: TextButton.icon(
onPressed: timeline.isRequestingFuture
? null
: controller.requestFuture,
icon: timeline.isRequestingFuture
? CircularProgressIndicator.adaptive(strokeWidth: 2)
: const Icon(Icons.arrow_downward_outlined),
label: Text(L10n.of(context).loadMore),
),
);
}
@ -101,16 +102,14 @@ class ChatEventList extends StatelessWidget {
}
}
return Center(
child: AnimatedSwitcher(
duration: FluffyThemes.animationDuration,
child: timeline.canRequestHistory
? IconButton(
onPressed: controller.requestHistory,
icon: const Icon(Icons.refresh_outlined),
)
: const CircularProgressIndicator.adaptive(
strokeWidth: 2,
),
child: TextButton.icon(
onPressed: timeline.isRequestingHistory
? null
: controller.requestHistory,
icon: timeline.isRequestingHistory
? CircularProgressIndicator.adaptive(strokeWidth: 2)
: const Icon(Icons.arrow_upward_outlined),
label: Text(L10n.of(context).loadMore),
),
);
},

View file

@ -289,8 +289,6 @@ class ChatView extends StatelessWidget {
),
),
),
floatingActionButtonLocation:
FloatingActionButtonLocation.miniCenterFloat,
floatingActionButton:
controller.showScrollDownButton &&
controller.selectedEvents.isEmpty

View file

@ -544,22 +544,27 @@ class MatrixPill extends StatelessWidget {
return InkWell(
splashColor: Colors.transparent,
onTap: UrlLauncher(outerContext, uri).launchUrl,
child: Row(
mainAxisSize: .min,
children: [
Avatar(mxContent: avatar, name: name, size: 16),
const SizedBox(width: 6),
Text(
name,
style: TextStyle(
color: color,
decorationColor: color,
decoration: TextDecoration.underline,
fontSize: fontSize,
height: 1.25,
child: Text.rich(
TextSpan(
children: [
WidgetSpan(
child: Padding(
padding: const EdgeInsets.only(right: 4.0),
child: Avatar(mxContent: avatar, name: name, size: 16),
),
),
),
],
TextSpan(
text: name,
style: TextStyle(
color: color,
decorationColor: color,
decoration: TextDecoration.underline,
fontSize: fontSize,
height: 1.25,
),
),
],
),
),
);
}