mirror of
https://gitlab.com/famedly/fluffychat.git
synced 2024-12-25 06:52:35 +01:00
design: Hide unimportant state events instead of folding
This commit is contained in:
parent
b4bf23cd34
commit
c365469dc5
@ -2949,5 +2949,6 @@
|
|||||||
"placeholders": {
|
"placeholders": {
|
||||||
"number": {}
|
"number": {}
|
||||||
}
|
}
|
||||||
}
|
},
|
||||||
|
"hideUnimportantStateEvents": "Hide unimportant state events"
|
||||||
}
|
}
|
||||||
|
@ -37,6 +37,7 @@ abstract class AppConfig {
|
|||||||
static bool renderHtml = true;
|
static bool renderHtml = true;
|
||||||
static bool hideRedactedEvents = false;
|
static bool hideRedactedEvents = false;
|
||||||
static bool hideUnknownEvents = true;
|
static bool hideUnknownEvents = true;
|
||||||
|
static bool hideUnimportantStateEvents = true;
|
||||||
static bool showDirectChatsInSpaces = true;
|
static bool showDirectChatsInSpaces = true;
|
||||||
static bool separateChatTypes = false;
|
static bool separateChatTypes = false;
|
||||||
static bool autoplayImages = true;
|
static bool autoplayImages = true;
|
||||||
|
@ -3,6 +3,8 @@ abstract class SettingKeys {
|
|||||||
static const String renderHtml = 'chat.fluffy.renderHtml';
|
static const String renderHtml = 'chat.fluffy.renderHtml';
|
||||||
static const String hideRedactedEvents = 'chat.fluffy.hideRedactedEvents';
|
static const String hideRedactedEvents = 'chat.fluffy.hideRedactedEvents';
|
||||||
static const String hideUnknownEvents = 'chat.fluffy.hideUnknownEvents';
|
static const String hideUnknownEvents = 'chat.fluffy.hideUnknownEvents';
|
||||||
|
static const String hideUnimportantStateEvents =
|
||||||
|
'chat.fluffy.hideUnimportantStateEvents';
|
||||||
static const String showDirectChatsInSpaces =
|
static const String showDirectChatsInSpaces =
|
||||||
'chat.fluffy.showDirectChatsInSpaces';
|
'chat.fluffy.showDirectChatsInSpaces';
|
||||||
static const String separateChatTypes = 'chat.fluffy.separateChatTypes';
|
static const String separateChatTypes = 'chat.fluffy.separateChatTypes';
|
||||||
|
@ -28,7 +28,6 @@ import 'package:fluffychat/utils/platform_infos.dart';
|
|||||||
import 'package:fluffychat/widgets/matrix.dart';
|
import 'package:fluffychat/widgets/matrix.dart';
|
||||||
import '../../utils/account_bundles.dart';
|
import '../../utils/account_bundles.dart';
|
||||||
import '../../utils/localized_exception_extension.dart';
|
import '../../utils/localized_exception_extension.dart';
|
||||||
import '../../utils/matrix_sdk_extensions.dart/filtered_timeline_extension.dart';
|
|
||||||
import '../../utils/matrix_sdk_extensions.dart/matrix_file_extension.dart';
|
import '../../utils/matrix_sdk_extensions.dart/matrix_file_extension.dart';
|
||||||
import 'send_file_dialog.dart';
|
import 'send_file_dialog.dart';
|
||||||
import 'send_location_dialog.dart';
|
import 'send_location_dialog.dart';
|
||||||
@ -111,8 +110,6 @@ class ChatController extends State<Chat> {
|
|||||||
|
|
||||||
List<Event> selectedEvents = [];
|
List<Event> selectedEvents = [];
|
||||||
|
|
||||||
late List<Event> filteredEvents;
|
|
||||||
|
|
||||||
final Set<String> unfolded = {};
|
final Set<String> unfolded = {};
|
||||||
|
|
||||||
Event? replyEvent;
|
Event? replyEvent;
|
||||||
@ -184,22 +181,7 @@ class ChatController extends State<Chat> {
|
|||||||
|
|
||||||
void updateView() {
|
void updateView() {
|
||||||
if (!mounted) return;
|
if (!mounted) return;
|
||||||
setState(
|
setState(() {});
|
||||||
() {
|
|
||||||
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() async {
|
Future<bool> getTimeline() async {
|
||||||
@ -225,7 +207,6 @@ class ChatController extends State<Chat> {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
filteredEvents = timeline!.getFilteredEvents(unfolded: unfolded);
|
|
||||||
timeline!.requestKeys(onlineKeyBackupOnly: false);
|
timeline!.requestKeys(onlineKeyBackupOnly: false);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@ -656,7 +637,7 @@ class ChatController extends State<Chat> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void scrollToEventId(String eventId) async {
|
void scrollToEventId(String eventId) async {
|
||||||
var eventIndex = filteredEvents.indexWhere((e) => e.eventId == eventId);
|
var eventIndex = timeline!.events.indexWhere((e) => e.eventId == eventId);
|
||||||
if (eventIndex == -1) {
|
if (eventIndex == -1) {
|
||||||
// event id not found...maybe we can fetch it?
|
// event id not found...maybe we can fetch it?
|
||||||
// the try...finally is here to start and close the loading dialog reliably
|
// the try...finally is here to start and close the loading dialog reliably
|
||||||
@ -693,7 +674,7 @@ class ChatController extends State<Chat> {
|
|||||||
rethrow;
|
rethrow;
|
||||||
}
|
}
|
||||||
eventIndex =
|
eventIndex =
|
||||||
filteredEvents.indexWhere((e) => e.eventId == eventId);
|
timeline!.events.indexWhere((e) => e.eventId == eventId);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -10,6 +10,7 @@ import 'package:fluffychat/pages/chat/events/message.dart';
|
|||||||
import 'package:fluffychat/pages/chat/seen_by_row.dart';
|
import 'package:fluffychat/pages/chat/seen_by_row.dart';
|
||||||
import 'package:fluffychat/pages/chat/typing_indicators.dart';
|
import 'package:fluffychat/pages/chat/typing_indicators.dart';
|
||||||
import 'package:fluffychat/pages/user_bottom_sheet/user_bottom_sheet.dart';
|
import 'package:fluffychat/pages/user_bottom_sheet/user_bottom_sheet.dart';
|
||||||
|
import 'package:fluffychat/utils/matrix_sdk_extensions.dart/filtered_timeline_extension.dart';
|
||||||
import 'package:fluffychat/utils/platform_infos.dart';
|
import 'package:fluffychat/utils/platform_infos.dart';
|
||||||
|
|
||||||
class ChatEventList extends StatelessWidget {
|
class ChatEventList extends StatelessWidget {
|
||||||
@ -26,9 +27,10 @@ class ChatEventList extends StatelessWidget {
|
|||||||
// create a map of eventId --> index to greatly improve performance of
|
// create a map of eventId --> index to greatly improve performance of
|
||||||
// ListView's findChildIndexCallback
|
// ListView's findChildIndexCallback
|
||||||
final thisEventsKeyMap = <String, int>{};
|
final thisEventsKeyMap = <String, int>{};
|
||||||
for (var i = 0; i < controller.filteredEvents.length; i++) {
|
for (var i = 0; i < controller.timeline!.events.length; i++) {
|
||||||
thisEventsKeyMap[controller.filteredEvents[i].eventId] = i;
|
thisEventsKeyMap[controller.timeline!.events[i].eventId] = i;
|
||||||
}
|
}
|
||||||
|
|
||||||
return ListView.custom(
|
return ListView.custom(
|
||||||
padding: EdgeInsets.only(
|
padding: EdgeInsets.only(
|
||||||
top: 16,
|
top: 16,
|
||||||
@ -55,7 +57,7 @@ class ChatEventList extends StatelessWidget {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Request history button or progress indicator:
|
// Request history button or progress indicator:
|
||||||
if (i == controller.filteredEvents.length + 1) {
|
if (i == controller.timeline!.events.length + 1) {
|
||||||
if (controller.timeline!.isRequestingHistory) {
|
if (controller.timeline!.isRequestingHistory) {
|
||||||
return const Center(
|
return const Center(
|
||||||
child: CircularProgressIndicator.adaptive(strokeWidth: 2),
|
child: CircularProgressIndicator.adaptive(strokeWidth: 2),
|
||||||
@ -76,13 +78,16 @@ class ChatEventList extends StatelessWidget {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// The message at this index:
|
// The message at this index:
|
||||||
|
final event = controller.timeline!.events[i - 1];
|
||||||
|
|
||||||
return AutoScrollTag(
|
return AutoScrollTag(
|
||||||
key: ValueKey(controller.filteredEvents[i - 1].eventId),
|
key: ValueKey(event.eventId),
|
||||||
index: i - 1,
|
index: i - 1,
|
||||||
controller: controller.scrollController,
|
controller: controller.scrollController,
|
||||||
child: Message(controller.filteredEvents[i - 1],
|
child: event.isVisibleInGui
|
||||||
onSwipe: (direction) => controller.replyAction(
|
? Message(event,
|
||||||
replyTo: controller.filteredEvents[i - 1]),
|
onSwipe: (direction) =>
|
||||||
|
controller.replyAction(replyTo: event),
|
||||||
onInfoTab: controller.showEventInfo,
|
onInfoTab: controller.showEventInfo,
|
||||||
onAvatarTab: (Event event) => showModalBottomSheet(
|
onAvatarTab: (Event event) => showModalBottomSheet(
|
||||||
context: context,
|
context: context,
|
||||||
@ -93,20 +98,20 @@ class ChatEventList extends StatelessWidget {
|
|||||||
'${event.senderFromMemoryOrFallback.mention} ',
|
'${event.senderFromMemoryOrFallback.mention} ',
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
unfold: controller.unfold,
|
|
||||||
onSelect: controller.onSelectMessage,
|
onSelect: controller.onSelectMessage,
|
||||||
scrollToEventId: (String eventId) =>
|
scrollToEventId: (String eventId) =>
|
||||||
controller.scrollToEventId(eventId),
|
controller.scrollToEventId(eventId),
|
||||||
longPressSelect: controller.selectedEvents.isEmpty,
|
longPressSelect: controller.selectedEvents.isEmpty,
|
||||||
selected: controller.selectedEvents.any((e) =>
|
selected: controller.selectedEvents
|
||||||
e.eventId == controller.filteredEvents[i - 1].eventId),
|
.any((e) => e.eventId == event.eventId),
|
||||||
timeline: controller.timeline!,
|
timeline: controller.timeline!,
|
||||||
nextEvent: i < controller.filteredEvents.length
|
nextEvent: i < controller.timeline!.events.length
|
||||||
? controller.filteredEvents[i]
|
? controller.timeline!.events[i]
|
||||||
: null),
|
: null)
|
||||||
|
: Container(),
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
childCount: controller.filteredEvents.length + 2,
|
childCount: controller.timeline!.events.length + 2,
|
||||||
findChildIndexCallback: (key) =>
|
findChildIndexCallback: (key) =>
|
||||||
controller.findChildIndexCallback(key, thisEventsKeyMap),
|
controller.findChildIndexCallback(key, thisEventsKeyMap),
|
||||||
),
|
),
|
||||||
|
@ -22,7 +22,6 @@ class Message extends StatelessWidget {
|
|||||||
final void Function(Event)? onAvatarTab;
|
final void Function(Event)? onAvatarTab;
|
||||||
final void Function(Event)? onInfoTab;
|
final void Function(Event)? onInfoTab;
|
||||||
final void Function(String)? scrollToEventId;
|
final void Function(String)? scrollToEventId;
|
||||||
final void Function(String) unfold;
|
|
||||||
final void Function(SwipeDirection) onSwipe;
|
final void Function(SwipeDirection) onSwipe;
|
||||||
final bool longPressSelect;
|
final bool longPressSelect;
|
||||||
final bool selected;
|
final bool selected;
|
||||||
@ -36,7 +35,6 @@ class Message extends StatelessWidget {
|
|||||||
this.onAvatarTab,
|
this.onAvatarTab,
|
||||||
this.scrollToEventId,
|
this.scrollToEventId,
|
||||||
required this.onSwipe,
|
required this.onSwipe,
|
||||||
required this.unfold,
|
|
||||||
this.selected = false,
|
this.selected = false,
|
||||||
required this.timeline,
|
required this.timeline,
|
||||||
Key? key})
|
Key? key})
|
||||||
@ -57,7 +55,7 @@ class Message extends StatelessWidget {
|
|||||||
if (event.type.startsWith('m.call.')) {
|
if (event.type.startsWith('m.call.')) {
|
||||||
return Container();
|
return Container();
|
||||||
}
|
}
|
||||||
return StateMessage(event, unfold: unfold);
|
return StateMessage(event);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (event.type == EventTypes.Message &&
|
if (event.type == EventTypes.Message &&
|
||||||
|
@ -8,9 +8,7 @@ import '../../../config/app_config.dart';
|
|||||||
|
|
||||||
class StateMessage extends StatelessWidget {
|
class StateMessage extends StatelessWidget {
|
||||||
final Event event;
|
final Event event;
|
||||||
final void Function(String) unfold;
|
const StateMessage(this.event, {Key? key}) : super(key: key);
|
||||||
const StateMessage(this.event, {required this.unfold, Key? key})
|
|
||||||
: super(key: key);
|
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
@ -25,9 +23,6 @@ class StateMessage extends StatelessWidget {
|
|||||||
vertical: 4.0,
|
vertical: 4.0,
|
||||||
),
|
),
|
||||||
child: Center(
|
child: Center(
|
||||||
child: InkWell(
|
|
||||||
onTap: counter != 0 ? () => unfold(event.eventId) : null,
|
|
||||||
borderRadius: BorderRadius.circular(AppConfig.borderRadius),
|
|
||||||
child: Container(
|
child: Container(
|
||||||
padding: const EdgeInsets.all(8),
|
padding: const EdgeInsets.all(8),
|
||||||
decoration: BoxDecoration(
|
decoration: BoxDecoration(
|
||||||
@ -40,8 +35,8 @@ class StateMessage extends StatelessWidget {
|
|||||||
mainAxisSize: MainAxisSize.min,
|
mainAxisSize: MainAxisSize.min,
|
||||||
children: [
|
children: [
|
||||||
FutureBuilder<String>(
|
FutureBuilder<String>(
|
||||||
future: event
|
future:
|
||||||
.calcLocalizedBody(MatrixLocals(L10n.of(context)!)),
|
event.calcLocalizedBody(MatrixLocals(L10n.of(context)!)),
|
||||||
builder: (context, snapshot) {
|
builder: (context, snapshot) {
|
||||||
return Text(
|
return Text(
|
||||||
snapshot.data ??
|
snapshot.data ??
|
||||||
@ -51,9 +46,8 @@ class StateMessage extends StatelessWidget {
|
|||||||
style: TextStyle(
|
style: TextStyle(
|
||||||
fontSize: 14 * AppConfig.fontSizeFactor,
|
fontSize: 14 * AppConfig.fontSizeFactor,
|
||||||
color: Theme.of(context).textTheme.bodyText2!.color,
|
color: Theme.of(context).textTheme.bodyText2!.color,
|
||||||
decoration: event.redacted
|
decoration:
|
||||||
? TextDecoration.lineThrough
|
event.redacted ? TextDecoration.lineThrough : null,
|
||||||
: null,
|
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
}),
|
}),
|
||||||
@ -69,7 +63,6 @@ class StateMessage extends StatelessWidget {
|
|||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -12,11 +12,7 @@ class SeenByRow extends StatelessWidget {
|
|||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
final seenByUsers = controller.room!.getSeenByUsers(
|
final seenByUsers = controller.room!.getSeenByUsers(controller.timeline!);
|
||||||
controller.timeline!,
|
|
||||||
controller.filteredEvents,
|
|
||||||
controller.unfolded,
|
|
||||||
);
|
|
||||||
const maxAvatars = 7;
|
const maxAvatars = 7;
|
||||||
return Container(
|
return Container(
|
||||||
width: double.infinity,
|
width: double.infinity,
|
||||||
@ -28,8 +24,8 @@ class SeenByRow extends StatelessWidget {
|
|||||||
duration: seenByUsers.isEmpty
|
duration: seenByUsers.isEmpty
|
||||||
? const Duration(milliseconds: 0)
|
? const Duration(milliseconds: 0)
|
||||||
: const Duration(milliseconds: 300),
|
: const Duration(milliseconds: 300),
|
||||||
alignment: controller.filteredEvents.isNotEmpty &&
|
alignment: controller.timeline!.events.isNotEmpty &&
|
||||||
controller.filteredEvents.first.senderId ==
|
controller.timeline!.events.first.senderId ==
|
||||||
Matrix.of(context).client.userID
|
Matrix.of(context).client.userID
|
||||||
? Alignment.topRight
|
? Alignment.topRight
|
||||||
: Alignment.topLeft,
|
: Alignment.topLeft,
|
||||||
|
@ -26,8 +26,8 @@ class TypingIndicators extends StatelessWidget {
|
|||||||
height: typingUsers.isEmpty ? 0 : Avatar.defaultSize + bottomPadding,
|
height: typingUsers.isEmpty ? 0 : Avatar.defaultSize + bottomPadding,
|
||||||
duration: const Duration(milliseconds: 300),
|
duration: const Duration(milliseconds: 300),
|
||||||
curve: Curves.bounceInOut,
|
curve: Curves.bounceInOut,
|
||||||
alignment: controller.filteredEvents.isNotEmpty &&
|
alignment: controller.timeline!.events.isNotEmpty &&
|
||||||
controller.filteredEvents.first.senderId ==
|
controller.timeline!.events.first.senderId ==
|
||||||
Matrix.of(context).client.userID
|
Matrix.of(context).client.userID
|
||||||
? Alignment.topRight
|
? Alignment.topRight
|
||||||
: Alignment.topLeft,
|
: Alignment.topLeft,
|
||||||
|
@ -45,6 +45,12 @@ class SettingsChatView extends StatelessWidget {
|
|||||||
storeKey: SettingKeys.hideUnknownEvents,
|
storeKey: SettingKeys.hideUnknownEvents,
|
||||||
defaultValue: AppConfig.hideUnknownEvents,
|
defaultValue: AppConfig.hideUnknownEvents,
|
||||||
),
|
),
|
||||||
|
SettingsSwitchListTile.adaptive(
|
||||||
|
title: L10n.of(context)!.hideUnimportantStateEvents,
|
||||||
|
onChanged: (b) => AppConfig.hideUnimportantStateEvents = b,
|
||||||
|
storeKey: SettingKeys.hideUnimportantStateEvents,
|
||||||
|
defaultValue: AppConfig.hideUnimportantStateEvents,
|
||||||
|
),
|
||||||
if (PlatformInfos.isMobile)
|
if (PlatformInfos.isMobile)
|
||||||
SettingsSwitchListTile.adaptive(
|
SettingsSwitchListTile.adaptive(
|
||||||
title: L10n.of(context)!.autoplayImages,
|
title: L10n.of(context)!.autoplayImages,
|
||||||
|
@ -110,8 +110,6 @@ class StoryPageController extends State<StoryPage> {
|
|||||||
if (timeline == null || currentEvent == null) return [];
|
if (timeline == null || currentEvent == null) return [];
|
||||||
return Matrix.of(context).client.getRoomById(roomId)?.getSeenByUsers(
|
return Matrix.of(context).client.getRoomById(roomId)?.getSeenByUsers(
|
||||||
timeline,
|
timeline,
|
||||||
events,
|
|
||||||
{},
|
|
||||||
eventId: currentEvent.eventId,
|
eventId: currentEvent.eventId,
|
||||||
) ??
|
) ??
|
||||||
[];
|
[];
|
||||||
|
@ -2,50 +2,39 @@ import 'package:matrix/matrix.dart';
|
|||||||
|
|
||||||
import '../../config/app_config.dart';
|
import '../../config/app_config.dart';
|
||||||
|
|
||||||
extension FilteredTimelineExtension on Timeline {
|
extension IsStateExtension on Event {
|
||||||
List<Event> getFilteredEvents({Set<String> unfolded = const {}}) {
|
bool get isVisibleInGui =>
|
||||||
final filteredEvents = events
|
|
||||||
.where((e) =>
|
|
||||||
// always filter out edit and reaction relationships
|
// always filter out edit and reaction relationships
|
||||||
!{RelationshipTypes.edit, RelationshipTypes.reaction}
|
!{RelationshipTypes.edit, RelationshipTypes.reaction}
|
||||||
.contains(e.relationshipType) &&
|
.contains(relationshipType) &&
|
||||||
// always filter out m.key.* events
|
// always filter out m.key.* events
|
||||||
!e.type.startsWith('m.key.verification.') &&
|
!type.startsWith('m.key.verification.') &&
|
||||||
// event types to hide: redaction and reaction events
|
// event types to hide: redaction and reaction events
|
||||||
// if a reaction has been redacted we also want it to be hidden in the timeline
|
// if a reaction has been redacted we also want it to be hidden in the timeline
|
||||||
!{EventTypes.Reaction, EventTypes.Redaction}.contains(e.type) &&
|
!{EventTypes.Reaction, EventTypes.Redaction}.contains(type) &&
|
||||||
// if we enabled to hide all redacted events, don't show those
|
// if we enabled to hide all redacted events, don't show those
|
||||||
(!AppConfig.hideRedactedEvents || !e.redacted) &&
|
(!AppConfig.hideRedactedEvents || !redacted) &&
|
||||||
// if we enabled to hide all unknown events, don't show those
|
// if we enabled to hide all unknown events, don't show those
|
||||||
(!AppConfig.hideUnknownEvents || e.isEventTypeKnown) &&
|
(!AppConfig.hideUnknownEvents || isEventTypeKnown) &&
|
||||||
// remove state events that we don't want to render
|
// remove state events that we don't want to render
|
||||||
(e.isState || !AppConfig.hideAllStateEvents))
|
(isState || !AppConfig.hideAllStateEvents) &&
|
||||||
.toList();
|
// hide unimportant state events
|
||||||
|
(!AppConfig.hideUnimportantStateEvents ||
|
||||||
|
!isState ||
|
||||||
|
importantStateEvents.contains(type)) &&
|
||||||
|
// hide member events in public rooms
|
||||||
|
(!AppConfig.hideUnimportantStateEvents ||
|
||||||
|
type != EventTypes.RoomMember ||
|
||||||
|
room.joinRules != JoinRules.public);
|
||||||
|
|
||||||
// Fold state events
|
static const Set<String> importantStateEvents = {
|
||||||
var counter = 0;
|
EventTypes.Encryption,
|
||||||
for (var i = filteredEvents.length - 1; i >= 0; i--) {
|
EventTypes.RoomCreate,
|
||||||
if (!filteredEvents[i].isState) continue;
|
EventTypes.RoomMember,
|
||||||
if (i > 0 &&
|
EventTypes.RoomTombstone,
|
||||||
filteredEvents[i - 1].isState &&
|
EventTypes.CallInvite,
|
||||||
!unfolded.contains(filteredEvents[i - 1].eventId)) {
|
};
|
||||||
counter++;
|
|
||||||
filteredEvents[i].unsigned ??= {};
|
|
||||||
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 => !{
|
bool get isState => !{
|
||||||
EventTypes.Message,
|
EventTypes.Message,
|
||||||
EventTypes.Sticker,
|
EventTypes.Sticker,
|
||||||
|
@ -5,7 +5,6 @@ import 'package:matrix/matrix.dart';
|
|||||||
|
|
||||||
import '../config/app_config.dart';
|
import '../config/app_config.dart';
|
||||||
import 'date_time_extension.dart';
|
import 'date_time_extension.dart';
|
||||||
import 'matrix_sdk_extensions.dart/filtered_timeline_extension.dart';
|
|
||||||
|
|
||||||
extension RoomStatusExtension on Room {
|
extension RoomStatusExtension on Room {
|
||||||
CachedPresence? get directChatPresence =>
|
CachedPresence? get directChatPresence =>
|
||||||
@ -65,14 +64,9 @@ extension RoomStatusExtension on Room {
|
|||||||
return typingText;
|
return typingText;
|
||||||
}
|
}
|
||||||
|
|
||||||
List<User> getSeenByUsers(
|
List<User> getSeenByUsers(Timeline timeline, {String? eventId}) {
|
||||||
Timeline timeline, List<Event> filteredEvents, Set<String> unfolded,
|
|
||||||
{String? eventId}) {
|
|
||||||
if (timeline.events.isEmpty) return [];
|
if (timeline.events.isEmpty) return [];
|
||||||
|
eventId ??= timeline.events.first.eventId;
|
||||||
final filteredEvents = timeline.getFilteredEvents(unfolded: unfolded);
|
|
||||||
if (filteredEvents.isEmpty) return [];
|
|
||||||
eventId ??= filteredEvents.first.eventId;
|
|
||||||
|
|
||||||
final lastReceipts = <User>{};
|
final lastReceipts = <User>{};
|
||||||
// now we iterate the timeline events until we hit the first rendered event
|
// now we iterate the timeline events until we hit the first rendered event
|
||||||
@ -83,7 +77,7 @@ extension RoomStatusExtension on Room {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
lastReceipts.removeWhere((user) =>
|
lastReceipts.removeWhere((user) =>
|
||||||
user.id == client.userID || user.id == filteredEvents.first.senderId);
|
user.id == client.userID || user.id == timeline.events.first.senderId);
|
||||||
return lastReceipts.toList();
|
return lastReceipts.toList();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user