Merge branch 'feature/new-ui' into feature/group-info-screen
This commit is contained in:
@@ -5,7 +5,7 @@ import 'channel_info.dart';
|
||||
import 'option_list_tile.dart';
|
||||
|
||||
class ChannelBottomSheet extends StatefulWidget {
|
||||
VoidCallback onViewInfoTap;
|
||||
final VoidCallback onViewInfoTap;
|
||||
|
||||
ChannelBottomSheet({this.onViewInfoTap});
|
||||
|
||||
|
||||
@@ -47,14 +47,10 @@ class ImageFooter extends StatefulWidget implements PreferredSizeWidget {
|
||||
this.message,
|
||||
this.videoPackages,
|
||||
this.mediaSelectedCallBack,
|
||||
}) : preferredSize = Size.fromHeight(kToolbarHeight),
|
||||
super(key: key);
|
||||
}) : super(key: key);
|
||||
|
||||
@override
|
||||
_ImageFooterState createState() => _ImageFooterState();
|
||||
|
||||
@override
|
||||
final Size preferredSize;
|
||||
}
|
||||
|
||||
class _ImageFooterState extends State<ImageFooter> {
|
||||
@@ -168,7 +164,7 @@ class _ImageFooterState extends State<ImageFooter> {
|
||||
);
|
||||
}
|
||||
|
||||
Widget _buildPhotosModal(context) {
|
||||
void _buildPhotosModal(context) {
|
||||
var videoAttachments = widget.mediaAttachments
|
||||
.where((element) => element.type == 'video')
|
||||
.toList();
|
||||
|
||||
@@ -37,13 +37,12 @@ class _MediaListViewState extends State<MediaListView> {
|
||||
final _media = <AssetEntity>[];
|
||||
final ScrollController _scrollController = ScrollController();
|
||||
int _currentPage = 0;
|
||||
bool _endPagination = false;
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return LazyLoadScrollView(
|
||||
onEndOfPage: () {
|
||||
_getMedia();
|
||||
onEndOfPage: () async {
|
||||
return _getMedia();
|
||||
},
|
||||
child: GridView.builder(
|
||||
itemCount: _media.length,
|
||||
@@ -161,11 +160,7 @@ class _MediaListViewState extends State<MediaListView> {
|
||||
|
||||
final media = await assetList.getAssetListPaged(_currentPage, 50);
|
||||
|
||||
if (media.isEmpty) {
|
||||
setState(() {
|
||||
_endPagination = true;
|
||||
});
|
||||
} else {
|
||||
if (!media.isEmpty) {
|
||||
setState(() {
|
||||
_media.addAll(media);
|
||||
});
|
||||
|
||||
+179
-205
@@ -266,174 +266,181 @@ class _MessageWidgetState extends State<MessageWidget> {
|
||||
true;
|
||||
|
||||
return Portal(
|
||||
child: Padding(
|
||||
padding: widget.padding ?? EdgeInsets.all(8),
|
||||
child: Transform(
|
||||
alignment: Alignment.center,
|
||||
transform: Matrix4.rotationY(widget.reverse ? pi : 0),
|
||||
child: FractionallySizedBox(
|
||||
alignment: Alignment.centerLeft,
|
||||
widthFactor: 0.75,
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: <Widget>[
|
||||
Stack(
|
||||
clipBehavior: Clip.none,
|
||||
alignment: AlignmentDirectional.bottomStart,
|
||||
children: [
|
||||
Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: [
|
||||
Row(
|
||||
mainAxisAlignment: MainAxisAlignment.start,
|
||||
crossAxisAlignment: CrossAxisAlignment.end,
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: <Widget>[
|
||||
if (widget.showUserAvatar == DisplayWidget.show)
|
||||
_buildUserAvatar(),
|
||||
SizedBox(width: 6),
|
||||
if (widget.showUserAvatar == DisplayWidget.hide)
|
||||
SizedBox(
|
||||
width: widget.messageTheme.avatarTheme
|
||||
.constraints.maxWidth +
|
||||
8,
|
||||
),
|
||||
Flexible(
|
||||
child: PortalEntry(
|
||||
portal: Container(
|
||||
transform:
|
||||
Matrix4.translationValues(-16, 2, 0),
|
||||
child: _buildReactionIndicator(context),
|
||||
constraints:
|
||||
BoxConstraints(maxWidth: 22 * 6.0),
|
||||
child: GestureDetector(
|
||||
onLongPress: () => onLongPress(context),
|
||||
child: Padding(
|
||||
padding: widget.padding ?? EdgeInsets.all(8),
|
||||
child: Transform(
|
||||
alignment: Alignment.center,
|
||||
transform: Matrix4.rotationY(widget.reverse ? pi : 0),
|
||||
child: FractionallySizedBox(
|
||||
alignment: Alignment.centerLeft,
|
||||
widthFactor: 0.75,
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: <Widget>[
|
||||
Stack(
|
||||
clipBehavior: Clip.none,
|
||||
alignment: AlignmentDirectional.bottomStart,
|
||||
children: [
|
||||
Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: [
|
||||
Row(
|
||||
mainAxisAlignment: MainAxisAlignment.start,
|
||||
crossAxisAlignment: CrossAxisAlignment.end,
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: <Widget>[
|
||||
if (widget.showUserAvatar == DisplayWidget.show)
|
||||
_buildUserAvatar(),
|
||||
SizedBox(width: 6),
|
||||
if (widget.showUserAvatar == DisplayWidget.hide)
|
||||
SizedBox(
|
||||
width: widget.messageTheme.avatarTheme
|
||||
.constraints.maxWidth +
|
||||
8,
|
||||
),
|
||||
portalAnchor: Alignment(-1.0, -1.0),
|
||||
childAnchor: Alignment(1, -1.0),
|
||||
child: Stack(
|
||||
clipBehavior: Clip.none,
|
||||
children: [
|
||||
Padding(
|
||||
padding: widget.showReactions
|
||||
? EdgeInsets.only(
|
||||
top: widget.message.reactionCounts
|
||||
?.isNotEmpty ==
|
||||
true
|
||||
? 18
|
||||
: 0,
|
||||
)
|
||||
: EdgeInsets.zero,
|
||||
child: (widget.message.isDeleted &&
|
||||
!isFailedState)
|
||||
? Transform(
|
||||
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,
|
||||
),
|
||||
)
|
||||
: Material(
|
||||
clipBehavior: Clip.antiAlias,
|
||||
shape: widget.shape ??
|
||||
RoundedRectangleBorder(
|
||||
side: isOnlyEmoji
|
||||
? BorderSide.none
|
||||
: widget.borderSide ??
|
||||
BorderSide(
|
||||
color: Theme.of(context)
|
||||
.brightness ==
|
||||
Brightness
|
||||
.dark
|
||||
? StreamChatTheme.of(
|
||||
context)
|
||||
.colorTheme
|
||||
.white
|
||||
.withAlpha(
|
||||
24)
|
||||
: StreamChatTheme.of(
|
||||
context)
|
||||
.colorTheme
|
||||
.black
|
||||
.withAlpha(
|
||||
24),
|
||||
),
|
||||
borderRadius: widget
|
||||
.borderRadiusGeometry ??
|
||||
BorderRadius.zero,
|
||||
Flexible(
|
||||
child: PortalEntry(
|
||||
portal: Container(
|
||||
transform:
|
||||
Matrix4.translationValues(-16, 2, 0),
|
||||
child: _buildReactionIndicator(context),
|
||||
constraints:
|
||||
BoxConstraints(maxWidth: 22 * 6.0),
|
||||
),
|
||||
portalAnchor: Alignment(-1.0, -1.0),
|
||||
childAnchor: Alignment(1, -1.0),
|
||||
child: Stack(
|
||||
clipBehavior: Clip.none,
|
||||
children: [
|
||||
Padding(
|
||||
padding: widget.showReactions
|
||||
? EdgeInsets.only(
|
||||
top: widget
|
||||
.message
|
||||
.reactionCounts
|
||||
?.isNotEmpty ==
|
||||
true
|
||||
? 18
|
||||
: 0,
|
||||
)
|
||||
: EdgeInsets.zero,
|
||||
child: (widget.message.isDeleted &&
|
||||
!isFailedState)
|
||||
? Transform(
|
||||
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,
|
||||
),
|
||||
)
|
||||
: Material(
|
||||
clipBehavior: Clip.antiAlias,
|
||||
shape: widget.shape ??
|
||||
RoundedRectangleBorder(
|
||||
side: isOnlyEmoji
|
||||
? BorderSide.none
|
||||
: widget.borderSide ??
|
||||
BorderSide(
|
||||
color: Theme.of(context)
|
||||
.brightness ==
|
||||
Brightness
|
||||
.dark
|
||||
? StreamChatTheme.of(
|
||||
context)
|
||||
.colorTheme
|
||||
.white
|
||||
.withAlpha(
|
||||
24)
|
||||
: StreamChatTheme.of(
|
||||
context)
|
||||
.colorTheme
|
||||
.black
|
||||
.withAlpha(
|
||||
24),
|
||||
),
|
||||
borderRadius: widget
|
||||
.borderRadiusGeometry ??
|
||||
BorderRadius.zero,
|
||||
),
|
||||
color: _getBackgroundColor(),
|
||||
child: Padding(
|
||||
padding: EdgeInsets.all(
|
||||
hasFiles ? 2.0 : 0.0),
|
||||
child: Column(
|
||||
crossAxisAlignment:
|
||||
CrossAxisAlignment
|
||||
.start,
|
||||
mainAxisSize:
|
||||
MainAxisSize.min,
|
||||
children: <Widget>[
|
||||
..._parseAttachments(
|
||||
context),
|
||||
if (widget.message.text
|
||||
.trim()
|
||||
.isNotEmpty &&
|
||||
!isGiphy)
|
||||
_buildTextBubble(
|
||||
context),
|
||||
],
|
||||
),
|
||||
color: _getBackgroundColor(),
|
||||
child: Padding(
|
||||
padding: EdgeInsets.all(
|
||||
hasFiles ? 2.0 : 0.0),
|
||||
child: Column(
|
||||
crossAxisAlignment:
|
||||
CrossAxisAlignment.start,
|
||||
mainAxisSize:
|
||||
MainAxisSize.min,
|
||||
children: <Widget>[
|
||||
..._parseAttachments(
|
||||
context),
|
||||
if (widget.message.text
|
||||
.trim()
|
||||
.isNotEmpty &&
|
||||
!isGiphy)
|
||||
_buildTextBubble(context),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
if (widget.showReactionPickerIndicator)
|
||||
Positioned(
|
||||
right: 0,
|
||||
top: -6,
|
||||
child: Transform(
|
||||
transform: Matrix4.rotationY(
|
||||
widget.reverse ? pi : 0),
|
||||
child: CustomPaint(
|
||||
painter: ReactionBubblePainter(
|
||||
widget.messageTheme
|
||||
.reactionsBackgroundColor,
|
||||
widget.messageTheme
|
||||
.reactionsBorderColor,
|
||||
),
|
||||
if (widget.showReactionPickerIndicator)
|
||||
Positioned(
|
||||
right: 0,
|
||||
top: -6,
|
||||
child: Transform(
|
||||
transform: Matrix4.rotationY(
|
||||
widget.reverse ? pi : 0),
|
||||
child: CustomPaint(
|
||||
painter: ReactionBubblePainter(
|
||||
widget.messageTheme
|
||||
.reactionsBackgroundColor,
|
||||
widget.messageTheme
|
||||
.reactionsBorderColor,
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
if (showBottomRow) SizedBox(height: 20.0),
|
||||
],
|
||||
),
|
||||
if (showBottomRow) _buildBottomRow(leftPadding),
|
||||
if (isFailedState)
|
||||
Positioned(
|
||||
left: widget.reverse ? -3 : null,
|
||||
right: widget.reverse ? null : -9,
|
||||
bottom: showBottomRow ? 20 : 0,
|
||||
child: Container(
|
||||
decoration: BoxDecoration(
|
||||
color: Colors.white,
|
||||
shape: BoxShape.circle,
|
||||
],
|
||||
),
|
||||
child: StreamSvgIcon.error(size: 20),
|
||||
),
|
||||
if (showBottomRow) SizedBox(height: 20.0),
|
||||
],
|
||||
),
|
||||
],
|
||||
),
|
||||
],
|
||||
if (showBottomRow) _buildBottomRow(leftPadding),
|
||||
if (isFailedState)
|
||||
Positioned(
|
||||
left: widget.reverse ? -3 : null,
|
||||
right: widget.reverse ? null : -9,
|
||||
bottom: showBottomRow ? 20 : 0,
|
||||
child: Container(
|
||||
decoration: BoxDecoration(
|
||||
color: Colors.white,
|
||||
shape: BoxShape.circle,
|
||||
),
|
||||
child: StreamSvgIcon.error(size: 20),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
@@ -579,33 +586,6 @@ class _MessageWidgetState extends State<MessageWidget> {
|
||||
widget.message.attachments?.any((element) => element.type == 'giphy') ==
|
||||
true;
|
||||
|
||||
Widget _buildReadIndicator() {
|
||||
var padding = 0.0;
|
||||
return Stack(
|
||||
children: widget.readList.map((e) {
|
||||
padding += 10.0;
|
||||
return Positioned(
|
||||
left: padding - 10,
|
||||
bottom: 0,
|
||||
top: 0,
|
||||
child: Material(
|
||||
color: StreamChatTheme.of(context).colorTheme.white,
|
||||
clipBehavior: Clip.antiAlias,
|
||||
shape: CircleBorder(),
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.all(1.0),
|
||||
child: UserAvatar(
|
||||
user: e.user,
|
||||
constraints: BoxConstraints.loose(Size.fromRadius(8)),
|
||||
showOnlineStatus: false,
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
}).toList(),
|
||||
);
|
||||
}
|
||||
|
||||
Widget _buildReactionIndicator(
|
||||
BuildContext context,
|
||||
) {
|
||||
@@ -773,23 +753,20 @@ class _MessageWidgetState extends State<MessageWidget> {
|
||||
}) {
|
||||
final attachmentShape =
|
||||
widget.attachmentShape ?? widget.shape ?? _getDefaultShape(context);
|
||||
return GestureDetector(
|
||||
onLongPress: () => onLongPress(context),
|
||||
child: Material(
|
||||
color: _getBackgroundColor(),
|
||||
clipBehavior: Clip.antiAlias,
|
||||
shape: attachmentShape,
|
||||
child: Padding(
|
||||
padding: widget.attachmentPadding,
|
||||
child: Material(
|
||||
clipBehavior: Clip.hardEdge,
|
||||
shape: attachmentShape,
|
||||
type: MaterialType.transparency,
|
||||
child: Transform(
|
||||
transform: Matrix4.rotationY(widget.reverse ? pi : 0),
|
||||
alignment: Alignment.center,
|
||||
child: attachmentWidget,
|
||||
),
|
||||
return Material(
|
||||
color: _getBackgroundColor(),
|
||||
clipBehavior: Clip.antiAlias,
|
||||
shape: attachmentShape,
|
||||
child: Padding(
|
||||
padding: widget.attachmentPadding,
|
||||
child: Material(
|
||||
clipBehavior: Clip.hardEdge,
|
||||
shape: attachmentShape,
|
||||
type: MaterialType.transparency,
|
||||
child: Transform(
|
||||
transform: Matrix4.rotationY(widget.reverse ? pi : 0),
|
||||
alignment: Alignment.center,
|
||||
child: attachmentWidget,
|
||||
),
|
||||
),
|
||||
),
|
||||
@@ -888,10 +865,7 @@ class _MessageWidgetState extends State<MessageWidget> {
|
||||
],
|
||||
),
|
||||
);
|
||||
return GestureDetector(
|
||||
onLongPress: () => onLongPress(context),
|
||||
child: child,
|
||||
);
|
||||
return child;
|
||||
}
|
||||
|
||||
bool get isOnlyEmoji =>
|
||||
|
||||
@@ -136,11 +136,11 @@ class _ReactionPickerState extends State<ReactionPicker>
|
||||
|
||||
/// Add a reaction to the message
|
||||
void sendReaction(BuildContext context, String reactionType) {
|
||||
StreamChannel.of(context)
|
||||
.channel
|
||||
.sendReaction(widget.message, reactionType, extraData: {
|
||||
'enforce_unique': true,
|
||||
});
|
||||
StreamChannel.of(context).channel.sendReaction(
|
||||
widget.message,
|
||||
reactionType,
|
||||
enforceUnique: true,
|
||||
);
|
||||
pop();
|
||||
}
|
||||
|
||||
|
||||
@@ -112,7 +112,6 @@ class StreamChatState extends State<StreamChat> with WidgetsBindingObserver {
|
||||
inputBackground: themeData?.channelTheme?.inputBackground,
|
||||
messageInputButtonIconTheme:
|
||||
themeData?.channelTheme?.messageInputButtonIconTheme,
|
||||
inputGradient: themeData?.channelTheme?.inputGradient,
|
||||
messageInputButtonTheme:
|
||||
themeData?.channelTheme?.messageInputButtonTheme,
|
||||
),
|
||||
|
||||
@@ -92,12 +92,7 @@ class StreamChatThemeData {
|
||||
|
||||
return defaultTheme.copyWith(
|
||||
primaryIconTheme: theme.primaryIconTheme,
|
||||
channelTheme: defaultTheme.channelTheme.copyWith(
|
||||
inputGradient: LinearGradient(colors: [
|
||||
theme.accentColor.withOpacity(.5),
|
||||
theme.accentColor,
|
||||
]),
|
||||
),
|
||||
channelTheme: defaultTheme.channelTheme,
|
||||
ownMessageTheme: defaultTheme.ownMessageTheme.copyWith(
|
||||
replies: defaultTheme.ownMessageTheme.replies.copyWith(
|
||||
color: theme.accentColor,
|
||||
@@ -168,8 +163,6 @@ class StreamChatThemeData {
|
||||
this.channelTheme.messageInputButtonIconTheme,
|
||||
messageInputButtonTheme: channelTheme.messageInputButtonTheme ??
|
||||
this.channelTheme.messageInputButtonTheme,
|
||||
inputGradient:
|
||||
channelTheme.inputGradient ?? this.channelTheme.inputGradient,
|
||||
inputBackground: channelTheme.inputBackground ??
|
||||
this.channelTheme.inputBackground,
|
||||
) ??
|
||||
@@ -273,10 +266,6 @@ class StreamChatThemeData {
|
||||
),
|
||||
),
|
||||
inputBackground: colorTheme.white.withAlpha(12),
|
||||
inputGradient: LinearGradient(colors: [
|
||||
Color(0xFF00AEFF),
|
||||
Color(0xFF0076FF),
|
||||
]),
|
||||
),
|
||||
ownMessageTheme: MessageTheme(
|
||||
messageText: TextStyle(
|
||||
@@ -342,19 +331,19 @@ class StreamChatThemeData {
|
||||
assetName: 'Icon_love_reaction.svg',
|
||||
),
|
||||
ReactionIcon(
|
||||
type: 'thumbs_up',
|
||||
type: 'like',
|
||||
assetName: 'Icon_thumbs_up_reaction.svg',
|
||||
),
|
||||
ReactionIcon(
|
||||
type: 'thumbs_down',
|
||||
type: 'sad',
|
||||
assetName: 'Icon_thumbs_down_reaction.svg',
|
||||
),
|
||||
ReactionIcon(
|
||||
type: 'lol',
|
||||
type: 'haha',
|
||||
assetName: 'Icon_LOL_reaction.svg',
|
||||
),
|
||||
ReactionIcon(
|
||||
type: 'wut',
|
||||
type: 'wow',
|
||||
assetName: 'Icon_wut_reaction.svg',
|
||||
),
|
||||
],
|
||||
@@ -597,9 +586,6 @@ class ChannelTheme {
|
||||
/// Theme of the send button in [MessageInput]
|
||||
final ButtonThemeData messageInputButtonTheme;
|
||||
|
||||
/// Gradient of [MessageInput]
|
||||
final Gradient inputGradient;
|
||||
|
||||
/// Background color of [MessageInput]
|
||||
final Color inputBackground;
|
||||
|
||||
@@ -608,7 +594,6 @@ class ChannelTheme {
|
||||
this.messageInputButtonIconTheme,
|
||||
this.messageInputButtonTheme,
|
||||
this.inputBackground,
|
||||
this.inputGradient,
|
||||
});
|
||||
|
||||
/// Creates a copy of [ChannelTheme] with specified attributes overridden.
|
||||
@@ -616,7 +601,6 @@ class ChannelTheme {
|
||||
ChannelHeaderTheme channelHeaderTheme,
|
||||
IconThemeData messageInputButtonIconTheme,
|
||||
ButtonThemeData messageInputButtonTheme,
|
||||
Gradient inputGradient,
|
||||
Color inputBackground,
|
||||
}) =>
|
||||
ChannelTheme(
|
||||
@@ -633,8 +617,6 @@ class ChannelTheme {
|
||||
messageInputButtonIconTheme ?? this.messageInputButtonIconTheme,
|
||||
messageInputButtonTheme:
|
||||
messageInputButtonTheme ?? this.messageInputButtonTheme,
|
||||
inputGradient: inputGradient ?? this.inputGradient,
|
||||
inputBackground: inputBackground ?? this.inputBackground,
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
+1
-1
@@ -28,7 +28,7 @@ dependencies:
|
||||
file_picker: ^2.0.12
|
||||
image_picker: ^0.6.7+2
|
||||
flutter_keyboard_visibility: ^3.3.0
|
||||
stream_chat: ^0.2.20
|
||||
stream_chat: ^0.2.21+2
|
||||
mime: ^0.9.6+3
|
||||
video_compress: ^2.1.1
|
||||
visibility_detector: ^0.1.5
|
||||
|
||||
Reference in New Issue
Block a user