From 264f36ea59775002dc3218f9f4d6a45736a05fbd Mon Sep 17 00:00:00 2001 From: Krille Date: Tue, 3 Jan 2023 18:00:56 +0100 Subject: [PATCH] design: Nicer navigationrail --- lib/pages/chat_list/chat_list_view.dart | 95 +++++-------------------- lib/pages/chat_list/navi_rail_item.dart | 66 +++++++++++++++++ 2 files changed, 83 insertions(+), 78 deletions(-) create mode 100644 lib/pages/chat_list/navi_rail_item.dart diff --git a/lib/pages/chat_list/chat_list_view.dart b/lib/pages/chat_list/chat_list_view.dart index 99ee5c9e..a3e42d9f 100644 --- a/lib/pages/chat_list/chat_list_view.dart +++ b/lib/pages/chat_list/chat_list_view.dart @@ -9,6 +9,7 @@ import 'package:vrouter/vrouter.dart'; import 'package:fluffychat/config/app_config.dart'; import 'package:fluffychat/config/themes.dart'; import 'package:fluffychat/pages/chat_list/chat_list.dart'; +import 'package:fluffychat/pages/chat_list/navi_rail_item.dart'; import 'package:fluffychat/widgets/avatar.dart'; import 'package:fluffychat/widgets/unread_rooms_badge.dart'; import '../../widgets/matrix.dart'; @@ -126,90 +127,28 @@ class ChatListView extends StatelessWidget { itemCount: rootSpaces.length + destinations.length, itemBuilder: (context, i) { if (i < destinations.length) { - final isSelected = i == controller.selectedIndex; - return Container( - height: 64, - width: 64, - decoration: BoxDecoration( - border: Border( - bottom: i == (destinations.length - 1) - ? BorderSide( - width: 1, - color: Theme.of(context).dividerColor, - ) - : BorderSide.none, - left: BorderSide( - color: isSelected - ? Theme.of(context).colorScheme.primary - : Colors.transparent, - width: 4, - ), - right: const BorderSide( - color: Colors.transparent, - width: 4, - ), - ), - ), - alignment: Alignment.center, - child: IconButton( - color: isSelected - ? Theme.of(context).colorScheme.secondary - : null, - icon: CircleAvatar( - backgroundColor: isSelected - ? Theme.of(context).colorScheme.secondary - : Theme.of(context) - .colorScheme - .background, - foregroundColor: isSelected - ? Theme.of(context) - .colorScheme - .onSecondary - : Theme.of(context) - .colorScheme - .onBackground, - child: i == controller.selectedIndex - ? destinations[i].selectedIcon ?? - destinations[i].icon - : destinations[i].icon), - tooltip: destinations[i].label, - onPressed: () => - controller.onDestinationSelected(i), - ), + return NaviRailItem( + isSelected: i == controller.selectedIndex, + onTap: () => controller.onDestinationSelected(i), + icon: destinations[i].icon, + selectedIcon: destinations[i].selectedIcon, + toolTip: destinations[i].label, ); } i -= destinations.length; final isSelected = controller.activeFilter == ActiveFilter.spaces && rootSpaces[i].id == controller.activeSpaceId; - return Container( - height: 64, - width: 64, - decoration: BoxDecoration( - border: Border( - left: BorderSide( - color: isSelected - ? Theme.of(context).colorScheme.secondary - : Colors.transparent, - width: 4, - ), - right: const BorderSide( - color: Colors.transparent, - width: 4, - ), - ), - ), - alignment: Alignment.center, - child: IconButton( - tooltip: rootSpaces[i].displayname, - icon: Avatar( - mxContent: rootSpaces[i].avatar, - name: rootSpaces[i].displayname, - size: 32, - fontSize: 12, - ), - onPressed: () => - controller.setActiveSpace(rootSpaces[i].id), + return NaviRailItem( + toolTip: rootSpaces[i].displayname, + isSelected: isSelected, + onTap: () => + controller.setActiveSpace(rootSpaces[i].id), + icon: Avatar( + mxContent: rootSpaces[i].avatar, + name: rootSpaces[i].displayname, + size: 32, + fontSize: 12, ), ); }, diff --git a/lib/pages/chat_list/navi_rail_item.dart b/lib/pages/chat_list/navi_rail_item.dart new file mode 100644 index 00000000..e836a26a --- /dev/null +++ b/lib/pages/chat_list/navi_rail_item.dart @@ -0,0 +1,66 @@ +import 'package:flutter/material.dart'; + +import 'package:fluffychat/config/app_config.dart'; + +class NaviRailItem extends StatelessWidget { + final String toolTip; + final bool isSelected; + final void Function() onTap; + final Widget icon; + final Widget? selectedIcon; + + const NaviRailItem({ + required this.toolTip, + required this.isSelected, + required this.onTap, + required this.icon, + this.selectedIcon, + Key? key, + }) : super(key: key); + + @override + Widget build(BuildContext context) { + return SizedBox( + height: 64, + width: 64, + child: Stack( + children: [ + Positioned( + top: 16, + bottom: 16, + left: 0, + child: AnimatedContainer( + width: isSelected ? 4 : 0, + duration: const Duration(milliseconds: 200), + decoration: BoxDecoration( + color: Theme.of(context).primaryColor, + borderRadius: const BorderRadius.only( + topRight: Radius.circular(90), + bottomRight: Radius.circular(90), + ), + ), + ), + ), + Center( + child: IconButton( + onPressed: onTap, + tooltip: toolTip, + icon: Material( + borderRadius: BorderRadius.circular(AppConfig.borderRadius), + color: isSelected + ? Theme.of(context).colorScheme.primaryContainer + : Theme.of(context).colorScheme.background, + child: Padding( + padding: const EdgeInsets.symmetric( + horizontal: 8.0, + vertical: 8.0, + ), + child: isSelected ? selectedIcon ?? icon : icon, + )), + ), + ), + ], + ), + ); + } +}