diff --git a/lib/components/default_bottom_navigation_bar.dart b/lib/components/default_bottom_navigation_bar.dart new file mode 100644 index 00000000..296f2f3d --- /dev/null +++ b/lib/components/default_bottom_navigation_bar.dart @@ -0,0 +1,65 @@ +import 'package:flutter/cupertino.dart'; +import 'package:flutter/material.dart'; +import 'package:adaptive_page_layout/adaptive_page_layout.dart'; +import 'package:flutter_gen/gen_l10n/l10n.dart'; + +class DefaultBottomNavigationBar extends StatelessWidget { + final int currentIndex; + + const DefaultBottomNavigationBar({Key key, this.currentIndex = 1}) + : super(key: key); + @override + Widget build(BuildContext context) { + return BottomNavigationBar( + onTap: (i) { + if (i == currentIndex) return; + switch (i) { + case 0: + AdaptivePageLayout.of(context) + .pushNamedAndRemoveUntilIsFirst('/contacts'); + break; + case 1: + AdaptivePageLayout.of(context).pushNamedAndRemoveAllOthers('/'); + break; + case 2: + AdaptivePageLayout.of(context) + .pushNamedAndRemoveUntilIsFirst('/discover'); + break; + case 3: + AdaptivePageLayout.of(context) + .pushNamedAndRemoveUntilIsFirst('/settings'); + break; + } + }, + backgroundColor: Theme.of(context).scaffoldBackgroundColor, + selectedItemColor: Theme.of(context).accentColor, + currentIndex: currentIndex, + //unselectedItemColor: Theme.of(context).textTheme.bodyText1.color, + type: BottomNavigationBarType.fixed, + showUnselectedLabels: false, + items: [ + BottomNavigationBarItem( + icon: Icon(currentIndex == 0 ? Icons.people : Icons.people_outlined), + label: L10n.of(context).contacts, + ), + BottomNavigationBarItem( + icon: Icon(currentIndex == 1 + ? CupertinoIcons.chat_bubble_2_fill + : CupertinoIcons.chat_bubble_2), + label: L10n.of(context).messages, + ), + BottomNavigationBarItem( + icon: Icon(currentIndex == 2 + ? CupertinoIcons.compass_fill + : CupertinoIcons.compass), + label: L10n.of(context).discover, + ), + BottomNavigationBarItem( + icon: Icon( + currentIndex == 3 ? Icons.settings : Icons.settings_outlined), + label: L10n.of(context).settings, + ), + ], + ); + } +} diff --git a/lib/components/horizontal_stories_list.dart b/lib/components/horizontal_stories_list.dart deleted file mode 100644 index 5436573f..00000000 --- a/lib/components/horizontal_stories_list.dart +++ /dev/null @@ -1,162 +0,0 @@ -import 'dart:async'; - -import 'package:adaptive_dialog/adaptive_dialog.dart'; -import 'package:famedlysdk/famedlysdk.dart'; -import 'package:fluffychat/components/matrix.dart'; -import 'package:flutter/material.dart'; -import 'package:adaptive_page_layout/adaptive_page_layout.dart'; -import '../utils/client_presence_extension.dart'; -import '../utils/presence_extension.dart'; -import 'package:flutter_gen/gen_l10n/l10n.dart'; -import 'avatar.dart'; - -class HorizontalStoriesList extends StatefulWidget { - final String searchQuery; - - const HorizontalStoriesList({Key key, this.searchQuery = ''}) - : super(key: key); - @override - _HorizontalStoriesListState createState() => _HorizontalStoriesListState(); -} - -class _HorizontalStoriesListState extends State { - StreamSubscription _onSync; - - @override - void dispose() { - _onSync?.cancel(); - super.dispose(); - } - - DateTime _lastSetState = DateTime.now(); - Timer _coolDown; - - void _updateView() { - _lastSetState = DateTime.now(); - setState(() => null); - } - - static const double height = 68.0; - - @override - Widget build(BuildContext context) { - _onSync ??= Matrix.of(context).client.onSync.stream.listen((_) { - if (DateTime.now().millisecondsSinceEpoch - - _lastSetState.millisecondsSinceEpoch < - 1000) { - _coolDown?.cancel(); - _coolDown = Timer(Duration(seconds: 1), _updateView); - } else { - _updateView(); - } - }); - final contactList = Matrix.of(context) - .client - .contactList - .where((p) => - p.senderId.toLowerCase().contains(widget.searchQuery.toLowerCase())) - .toList(); - return AnimatedContainer( - height: contactList.isEmpty ? 0 : height, - duration: Duration(milliseconds: 300), - child: contactList.isEmpty - ? null - : ListView.builder( - scrollDirection: Axis.horizontal, - itemCount: contactList.length, - itemBuilder: (context, i) => - _StoriesListTile(story: contactList[i]), - ), - ); - } -} - -class _StoriesListTile extends StatelessWidget { - final Presence story; - - const _StoriesListTile({ - Key key, - @required this.story, - }) : super(key: key); - @override - Widget build(BuildContext context) { - final hasStatusMessage = story.presence.statusMsg?.isNotEmpty ?? false; - return FutureBuilder( - future: Matrix.of(context).client.getProfileFromUserId(story.senderId), - builder: (context, snapshot) { - final displayname = - snapshot.data?.displayname ?? story.senderId.localpart; - final avatarUrl = snapshot.data?.avatarUrl; - return Container( - width: Avatar.defaultSize + 32, - height: _HorizontalStoriesListState.height, - child: InkWell( - borderRadius: BorderRadius.circular(8), - onTap: () async { - if (story.senderId == Matrix.of(context).client.userID) { - await showOkAlertDialog( - context: context, - title: displayname, - message: story.presence.statusMsg, - okLabel: L10n.of(context).close, - ); - return; - } - if (hasStatusMessage) { - if (OkCancelResult.ok != - await showOkCancelAlertDialog( - context: context, - title: displayname, - message: story.presence.statusMsg, - okLabel: L10n.of(context).sendAMessage, - cancelLabel: L10n.of(context).close, - )) { - return; - } - } - final roomId = await Matrix.of(context) - .client - .startDirectChat(story.senderId); - await AdaptivePageLayout.of(context) - .pushNamedAndRemoveUntilIsFirst('/rooms/${roomId}'); - }, - child: Column( - crossAxisAlignment: CrossAxisAlignment.center, - mainAxisAlignment: MainAxisAlignment.center, - children: [ - Container( - width: Avatar.defaultSize, - height: Avatar.defaultSize, - child: Stack( - children: [ - Center(child: Avatar(avatarUrl, displayname)), - Align( - alignment: Alignment.bottomRight, - child: Icon( - Icons.circle, - color: story.color, - size: 12, - ), - ), - ], - ), - ), - Padding( - padding: - const EdgeInsets.only(left: 4.0, right: 4.0, top: 4.0), - child: Text(displayname.split(' ').first, - maxLines: 1, - style: TextStyle( - fontWeight: hasStatusMessage ? FontWeight.bold : null, - color: hasStatusMessage - ? Theme.of(context).accentColor - : null, - )), - ), - ], - ), - ), - ); - }); - } -} diff --git a/lib/config/routes.dart b/lib/config/routes.dart index 5677e8e7..83a3b647 100644 --- a/lib/config/routes.dart +++ b/lib/config/routes.dart @@ -5,6 +5,7 @@ import 'package:fluffychat/views/archive.dart'; import 'package:fluffychat/views/chat.dart'; import 'package:fluffychat/views/chat_details.dart'; import 'package:fluffychat/views/chat_encryption_settings.dart'; +import 'package:fluffychat/views/contacts.dart'; import 'package:fluffychat/views/discover.dart'; import 'package:fluffychat/views/chat_list.dart'; import 'package:fluffychat/views/chat_permissions_settings.dart'; @@ -61,6 +62,7 @@ class FluffyRoutes { } // Routes IF user is logged in else { + final activeRoomId = Matrix.of(context).client.activeRoomId; switch (parts[1]) { case '': return ViewData( @@ -138,11 +140,18 @@ class FluffyRoutes { leftView: (_) => ChatList(), mainView: (_) => NewPrivateChat(), ); + case 'contacts': + return ViewData( + mainView: (_) => Contacts(), + emptyView: (_) => + activeRoomId != null ? Chat(activeRoomId) : EmptyPage(), + ); case 'discover': if (parts.length == 3) { return ViewData( mainView: (_) => Discover(alias: parts[2]), - emptyView: (_) => EmptyPage(), + emptyView: (_) => + activeRoomId != null ? Chat(activeRoomId) : EmptyPage(), ); } return ViewData( @@ -192,12 +201,14 @@ class FluffyRoutes { } else { return ViewData( mainView: (_) => Settings(), - emptyView: (_) => EmptyPage(), + emptyView: (_) => + activeRoomId != null ? Chat(activeRoomId) : EmptyPage(), ); } return ViewData( mainView: (_) => ChatList(), - emptyView: (_) => EmptyPage(), + emptyView: (_) => + activeRoomId != null ? Chat(activeRoomId) : EmptyPage(), ); } } diff --git a/lib/main.dart b/lib/main.dart index d8111cda..2f94be52 100644 --- a/lib/main.dart +++ b/lib/main.dart @@ -78,7 +78,13 @@ class App extends StatelessWidget { dividerColor: Theme.of(context).dividerColor, columnWidth: FluffyThemes.columnWidth, routeBuilder: (builder, settings) => - Matrix.of(context).loginState == LoginState.logged + Matrix.of(context).loginState == LoginState.logged && + !{ + '/', + '/discover', + '/contacts', + '/settings', + }.contains(settings.name) ? CupertinoPageRoute(builder: builder) : FadeRoute(page: builder(context)), ), diff --git a/lib/utils/presence_extension.dart b/lib/utils/presence_extension.dart index 4da61f3c..c9ccc92c 100644 --- a/lib/utils/presence_extension.dart +++ b/lib/utils/presence_extension.dart @@ -4,20 +4,6 @@ import 'package:flutter_gen/gen_l10n/l10n.dart'; import 'date_time_extension.dart'; -extension on PresenceType { - String getLocalized(BuildContext context) { - switch (this) { - case PresenceType.online: - return L10n.of(context).online; - case PresenceType.unavailable: - return L10n.of(context).unavailable; - case PresenceType.offline: - default: - return L10n.of(context).offline; - } - } -} - extension PresenceExtension on Presence { String getLocalizedLastActiveAgo(BuildContext context) { if (presence.lastActiveAgo != null && presence.lastActiveAgo != 0) { @@ -35,7 +21,7 @@ extension PresenceExtension on Presence { if (presence.currentlyActive ?? false) { return L10n.of(context).currentlyActive; } - return presence.presence.getLocalized(context); + return getLocalizedLastActiveAgo(context); } Color get color { diff --git a/lib/views/chat_list.dart b/lib/views/chat_list.dart index c8ae866f..87ba913d 100644 --- a/lib/views/chat_list.dart +++ b/lib/views/chat_list.dart @@ -6,9 +6,8 @@ import 'package:adaptive_page_layout/adaptive_page_layout.dart'; import 'package:famedlysdk/famedlysdk.dart'; import 'package:fluffychat/components/connection_status_header.dart'; import 'package:fluffychat/components/default_app_bar_search_field.dart'; -import 'package:fluffychat/components/horizontal_stories_list.dart'; +import 'package:fluffychat/components/default_bottom_navigation_bar.dart'; import 'package:fluffychat/components/list_items/chat_list_item.dart'; -import 'package:fluffychat/utils/fluffy_share.dart'; import 'package:flutter/cupertino.dart'; import 'package:fluffychat/app_config.dart'; import 'package:fluffychat/utils/platform_infos.dart'; @@ -105,51 +104,6 @@ class _ChatListState extends State { super.dispose(); } - void _onPopupMenuButtonSelect(ChatListPopupMenuItemActions action) { - switch (action) { - case ChatListPopupMenuItemActions.createGroup: - AdaptivePageLayout.of(context).pushNamed('/newgroup'); - break; - case ChatListPopupMenuItemActions.discover: - AdaptivePageLayout.of(context).pushNamed('/discover'); - break; - case ChatListPopupMenuItemActions.setStatus: - _setStatus(); - break; - case ChatListPopupMenuItemActions.inviteContact: - FluffyShare.share( - L10n.of(context).inviteText(Matrix.of(context).client.userID, - 'https://matrix.to/#/${Matrix.of(context).client.userID}'), - context); - break; - case ChatListPopupMenuItemActions.settings: - AdaptivePageLayout.of(context).pushNamed('/settings'); - break; - } - } - - void _setStatus() async { - final input = await showTextInputDialog( - context: context, - title: L10n.of(context).setStatus, - okLabel: L10n.of(context).ok, - cancelLabel: L10n.of(context).cancel, - textFields: [ - DialogTextField( - hintText: L10n.of(context).statusExampleMessage, - ), - ]); - if (input == null) return; - await showFutureLoadingDialog( - context: context, - future: () => Matrix.of(context).client.sendPresence( - Matrix.of(context).client.userID, - PresenceType.online, - statusMsg: input.single, - ), - ); - } - void _toggleSelection(String roomId) { setState(() => _selectedRoomIds.contains(roomId) ? _selectedRoomIds.remove(roomId) @@ -231,6 +185,7 @@ class _ChatListState extends State { return Scaffold( appBar: appBar ?? AppBar( + elevation: 1, leading: selectMode == SelectMode.normal ? null : IconButton( @@ -299,66 +254,6 @@ class _ChatListState extends State { ); }, ), - PopupMenuButton( - onSelected: _onPopupMenuButtonSelect, - itemBuilder: (_) => [ - PopupMenuItem( - value: ChatListPopupMenuItemActions - .createGroup, - child: Row( - children: [ - Icon(Icons.group_add_outlined), - SizedBox(width: 12), - Text(L10n.of(context).createNewGroup), - ], - ), - ), - PopupMenuItem( - value: - ChatListPopupMenuItemActions.discover, - child: Row( - children: [ - Icon(Icons.group_work_outlined), - SizedBox(width: 12), - Text(L10n.of(context).discoverGroups), - ], - ), - ), - PopupMenuItem( - value: - ChatListPopupMenuItemActions.setStatus, - child: Row( - children: [ - Icon(Icons.edit_outlined), - SizedBox(width: 12), - Text(L10n.of(context).setStatus), - ], - ), - ), - PopupMenuItem( - value: ChatListPopupMenuItemActions - .inviteContact, - child: Row( - children: [ - Icon(Icons.share_outlined), - SizedBox(width: 12), - Text(L10n.of(context).inviteContact), - ], - ), - ), - PopupMenuItem( - value: - ChatListPopupMenuItemActions.settings, - child: Row( - children: [ - Icon(Icons.settings_outlined), - SizedBox(width: 12), - Text(L10n.of(context).settings), - ], - ), - ), - ], - ), ], title: Text(selectMode == SelectMode.share ? L10n.of(context).share @@ -422,32 +317,16 @@ class _ChatListState extends State { itemCount: totalCount + 1, itemBuilder: (BuildContext context, int i) => i == 0 - ? Column( - mainAxisSize: MainAxisSize.min, - children: [ - Padding( - padding: EdgeInsets.all(12), - child: DefaultAppBarSearchField( - key: _searchFieldKey, - hintText: L10n.of(context).search, - prefixIcon: - Icon(Icons.search_outlined), - searchController: searchController, - onChanged: (_) => - setState(() => null), - padding: EdgeInsets.zero, - ), - ), - if (selectMode == SelectMode.normal) - Padding( - padding: - const EdgeInsets.only(top: 4.0), - child: HorizontalStoriesList( - searchQuery: - searchController.text, - ), - ), - ], + ? Padding( + padding: EdgeInsets.all(12), + child: DefaultAppBarSearchField( + key: _searchFieldKey, + hintText: L10n.of(context).search, + prefixIcon: Icon(Icons.search_outlined), + searchController: searchController, + onChanged: (_) => setState(() => null), + padding: EdgeInsets.zero, + ), ) : ChatListItem( rooms[i - 1], @@ -473,11 +352,18 @@ class _ChatListState extends State { }), ), ]), - floatingActionButton: FloatingActionButton( - child: Icon(Icons.add_outlined), - onPressed: () => AdaptivePageLayout.of(context) - .pushNamedAndRemoveUntilIsFirst('/newprivatechat'), - ), + floatingActionButton: selectMode == SelectMode.normal + ? FloatingActionButton( + child: Icon(Icons.add_outlined), + onPressed: () => AdaptivePageLayout.of(context) + .pushNamedAndRemoveUntilIsFirst('/newprivatechat'), + ) + : null, + floatingActionButtonLocation: + FloatingActionButtonLocation.centerDocked, + bottomNavigationBar: selectMode == SelectMode.normal + ? DefaultBottomNavigationBar(currentIndex: 1) + : null, ); }); } diff --git a/lib/views/contacts.dart b/lib/views/contacts.dart new file mode 100644 index 00000000..eb552882 --- /dev/null +++ b/lib/views/contacts.dart @@ -0,0 +1,204 @@ +import 'dart:async'; + +import 'package:adaptive_dialog/adaptive_dialog.dart'; +import 'package:famedlysdk/famedlysdk.dart'; +import 'package:fluffychat/components/avatar.dart'; +import 'package:fluffychat/components/default_app_bar_search_field.dart'; +import 'package:fluffychat/components/default_bottom_navigation_bar.dart'; +import 'package:fluffychat/components/matrix.dart'; +import 'package:fluffychat/utils/fluffy_share.dart'; +import 'package:flutter/material.dart'; +import 'package:flutter_gen/gen_l10n/l10n.dart'; +import 'package:future_loading_dialog/future_loading_dialog.dart'; +import '../utils/client_presence_extension.dart'; +import '../utils/presence_extension.dart'; +import 'package:adaptive_page_layout/adaptive_page_layout.dart'; + +class Contacts extends StatefulWidget { + @override + _ContactsState createState() => _ContactsState(); +} + +class _ContactsState extends State { + StreamSubscription _onSync; + final TextEditingController _controller = TextEditingController(); + + @override + void dispose() { + _onSync?.cancel(); + super.dispose(); + } + + DateTime _lastSetState = DateTime.now(); + Timer _coolDown; + + void _updateView() { + _lastSetState = DateTime.now(); + setState(() => null); + } + + void _setStatus(BuildContext context) async { + final input = await showTextInputDialog( + context: context, + title: L10n.of(context).setStatus, + okLabel: L10n.of(context).ok, + cancelLabel: L10n.of(context).cancel, + textFields: [ + DialogTextField( + hintText: L10n.of(context).statusExampleMessage, + ), + ]); + if (input == null) return; + await showFutureLoadingDialog( + context: context, + future: () => Matrix.of(context).client.sendPresence( + Matrix.of(context).client.userID, + PresenceType.online, + statusMsg: input.single, + ), + ); + } + + @override + Widget build(BuildContext context) { + _onSync ??= Matrix.of(context).client.onSync.stream.listen((_) { + if (DateTime.now().millisecondsSinceEpoch - + _lastSetState.millisecondsSinceEpoch < + 1000) { + _coolDown?.cancel(); + _coolDown = Timer(Duration(seconds: 1), _updateView); + } else { + _updateView(); + } + }); + final contactList = Matrix.of(context) + .client + .contactList + .where((p) => + p.senderId.toLowerCase().contains(_controller.text.toLowerCase())) + .toList(); + return Scaffold( + appBar: AppBar( + automaticallyImplyLeading: false, + elevation: 1, + title: Text(L10n.of(context).contacts), + actions: [ + TextButton.icon( + label: Text( + L10n.of(context).status, + style: TextStyle(color: Theme.of(context).accentColor), + ), + icon: + Icon(Icons.edit_outlined, color: Theme.of(context).accentColor), + onPressed: () => _setStatus(context), + ), + ], + ), + body: ListView.builder( + itemCount: contactList.length + 1, + itemBuilder: (_, i) => i == 0 + ? Column( + mainAxisSize: MainAxisSize.min, + children: [ + Padding( + padding: EdgeInsets.all(12), + child: DefaultAppBarSearchField( + hintText: L10n.of(context).search, + prefixIcon: Icon(Icons.search_outlined), + searchController: _controller, + onChanged: (_) => setState(() => null), + padding: EdgeInsets.zero, + ), + ), + ListTile( + leading: CircleAvatar( + radius: Avatar.defaultSize / 2, + child: Icon(Icons.person_add_outlined), + backgroundColor: Theme.of(context).primaryColor, + foregroundColor: Colors.white, + ), + title: Text(L10n.of(context).addNewContact), + onTap: () => AdaptivePageLayout.of(context) + .pushNamed('/newprivatechat'), + ), + Divider(height: 1), + if (contactList.isEmpty) + Column( + mainAxisAlignment: MainAxisAlignment.center, + mainAxisSize: MainAxisSize.min, + children: [ + SizedBox(height: 16), + Icon( + Icons.share_outlined, + size: 80, + color: Colors.grey, + ), + Center( + child: RaisedButton( + elevation: 7, + color: Theme.of(context).scaffoldBackgroundColor, + shape: RoundedRectangleBorder( + borderRadius: BorderRadius.circular(6), + ), + child: Text( + L10n.of(context).inviteContact, + style: TextStyle( + color: Theme.of(context).accentColor), + ), + onPressed: () => FluffyShare.share( + L10n.of(context).inviteText( + Matrix.of(context).client.userID, + 'https://matrix.to/#/${Matrix.of(context).client.userID}'), + context), + ), + ), + ], + ), + ], + ) + : _ContactListTile(contact: contactList[i - 1]), + ), + bottomNavigationBar: DefaultBottomNavigationBar(currentIndex: 0), + ); + } +} + +class _ContactListTile extends StatelessWidget { + final Presence contact; + + const _ContactListTile({Key key, @required this.contact}) : super(key: key); + @override + Widget build(BuildContext context) { + return FutureBuilder( + future: + Matrix.of(context).client.getProfileFromUserId(contact.senderId), + builder: (context, snapshot) { + final displayname = + snapshot.data?.displayname ?? contact.senderId.localpart; + final avatarUrl = snapshot.data?.avatarUrl; + return ListTile( + leading: Container( + width: Avatar.defaultSize, + height: Avatar.defaultSize, + child: Stack( + children: [ + Center(child: Avatar(avatarUrl, displayname)), + Align( + alignment: Alignment.bottomRight, + child: Icon( + Icons.circle, + color: contact.color, + size: 12, + ), + ), + ], + ), + ), + title: Text(displayname), + subtitle: Text(contact.getLocalizedStatusMessage(context)), + onTap: () => AdaptivePageLayout.of(context).pushNamed( + '/rooms/${Matrix.of(context).client.getDirectChatFromUserId(contact.senderId)}'), + ); + }); + } +} diff --git a/lib/views/discover.dart b/lib/views/discover.dart index 6176607d..89e2f7b8 100644 --- a/lib/views/discover.dart +++ b/lib/views/discover.dart @@ -5,6 +5,7 @@ import 'package:adaptive_page_layout/adaptive_page_layout.dart'; import 'package:famedlysdk/famedlysdk.dart'; import 'package:fluffychat/components/avatar.dart'; import 'package:fluffychat/components/default_app_bar_search_field.dart'; +import 'package:fluffychat/components/default_bottom_navigation_bar.dart'; import 'package:future_loading_dialog/future_loading_dialog.dart'; import 'package:fluffychat/components/matrix.dart'; import 'package:flutter/material.dart'; @@ -148,12 +149,18 @@ class _DiscoverState extends State { }); return Scaffold( appBar: AppBar( + elevation: 1, + automaticallyImplyLeading: false, title: Text(L10n.of(context).discoverGroups), actions: [ - FlatButton( - child: Text( + TextButton.icon( + label: Text( server ?? Matrix.of(context).client.userID.domain, - style: TextStyle(color: Theme.of(context).primaryColor), + style: TextStyle(color: Theme.of(context).accentColor), + ), + icon: Icon( + Icons.edit_outlined, + color: Theme.of(context).accentColor, ), onPressed: () => _setServer(context), ), @@ -287,6 +294,7 @@ class _DiscoverState extends State { }), ], ), + bottomNavigationBar: DefaultBottomNavigationBar(currentIndex: 2), ); } } diff --git a/lib/views/settings.dart b/lib/views/settings.dart index 4b9f2a00..c787677c 100644 --- a/lib/views/settings.dart +++ b/lib/views/settings.dart @@ -2,6 +2,7 @@ import 'dart:async'; import 'package:adaptive_dialog/adaptive_dialog.dart'; import 'package:adaptive_page_layout/adaptive_page_layout.dart'; +import 'package:fluffychat/components/default_bottom_navigation_bar.dart'; import 'package:fluffychat/components/dialogs/bootstrap_dialog.dart'; import 'package:fluffychat/components/sentry_switch_list_tile.dart'; import 'package:fluffychat/components/settings_switch_list_tile.dart'; @@ -349,8 +350,8 @@ class _SettingsState extends State { headerSliverBuilder: (BuildContext context, bool innerBoxIsScrolled) => [ SliverAppBar( - elevation: Theme.of(context).appBarTheme.elevation, - leading: BackButton(), + elevation: 1, + automaticallyImplyLeading: false, expandedHeight: 300.0, floating: true, pinned: true, @@ -578,6 +579,7 @@ class _SettingsState extends State { ], ), ), + bottomNavigationBar: DefaultBottomNavigationBar(currentIndex: 3), ); } }