feat: New chat background colors and chatlist design

This commit is contained in:
Christian Pauly 2021-08-29 11:29:14 +02:00
parent 4598d738f2
commit 114685ef87
8 changed files with 92 additions and 48 deletions

View File

@ -51,6 +51,17 @@ class ChatListController extends State<ChatList> {
String _activeSpaceId; String _activeSpaceId;
String get activeSpaceId => _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) { void setActiveSpaceId(BuildContext context, String spaceId) {
Scaffold.of(context).openEndDrawer(); Scaffold.of(context).openEndDrawer();
@ -156,6 +167,7 @@ class ChatListController extends State<ChatList> {
WidgetsBinding.instance.addPostFrameCallback( WidgetsBinding.instance.addPostFrameCallback(
(_) => waitForFirstSync().then((_) => checkBootstrap()), (_) => waitForFirstSync().then((_) => checkBootstrap()),
); );
scrollController.addListener(_onScroll);
super.initState(); super.initState();
} }
@ -181,6 +193,7 @@ class ChatListController extends State<ChatList> {
_intentDataStreamSubscription?.cancel(); _intentDataStreamSubscription?.cancel();
_intentFileStreamSubscription?.cancel(); _intentFileStreamSubscription?.cancel();
_intentUriStreamSubscription?.cancel(); _intentUriStreamSubscription?.cancel();
scrollController.removeListener(_onScroll);
super.dispose(); super.dispose();
} }

View File

@ -31,6 +31,7 @@ class ChatListView extends StatelessWidget {
}, },
child: Scaffold( child: Scaffold(
appBar: AppBar( appBar: AppBar(
elevation: controller.scrolledToTop ? 0 : null,
actionsIconTheme: IconThemeData( actionsIconTheme: IconThemeData(
color: controller.selectedRoomIds.isEmpty color: controller.selectedRoomIds.isEmpty
? null ? null
@ -200,12 +201,20 @@ class ChatListView extends StatelessWidget {
Expanded(child: _ChatListViewBody(controller)), Expanded(child: _ChatListViewBody(controller)),
]), ]),
floatingActionButton: selectMode == SelectMode.normal floatingActionButton: selectMode == SelectMode.normal
? FloatingActionButton( ? controller.scrolledToTop
heroTag: 'main_fab', ? FloatingActionButton.extended(
onPressed: () => heroTag: 'main_fab',
VRouter.of(context).to('/newprivatechat'), onPressed: () =>
child: Icon(CupertinoIcons.chat_bubble), 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, : null,
drawer: controller.spaces.isEmpty drawer: controller.spaces.isEmpty
? null ? null
@ -307,6 +316,7 @@ class _ChatListViewBody extends StatelessWidget {
); );
} }
return ListView.builder( return ListView.builder(
controller: controller.scrollController,
itemCount: rooms.length, itemCount: rooms.length,
itemBuilder: (BuildContext context, int i) { itemBuilder: (BuildContext context, int i) {
return ChatListItem( return ChatListItem(

View File

@ -2,6 +2,7 @@ import 'dart:ui';
import 'package:emoji_picker_flutter/emoji_picker_flutter.dart'; import 'package:emoji_picker_flutter/emoji_picker_flutter.dart';
import 'package:fluffychat/config/app_config.dart'; import 'package:fluffychat/config/app_config.dart';
import 'package:fluffychat/widgets/background_gradient_box.dart';
import 'package:matrix/matrix.dart'; import 'package:matrix/matrix.dart';
import 'package:fluffychat/pages/chat.dart'; import 'package:fluffychat/pages/chat.dart';
import 'package:fluffychat/widgets/avatar.dart'; import 'package:fluffychat/widgets/avatar.dart';
@ -204,6 +205,7 @@ class ChatView extends StatelessWidget {
: null, : null,
body: Stack( body: Stack(
children: <Widget>[ children: <Widget>[
BackgroundGradientBox(),
if (Matrix.of(context).wallpaper != null) if (Matrix.of(context).wallpaper != null)
Image.file( Image.file(
Matrix.of(context).wallpaper, Matrix.of(context).wallpaper,

View File

@ -1,5 +1,6 @@
import 'dart:math'; import 'dart:math';
import 'package:fluffychat/widgets/background_gradient_box.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
class EmptyPage extends StatelessWidget { class EmptyPage extends StatelessWidget {
@ -10,26 +11,31 @@ class EmptyPage extends StatelessWidget {
Widget build(BuildContext context) { Widget build(BuildContext context) {
final _width = min(MediaQuery.of(context).size.width, EmptyPage._width); final _width = min(MediaQuery.of(context).size.width, EmptyPage._width);
return Scaffold( return Scaffold(
body: Column( body: Stack(
mainAxisAlignment: MainAxisAlignment.center,
children: [ children: [
Center( BackgroundGradientBox(),
child: Hero( Column(
tag: 'info-logo', mainAxisAlignment: MainAxisAlignment.center,
child: Image.asset( children: [
'assets/info-logo.png', Center(
width: _width, child: Hero(
height: _width, 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(),
),
),
], ],
), ),
); );

View File

@ -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,
);
}
}

View File

@ -54,7 +54,7 @@ class Message extends StatelessWidget {
final client = Matrix.of(context).client; final client = Matrix.of(context).client;
final ownMessage = event.senderId == client.userID; final ownMessage = event.senderId == client.userID;
final alignment = ownMessage ? Alignment.topRight : Alignment.topLeft; final alignment = ownMessage ? Alignment.topRight : Alignment.topLeft;
var color = Theme.of(context).secondaryHeaderColor; var color = Theme.of(context).scaffoldBackgroundColor;
final sameSender = nextEvent != null && final sameSender = nextEvent != null &&
[EventTypes.Message, EventTypes.Sticker].contains(nextEvent.type) [EventTypes.Message, EventTypes.Sticker].contains(nextEvent.type)
? nextEvent.sender.id == event.sender.id ? nextEvent.sender.id == event.sender.id

View File

@ -32,6 +32,7 @@ class StateMessage extends StatelessWidget {
border: Border.all( border: Border.all(
color: Theme.of(context).dividerColor, color: Theme.of(context).dividerColor,
), ),
color: Theme.of(context).scaffoldBackgroundColor,
borderRadius: BorderRadius.circular(AppConfig.borderRadius), borderRadius: BorderRadius.circular(AppConfig.borderRadius),
), ),
child: Column( child: Column(

View File

@ -3,6 +3,8 @@ import 'dart:math';
import 'package:fluffychat/config/themes.dart'; import 'package:fluffychat/config/themes.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import '../background_gradient_box.dart';
class OnePageCard extends StatelessWidget { class OnePageCard extends StatelessWidget {
final Widget child; final Widget child;
@ -16,32 +18,16 @@ class OnePageCard extends StatelessWidget {
? child ? child
: Material( : Material(
color: Theme.of(context).backgroundColor, color: Theme.of(context).backgroundColor,
child: Container( child: BackgroundGradientBox(
decoration: BoxDecoration( child: Padding(
gradient: LinearGradient( padding: EdgeInsets.symmetric(
begin: Alignment.topRight, horizontal:
end: Alignment.bottomLeft, max((MediaQuery.of(context).size.width - 600) / 2, 12),
stops: [ vertical:
0.1, max((MediaQuery.of(context).size.height - 800) / 2, 12),
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: 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)),
), ),
); );
} }