Merge branch 'background-click' into 'main'

Click on background to clear selected events

See merge request famedly/fluffychat!631
This commit is contained in:
Krille Fear 2022-01-03 16:12:09 +00:00
commit 8e31a30fd0
2 changed files with 159 additions and 141 deletions

View File

@ -698,6 +698,12 @@ class ChatController extends State<Chat> {
showEmojiPicker = false; showEmojiPicker = false;
}); });
void clearSingleSelectedEvent() {
if (selectedEvents.length <= 1) {
clearSelectedEvents();
}
}
void editSelectedEventAction() { void editSelectedEventAction() {
final client = currentRoomBundle.firstWhere( final client = currentRoomBundle.firstWhere(
(cl) => selectedEvents.first.senderId == cl.userID, (cl) => selectedEvents.first.senderId == cl.userID,

View File

@ -194,151 +194,163 @@ class ChatView extends StatelessWidget {
children: <Widget>[ children: <Widget>[
TombstoneDisplay(controller), TombstoneDisplay(controller),
Expanded( Expanded(
child: FutureBuilder<bool>( child: GestureDetector(
future: controller.getTimeline(), onTap: controller.clearSingleSelectedEvent,
builder: (BuildContext context, snapshot) { child: FutureBuilder<bool>(
if (snapshot.hasError) { future: controller.getTimeline(),
SentryController.captureException( builder: (BuildContext context, snapshot) {
snapshot.error, if (snapshot.hasError) {
StackTrace.current, SentryController.captureException(
); snapshot.error,
} StackTrace.current,
if (controller.timeline == null) { );
return const Center( }
child: CircularProgressIndicator.adaptive( if (controller.timeline == null) {
strokeWidth: 2), return const Center(
); child: CircularProgressIndicator.adaptive(
} strokeWidth: 2),
);
}
// 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; for (var i = 0;
i < controller.filteredEvents.length; i < controller.filteredEvents.length;
i++) { i++) {
thisEventsKeyMap[ thisEventsKeyMap[
controller.filteredEvents[i].eventId] = i; controller.filteredEvents[i].eventId] = i;
} }
return ListView.custom( return ListView.custom(
padding: EdgeInsets.only( padding: EdgeInsets.only(
top: 16, top: 16,
bottom: 4, bottom: 4,
left: horizontalPadding, left: horizontalPadding,
right: horizontalPadding, right: horizontalPadding,
), ),
reverse: true, reverse: true,
controller: controller.scrollController, controller: controller.scrollController,
keyboardDismissBehavior: PlatformInfos.isIOS keyboardDismissBehavior: PlatformInfos.isIOS
? ScrollViewKeyboardDismissBehavior.onDrag ? ScrollViewKeyboardDismissBehavior.onDrag
: ScrollViewKeyboardDismissBehavior.manual, : ScrollViewKeyboardDismissBehavior
childrenDelegate: SliverChildBuilderDelegate( .manual,
(BuildContext context, int i) { childrenDelegate: SliverChildBuilderDelegate(
return i == (BuildContext context, int i) {
controller.filteredEvents.length + 1 return i ==
? controller.timeline.isRequestingHistory controller.filteredEvents.length +
? const Center( 1
child: CircularProgressIndicator ? controller
.adaptive(strokeWidth: 2), .timeline.isRequestingHistory
) ? const Center(
: controller.canLoadMore child:
? Center( CircularProgressIndicator
child: OutlinedButton( .adaptive(
style: OutlinedButton strokeWidth: 2),
.styleFrom(
backgroundColor: Theme.of(
context)
.scaffoldBackgroundColor,
),
onPressed: controller
.requestHistory,
child: Text(L10n.of(context)
.loadMore),
),
) )
: Container() : controller.canLoadMore
: i == 0 ? Center(
? Column( child: OutlinedButton(
mainAxisSize: MainAxisSize.min, style: OutlinedButton
children: [ .styleFrom(
SeenByRow(controller), backgroundColor: Theme
TypingIndicators(controller), .of(context)
], .scaffoldBackgroundColor,
)
: AutoScrollTag(
key: ValueKey(controller
.filteredEvents[i - 1]
.eventId),
index: i - 1,
controller:
controller.scrollController,
child: Swipeable(
key: ValueKey(controller
.filteredEvents[i - 1]
.eventId),
background: const Padding(
padding: EdgeInsets.symmetric(
horizontal: 12.0),
child: Center(
child: Icon(
Icons.reply_outlined),
),
),
direction:
SwipeDirection.endToStart,
onSwipe: (direction) =>
controller.replyAction(
replyTo: controller
.filteredEvents[
i - 1]),
child: Message(
controller
.filteredEvents[i - 1],
onInfoTab: controller
.showEventInfo,
onAvatarTab: (Event event) =>
showModalBottomSheet(
context: context,
builder: (c) =>
UserBottomSheet(
user: event.sender,
outerContext:
context,
onMention: () => controller
.sendController
.text +=
'${event.sender.mention} ',
),
), ),
unfold: controller.unfold, onPressed: controller
onSelect: controller .requestHistory,
.onSelectMessage, child: Text(
scrollToEventId: L10n.of(context)
(String eventId) => .loadMore),
controller.scrollToEventId( ),
eventId), )
longPressSelect: controller : Container()
.selectedEvents.isEmpty, : i == 0
selected: controller ? Column(
.selectedEvents mainAxisSize:
.any((e) => MainAxisSize.min,
e.eventId == children: [
SeenByRow(controller),
TypingIndicators(
controller),
],
)
: AutoScrollTag(
key: ValueKey(controller
.filteredEvents[i - 1]
.eventId),
index: i - 1,
controller: controller
.scrollController,
child: Swipeable(
key: ValueKey(controller
.filteredEvents[i - 1]
.eventId),
background: const Padding(
padding:
EdgeInsets.symmetric(
horizontal: 12.0),
child: Center(
child: Icon(Icons
.reply_outlined),
),
),
direction: SwipeDirection
.endToStart,
onSwipe: (direction) =>
controller.replyAction(
replyTo: controller
.filteredEvents[
i - 1]),
child: Message(
controller.filteredEvents[
i - 1],
onInfoTab: controller
.showEventInfo,
onAvatarTab: (Event event) =>
showModalBottomSheet(
context: context,
builder: (c) =>
UserBottomSheet(
user: event
.sender,
outerContext:
context,
onMention: () => controller
.sendController
.text +=
'${event.sender.mention} ',
),
),
unfold:
controller.unfold,
onSelect: controller
.onSelectMessage,
scrollToEventId:
(String eventId) =>
controller
.scrollToEventId(
eventId),
longPressSelect:
controller controller
.filteredEvents[i - 1] .selectedEvents
.eventId), .isEmpty,
timeline: controller.timeline, selected: controller
nextEvent: i < controller.filteredEvents.length ? controller.filteredEvents[i] : null), .selectedEvents
), .any((e) => e.eventId == controller.filteredEvents[i - 1].eventId),
); timeline: controller.timeline,
}, nextEvent: i < controller.filteredEvents.length ? controller.filteredEvents[i] : null),
childCount: ),
controller.filteredEvents.length + 2, );
findChildIndexCallback: (key) => },
controller.findChildIndexCallback( childCount:
key, thisEventsKeyMap), controller.filteredEvents.length + 2,
), findChildIndexCallback: (key) =>
); controller.findChildIndexCallback(
}, key, thisEventsKeyMap),
), ),
);
},
)),
), ),
if (controller.room.canSendDefaultMessages && if (controller.room.canSendDefaultMessages &&
controller.room.membership == Membership.join) controller.room.membership == Membership.join)