diff --git a/lib/pages/chat_list.dart b/lib/pages/chat_list.dart index 8aeb6a05..00e09e7d 100644 --- a/lib/pages/chat_list.dart +++ b/lib/pages/chat_list.dart @@ -51,6 +51,17 @@ class ChatListController extends State { String _activeSpaceId; String get activeSpaceId => _activeSpaceId; + final ScrollController scrollController = ScrollController(); + bool scrolledToTop = true; + + void _onScroll() { + final newScrolledToTop = scrollController.position.pixels <= 0; + if (newScrolledToTop != scrolledToTop) { + setState(() { + scrolledToTop = newScrolledToTop; + }); + } + } void setActiveSpaceId(BuildContext context, String spaceId) { Scaffold.of(context).openEndDrawer(); @@ -156,6 +167,7 @@ class ChatListController extends State { WidgetsBinding.instance.addPostFrameCallback( (_) => waitForFirstSync().then((_) => checkBootstrap()), ); + scrollController.addListener(_onScroll); super.initState(); } @@ -181,6 +193,7 @@ class ChatListController extends State { _intentDataStreamSubscription?.cancel(); _intentFileStreamSubscription?.cancel(); _intentUriStreamSubscription?.cancel(); + scrollController.removeListener(_onScroll); super.dispose(); } diff --git a/lib/pages/views/chat_list_view.dart b/lib/pages/views/chat_list_view.dart index fb6c4834..5e071581 100644 --- a/lib/pages/views/chat_list_view.dart +++ b/lib/pages/views/chat_list_view.dart @@ -31,6 +31,7 @@ class ChatListView extends StatelessWidget { }, child: Scaffold( appBar: AppBar( + elevation: controller.scrolledToTop ? 0 : null, actionsIconTheme: IconThemeData( color: controller.selectedRoomIds.isEmpty ? null @@ -200,12 +201,20 @@ class ChatListView extends StatelessWidget { Expanded(child: _ChatListViewBody(controller)), ]), floatingActionButton: selectMode == SelectMode.normal - ? FloatingActionButton( - heroTag: 'main_fab', - onPressed: () => - VRouter.of(context).to('/newprivatechat'), - child: Icon(CupertinoIcons.chat_bubble), - ) + ? controller.scrolledToTop + ? FloatingActionButton.extended( + heroTag: 'main_fab', + onPressed: () => + VRouter.of(context).to('/newprivatechat'), + icon: Icon(CupertinoIcons.chat_bubble), + label: Text(L10n.of(context).newChat), + ) + : FloatingActionButton( + heroTag: 'main_fab', + onPressed: () => + VRouter.of(context).to('/newprivatechat'), + child: Icon(CupertinoIcons.chat_bubble), + ) : null, drawer: controller.spaces.isEmpty ? null @@ -307,6 +316,7 @@ class _ChatListViewBody extends StatelessWidget { ); } return ListView.builder( + controller: controller.scrollController, itemCount: rooms.length, itemBuilder: (BuildContext context, int i) { return ChatListItem( diff --git a/lib/pages/views/chat_view.dart b/lib/pages/views/chat_view.dart index 05a25cc2..6b364ec3 100644 --- a/lib/pages/views/chat_view.dart +++ b/lib/pages/views/chat_view.dart @@ -2,6 +2,7 @@ import 'dart:ui'; import 'package:emoji_picker_flutter/emoji_picker_flutter.dart'; import 'package:fluffychat/config/app_config.dart'; +import 'package:fluffychat/widgets/background_gradient_box.dart'; import 'package:matrix/matrix.dart'; import 'package:fluffychat/pages/chat.dart'; import 'package:fluffychat/widgets/avatar.dart'; @@ -204,6 +205,7 @@ class ChatView extends StatelessWidget { : null, body: Stack( children: [ + BackgroundGradientBox(), if (Matrix.of(context).wallpaper != null) Image.file( Matrix.of(context).wallpaper, diff --git a/lib/pages/views/empty_page_view.dart b/lib/pages/views/empty_page_view.dart index 38b104fb..d8de9c24 100644 --- a/lib/pages/views/empty_page_view.dart +++ b/lib/pages/views/empty_page_view.dart @@ -1,5 +1,6 @@ import 'dart:math'; +import 'package:fluffychat/widgets/background_gradient_box.dart'; import 'package:flutter/material.dart'; class EmptyPage extends StatelessWidget { @@ -10,26 +11,31 @@ class EmptyPage extends StatelessWidget { Widget build(BuildContext context) { final _width = min(MediaQuery.of(context).size.width, EmptyPage._width); return Scaffold( - body: Column( - mainAxisAlignment: MainAxisAlignment.center, + body: Stack( children: [ - Center( - child: Hero( - tag: 'info-logo', - child: Image.asset( - 'assets/info-logo.png', - width: _width, - height: _width, + BackgroundGradientBox(), + Column( + mainAxisAlignment: MainAxisAlignment.center, + children: [ + Center( + child: Hero( + tag: 'info-logo', + child: Image.asset( + 'assets/info-logo.png', + width: _width, + height: _width, + ), + ), ), - ), + if (loading) + Center( + child: SizedBox( + width: _width, + child: LinearProgressIndicator(), + ), + ), + ], ), - if (loading) - Center( - child: SizedBox( - width: _width, - child: LinearProgressIndicator(), - ), - ), ], ), ); diff --git a/lib/widgets/background_gradient_box.dart b/lib/widgets/background_gradient_box.dart new file mode 100644 index 00000000..04864c88 --- /dev/null +++ b/lib/widgets/background_gradient_box.dart @@ -0,0 +1,26 @@ +import 'package:flutter/material.dart'; + +class BackgroundGradientBox extends StatelessWidget { + final Widget child; + const BackgroundGradientBox({ + Key key, + this.child, + }) : super(key: key); + + @override + Widget build(BuildContext context) { + return Container( + decoration: BoxDecoration( + gradient: LinearGradient( + begin: Alignment.topRight, + end: Alignment.bottomLeft, + colors: [ + Theme.of(context).scaffoldBackgroundColor, + Theme.of(context).secondaryHeaderColor, + ], + ), + ), + child: child, + ); + } +} diff --git a/lib/widgets/event_content/message.dart b/lib/widgets/event_content/message.dart index e5d04311..482934d2 100644 --- a/lib/widgets/event_content/message.dart +++ b/lib/widgets/event_content/message.dart @@ -54,7 +54,7 @@ class Message extends StatelessWidget { final client = Matrix.of(context).client; final ownMessage = event.senderId == client.userID; final alignment = ownMessage ? Alignment.topRight : Alignment.topLeft; - var color = Theme.of(context).secondaryHeaderColor; + var color = Theme.of(context).scaffoldBackgroundColor; final sameSender = nextEvent != null && [EventTypes.Message, EventTypes.Sticker].contains(nextEvent.type) ? nextEvent.sender.id == event.sender.id diff --git a/lib/widgets/event_content/state_message.dart b/lib/widgets/event_content/state_message.dart index c9767462..66933bbb 100644 --- a/lib/widgets/event_content/state_message.dart +++ b/lib/widgets/event_content/state_message.dart @@ -32,6 +32,7 @@ class StateMessage extends StatelessWidget { border: Border.all( color: Theme.of(context).dividerColor, ), + color: Theme.of(context).scaffoldBackgroundColor, borderRadius: BorderRadius.circular(AppConfig.borderRadius), ), child: Column( diff --git a/lib/widgets/layouts/one_page_card.dart b/lib/widgets/layouts/one_page_card.dart index 283f0dc5..bddb181a 100644 --- a/lib/widgets/layouts/one_page_card.dart +++ b/lib/widgets/layouts/one_page_card.dart @@ -3,6 +3,8 @@ import 'dart:math'; import 'package:fluffychat/config/themes.dart'; import 'package:flutter/material.dart'; +import '../background_gradient_box.dart'; + class OnePageCard extends StatelessWidget { final Widget child; @@ -16,32 +18,16 @@ class OnePageCard extends StatelessWidget { ? child : Material( color: Theme.of(context).backgroundColor, - child: Container( - decoration: BoxDecoration( - gradient: LinearGradient( - begin: Alignment.topRight, - end: Alignment.bottomLeft, - stops: [ - 0.1, - 0.4, - 0.6, - 0.9, - ], - colors: [ - Theme.of(context).secondaryHeaderColor.withAlpha(alpha), - Theme.of(context).primaryColor.withAlpha(alpha), - Theme.of(context).colorScheme.secondary.withAlpha(alpha), - Theme.of(context).backgroundColor.withAlpha(alpha), - ], + child: BackgroundGradientBox( + child: Padding( + padding: EdgeInsets.symmetric( + horizontal: + max((MediaQuery.of(context).size.width - 600) / 2, 12), + vertical: + max((MediaQuery.of(context).size.height - 800) / 2, 12), ), + child: SafeArea(child: Card(elevation: 3, child: child)), ), - padding: EdgeInsets.symmetric( - horizontal: - max((MediaQuery.of(context).size.width - 600) / 2, 12), - vertical: - max((MediaQuery.of(context).size.height - 800) / 2, 12), - ), - child: SafeArea(child: Card(elevation: 7, child: child)), ), ); }