feat: Added info tile and wrapped channel list and channel header
This commit is contained in:
+76
-45
@@ -3,6 +3,7 @@ import 'package:stream_chat/stream_chat.dart';
|
||||
import 'package:stream_chat_flutter/src/back_button.dart';
|
||||
import 'package:stream_chat_flutter/src/channel_info.dart';
|
||||
import 'package:stream_chat_flutter/src/channel_name.dart';
|
||||
import 'package:stream_chat_flutter/src/info_tile.dart';
|
||||
import 'package:stream_chat_flutter/src/stream_chat_theme.dart';
|
||||
|
||||
import '../stream_chat_flutter.dart';
|
||||
@@ -82,54 +83,84 @@ class ChannelHeader extends StatelessWidget implements PreferredSizeWidget {
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final channel = StreamChannel.of(context).channel;
|
||||
return AppBar(
|
||||
brightness: Theme.of(context).brightness,
|
||||
elevation: 1,
|
||||
leading: showBackButton
|
||||
? StreamBackButton(
|
||||
onPressed: onBackPressed,
|
||||
showUnreads: true,
|
||||
)
|
||||
: SizedBox(),
|
||||
backgroundColor:
|
||||
StreamChatTheme.of(context).channelTheme.channelHeaderTheme.color,
|
||||
actions: <Widget>[
|
||||
Padding(
|
||||
padding: const EdgeInsets.only(right: 10.0),
|
||||
child: Center(
|
||||
child: ChannelImage(
|
||||
onTap: onImageTap,
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
centerTitle: true,
|
||||
title: InkWell(
|
||||
onTap: onTitleTap,
|
||||
child: Container(
|
||||
height: preferredSize.height,
|
||||
width: preferredSize.width,
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.center,
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
children: <Widget>[
|
||||
ChannelName(
|
||||
textStyle: StreamChatTheme.of(context)
|
||||
.channelTheme
|
||||
.channelHeaderTheme
|
||||
.title,
|
||||
),
|
||||
SizedBox(height: 2),
|
||||
ChannelInfo(
|
||||
showTypingIndicator: showTypingIndicator,
|
||||
channel: channel,
|
||||
textStyle:
|
||||
StreamChatTheme.of(context).channelPreviewTheme.subtitle,
|
||||
final _client = StreamChat.of(context).client;
|
||||
|
||||
return ValueListenableBuilder<ConnectionStatus>(
|
||||
valueListenable: _client.wsConnectionStatus,
|
||||
builder: (context, status, _) {
|
||||
String statusString = '';
|
||||
bool showStatus = true;
|
||||
|
||||
switch (status) {
|
||||
case ConnectionStatus.connected:
|
||||
statusString = 'Connected';
|
||||
showStatus = false;
|
||||
break;
|
||||
case ConnectionStatus.connecting:
|
||||
statusString = 'Connecting';
|
||||
break;
|
||||
case ConnectionStatus.disconnected:
|
||||
statusString = 'Disconnected';
|
||||
break;
|
||||
}
|
||||
|
||||
return InfoTile(
|
||||
showMessage: showStatus,
|
||||
message: statusString,
|
||||
child: AppBar(
|
||||
brightness: Theme.of(context).brightness,
|
||||
elevation: 1,
|
||||
leading: showBackButton
|
||||
? StreamBackButton(
|
||||
onPressed: onBackPressed,
|
||||
showUnreads: true,
|
||||
)
|
||||
: SizedBox(),
|
||||
backgroundColor: StreamChatTheme.of(context)
|
||||
.channelTheme
|
||||
.channelHeaderTheme
|
||||
.color,
|
||||
actions: <Widget>[
|
||||
Padding(
|
||||
padding: const EdgeInsets.only(right: 10.0),
|
||||
child: Center(
|
||||
child: ChannelImage(
|
||||
onTap: onImageTap,
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
centerTitle: true,
|
||||
title: InkWell(
|
||||
onTap: onTitleTap,
|
||||
child: Container(
|
||||
height: preferredSize.height,
|
||||
width: preferredSize.width,
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.center,
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
children: <Widget>[
|
||||
ChannelName(
|
||||
textStyle: StreamChatTheme.of(context)
|
||||
.channelTheme
|
||||
.channelHeaderTheme
|
||||
.title,
|
||||
),
|
||||
SizedBox(height: 2),
|
||||
ChannelInfo(
|
||||
showTypingIndicator: showTypingIndicator,
|
||||
channel: channel,
|
||||
textStyle: StreamChatTheme.of(context)
|
||||
.channelPreviewTheme
|
||||
.subtitle,
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
@@ -6,6 +6,7 @@ import 'package:stream_chat/stream_chat.dart';
|
||||
import 'package:stream_chat_flutter/src/stream_neumorphic_button.dart';
|
||||
import 'package:stream_chat_flutter/stream_chat_flutter.dart';
|
||||
|
||||
import 'info_tile.dart';
|
||||
import 'stream_chat.dart';
|
||||
|
||||
typedef _TitleBuilder = Widget Function(
|
||||
@@ -72,73 +73,101 @@ class ChannelListHeader extends StatelessWidget implements PreferredSizeWidget {
|
||||
Widget build(BuildContext context) {
|
||||
final _client = client ?? StreamChat.of(context).client;
|
||||
final user = _client.state.user;
|
||||
return AppBar(
|
||||
brightness: Theme.of(context).brightness,
|
||||
elevation: 1,
|
||||
backgroundColor:
|
||||
StreamChatTheme.of(context).channelTheme.channelHeaderTheme.color,
|
||||
centerTitle: true,
|
||||
leading: Center(
|
||||
child: UserAvatar(
|
||||
user: user,
|
||||
showOnlineStatus: false,
|
||||
onTap: onUserAvatarTap ?? (_) => Scaffold.of(context).openDrawer(),
|
||||
borderRadius: BorderRadius.circular(20),
|
||||
constraints: BoxConstraints.tightFor(
|
||||
height: 40,
|
||||
width: 40,
|
||||
),
|
||||
),
|
||||
),
|
||||
actions: [
|
||||
StreamNeumorphicButton(
|
||||
child: IconButton(
|
||||
icon: ValueListenableBuilder<ConnectionStatus>(
|
||||
valueListenable: _client.wsConnectionStatus,
|
||||
builder: (context, status, child) {
|
||||
var color;
|
||||
return ValueListenableBuilder<ConnectionStatus>(
|
||||
valueListenable: _client.wsConnectionStatus,
|
||||
builder: (context, status, child) {
|
||||
String statusString = '';
|
||||
bool showStatus = true;
|
||||
|
||||
switch (status) {
|
||||
case ConnectionStatus.connected:
|
||||
statusString = 'Connected';
|
||||
showStatus = false;
|
||||
break;
|
||||
case ConnectionStatus.connecting:
|
||||
statusString = 'Connecting';
|
||||
break;
|
||||
case ConnectionStatus.disconnected:
|
||||
statusString = 'Disconnected';
|
||||
break;
|
||||
}
|
||||
|
||||
return InfoTile(
|
||||
showMessage: showStatus,
|
||||
message: statusString,
|
||||
child: AppBar(
|
||||
brightness: Theme.of(context).brightness,
|
||||
elevation: 1,
|
||||
backgroundColor: StreamChatTheme.of(context)
|
||||
.channelTheme
|
||||
.channelHeaderTheme
|
||||
.color,
|
||||
centerTitle: true,
|
||||
leading: Center(
|
||||
child: UserAvatar(
|
||||
user: user,
|
||||
showOnlineStatus: false,
|
||||
onTap:
|
||||
onUserAvatarTap ?? (_) => Scaffold.of(context).openDrawer(),
|
||||
borderRadius: BorderRadius.circular(20),
|
||||
constraints: BoxConstraints.tightFor(
|
||||
height: 40,
|
||||
width: 40,
|
||||
),
|
||||
),
|
||||
),
|
||||
actions: [
|
||||
StreamNeumorphicButton(
|
||||
child: IconButton(
|
||||
icon: ValueListenableBuilder<ConnectionStatus>(
|
||||
valueListenable: _client.wsConnectionStatus,
|
||||
builder: (context, status, child) {
|
||||
var color;
|
||||
switch (status) {
|
||||
case ConnectionStatus.connected:
|
||||
color =
|
||||
StreamChatTheme.of(context).colorTheme.accentBlue;
|
||||
break;
|
||||
case ConnectionStatus.connecting:
|
||||
color = Colors.grey;
|
||||
break;
|
||||
case ConnectionStatus.disconnected:
|
||||
color = Colors.grey;
|
||||
break;
|
||||
}
|
||||
return SvgPicture.asset(
|
||||
'svgs/icon_pen_write.svg',
|
||||
package: 'stream_chat_flutter',
|
||||
width: 24.0,
|
||||
height: 24.0,
|
||||
color: color,
|
||||
);
|
||||
},
|
||||
),
|
||||
onPressed: onNewChatButtonTap,
|
||||
),
|
||||
)
|
||||
],
|
||||
title: Builder(
|
||||
builder: (context) {
|
||||
if (titleBuilder != null) {
|
||||
return titleBuilder(context, status, _client);
|
||||
}
|
||||
switch (status) {
|
||||
case ConnectionStatus.connected:
|
||||
color = StreamChatTheme.of(context).colorTheme.accentBlue;
|
||||
break;
|
||||
return _buildConnectedTitleState(context);
|
||||
case ConnectionStatus.connecting:
|
||||
color = Colors.grey;
|
||||
break;
|
||||
return _buildConnectingTitleState(context);
|
||||
case ConnectionStatus.disconnected:
|
||||
color = Colors.grey;
|
||||
break;
|
||||
return _buildDisconnectedTitleState(context, _client);
|
||||
default:
|
||||
return Offstage();
|
||||
}
|
||||
return SvgPicture.asset(
|
||||
'svgs/icon_pen_write.svg',
|
||||
package: 'stream_chat_flutter',
|
||||
width: 24.0,
|
||||
height: 24.0,
|
||||
color: color,
|
||||
);
|
||||
},
|
||||
),
|
||||
onPressed: onNewChatButtonTap,
|
||||
),
|
||||
)
|
||||
],
|
||||
title: ValueListenableBuilder<ConnectionStatus>(
|
||||
valueListenable: _client.wsConnectionStatus,
|
||||
builder: (context, status, child) {
|
||||
if (titleBuilder != null) {
|
||||
return titleBuilder(context, status, _client);
|
||||
}
|
||||
switch (status) {
|
||||
case ConnectionStatus.connected:
|
||||
return _buildConnectedTitleState(context);
|
||||
case ConnectionStatus.connecting:
|
||||
return _buildConnectingTitleState(context);
|
||||
case ConnectionStatus.disconnected:
|
||||
return _buildDisconnectedTitleState(context, _client);
|
||||
default:
|
||||
return Offstage();
|
||||
}
|
||||
},
|
||||
),
|
||||
);
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,35 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_portal/flutter_portal.dart';
|
||||
import 'package:stream_chat_flutter/src/stream_chat_theme.dart';
|
||||
|
||||
class InfoTile extends StatelessWidget {
|
||||
final String message;
|
||||
final Widget child;
|
||||
final bool showMessage;
|
||||
|
||||
InfoTile({this.message, this.child, this.showMessage});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return PortalEntry(
|
||||
visible: showMessage,
|
||||
portalAnchor: Alignment.topCenter,
|
||||
childAnchor: Alignment.bottomCenter,
|
||||
portal: Container(
|
||||
height: 25.0,
|
||||
color: StreamChatTheme.of(context).colorTheme.grey,
|
||||
child: Center(
|
||||
child: Text(
|
||||
message,
|
||||
style: StreamChatTheme.of(context).textTheme.body.copyWith(
|
||||
color: Colors.white,
|
||||
),
|
||||
maxLines: 1,
|
||||
overflow: TextOverflow.ellipsis,
|
||||
),
|
||||
),
|
||||
),
|
||||
child: child,
|
||||
);
|
||||
}
|
||||
}
|
||||
+19
-16
@@ -3,6 +3,7 @@ import 'dart:async';
|
||||
import 'package:flutter/foundation.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_app_badger/flutter_app_badger.dart';
|
||||
import 'package:flutter_portal/flutter_portal.dart';
|
||||
import 'package:stream_chat/stream_chat.dart';
|
||||
import 'package:stream_chat_flutter/src/stream_chat_theme.dart';
|
||||
|
||||
@@ -67,22 +68,24 @@ class StreamChatState extends State<StreamChat> with WidgetsBindingObserver {
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final theme = _getTheme(context, widget.streamChatThemeData);
|
||||
return StreamChatTheme(
|
||||
data: theme,
|
||||
child: Builder(
|
||||
builder: (context) {
|
||||
final materialTheme = Theme.of(context);
|
||||
final streamTheme = StreamChatTheme.of(context);
|
||||
return Theme(
|
||||
data: materialTheme.copyWith(
|
||||
primaryIconTheme: streamTheme.primaryIconTheme,
|
||||
accentColor: streamTheme.colorTheme.accentBlue,
|
||||
scaffoldBackgroundColor: streamTheme.colorTheme.white,
|
||||
buttonTheme: streamTheme.buttonTheme,
|
||||
),
|
||||
child: widget.child,
|
||||
);
|
||||
},
|
||||
return Portal(
|
||||
child: StreamChatTheme(
|
||||
data: theme,
|
||||
child: Builder(
|
||||
builder: (context) {
|
||||
final materialTheme = Theme.of(context);
|
||||
final streamTheme = StreamChatTheme.of(context);
|
||||
return Theme(
|
||||
data: materialTheme.copyWith(
|
||||
primaryIconTheme: streamTheme.primaryIconTheme,
|
||||
accentColor: streamTheme.colorTheme.accentBlue,
|
||||
scaffoldBackgroundColor: streamTheme.colorTheme.white,
|
||||
buttonTheme: streamTheme.buttonTheme,
|
||||
),
|
||||
child: widget.child,
|
||||
);
|
||||
},
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user