Merge branch 'feature/new-ui' into feature/group-info-screen

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