fix tutorial examples
This commit is contained in:
@@ -41,11 +41,12 @@ class MyApp extends StatelessWidget {
|
||||
Widget build(BuildContext context) {
|
||||
final themeData = ThemeData(primarySwatch: Colors.green);
|
||||
final defaultTheme = StreamChatThemeData.fromTheme(themeData);
|
||||
final colorTheme = defaultTheme.colorTheme;
|
||||
final customTheme = defaultTheme.merge(StreamChatThemeData(
|
||||
ownMessageTheme: MessageTheme(
|
||||
messageBackgroundColor: StreamChatTheme.of(context).colorTheme.black,
|
||||
messageBackgroundColor: colorTheme.black,
|
||||
messageText: TextStyle(
|
||||
color: StreamChatTheme.of(context).colorTheme.white,
|
||||
color: colorTheme.white,
|
||||
),
|
||||
avatarTheme: AvatarTheme(
|
||||
borderRadius: BorderRadius.circular(8),
|
||||
|
||||
@@ -80,6 +80,17 @@ class ChannelListPage extends StatelessWidget {
|
||||
final opacity = channel.state.unreadCount > .0 ? 1.0 : 0.5;
|
||||
|
||||
return ListTile(
|
||||
onTap: () {
|
||||
Navigator.push(
|
||||
context,
|
||||
MaterialPageRoute(
|
||||
builder: (_) => StreamChannel(
|
||||
child: ChannelPage(),
|
||||
channel: channel,
|
||||
),
|
||||
),
|
||||
);
|
||||
},
|
||||
leading: ChannelImage(
|
||||
channel: channel,
|
||||
),
|
||||
|
||||
@@ -97,7 +97,7 @@ class ChannelPage extends StatelessWidget {
|
||||
List<Message> messages,
|
||||
) {
|
||||
final message = details.message;
|
||||
final color = details.isMyMessage ? Colors.blueGrey : Colors.blue;
|
||||
final color = details.isMyMessage ? Colors.red : Colors.blue;
|
||||
if (message.isSystem) {
|
||||
return SizedBox();
|
||||
}
|
||||
@@ -110,7 +110,10 @@ class ChannelPage extends StatelessWidget {
|
||||
color: color,
|
||||
width: 2,
|
||||
),
|
||||
padding: const EdgeInsets.all(2),
|
||||
padding: const EdgeInsets.symmetric(
|
||||
vertical: 2,
|
||||
horizontal: 4,
|
||||
),
|
||||
attachmentBorderSide: BorderSide(
|
||||
color: color,
|
||||
width: 2,
|
||||
|
||||
@@ -529,123 +529,97 @@ class _ChannelListViewState extends State<ChannelListView>
|
||||
};
|
||||
}
|
||||
|
||||
final backgroundColor = StreamChatTheme.of(context).colorTheme.whiteSmoke;
|
||||
return StreamChannel(
|
||||
key: ValueKey<String>('CHANNEL-${channel.id}'),
|
||||
channel: channel,
|
||||
child: Builder(
|
||||
builder: (context) {
|
||||
Widget child;
|
||||
if (widget.channelPreviewBuilder != null) {
|
||||
child = Stack(
|
||||
children: [
|
||||
widget.channelPreviewBuilder(
|
||||
context,
|
||||
channel,
|
||||
),
|
||||
Positioned.fill(
|
||||
child: Material(
|
||||
color: Colors.transparent,
|
||||
child: InkWell(
|
||||
onTap: () {
|
||||
onTap(channel, widget.channelWidget);
|
||||
},
|
||||
onLongPress: widget.onChannelLongPress != null
|
||||
? () {
|
||||
widget.onChannelLongPress(channel);
|
||||
}
|
||||
: null,
|
||||
return Slidable(
|
||||
controller: _slideController,
|
||||
enabled: widget.swipeToAction,
|
||||
actionPane: SlidableBehindActionPane(),
|
||||
actionExtentRatio: 0.12,
|
||||
closeOnScroll: true,
|
||||
secondaryActions: <Widget>[
|
||||
IconSlideAction(
|
||||
color: backgroundColor,
|
||||
icon: Icons.more_horiz,
|
||||
onTap: () {
|
||||
showModalBottomSheet(
|
||||
clipBehavior: Clip.hardEdge,
|
||||
shape: RoundedRectangleBorder(
|
||||
borderRadius: BorderRadius.only(
|
||||
topLeft: Radius.circular(32),
|
||||
topRight: Radius.circular(32),
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
);
|
||||
} else {
|
||||
final backgroundColor =
|
||||
StreamChatTheme.of(context).colorTheme.whiteSmoke;
|
||||
child = Slidable(
|
||||
controller: _slideController,
|
||||
enabled: widget.swipeToAction,
|
||||
actionPane: SlidableBehindActionPane(),
|
||||
actionExtentRatio: 0.12,
|
||||
closeOnScroll: true,
|
||||
secondaryActions: <Widget>[
|
||||
context: context,
|
||||
builder: (context) {
|
||||
return StreamChannel(
|
||||
child: ChannelBottomSheet(
|
||||
onViewInfoTap: () {
|
||||
widget.onViewInfoTap(channel);
|
||||
},
|
||||
),
|
||||
channel: channel,
|
||||
);
|
||||
},
|
||||
);
|
||||
},
|
||||
),
|
||||
if ([
|
||||
'admin',
|
||||
'owner',
|
||||
].contains(channel.state.members
|
||||
.firstWhere((m) => m.userId == channel.client.state.user.id,
|
||||
orElse: () => null)
|
||||
?.role))
|
||||
IconSlideAction(
|
||||
color: backgroundColor,
|
||||
icon: Icons.more_horiz,
|
||||
onTap: () {
|
||||
showModalBottomSheet(
|
||||
clipBehavior: Clip.hardEdge,
|
||||
shape: RoundedRectangleBorder(
|
||||
borderRadius: BorderRadius.only(
|
||||
topLeft: Radius.circular(32),
|
||||
topRight: Radius.circular(32),
|
||||
),
|
||||
),
|
||||
context: context,
|
||||
builder: (context) {
|
||||
return StreamChannel(
|
||||
child: ChannelBottomSheet(
|
||||
onViewInfoTap: () {
|
||||
widget.onViewInfoTap(channel);
|
||||
},
|
||||
),
|
||||
channel: channel,
|
||||
);
|
||||
},
|
||||
);
|
||||
},
|
||||
),
|
||||
if ([
|
||||
'admin',
|
||||
'owner',
|
||||
].contains(channel.state.members
|
||||
.firstWhere(
|
||||
(m) => m.userId == channel.client.state.user.id,
|
||||
orElse: () => null)
|
||||
?.role))
|
||||
IconSlideAction(
|
||||
color: backgroundColor,
|
||||
iconWidget: StreamSvgIcon.delete(
|
||||
color: StreamChatTheme.of(context).colorTheme.accentRed,
|
||||
),
|
||||
onTap: () async {
|
||||
final res = await showConfirmationDialog(
|
||||
context,
|
||||
title: 'Delete Conversation',
|
||||
okText: 'DELETE',
|
||||
question:
|
||||
'Are you sure you want to delete this conversation?',
|
||||
cancelText: 'CANCEL',
|
||||
icon: StreamSvgIcon.delete(
|
||||
color: StreamChatTheme.of(context)
|
||||
.colorTheme
|
||||
.accentRed,
|
||||
),
|
||||
);
|
||||
if (res == true) {
|
||||
await channel.delete();
|
||||
}
|
||||
},
|
||||
iconWidget: StreamSvgIcon.delete(
|
||||
color: StreamChatTheme.of(context).colorTheme.accentRed,
|
||||
),
|
||||
],
|
||||
child: Container(
|
||||
color: StreamChatTheme.of(context).colorTheme.whiteSnow,
|
||||
child: ChannelPreview(
|
||||
onLongPress: widget.onChannelLongPress,
|
||||
channel: channel,
|
||||
onImageTap: widget.onImageTap != null
|
||||
? () {
|
||||
widget.onImageTap(channel);
|
||||
}
|
||||
: null,
|
||||
onTap: (channel) {
|
||||
onTap(channel, widget.channelWidget);
|
||||
onTap: () async {
|
||||
final res = await showConfirmationDialog(
|
||||
context,
|
||||
title: 'Delete Conversation',
|
||||
okText: 'DELETE',
|
||||
question:
|
||||
'Are you sure you want to delete this conversation?',
|
||||
cancelText: 'CANCEL',
|
||||
icon: StreamSvgIcon.delete(
|
||||
color:
|
||||
StreamChatTheme.of(context).colorTheme.accentRed,
|
||||
),
|
||||
);
|
||||
if (res == true) {
|
||||
await channel.delete();
|
||||
}
|
||||
},
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
return child;
|
||||
],
|
||||
child: Container(
|
||||
color: StreamChatTheme.of(context).colorTheme.whiteSnow,
|
||||
child: widget.channelPreviewBuilder != null
|
||||
? widget.channelPreviewBuilder(
|
||||
context,
|
||||
channel,
|
||||
)
|
||||
: ChannelPreview(
|
||||
onLongPress: widget.onChannelLongPress,
|
||||
channel: channel,
|
||||
onImageTap: widget.onImageTap != null
|
||||
? () {
|
||||
widget.onImageTap(channel);
|
||||
}
|
||||
: null,
|
||||
onTap: (channel) {
|
||||
onTap(channel, widget.channelWidget);
|
||||
},
|
||||
),
|
||||
),
|
||||
);
|
||||
},
|
||||
),
|
||||
);
|
||||
|
||||
@@ -41,7 +41,7 @@ class _FileAttachmentState extends State<FileAttachment> {
|
||||
@override
|
||||
void initState() {
|
||||
super.initState();
|
||||
if (MediaUtils.getMimeType(widget.attachment.title).type == 'video') {
|
||||
if (MediaUtils.getMimeType(widget.attachment.title)?.type == 'video') {
|
||||
if (widget.attachmentType == FileAttachmentType.online) {
|
||||
_controller = VideoPlayerController.network(
|
||||
widget.attachment.assetUrl,
|
||||
@@ -128,7 +128,7 @@ class _FileAttachmentState extends State<FileAttachment> {
|
||||
}
|
||||
|
||||
Widget _getFileTypeImage() {
|
||||
if ((MediaUtils.getMimeType(widget.attachment.title).type == 'image')) {
|
||||
if ((MediaUtils.getMimeType(widget.attachment.title)?.type == 'image')) {
|
||||
switch (widget.attachmentType) {
|
||||
case FileAttachmentType.local:
|
||||
return Image.memory(
|
||||
@@ -165,7 +165,7 @@ class _FileAttachmentState extends State<FileAttachment> {
|
||||
}
|
||||
}
|
||||
|
||||
if ((MediaUtils.getMimeType(widget.attachment.title).type == 'video')) {
|
||||
if ((MediaUtils.getMimeType(widget.attachment.title)?.type == 'video')) {
|
||||
switch (widget.attachmentType) {
|
||||
case FileAttachmentType.local:
|
||||
return FutureBuilder<File>(
|
||||
|
||||
@@ -159,8 +159,8 @@ class MessageWidget extends StatefulWidget {
|
||||
this.showReactionPickerIndicator = false,
|
||||
this.showUserAvatar = DisplayWidget.show,
|
||||
this.showSendingIndicator = true,
|
||||
this.showThreadReplyIndicator = true,
|
||||
this.showInChannelIndicator = true,
|
||||
this.showThreadReplyIndicator = false,
|
||||
this.showInChannelIndicator = false,
|
||||
this.onReplyTap,
|
||||
this.onThreadTap,
|
||||
this.showUsername = true,
|
||||
@@ -371,15 +371,24 @@ class _MessageWidgetState extends State<MessageWidget> {
|
||||
alignment: Alignment.center,
|
||||
transform: Matrix4.rotationY(
|
||||
widget.reverse ? pi : 0),
|
||||
child: DeletedMessage(
|
||||
reverse: widget.reverse,
|
||||
borderRadiusGeometry: widget
|
||||
.borderRadiusGeometry,
|
||||
borderSide:
|
||||
widget.borderSide,
|
||||
shape: widget.shape,
|
||||
messageTheme:
|
||||
widget.messageTheme,
|
||||
child: Container(
|
||||
margin: EdgeInsets.symmetric(
|
||||
horizontal:
|
||||
widget.showUserAvatar ==
|
||||
DisplayWidget
|
||||
.gone
|
||||
? 0
|
||||
: 4.0),
|
||||
child: DeletedMessage(
|
||||
reverse: widget.reverse,
|
||||
borderRadiusGeometry: widget
|
||||
.borderRadiusGeometry,
|
||||
borderSide:
|
||||
widget.borderSide,
|
||||
shape: widget.shape,
|
||||
messageTheme:
|
||||
widget.messageTheme,
|
||||
),
|
||||
),
|
||||
)
|
||||
: Card(
|
||||
|
||||
@@ -67,7 +67,7 @@ class ReactionBubble extends StatelessWidget {
|
||||
children: [
|
||||
if (constraints.maxWidth < double.infinity)
|
||||
...reactions
|
||||
.take((constraints.maxWidth) ~/ 22)
|
||||
.take((constraints.maxWidth) ~/ 24)
|
||||
.map((reaction) {
|
||||
return _buildReaction(
|
||||
reactionIcons,
|
||||
|
||||
@@ -45,9 +45,6 @@ class StreamChatThemeData {
|
||||
/// The text themes used in the widgets
|
||||
final TextTheme textTheme;
|
||||
|
||||
/// The button themes used in the widgets
|
||||
final ButtonThemeData buttonTheme;
|
||||
|
||||
/// The text themes used in the widgets
|
||||
final ColorTheme colorTheme;
|
||||
|
||||
@@ -78,7 +75,6 @@ class StreamChatThemeData {
|
||||
/// Create a theme from scratch
|
||||
const StreamChatThemeData({
|
||||
this.textTheme,
|
||||
this.buttonTheme,
|
||||
this.colorTheme,
|
||||
this.channelPreviewTheme,
|
||||
this.channelTheme,
|
||||
@@ -93,24 +89,20 @@ class StreamChatThemeData {
|
||||
/// Create a theme from a Material [Theme]
|
||||
factory StreamChatThemeData.fromTheme(ThemeData theme) {
|
||||
final defaultTheme = getDefaultTheme(theme);
|
||||
final customizedTheme = StreamChatThemeData(
|
||||
primaryIconTheme: theme.primaryIconTheme,
|
||||
ownMessageTheme: MessageTheme(
|
||||
replies: TextStyle(color: theme.accentColor),
|
||||
messageLinks: TextStyle(color: theme.accentColor),
|
||||
final customizedTheme = StreamChatThemeData.fromColorAndTextTheme(
|
||||
defaultTheme.colorTheme.copyWith(
|
||||
accentBlue: theme.accentColor,
|
||||
),
|
||||
otherMessageTheme: MessageTheme(
|
||||
replies: TextStyle(color: theme.accentColor),
|
||||
messageLinks: TextStyle(color: theme.accentColor),
|
||||
),
|
||||
);
|
||||
defaultTheme.textTheme,
|
||||
).copyWith(
|
||||
// primaryIconTheme: theme.primaryIconTheme,
|
||||
);
|
||||
return defaultTheme.merge(customizedTheme) ?? customizedTheme;
|
||||
}
|
||||
|
||||
/// Creates a copy of [StreamChatThemeData] with specified attributes overridden.
|
||||
StreamChatThemeData copyWith({
|
||||
TextTheme textTheme,
|
||||
ButtonThemeData buttonTheme,
|
||||
ColorTheme colorTheme,
|
||||
ChannelPreviewTheme channelPreviewTheme,
|
||||
ChannelTheme channelTheme,
|
||||
@@ -123,7 +115,6 @@ class StreamChatThemeData {
|
||||
}) =>
|
||||
StreamChatThemeData(
|
||||
textTheme: textTheme ?? this.textTheme,
|
||||
buttonTheme: buttonTheme ?? this.buttonTheme,
|
||||
colorTheme: colorTheme ?? this.colorTheme,
|
||||
primaryIconTheme: primaryIconTheme ?? this.primaryIconTheme,
|
||||
defaultChannelImage: defaultChannelImage ?? this.defaultChannelImage,
|
||||
@@ -139,7 +130,6 @@ class StreamChatThemeData {
|
||||
if (other == null) return this;
|
||||
return copyWith(
|
||||
textTheme: textTheme?.merge(other.textTheme) ?? other.textTheme,
|
||||
buttonTheme: other.buttonTheme,
|
||||
colorTheme: colorTheme?.merge(other.colorTheme) ?? other.colorTheme,
|
||||
primaryIconTheme: other.primaryIconTheme,
|
||||
defaultChannelImage: other.defaultChannelImage,
|
||||
@@ -157,26 +147,14 @@ class StreamChatThemeData {
|
||||
);
|
||||
}
|
||||
|
||||
/// Get the default Stream Chat theme
|
||||
static StreamChatThemeData getDefaultTheme(ThemeData theme) {
|
||||
final accentColor = Color(0xff006cff);
|
||||
final isDark = theme.brightness == Brightness.dark;
|
||||
final textTheme = isDark ? TextTheme.dark() : TextTheme.light();
|
||||
final colorTheme = isDark ? ColorTheme.dark() : ColorTheme.light();
|
||||
static StreamChatThemeData fromColorAndTextTheme(
|
||||
ColorTheme colorTheme,
|
||||
TextTheme textTheme,
|
||||
) {
|
||||
final accentColor = colorTheme.accentBlue;
|
||||
return StreamChatThemeData(
|
||||
textTheme: textTheme,
|
||||
colorTheme: colorTheme,
|
||||
buttonTheme: ButtonThemeData(
|
||||
height: 48.0,
|
||||
buttonColor: isDark ? Color(0xffffffff) : Color(0xff006aff),
|
||||
textTheme: ButtonTextTheme.accent,
|
||||
colorScheme: theme.colorScheme.copyWith(
|
||||
secondary: isDark ? Color(0xff005eff) : Color(0xffffffff),
|
||||
),
|
||||
shape: RoundedRectangleBorder(
|
||||
borderRadius: BorderRadius.circular(26),
|
||||
),
|
||||
),
|
||||
primaryIconTheme: IconThemeData(color: colorTheme.black.withOpacity(.5)),
|
||||
defaultChannelImage: (context, channel) => SizedBox(),
|
||||
defaultUserImage: (context, user) => Center(
|
||||
@@ -204,7 +182,7 @@ class StreamChatThemeData {
|
||||
),
|
||||
indicatorIconSize: 16.0),
|
||||
channelTheme: ChannelTheme(
|
||||
messageInputButtonIconTheme: theme.iconTheme.copyWith(
|
||||
messageInputButtonIconTheme: IconThemeData(
|
||||
color: accentColor,
|
||||
),
|
||||
channelHeaderTheme: ChannelHeaderTheme(
|
||||
@@ -291,6 +269,17 @@ class StreamChatThemeData {
|
||||
],
|
||||
);
|
||||
}
|
||||
|
||||
/// Get the default Stream Chat theme
|
||||
static StreamChatThemeData getDefaultTheme(ThemeData theme) {
|
||||
final isDark = theme.brightness == Brightness.dark;
|
||||
final textTheme = isDark ? TextTheme.dark() : TextTheme.light();
|
||||
final colorTheme = isDark ? ColorTheme.dark() : ColorTheme.light();
|
||||
return fromColorAndTextTheme(
|
||||
colorTheme,
|
||||
textTheme,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
enum TextThemeType {
|
||||
|
||||
Reference in New Issue
Block a user