feat: Collapse all state events by default
This commit is contained in:
parent
3d0a3ee226
commit
103cb8328d
9 changed files with 121 additions and 79 deletions
|
|
@ -339,6 +339,24 @@ class ChatController extends State<ChatPageWithRoom>
|
|||
}
|
||||
}
|
||||
|
||||
final Set<String> expandedEventIds = {};
|
||||
|
||||
void expandEventsFrom(Event event, bool expand) {
|
||||
final events = timeline!.events.filterByVisibleInGui();
|
||||
final start = events.indexOf(event);
|
||||
setState(() {
|
||||
for (var i = start; i < events.length; i++) {
|
||||
final event = events[i];
|
||||
if (!event.isCollapsedState) return;
|
||||
if (expand) {
|
||||
expandedEventIds.add(event.eventId);
|
||||
} else {
|
||||
expandedEventIds.remove(event.eventId);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
void _tryLoadTimeline() async {
|
||||
final initialEventId = widget.eventId;
|
||||
loadTimelineFuture = _getTimeline();
|
||||
|
|
|
|||
|
|
@ -119,6 +119,17 @@ class ChatEventList extends StatelessWidget {
|
|||
timeline.events.length > animateInEventIndex &&
|
||||
event == timeline.events[animateInEventIndex];
|
||||
|
||||
final nextEvent = i + 1 < events.length ? events[i + 1] : null;
|
||||
final previousEvent = i > 0 ? events[i - 1] : null;
|
||||
|
||||
// Collapsed state event
|
||||
final canExpand = event.isCollapsedState &&
|
||||
nextEvent?.isCollapsedState == true &&
|
||||
previousEvent?.isCollapsedState != true;
|
||||
final isCollapsed = event.isCollapsedState &&
|
||||
previousEvent?.isCollapsedState == true &&
|
||||
!controller.expandedEventIds.contains(event.eventId);
|
||||
|
||||
return AutoScrollTag(
|
||||
key: ValueKey(event.eventId),
|
||||
index: i,
|
||||
|
|
@ -148,11 +159,18 @@ class ChatEventList extends StatelessWidget {
|
|||
timeline: timeline,
|
||||
displayReadMarker:
|
||||
i > 0 && controller.readMarkerEventId == event.eventId,
|
||||
nextEvent: i + 1 < events.length ? events[i + 1] : null,
|
||||
previousEvent: i > 0 ? events[i - 1] : null,
|
||||
nextEvent: nextEvent,
|
||||
previousEvent: previousEvent,
|
||||
wallpaperMode: hasWallpaper,
|
||||
scrollController: controller.scrollController,
|
||||
colors: colors,
|
||||
isCollapsed: isCollapsed,
|
||||
onExpand: canExpand
|
||||
? () => controller.expandEventsFrom(
|
||||
event,
|
||||
!controller.expandedEventIds.contains(event.eventId),
|
||||
)
|
||||
: null,
|
||||
),
|
||||
);
|
||||
},
|
||||
|
|
|
|||
|
|
@ -44,6 +44,8 @@ class Message extends StatelessWidget {
|
|||
final bool wallpaperMode;
|
||||
final ScrollController scrollController;
|
||||
final List<Color> colors;
|
||||
final void Function()? onExpand;
|
||||
final bool isCollapsed;
|
||||
|
||||
const Message(
|
||||
this.event, {
|
||||
|
|
@ -66,6 +68,8 @@ class Message extends StatelessWidget {
|
|||
required this.onMention,
|
||||
required this.scrollController,
|
||||
required this.colors,
|
||||
this.onExpand,
|
||||
this.isCollapsed = false,
|
||||
super.key,
|
||||
});
|
||||
|
||||
|
|
@ -85,7 +89,7 @@ class Message extends StatelessWidget {
|
|||
if (event.type == EventTypes.RoomCreate) {
|
||||
return RoomCreationStateEvent(event: event);
|
||||
}
|
||||
return StateMessage(event);
|
||||
return StateMessage(event, onExpand: onExpand, isCollapsed: isCollapsed);
|
||||
}
|
||||
|
||||
if (event.type == EventTypes.Message &&
|
||||
|
|
|
|||
|
|
@ -1,46 +1,84 @@
|
|||
import 'package:flutter/gestures.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
import 'package:matrix/matrix.dart';
|
||||
|
||||
import 'package:fluffychat/config/themes.dart';
|
||||
import 'package:fluffychat/l10n/l10n.dart';
|
||||
import 'package:fluffychat/utils/matrix_sdk_extensions/matrix_locals.dart';
|
||||
import '../../../config/app_config.dart';
|
||||
|
||||
class StateMessage extends StatelessWidget {
|
||||
final Event event;
|
||||
const StateMessage(this.event, {super.key});
|
||||
final void Function()? onExpand;
|
||||
final bool isCollapsed;
|
||||
const StateMessage(
|
||||
this.event, {
|
||||
this.onExpand,
|
||||
this.isCollapsed = false,
|
||||
super.key,
|
||||
});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final theme = Theme.of(context);
|
||||
return Padding(
|
||||
padding: const EdgeInsets.symmetric(horizontal: 8.0),
|
||||
child: Center(
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.all(4),
|
||||
child: Material(
|
||||
color: theme.colorScheme.surface.withAlpha(128),
|
||||
borderRadius: BorderRadius.circular(AppConfig.borderRadius / 3),
|
||||
child: Padding(
|
||||
padding:
|
||||
const EdgeInsets.symmetric(horizontal: 8.0, vertical: 4.0),
|
||||
child: Text(
|
||||
event.calcLocalizedBodyFallback(
|
||||
MatrixLocals(L10n.of(context)),
|
||||
),
|
||||
textAlign: TextAlign.center,
|
||||
maxLines: 2,
|
||||
overflow: TextOverflow.ellipsis,
|
||||
style: TextStyle(
|
||||
fontSize: 12 * AppConfig.fontSizeFactor,
|
||||
decoration:
|
||||
event.redacted ? TextDecoration.lineThrough : null,
|
||||
return AnimatedSize(
|
||||
duration: FluffyThemes.animationDuration,
|
||||
curve: FluffyThemes.animationCurve,
|
||||
child: isCollapsed
|
||||
? const SizedBox.shrink()
|
||||
: Padding(
|
||||
padding: const EdgeInsets.symmetric(horizontal: 8.0),
|
||||
child: Center(
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.all(4),
|
||||
child: Material(
|
||||
color: theme.colorScheme.surface.withAlpha(128),
|
||||
borderRadius:
|
||||
BorderRadius.circular(AppConfig.borderRadius / 3),
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.symmetric(
|
||||
horizontal: 8.0,
|
||||
vertical: 4.0,
|
||||
),
|
||||
child: Text.rich(
|
||||
TextSpan(
|
||||
children: [
|
||||
TextSpan(
|
||||
text: event.calcLocalizedBodyFallback(
|
||||
MatrixLocals(L10n.of(context)),
|
||||
),
|
||||
),
|
||||
if (onExpand != null) ...[
|
||||
const TextSpan(
|
||||
text: ' + ',
|
||||
style: TextStyle(fontWeight: FontWeight.bold),
|
||||
),
|
||||
TextSpan(
|
||||
style: TextStyle(
|
||||
color: theme.colorScheme.primary,
|
||||
decoration: TextDecoration.underline,
|
||||
),
|
||||
recognizer: TapGestureRecognizer()
|
||||
..onTap = onExpand,
|
||||
text: L10n.of(context).moreEvents,
|
||||
),
|
||||
],
|
||||
],
|
||||
),
|
||||
textAlign: TextAlign.center,
|
||||
style: TextStyle(
|
||||
fontSize: 12 * AppConfig.fontSizeFactor,
|
||||
decoration: event.redacted
|
||||
? TextDecoration.lineThrough
|
||||
: null,
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue