style: Use SliverList for chatlist

This commit is contained in:
Krille 2023-03-19 19:59:50 +01:00
parent 46e0e4b65e
commit 61c4d0e61f
7 changed files with 336 additions and 275 deletions

View file

@ -16,7 +16,7 @@ abstract class AppConfig {
static const double messageFontSize = 15.75; static const double messageFontSize = 15.75;
static const bool allowOtherHomeservers = true; static const bool allowOtherHomeservers = true;
static const bool enableRegistration = true; static const bool enableRegistration = true;
static const Color primaryColor = Color.fromARGB(255, 135, 103, 172); static const Color primaryColor = Color(0xFF5625BA);
static const Color primaryColorLight = Color(0xFFCCBDEA); static const Color primaryColorLight = Color(0xFFCCBDEA);
static const Color secondaryColor = Color(0xFF41a2bc); static const Color secondaryColor = Color(0xFF41a2bc);
static String _privacyUrl = static String _privacyUrl =

View file

@ -8,6 +8,7 @@ import 'package:fluffychat/pages/chat_list/chat_list.dart';
import 'package:fluffychat/pages/chat_list/chat_list_item.dart'; import 'package:fluffychat/pages/chat_list/chat_list_item.dart';
import 'package:fluffychat/pages/chat_list/search_title.dart'; import 'package:fluffychat/pages/chat_list/search_title.dart';
import 'package:fluffychat/pages/chat_list/space_view.dart'; import 'package:fluffychat/pages/chat_list/space_view.dart';
import 'package:fluffychat/pages/chat_list/start_chat_fab.dart';
import 'package:fluffychat/pages/chat_list/stories_header.dart'; import 'package:fluffychat/pages/chat_list/stories_header.dart';
import 'package:fluffychat/utils/adaptive_bottom_sheet.dart'; import 'package:fluffychat/utils/adaptive_bottom_sheet.dart';
import 'package:fluffychat/utils/matrix_sdk_extensions/client_stories_extension.dart'; import 'package:fluffychat/utils/matrix_sdk_extensions/client_stories_extension.dart';
@ -19,6 +20,7 @@ import 'package:fluffychat/widgets/public_room_bottom_sheet.dart';
import '../../config/themes.dart'; import '../../config/themes.dart';
import '../../widgets/connection_status_header.dart'; import '../../widgets/connection_status_header.dart';
import '../../widgets/matrix.dart'; import '../../widgets/matrix.dart';
import 'chat_list_header.dart';
class ChatListViewBody extends StatelessWidget { class ChatListViewBody extends StatelessWidget {
final ChatListController controller; final ChatListController controller;
@ -70,15 +72,13 @@ class ChatListViewBody extends StatelessWidget {
ActiveFilter.messages, ActiveFilter.messages,
}.contains(controller.activeFilter) && }.contains(controller.activeFilter) &&
client.storiesRooms.isNotEmpty; client.storiesRooms.isNotEmpty;
return ListView.builder( return CustomScrollView(
controller: controller.scrollController, controller: controller.scrollController,
// add +1 space below in order to properly scroll below the spaces bar slivers: [
itemCount: rooms.length + 1, ChatListHeader(controller: controller),
itemBuilder: (BuildContext context, int i) { SliverList(
if (i == 0) { delegate: SliverChildListDelegate(
return Column( [
mainAxisSize: MainAxisSize.min,
children: [
if (controller.isSearchMode) ...[ if (controller.isSearchMode) ...[
SearchTitle( SearchTitle(
title: L10n.of(context)!.publicRooms, title: L10n.of(context)!.publicRooms,
@ -187,7 +187,7 @@ class ChatListViewBody extends StatelessWidget {
title: L10n.of(context)!.chats, title: L10n.of(context)!.chats,
icon: const Icon(Icons.forum_outlined), icon: const Icon(Icons.forum_outlined),
), ),
if (rooms.isEmpty && !controller.isSearchMode) if (rooms.isEmpty && !controller.isSearchMode) ...[
Padding( Padding(
padding: const EdgeInsets.all(32.0), padding: const EdgeInsets.all(32.0),
child: Column( child: Column(
@ -201,29 +201,47 @@ class ChatListViewBody extends StatelessWidget {
], ],
), ),
), ),
Center(
child: StartChatFloatingActionButton(
activeFilter: controller.activeFilter,
roomsIsEmpty: true,
scrolledToTop: controller.scrolledToTop,
),
),
],
], ],
); ),
} ),
i--; SliverList(
if (!rooms[i] delegate: SliverChildBuilderDelegate(
.getLocalizedDisplayname(MatrixLocals(L10n.of(context)!)) (BuildContext context, int i) {
.toLowerCase() if (!rooms[i]
.contains( .getLocalizedDisplayname(
controller.searchController.text.toLowerCase(), MatrixLocals(L10n.of(context)!),
)) { )
return Container(); .toLowerCase()
} .contains(
return ChatListItem( controller.searchController.text.toLowerCase(),
rooms[i], )) {
key: Key('chat_list_item_${rooms[i].id}'), return Container();
selected: controller.selectedRoomIds.contains(rooms[i].id), }
onTap: controller.selectMode == SelectMode.select return ChatListItem(
? () => controller.toggleSelection(rooms[i].id) rooms[i],
: null, key: Key('chat_list_item_${rooms[i].id}'),
onLongPress: () => controller.toggleSelection(rooms[i].id), selected:
activeChat: controller.activeChat == rooms[i].id, controller.selectedRoomIds.contains(rooms[i].id),
); onTap: controller.selectMode == SelectMode.select
}, ? () => controller.toggleSelection(rooms[i].id)
: null,
onLongPress: () =>
controller.toggleSelection(rooms[i].id),
activeChat: controller.activeChat == rooms[i].id,
);
},
childCount: rooms.length,
),
),
],
); );
} }
const dummyChatCount = 5; const dummyChatCount = 5;

View file

@ -3,6 +3,7 @@ import 'package:flutter/material.dart';
import 'package:flutter_gen/gen_l10n/l10n.dart'; import 'package:flutter_gen/gen_l10n/l10n.dart';
import 'package:fluffychat/config/app_config.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/chat_list.dart';
import 'package:fluffychat/pages/chat_list/client_chooser_button.dart'; import 'package:fluffychat/pages/chat_list/client_chooser_button.dart';
import '../../widgets/matrix.dart'; import '../../widgets/matrix.dart';
@ -16,7 +17,12 @@ class ChatListHeader extends StatelessWidget implements PreferredSizeWidget {
Widget build(BuildContext context) { Widget build(BuildContext context) {
final selectMode = controller.selectMode; final selectMode = controller.selectMode;
return AppBar( return SliverAppBar(
floating: true,
pinned: FluffyThemes.isColumnMode(context),
elevation: 0,
scrolledUnderElevation: 0,
backgroundColor: Colors.transparent,
automaticallyImplyLeading: false, automaticallyImplyLeading: false,
leading: selectMode == SelectMode.normal leading: selectMode == SelectMode.normal
? null ? null
@ -38,65 +44,70 @@ class ChatListHeader extends StatelessWidget implements PreferredSizeWidget {
) )
: SizedBox( : SizedBox(
height: 44, height: 44,
child: TextField( child: Material(
controller: controller.searchController, elevation:
textInputAction: TextInputAction.search, Theme.of(context).appBarTheme.scrolledUnderElevation ??
onChanged: controller.onSearchEnter, 4,
decoration: InputDecoration( shadowColor: Theme.of(context).appBarTheme.shadowColor,
fillColor: Theme.of(context) borderRadius: BorderRadius.circular(AppConfig.borderRadius),
.colorScheme child: TextField(
.secondaryContainer controller: controller.searchController,
.withAlpha(128), textInputAction: TextInputAction.search,
border: UnderlineInputBorder( onChanged: controller.onSearchEnter,
borderSide: BorderSide.none, decoration: InputDecoration(
borderRadius: border: UnderlineInputBorder(
BorderRadius.circular(AppConfig.borderRadius), borderSide: BorderSide.none,
), borderRadius:
hintText: L10n.of(context)!.search, BorderRadius.circular(AppConfig.borderRadius),
floatingLabelBehavior: FloatingLabelBehavior.never, ),
prefixIcon: controller.isSearchMode hintText: L10n.of(context)!.search,
? IconButton( floatingLabelBehavior: FloatingLabelBehavior.never,
tooltip: L10n.of(context)!.cancel, prefixIcon: controller.isSearchMode
icon: const Icon(Icons.close_outlined), ? IconButton(
onPressed: controller.cancelSearch, tooltip: L10n.of(context)!.cancel,
color: Theme.of(context).colorScheme.onBackground, icon: const Icon(Icons.close_outlined),
) onPressed: controller.cancelSearch,
: Icon( color:
Icons.search_outlined, Theme.of(context).colorScheme.onBackground,
color: Theme.of(context).colorScheme.onBackground, )
), : Icon(
suffixIcon: controller.isSearchMode Icons.search_outlined,
? controller.isSearching color:
? const Padding( Theme.of(context).colorScheme.onBackground,
padding: EdgeInsets.symmetric( ),
vertical: 10.0, suffixIcon: controller.isSearchMode
horizontal: 12, ? controller.isSearching
), ? const Padding(
child: SizedBox.square( padding: EdgeInsets.symmetric(
dimension: 24, vertical: 10.0,
child: CircularProgressIndicator.adaptive( horizontal: 12,
strokeWidth: 2,
), ),
), child: SizedBox.square(
) dimension: 24,
: TextButton( child: CircularProgressIndicator.adaptive(
onPressed: controller.setServer, strokeWidth: 2,
style: TextButton.styleFrom( ),
textStyle: const TextStyle(fontSize: 12), ),
), )
child: Text( : TextButton(
controller.searchServer ?? onPressed: controller.setServer,
Matrix.of(context) style: TextButton.styleFrom(
.client textStyle: const TextStyle(fontSize: 12),
.homeserver! ),
.host, child: Text(
maxLines: 2, controller.searchServer ??
), Matrix.of(context)
) .client
: SizedBox( .homeserver!
width: 0, .host,
child: ClientChooserButton(controller), maxLines: 2,
), ),
)
: SizedBox(
width: 0,
child: ClientChooserButton(controller),
),
),
), ),
), ),
), ),

View file

@ -15,7 +15,6 @@ import 'package:fluffychat/widgets/avatar.dart';
import 'package:fluffychat/widgets/unread_rooms_badge.dart'; import 'package:fluffychat/widgets/unread_rooms_badge.dart';
import '../../widgets/matrix.dart'; import '../../widgets/matrix.dart';
import 'chat_list_body.dart'; import 'chat_list_body.dart';
import 'chat_list_header.dart';
import 'start_chat_fab.dart'; import 'start_chat_fab.dart';
class ChatListView extends StatelessWidget { class ChatListView extends StatelessWidget {
@ -46,12 +45,12 @@ class ChatListView extends StatelessWidget {
icon: UnreadRoomsBadge( icon: UnreadRoomsBadge(
badgePosition: badgePosition, badgePosition: badgePosition,
filter: controller.getRoomFilterByActiveFilter(ActiveFilter.groups), filter: controller.getRoomFilterByActiveFilter(ActiveFilter.groups),
child: const Icon(Icons.groups_outlined), child: const Icon(Icons.group_outlined),
), ),
selectedIcon: UnreadRoomsBadge( selectedIcon: UnreadRoomsBadge(
badgePosition: badgePosition, badgePosition: badgePosition,
filter: controller.getRoomFilterByActiveFilter(ActiveFilter.groups), filter: controller.getRoomFilterByActiveFilter(ActiveFilter.groups),
child: const Icon(Icons.groups), child: const Icon(Icons.group),
), ),
label: L10n.of(context)!.groups, label: L10n.of(context)!.groups,
), ),
@ -174,7 +173,6 @@ class ChatListView extends StatelessWidget {
excludeFromSemantics: true, excludeFromSemantics: true,
behavior: HitTestBehavior.translucent, behavior: HitTestBehavior.translucent,
child: Scaffold( child: Scaffold(
appBar: ChatListHeader(controller: controller),
body: ChatListViewBody(controller), body: ChatListViewBody(controller),
bottomNavigationBar: controller.displayNavigationBar bottomNavigationBar: controller.displayNavigationBar
? NavigationBar( ? NavigationBar(
@ -185,24 +183,24 @@ class ChatListView extends StatelessWidget {
destinations: getNavigationDestinations(context), destinations: getNavigationDestinations(context),
) )
: null, : null,
floatingActionButtonLocation: floatingActionButton: KeyBoardShortcuts(
controller.filteredRooms.isEmpty keysToPress: {
? FloatingActionButtonLocation.centerFloat LogicalKeyboardKey.controlLeft,
: null, LogicalKeyboardKey.keyN
floatingActionButton: selectMode == SelectMode.normal },
? KeyBoardShortcuts( onKeysPressed: () =>
keysToPress: { VRouter.of(context).to('/newprivatechat'),
LogicalKeyboardKey.controlLeft, helpLabel: L10n.of(context)!.newChat,
LogicalKeyboardKey.keyN child: selectMode == SelectMode.normal &&
}, controller.filteredRooms.isNotEmpty &&
onKeysPressed: () => !controller.isSearchMode
VRouter.of(context).to('/newprivatechat'), ? StartChatFloatingActionButton(
helpLabel: L10n.of(context)!.newChat, activeFilter: controller.activeFilter,
child: StartChatFloatingActionButton( roomsIsEmpty: false,
controller: controller, scrolledToTop: controller.scrolledToTop,
), )
) : const SizedBox.shrink(),
: null, ),
), ),
), ),
), ),

View file

@ -14,6 +14,7 @@ import 'package:fluffychat/utils/matrix_sdk_extensions/matrix_locals.dart';
import 'package:fluffychat/widgets/avatar.dart'; import 'package:fluffychat/widgets/avatar.dart';
import '../../utils/localized_exception_extension.dart'; import '../../utils/localized_exception_extension.dart';
import '../../widgets/matrix.dart'; import '../../widgets/matrix.dart';
import 'chat_list_header.dart';
class SpaceView extends StatefulWidget { class SpaceView extends StatefulWidget {
final ChatListController controller; final ChatListController controller;
@ -154,36 +155,44 @@ class _SpaceViewState extends State<SpaceView> {
) )
.toList(); .toList();
return ListView.builder( return CustomScrollView(
itemCount: rootSpaces.length,
controller: widget.scrollController, controller: widget.scrollController,
itemBuilder: (context, i) { slivers: [
final rootSpace = rootSpaces[i]; ChatListHeader(controller: widget.controller),
final displayname = rootSpace.getLocalizedDisplayname( SliverList(
MatrixLocals(L10n.of(context)!), delegate: SliverChildBuilderDelegate(
); (context, i) {
return Material( final rootSpace = rootSpaces[i];
color: Theme.of(context).colorScheme.background, final displayname = rootSpace.getLocalizedDisplayname(
child: ListTile( MatrixLocals(L10n.of(context)!),
leading: Avatar( );
mxContent: rootSpace.avatar, return Material(
name: displayname, color: Theme.of(context).colorScheme.background,
), child: ListTile(
title: Text( leading: Avatar(
displayname, mxContent: rootSpace.avatar,
maxLines: 1, name: displayname,
overflow: TextOverflow.ellipsis, ),
), title: Text(
subtitle: Text( displayname,
L10n.of(context)! maxLines: 1,
.numChats(rootSpace.spaceChildren.length.toString()), overflow: TextOverflow.ellipsis,
), ),
onTap: () => widget.controller.setActiveSpace(rootSpace.id), subtitle: Text(
onLongPress: () => _onSpaceChildContextMenu(null, rootSpace), L10n.of(context)!
trailing: const Icon(Icons.chevron_right_outlined), .numChats(rootSpace.spaceChildren.length.toString()),
),
onTap: () => widget.controller.setActiveSpace(rootSpace.id),
onLongPress: () =>
_onSpaceChildContextMenu(null, rootSpace),
trailing: const Icon(Icons.chevron_right_outlined),
),
);
},
childCount: rootSpaces.length,
), ),
); ),
}, ],
); );
} }
return FutureBuilder<GetSpaceHierarchyResponse>( return FutureBuilder<GetSpaceHierarchyResponse>(
@ -208,7 +217,16 @@ class _SpaceViewState extends State<SpaceView> {
); );
} }
if (response == null) { if (response == null) {
return const Center(child: CircularProgressIndicator.adaptive()); return CustomScrollView(
slivers: [
ChatListHeader(controller: widget.controller),
const SliverFillRemaining(
child: Center(
child: CircularProgressIndicator.adaptive(),
),
),
],
);
} }
final parentSpace = allSpaces.firstWhereOrNull( final parentSpace = allSpaces.firstWhereOrNull(
(space) => (space) =>
@ -224,125 +242,139 @@ class _SpaceViewState extends State<SpaceView> {
return; return;
} }
}, },
child: ListView.builder( child: CustomScrollView(
itemCount: spaceChildren.length + 1 + (canLoadMore ? 1 : 0),
controller: widget.scrollController, controller: widget.scrollController,
itemBuilder: (context, i) { slivers: [
if (i == 0) { ChatListHeader(controller: widget.controller),
return ListTile( SliverList(
leading: BackButton( delegate: SliverChildBuilderDelegate(
onPressed: () => (context, i) {
widget.controller.setActiveSpace(parentSpace?.id), if (i == 0) {
), return ListTile(
title: Text( leading: BackButton(
parentSpace == null onPressed: () =>
? L10n.of(context)!.allSpaces widget.controller.setActiveSpace(parentSpace?.id),
: parentSpace.getLocalizedDisplayname( ),
MatrixLocals(L10n.of(context)!), title: Text(
), parentSpace == null
), ? L10n.of(context)!.allSpaces
trailing: IconButton( : parentSpace.getLocalizedDisplayname(
icon: snapshot.connectionState != ConnectionState.done MatrixLocals(L10n.of(context)!),
? const CircularProgressIndicator.adaptive() ),
: const Icon(Icons.refresh_outlined), ),
onPressed: snapshot.connectionState != ConnectionState.done trailing: IconButton(
icon: snapshot.connectionState != ConnectionState.done
? const CircularProgressIndicator.adaptive()
: const Icon(Icons.refresh_outlined),
onPressed:
snapshot.connectionState != ConnectionState.done
? null
: _refresh,
),
);
}
i--;
if (canLoadMore && i == spaceChildren.length) {
return ListTile(
title: Text(L10n.of(context)!.loadMore),
trailing: const Icon(Icons.chevron_right_outlined),
onTap: () {
prevBatch = response.nextBatch;
_refresh();
},
);
}
final spaceChild = spaceChildren[i];
final room = client.getRoomById(spaceChild.roomId);
if (room != null && !room.isSpace) {
return ChatListItem(
room,
onLongPress: () =>
_onSpaceChildContextMenu(spaceChild, room),
activeChat: widget.controller.activeChat == room.id,
);
}
final isSpace = spaceChild.roomType == 'm.space';
final topic = spaceChild.topic?.isEmpty ?? true
? null ? null
: _refresh, : spaceChild.topic;
), if (spaceChild.roomId == activeSpaceId) {
); return SearchTitle(
} title: spaceChild.name ??
i--;
if (canLoadMore && i == spaceChildren.length) {
return ListTile(
title: Text(L10n.of(context)!.loadMore),
trailing: const Icon(Icons.chevron_right_outlined),
onTap: () {
prevBatch = response.nextBatch;
_refresh();
},
);
}
final spaceChild = spaceChildren[i];
final room = client.getRoomById(spaceChild.roomId);
if (room != null && !room.isSpace) {
return ChatListItem(
room,
onLongPress: () => _onSpaceChildContextMenu(spaceChild, room),
activeChat: widget.controller.activeChat == room.id,
);
}
final isSpace = spaceChild.roomType == 'm.space';
final topic =
spaceChild.topic?.isEmpty ?? true ? null : spaceChild.topic;
if (spaceChild.roomId == activeSpaceId) {
return SearchTitle(
title:
spaceChild.name ?? spaceChild.canonicalAlias ?? 'Space',
icon: Padding(
padding: const EdgeInsets.symmetric(horizontal: 10.0),
child: Avatar(
size: 24,
mxContent: spaceChild.avatarUrl,
name: spaceChild.name,
fontSize: 9,
),
),
color: Theme.of(context)
.colorScheme
.secondaryContainer
.withAlpha(128),
trailing: const Padding(
padding: EdgeInsets.symmetric(horizontal: 16.0),
child: Icon(Icons.edit_outlined),
),
onTap: () => _onJoinSpaceChild(spaceChild),
);
}
return ListTile(
leading: Avatar(
mxContent: spaceChild.avatarUrl,
name: spaceChild.name,
),
title: Row(
children: [
Expanded(
child: Text(
spaceChild.name ??
spaceChild.canonicalAlias ?? spaceChild.canonicalAlias ??
L10n.of(context)!.chat, 'Space',
icon: Padding(
padding: const EdgeInsets.symmetric(horizontal: 10.0),
child: Avatar(
size: 24,
mxContent: spaceChild.avatarUrl,
name: spaceChild.name,
fontSize: 9,
),
),
color: Theme.of(context)
.colorScheme
.secondaryContainer
.withAlpha(128),
trailing: const Padding(
padding: EdgeInsets.symmetric(horizontal: 16.0),
child: Icon(Icons.edit_outlined),
),
onTap: () => _onJoinSpaceChild(spaceChild),
);
}
return ListTile(
leading: Avatar(
mxContent: spaceChild.avatarUrl,
name: spaceChild.name,
),
title: Row(
children: [
Expanded(
child: Text(
spaceChild.name ??
spaceChild.canonicalAlias ??
L10n.of(context)!.chat,
maxLines: 1,
style:
const TextStyle(fontWeight: FontWeight.bold),
),
),
if (!isSpace) ...[
const Icon(
Icons.people_outline,
size: 16,
),
const SizedBox(width: 4),
Text(
spaceChild.numJoinedMembers.toString(),
style: const TextStyle(fontSize: 14),
),
],
],
),
onTap: () => _onJoinSpaceChild(spaceChild),
onLongPress: () =>
_onSpaceChildContextMenu(spaceChild, room),
subtitle: Text(
topic ??
(isSpace
? L10n.of(context)!.enterSpace
: L10n.of(context)!.enterRoom),
maxLines: 1, maxLines: 1,
style: const TextStyle(fontWeight: FontWeight.bold), style: TextStyle(
color: Theme.of(context).colorScheme.onBackground,
),
), ),
), trailing: isSpace
if (!isSpace) ...[ ? const Icon(Icons.chevron_right_outlined)
const Icon( : null,
Icons.people_outline, );
size: 16, },
), childCount: spaceChildren.length + 1 + (canLoadMore ? 1 : 0),
const SizedBox(width: 4),
Text(
spaceChild.numJoinedMembers.toString(),
style: const TextStyle(fontSize: 14),
),
],
],
), ),
onTap: () => _onJoinSpaceChild(spaceChild), ),
onLongPress: () => _onSpaceChildContextMenu(spaceChild, room), ],
subtitle: Text(
topic ??
(isSpace
? L10n.of(context)!.enterSpace
: L10n.of(context)!.enterRoom),
maxLines: 1,
style: TextStyle(
color: Theme.of(context).colorScheme.onBackground,
),
),
trailing:
isSpace ? const Icon(Icons.chevron_right_outlined) : null,
);
},
), ),
); );
}, },

View file

@ -7,13 +7,19 @@ import '../../config/themes.dart';
import 'chat_list.dart'; import 'chat_list.dart';
class StartChatFloatingActionButton extends StatelessWidget { class StartChatFloatingActionButton extends StatelessWidget {
final ChatListController controller; final ActiveFilter activeFilter;
final bool scrolledToTop;
final bool roomsIsEmpty;
const StartChatFloatingActionButton({Key? key, required this.controller}) const StartChatFloatingActionButton({
: super(key: key); Key? key,
required this.activeFilter,
required this.scrolledToTop,
required this.roomsIsEmpty,
}) : super(key: key);
void _onPressed(BuildContext context) { void _onPressed(BuildContext context) {
switch (controller.activeFilter) { switch (activeFilter) {
case ActiveFilter.allChats: case ActiveFilter.allChats:
case ActiveFilter.messages: case ActiveFilter.messages:
VRouter.of(context).to('/newprivatechat'); VRouter.of(context).to('/newprivatechat');
@ -28,10 +34,10 @@ class StartChatFloatingActionButton extends StatelessWidget {
} }
IconData get icon { IconData get icon {
switch (controller.activeFilter) { switch (activeFilter) {
case ActiveFilter.allChats: case ActiveFilter.allChats:
case ActiveFilter.messages: case ActiveFilter.messages:
return Icons.edit_outlined; return Icons.add_outlined;
case ActiveFilter.groups: case ActiveFilter.groups:
return Icons.group_add_outlined; return Icons.group_add_outlined;
case ActiveFilter.spaces: case ActiveFilter.spaces:
@ -40,10 +46,10 @@ class StartChatFloatingActionButton extends StatelessWidget {
} }
String getLabel(BuildContext context) { String getLabel(BuildContext context) {
switch (controller.activeFilter) { switch (activeFilter) {
case ActiveFilter.allChats: case ActiveFilter.allChats:
case ActiveFilter.messages: case ActiveFilter.messages:
return controller.filteredRooms.isEmpty return roomsIsEmpty
? L10n.of(context)!.startFirstChat ? L10n.of(context)!.startFirstChat
: L10n.of(context)!.newChat; : L10n.of(context)!.newChat;
case ActiveFilter.groups: case ActiveFilter.groups:
@ -58,15 +64,13 @@ class StartChatFloatingActionButton extends StatelessWidget {
return AnimatedContainer( return AnimatedContainer(
duration: FluffyThemes.animationDuration, duration: FluffyThemes.animationDuration,
curve: FluffyThemes.animationCurve, curve: FluffyThemes.animationCurve,
width: controller.filteredRooms.isEmpty width: roomsIsEmpty
? null ? null
: controller.scrolledToTop : scrolledToTop
? 144 ? 144
: 56, : 56,
child: controller.scrolledToTop child: scrolledToTop
? FloatingActionButton.extended( ? FloatingActionButton.extended(
backgroundColor: Theme.of(context).colorScheme.primary,
foregroundColor: Theme.of(context).colorScheme.onPrimary,
onPressed: () => _onPressed(context), onPressed: () => _onPressed(context),
icon: Icon(icon), icon: Icon(icon),
label: Text( label: Text(
@ -75,8 +79,6 @@ class StartChatFloatingActionButton extends StatelessWidget {
), ),
) )
: FloatingActionButton( : FloatingActionButton(
backgroundColor: Theme.of(context).colorScheme.primary,
foregroundColor: Theme.of(context).colorScheme.onPrimary,
onPressed: () => _onPressed(context), onPressed: () => _onPressed(context),
child: Icon(icon), child: Icon(icon),
), ),

View file

@ -47,11 +47,11 @@ class SettingsStyleController extends State<SettingsStyle> {
static final List<Color?> customColors = [ static final List<Color?> customColors = [
AppConfig.chatColor, AppConfig.chatColor,
Colors.blue.shade800, Colors.indigo,
Colors.green.shade800, Colors.green,
Colors.orange.shade700, Colors.orange,
Colors.pink.shade700, Colors.pink,
Colors.blueGrey.shade600, Colors.blueGrey,
null, null,
]; ];