From 6d4113658706b3e236c09042e7f90349fd32d2ef Mon Sep 17 00:00:00 2001 From: Christian Pauly Date: Sat, 17 Oct 2020 09:28:33 +0000 Subject: [PATCH] feat: Implement mouse select chat list items --- lib/components/list_items/chat_list_item.dart | 17 ++++- lib/components/mouse_over_builder.dart | 28 +++++++++ lib/views/chat_list.dart | 63 +++++++++---------- pubspec.lock | 11 +++- pubspec.yaml | 1 + 5 files changed, 82 insertions(+), 38 deletions(-) create mode 100644 lib/components/mouse_over_builder.dart diff --git a/lib/components/list_items/chat_list_item.dart b/lib/components/list_items/chat_list_item.dart index 1111fe5..9b6ba7a 100644 --- a/lib/components/list_items/chat_list_item.dart +++ b/lib/components/list_items/chat_list_item.dart @@ -1,4 +1,5 @@ import 'package:bot_toast/bot_toast.dart'; +import 'package:circular_check_box/circular_check_box.dart'; import 'package:famedlysdk/famedlysdk.dart'; import 'package:fluffychat/utils/matrix_locals.dart'; import 'package:fluffychat/views/chat.dart'; @@ -13,6 +14,7 @@ import '../avatar.dart'; import '../dialogs/send_file_dialog.dart'; import '../dialogs/simple_dialogs.dart'; import '../matrix.dart'; +import '../mouse_over_builder.dart'; import '../theme_switcher.dart'; class ChatListItem extends StatelessWidget { @@ -128,7 +130,20 @@ class ChatListItem extends StatelessWidget { color: chatListItemColor(context, activeChat, selected), child: ListTile( onLongPress: onLongPress, - leading: Avatar(room.avatar, room.displayname), + leading: MouseOverBuilder( + builder: (context, hover) => + onLongPress != null && (hover || selected) + ? Container( + width: Avatar.defaultSize, + height: Avatar.defaultSize, + alignment: Alignment.center, + child: CircularCheckBox( + value: selected, + onChanged: (_) => onLongPress(), + ), + ) + : Avatar(room.avatar, room.displayname), + ), title: Row( children: [ Expanded( diff --git a/lib/components/mouse_over_builder.dart b/lib/components/mouse_over_builder.dart new file mode 100644 index 0000000..017eddc --- /dev/null +++ b/lib/components/mouse_over_builder.dart @@ -0,0 +1,28 @@ +import 'package:flutter/material.dart'; + +class MouseOverBuilder extends StatefulWidget { + final Function(BuildContext, bool) builder; + + const MouseOverBuilder({Key key, this.builder}) : super(key: key); + @override + _MouseOverBuilderState createState() => _MouseOverBuilderState(); +} + +class _MouseOverBuilderState extends State { + bool _hover = false; + + void _toggleHover(bool hover) { + if (_hover != hover) { + setState(() => _hover = hover); + } + } + + @override + Widget build(BuildContext context) { + return MouseRegion( + onEnter: (_) => _toggleHover(true), + onExit: (_) => _toggleHover(false), + child: widget.builder != null ? widget.builder(context, _hover) : null, + ); + } +} diff --git a/lib/views/chat_list.dart b/lib/views/chat_list.dart index b0aa931..d56c3d4 100644 --- a/lib/views/chat_list.dart +++ b/lib/views/chat_list.dart @@ -420,37 +420,34 @@ class _ChatListState extends State { ), ), ), - floatingActionButton: - (AdaptivePageLayout.columnMode(context) || - selectMode != SelectMode.normal) - ? null - : Column( - mainAxisSize: MainAxisSize.min, - children: [ - FloatingActionButton( - heroTag: null, - child: Icon( - Icons.edit, - color: Theme.of(context).primaryColor, - ), - elevation: 1, - backgroundColor: - Theme.of(context).secondaryHeaderColor, - onPressed: () => _setStatus(context), - ), - SizedBox(height: 16.0), - FloatingActionButton( - child: Icon(Icons.add), - backgroundColor: - Theme.of(context).primaryColor, - onPressed: () => Navigator.of(context) - .pushAndRemoveUntil( - AppRoute.defaultRoute( - context, NewPrivateChatView()), - (r) => r.isFirst), - ), - ], + floatingActionButton: AdaptivePageLayout.columnMode(context) + ? null + : Column( + mainAxisSize: MainAxisSize.min, + children: [ + FloatingActionButton( + heroTag: null, + child: Icon( + Icons.edit, + color: Theme.of(context).primaryColor, + ), + elevation: 1, + backgroundColor: + Theme.of(context).secondaryHeaderColor, + onPressed: () => _setStatus(context), ), + SizedBox(height: 16.0), + FloatingActionButton( + child: Icon(Icons.add), + backgroundColor: Theme.of(context).primaryColor, + onPressed: () => Navigator.of(context) + .pushAndRemoveUntil( + AppRoute.defaultRoute( + context, NewPrivateChatView()), + (r) => r.isFirst), + ), + ], + ), body: Column( children: [ ConnectionStatusHeader(), @@ -532,11 +529,7 @@ class _ChatListState extends State { (BuildContext context, int i) { if (i == 0) { final displayPresences = - Matrix.of(context) - .userStatuses - .isNotEmpty && - selectMode == - SelectMode.normal; + selectMode != SelectMode.share; final displayShareStatus = selectMode == SelectMode.share && diff --git a/pubspec.lock b/pubspec.lock index 40e5e14..ff9b2ab 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -99,6 +99,13 @@ packages: url: "https://pub.dartlang.org" source: hosted version: "1.2.0-nullsafety.1" + circular_check_box: + dependency: "direct main" + description: + name: circular_check_box + url: "https://pub.dartlang.org" + source: hosted + version: "1.0.4" cli_util: dependency: transitive description: @@ -526,7 +533,7 @@ packages: name: meta url: "https://pub.dartlang.org" source: hosted - version: "1.3.0-nullsafety.3" + version: "1.3.0-nullsafety.4" mime: dependency: transitive description: @@ -862,7 +869,7 @@ packages: name: stack_trace url: "https://pub.dartlang.org" source: hosted - version: "1.10.0-nullsafety.1" + version: "1.10.0-nullsafety.2" stream_channel: dependency: transitive description: diff --git a/pubspec.yaml b/pubspec.yaml index d71bf77..55acd68 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -60,6 +60,7 @@ dependencies: flutter_olm: ^1.0.1 intl: ^0.16.1 intl_translation: ^0.17.9 + circular_check_box: ^1.0.4 flutter_localizations: sdk: flutter sqflite: ^1.1.7 # Still used to obtain the database location