change: Remove previous collapse solution

This commit is contained in:
Christian Pauly 2021-02-25 09:11:17 +01:00
parent 61a8eb553c
commit 949890c926
6 changed files with 124 additions and 65 deletions

View File

@ -16,9 +16,10 @@ import 'state_message.dart';
class Message extends StatelessWidget {
final Event event;
final Event nextEvent;
final Function(Event) onSelect;
final Function(Event) onAvatarTab;
final Function(String) scrollToEventId;
final void Function(Event) onSelect;
final void Function(Event) onAvatarTab;
final void Function(String) scrollToEventId;
final void Function(String) unfold;
final bool longPressSelect;
final bool selected;
final Timeline timeline;
@ -29,6 +30,7 @@ class Message extends StatelessWidget {
this.onSelect,
this.onAvatarTab,
this.scrollToEventId,
@required this.unfold,
this.selected,
this.timeline});
@ -38,15 +40,9 @@ class Message extends StatelessWidget {
@override
Widget build(BuildContext context) {
if (event.type == EventTypes.RoomCreate) {
return InkWell(
onTap: () => onSelect(event),
child: StateMessage(event),
);
}
if (![EventTypes.Message, EventTypes.Sticker, EventTypes.Encrypted]
.contains(event.type)) {
return StateMessage(event);
return StateMessage(event, unfold: unfold);
}
var client = Matrix.of(context).client;

View File

@ -7,31 +7,55 @@ import '../../app_config.dart';
class StateMessage extends StatelessWidget {
final Event event;
const StateMessage(this.event);
final void Function(String) unfold;
const StateMessage(this.event, {@required this.unfold});
@override
Widget build(BuildContext context) {
return Padding(
padding: const EdgeInsets.only(
left: 8.0,
right: 8.0,
bottom: 8.0,
),
child: Center(
child: Container(
padding: const EdgeInsets.all(8),
decoration: BoxDecoration(
color: Theme.of(context).secondaryHeaderColor,
borderRadius: BorderRadius.circular(7),
),
child: Text(
event.getLocalizedBody(MatrixLocals(L10n.of(context))),
textAlign: TextAlign.center,
style: TextStyle(
fontSize: Theme.of(context).textTheme.bodyText1.fontSize *
AppConfig.fontSizeFactor,
color: Theme.of(context).textTheme.bodyText2.color,
decoration: event.redacted ? TextDecoration.lineThrough : null,
if (event.unsigned['im.fluffychat.collapsed_state_event'] == true) {
return Container();
}
final int counter =
event.unsigned['im.fluffychat.collapsed_state_event_count'] ?? 0;
return InkWell(
onTap: counter != 0 ? () => unfold(event.eventId) : null,
child: Padding(
padding: const EdgeInsets.only(
left: 8.0,
right: 8.0,
bottom: 8.0,
),
child: Center(
child: Container(
padding: const EdgeInsets.all(8),
decoration: BoxDecoration(
color: Theme.of(context).secondaryHeaderColor,
borderRadius: BorderRadius.circular(7),
),
child: Column(
mainAxisSize: MainAxisSize.min,
children: [
Text(
event.getLocalizedBody(MatrixLocals(L10n.of(context))),
textAlign: TextAlign.center,
style: TextStyle(
fontSize: Theme.of(context).textTheme.bodyText1.fontSize *
AppConfig.fontSizeFactor,
color: Theme.of(context).textTheme.bodyText2.color,
decoration:
event.redacted ? TextDecoration.lineThrough : null,
),
),
if (counter != 0)
Text(
counter == 1
? L10n.of(context).oneMoreEvent
: L10n.of(context).xMoreEvents(counter.toString()),
style: TextStyle(
fontWeight: FontWeight.bold,
),
),
],
),
),
),

View File

@ -513,6 +513,18 @@
"type": "text",
"placeholders": {}
},
"oneMoreEvent": "1 more event",
"@oneMoreEvent": {
"type": "text",
"placeholders": {}
},
"xMoreEvents": "{count} more events",
"@xMoreEvents": {
"type": "text",
"placeholders": {
"count": {}
}
},
"createdTheChat": "{username} created the chat",
"@createdTheChat": {
"type": "text",

View File

@ -3,7 +3,7 @@ import 'package:famedlysdk/famedlysdk.dart';
import '../app_config.dart';
extension FilteredTimelineExtension on Timeline {
List<Event> getFilteredEvents({bool collapseRoomCreate = true}) {
List<Event> getFilteredEvents({Set<String> unfolded = const {}}) {
final filteredEvents = events
.where((e) =>
// always filter out edit and reaction relationships
@ -19,23 +19,35 @@ extension FilteredTimelineExtension on Timeline {
// if we enabled to hide all unknown events, don't show those
(!AppConfig.hideUnknownEvents || e.isEventTypeKnown) &&
// remove state events that we don't want to render
(!{EventTypes.Message, EventTypes.Sticker, EventTypes.Encrypted}
.contains(e.type) ||
!AppConfig.hideAllStateEvents))
(e.isState || !AppConfig.hideAllStateEvents))
.toList();
// Hide state events from the room creater right after the room created event
if (collapseRoomCreate &&
filteredEvents[filteredEvents.length - 1].type ==
EventTypes.RoomCreate) {
while (filteredEvents.length >= 3 &&
filteredEvents[filteredEvents.length - 2].senderId ==
filteredEvents[filteredEvents.length - 1].senderId &&
![EventTypes.Message, EventTypes.Sticker, EventTypes.Encrypted]
.contains(filteredEvents[filteredEvents.length - 2].type)) {
filteredEvents.removeAt(filteredEvents.length - 2);
// Fold state events
var counter = 0;
for (var i = filteredEvents.length - 1; i >= 0; i--) {
if (!filteredEvents[i].isState) continue;
if (i > 0 &&
filteredEvents[i - 1].isState &&
!unfolded.contains(filteredEvents[i - 1].eventId)) {
counter++;
filteredEvents[i].unsigned['im.fluffychat.collapsed_state_event'] =
true;
} else {
filteredEvents[i].unsigned['im.fluffychat.collapsed_state_event'] =
false;
filteredEvents[i]
.unsigned['im.fluffychat.collapsed_state_event_count'] = counter;
counter = 0;
}
}
return filteredEvents;
}
}
extension IsStateExtension on Event {
bool get isState => !{
EventTypes.Message,
EventTypes.Sticker,
EventTypes.Encrypted
}.contains(type);
}

View File

@ -63,11 +63,14 @@ extension RoomStatusExtension on Room {
}
String getLocalizedSeenByText(
BuildContext context, Timeline timeline, List<Event> filteredEvents) {
BuildContext context,
Timeline timeline,
List<Event> filteredEvents,
Set<String> unfolded,
) {
var seenByText = '';
if (timeline.events.isNotEmpty) {
final filteredEvents =
timeline.getFilteredEvents(collapseRoomCreate: false);
final filteredEvents = timeline.getFilteredEvents(unfolded: unfolded);
final lastReceipts = <User>{};
// now we iterate the timeline events until we hit the first rendered event
for (final event in timeline.events) {

View File

@ -72,7 +72,7 @@ class _ChatState extends State<Chat> {
List<Event> filteredEvents;
bool _collapseRoomCreate = true;
final Set<String> _unfolded = {};
Event replyEvent;
@ -146,12 +146,22 @@ class _ChatState extends State<Chat> {
if (!mounted) return;
setState(
() {
filteredEvents =
timeline.getFilteredEvents(collapseRoomCreate: _collapseRoomCreate);
filteredEvents = timeline.getFilteredEvents(unfolded: _unfolded);
},
);
}
void _unfold(String eventId) {
var i = filteredEvents.indexWhere((e) => e.eventId == eventId);
setState(() {
while (i < filteredEvents.length - 1 && filteredEvents[i].isState) {
_unfolded.add(filteredEvents[i].eventId);
i++;
}
filteredEvents = timeline.getFilteredEvents(unfolded: _unfolded);
});
}
Future<bool> getTimeline(BuildContext context) async {
if (timeline == null) {
timeline = await room.getTimeline(onUpdate: updateView);
@ -712,9 +722,7 @@ class _ChatState extends State<Chat> {
thisEventsKeyMap[filteredEvents[i].eventId] = i;
}
return ListView.custom(
padding: EdgeInsets.symmetric(
horizontal: max(
final horizontalPadding = max(
0,
(MediaQuery.of(context).size.width -
FluffyThemes.columnWidth *
@ -724,7 +732,14 @@ class _ChatState extends State<Chat> {
null
? 4.5
: 3.5)) /
2),
2)
.toDouble();
return ListView.custom(
padding: EdgeInsets.only(
top: 16,
left: horizontalPadding,
right: horizontalPadding,
),
reverse: true,
controller: _scrollController,
@ -759,9 +774,11 @@ class _ChatState extends State<Chat> {
builder: (_, __) {
final seenByText =
room.getLocalizedSeenByText(
context,
timeline,
filteredEvents);
context,
timeline,
filteredEvents,
_unfolded,
);
return AnimatedContainer(
height: seenByText.isEmpty ? 0 : 24,
duration: seenByText.isEmpty
@ -830,13 +847,8 @@ class _ChatState extends State<Chat> {
'${event.senderId} ',
),
),
unfold: _unfold,
onSelect: (Event event) {
if (event.type ==
EventTypes.RoomCreate) {
return setState(() =>
_collapseRoomCreate =
false);
}
if (!event.redacted) {
if (selectedEvents
.contains(event)) {