add custom theme example
This commit is contained in:
@@ -23,27 +23,19 @@ class MyApp extends StatelessWidget {
|
|||||||
primarySwatch: Colors.green,
|
primarySwatch: Colors.green,
|
||||||
);
|
);
|
||||||
|
|
||||||
final streamTheme = StreamChatThemeData.fromTheme(theme);
|
|
||||||
|
|
||||||
return MaterialApp(
|
return MaterialApp(
|
||||||
theme: theme,
|
theme: theme,
|
||||||
home: Container(
|
home: Container(
|
||||||
child: StreamChat(
|
child: StreamChat(
|
||||||
streamChatThemeData: streamTheme.copyWith(
|
streamChatThemeData: StreamChatThemeData.fromTheme(theme).copyWith(
|
||||||
channelPreviewTheme: ChannelPreviewTheme(
|
|
||||||
avatarTheme: AvatarTheme(
|
|
||||||
borderRadius: BorderRadius.circular(16),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
ownMessageTheme: MessageTheme(
|
ownMessageTheme: MessageTheme(
|
||||||
replies: streamTheme.ownMessageTheme.replies
|
messageBackgroundColor: Colors.black,
|
||||||
.copyWith(fontStyle: FontStyle.italic),
|
messageText: TextStyle(
|
||||||
|
color: Colors.white,
|
||||||
|
),
|
||||||
avatarTheme: AvatarTheme(
|
avatarTheme: AvatarTheme(
|
||||||
borderRadius: BorderRadius.circular(12),
|
borderRadius: BorderRadius.circular(8),
|
||||||
),
|
),
|
||||||
),
|
|
||||||
otherMessageTheme: MessageTheme(
|
|
||||||
messageBackgroundColor: Colors.red,
|
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
client: client,
|
client: client,
|
||||||
|
|||||||
@@ -103,6 +103,8 @@ class ChannelPreview extends StatelessWidget {
|
|||||||
return '📷';
|
return '📷';
|
||||||
} else if (e.type == 'video') {
|
} else if (e.type == 'video') {
|
||||||
return '🎬';
|
return '🎬';
|
||||||
|
} else if (e.type == 'giphy') {
|
||||||
|
return 'GIF';
|
||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
})
|
})
|
||||||
|
|||||||
@@ -218,7 +218,7 @@ class _MessageListViewState extends State<MessageListView> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
Widget _buildBottomMessage(
|
Widget _buildBottomMessage(
|
||||||
StreamChannelState channel,
|
StreamChannelState streamChannel,
|
||||||
Message previousMessage,
|
Message previousMessage,
|
||||||
Message message,
|
Message message,
|
||||||
BuildContext context,
|
BuildContext context,
|
||||||
@@ -243,9 +243,9 @@ class _MessageListViewState extends State<MessageListView> {
|
|||||||
key: ValueKey<String>('BOTTOM-MESSAGE'),
|
key: ValueKey<String>('BOTTOM-MESSAGE'),
|
||||||
onVisibilityChanged: (visibility) {
|
onVisibilityChanged: (visibility) {
|
||||||
_isBottom = visibility.visibleBounds != Rect.zero;
|
_isBottom = visibility.visibleBounds != Rect.zero;
|
||||||
if (_isBottom) {
|
if (_isBottom && streamChannel.channel.config.readEvents) {
|
||||||
if (channel.channel.state.unreadCount > 0) {
|
if (streamChannel.channel.state.unreadCount > 0) {
|
||||||
channel.channel.markRead();
|
streamChannel.channel.markRead();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|||||||
+83
-67
@@ -42,12 +42,16 @@ class _MessageWidgetState extends State<MessageWidget>
|
|||||||
final Map<String, ChangeNotifier> _chuwieControllers = {};
|
final Map<String, ChangeNotifier> _chuwieControllers = {};
|
||||||
|
|
||||||
MessageTheme messageTheme;
|
MessageTheme messageTheme;
|
||||||
|
StreamChatState streamChat;
|
||||||
|
StreamChannelState streamChannel;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
super.build(context);
|
super.build(context);
|
||||||
|
|
||||||
final streamChat = StreamChat.of(context);
|
streamChat = StreamChat.of(context);
|
||||||
|
streamChannel = StreamChannel.of(context);
|
||||||
|
|
||||||
final currentUserId = streamChat.client.state.user.id;
|
final currentUserId = streamChat.client.state.user.id;
|
||||||
final messageUserId = widget.message.user.id;
|
final messageUserId = widget.message.user.id;
|
||||||
final previousUserId = widget.previousMessage?.user?.id;
|
final previousUserId = widget.previousMessage?.user?.id;
|
||||||
@@ -73,7 +77,9 @@ class _MessageWidgetState extends State<MessageWidget>
|
|||||||
isMyMessage ? CrossAxisAlignment.end : CrossAxisAlignment.start,
|
isMyMessage ? CrossAxisAlignment.end : CrossAxisAlignment.start,
|
||||||
children: <Widget>[
|
children: <Widget>[
|
||||||
_buildBubble(context, isMyMessage, isLastUser),
|
_buildBubble(context, isMyMessage, isLastUser),
|
||||||
_buildThreadIndicator(context, isMyMessage),
|
streamChannel.channel.config.replies
|
||||||
|
? _buildThreadIndicator(context, isMyMessage)
|
||||||
|
: SizedBox(),
|
||||||
isNextUser ? SizedBox() : _buildTimestamp(isMyMessage, alignment),
|
isNextUser ? SizedBox() : _buildTimestamp(isMyMessage, alignment),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
@@ -287,12 +293,14 @@ class _MessageWidgetState extends State<MessageWidget>
|
|||||||
? CrossAxisAlignment.end
|
? CrossAxisAlignment.end
|
||||||
: CrossAxisAlignment.start,
|
: CrossAxisAlignment.start,
|
||||||
children: <Widget>[
|
children: <Widget>[
|
||||||
Align(
|
streamChannel.channel.config.reactions
|
||||||
child: _buildReactions(isMyMessage),
|
? Align(
|
||||||
alignment: isMyMessage
|
child: _buildReactions(isMyMessage),
|
||||||
? Alignment.centerLeft
|
alignment: isMyMessage
|
||||||
: Alignment.centerRight,
|
? Alignment.centerLeft
|
||||||
),
|
: Alignment.centerRight,
|
||||||
|
)
|
||||||
|
: SizedBox(),
|
||||||
Stack(
|
Stack(
|
||||||
overflow: Overflow.visible,
|
overflow: Overflow.visible,
|
||||||
children: <Widget>[
|
children: <Widget>[
|
||||||
@@ -346,6 +354,11 @@ class _MessageWidgetState extends State<MessageWidget>
|
|||||||
}
|
}
|
||||||
|
|
||||||
void _showMessageBottomSheet(BuildContext context, bool isMyMessage) {
|
void _showMessageBottomSheet(BuildContext context, bool isMyMessage) {
|
||||||
|
if (!streamChannel.channel.config.reactions &&
|
||||||
|
!streamChannel.channel.config.replies) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
showModalBottomSheet(
|
showModalBottomSheet(
|
||||||
clipBehavior: Clip.hardEdge,
|
clipBehavior: Clip.hardEdge,
|
||||||
shape: RoundedRectangleBorder(
|
shape: RoundedRectangleBorder(
|
||||||
@@ -367,47 +380,52 @@ class _MessageWidgetState extends State<MessageWidget>
|
|||||||
children: <Widget>[
|
children: <Widget>[
|
||||||
Container(
|
Container(
|
||||||
color: Colors.black87,
|
color: Colors.black87,
|
||||||
child: Row(
|
child: streamChannel.channel.config.reactions
|
||||||
crossAxisAlignment: CrossAxisAlignment.start,
|
? Row(
|
||||||
mainAxisAlignment: MainAxisAlignment.center,
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
mainAxisSize: MainAxisSize.min,
|
mainAxisAlignment: MainAxisAlignment.center,
|
||||||
children: reactionToEmoji.keys.map((reactionType) {
|
mainAxisSize: MainAxisSize.min,
|
||||||
final ownReactionIndex = widget.message.ownReactions
|
children: reactionToEmoji.keys.map((reactionType) {
|
||||||
.indexWhere(
|
final ownReactionIndex = widget.message.ownReactions
|
||||||
(reaction) => reaction.type == reactionType);
|
.indexWhere((reaction) =>
|
||||||
return Column(
|
reaction.type == reactionType);
|
||||||
mainAxisSize: MainAxisSize.min,
|
return Column(
|
||||||
mainAxisAlignment: MainAxisAlignment.start,
|
mainAxisSize: MainAxisSize.min,
|
||||||
children: <Widget>[
|
mainAxisAlignment: MainAxisAlignment.start,
|
||||||
IconButton(
|
children: <Widget>[
|
||||||
iconSize: fontSize + 10,
|
IconButton(
|
||||||
icon: Text(
|
iconSize: fontSize + 10,
|
||||||
reactionToEmoji[reactionType],
|
icon: Text(
|
||||||
style: textStyle,
|
reactionToEmoji[reactionType],
|
||||||
),
|
style: textStyle,
|
||||||
onPressed: () {
|
|
||||||
if (ownReactionIndex != -1) {
|
|
||||||
removeReaction(reactionType);
|
|
||||||
} else {
|
|
||||||
sendReaction(reactionType);
|
|
||||||
}
|
|
||||||
},
|
|
||||||
),
|
|
||||||
ownReactionIndex != -1
|
|
||||||
? Padding(
|
|
||||||
padding: const EdgeInsets.only(bottom: 4.0),
|
|
||||||
child: Text(
|
|
||||||
widget.message
|
|
||||||
.ownReactions[ownReactionIndex].score
|
|
||||||
.toString(),
|
|
||||||
style: TextStyle(color: Colors.white),
|
|
||||||
),
|
),
|
||||||
)
|
onPressed: () {
|
||||||
: SizedBox(),
|
if (ownReactionIndex != -1) {
|
||||||
],
|
removeReaction(reactionType);
|
||||||
);
|
} else {
|
||||||
}).toList(),
|
sendReaction(reactionType);
|
||||||
),
|
}
|
||||||
|
},
|
||||||
|
),
|
||||||
|
ownReactionIndex != -1
|
||||||
|
? Padding(
|
||||||
|
padding:
|
||||||
|
const EdgeInsets.only(bottom: 4.0),
|
||||||
|
child: Text(
|
||||||
|
widget
|
||||||
|
.message
|
||||||
|
.ownReactions[ownReactionIndex]
|
||||||
|
.score
|
||||||
|
.toString(),
|
||||||
|
style: TextStyle(color: Colors.white),
|
||||||
|
),
|
||||||
|
)
|
||||||
|
: SizedBox(),
|
||||||
|
],
|
||||||
|
);
|
||||||
|
}).toList(),
|
||||||
|
)
|
||||||
|
: SizedBox(),
|
||||||
),
|
),
|
||||||
isMyMessage
|
isMyMessage
|
||||||
? FlatButton(
|
? FlatButton(
|
||||||
@@ -429,19 +447,21 @@ class _MessageWidgetState extends State<MessageWidget>
|
|||||||
},
|
},
|
||||||
)
|
)
|
||||||
: SizedBox(),
|
: SizedBox(),
|
||||||
FlatButton(
|
streamChannel.channel.config.replies
|
||||||
child: Padding(
|
? FlatButton(
|
||||||
padding: const EdgeInsets.all(28.0),
|
child: Padding(
|
||||||
child: Text(
|
padding: const EdgeInsets.all(28.0),
|
||||||
'Start a thread',
|
child: Text(
|
||||||
style: Theme.of(context).textTheme.headline,
|
'Start a thread',
|
||||||
),
|
style: Theme.of(context).textTheme.headline,
|
||||||
),
|
),
|
||||||
onPressed: () {
|
),
|
||||||
Navigator.pop(context);
|
onPressed: () {
|
||||||
widget.onThreadTap(widget.message);
|
Navigator.pop(context);
|
||||||
},
|
widget.onThreadTap(widget.message);
|
||||||
),
|
},
|
||||||
|
)
|
||||||
|
: SizedBox(),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
@@ -502,16 +522,12 @@ class _MessageWidgetState extends State<MessageWidget>
|
|||||||
};
|
};
|
||||||
|
|
||||||
void sendReaction(String reactionType) {
|
void sendReaction(String reactionType) {
|
||||||
StreamChannel.of(context)
|
streamChannel.channel.sendReaction(widget.message.id, reactionType);
|
||||||
.channel
|
|
||||||
.sendReaction(widget.message.id, reactionType);
|
|
||||||
Navigator.of(context).pop();
|
Navigator.of(context).pop();
|
||||||
}
|
}
|
||||||
|
|
||||||
void removeReaction(String reactionType) {
|
void removeReaction(String reactionType) {
|
||||||
StreamChannel.of(context)
|
streamChannel.channel.deleteReaction(widget.message.id, reactionType);
|
||||||
.channel
|
|
||||||
.deleteReaction(widget.message.id, reactionType);
|
|
||||||
Navigator.of(context).pop();
|
Navigator.of(context).pop();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+1
-2
@@ -18,8 +18,7 @@ dependencies:
|
|||||||
url_launcher: ^5.4.1
|
url_launcher: ^5.4.1
|
||||||
video_player: ^0.10.7
|
video_player: ^0.10.7
|
||||||
chewie: ^0.9.8+1
|
chewie: ^0.9.8+1
|
||||||
animations: ^1.0.0+3
|
stream_chat: ^0.1.11
|
||||||
stream_chat: ^0.1.10
|
|
||||||
|
|
||||||
dev_dependencies:
|
dev_dependencies:
|
||||||
pedantic: ^1.8.0+1
|
pedantic: ^1.8.0+1
|
||||||
|
|||||||
Reference in New Issue
Block a user