chore: 1.5.1 (#387)
* lint(persistence): Apply team linter Signed-off-by: Sahil Kumar <[email protected]> * style: flutter format Signed-off-by: Sahil Kumar <[email protected]> * test(persistence): Add tests for channel dao Signed-off-by: Sahil Kumar <[email protected]> * refactor(persistence): remove dummy comments Signed-off-by: Sahil Kumar <[email protected]> * test(persistence): Add test for channel query dao Signed-off-by: Sahil Kumar <[email protected]> * test(persistence): add tests for connection event dao Signed-off-by: Sahil Kumar <[email protected]> * test(persistence): add test for member dao Signed-off-by: Sahil Kumar <[email protected]> * test(persistence): add tests for message dao Signed-off-by: Sahil Kumar <[email protected]> * test(persistence): add test for pinned message dao Signed-off-by: Sahil Kumar <[email protected]> * test(persistence): add test for reaction dao Signed-off-by: Sahil Kumar <[email protected]> * test(persistence): add test for read dao Signed-off-by: Sahil Kumar <[email protected]> * test(persistence): minor improvement in update function tests Signed-off-by: Sahil Kumar <[email protected]> * test(persistence): add tests for user dao Signed-off-by: Sahil Kumar <[email protected]> * test(persistence): add test for list converter Signed-off-by: Sahil Kumar <[email protected]> * test(persistence): add test for map converter Signed-off-by: Sahil Kumar <[email protected]> * test(persistence): add tests for message sending status converter Signed-off-by: Sahil Kumar <[email protected]> * test(persistence): add tests for channel mapper Signed-off-by: Sahil Kumar <[email protected]> * test(persistence): add test for event mapper Signed-off-by: Sahil Kumar <[email protected]> * test(persistence): add tests for member mapper Signed-off-by: Sahil Kumar <[email protected]> * remove useless dependencies * test(persistence): add tests for message mapper Signed-off-by: Sahil Kumar <[email protected]> * test(persistence): add tests for pinned message mapper Signed-off-by: Sahil Kumar <[email protected]> * test(persistence): add tests for reaction mapper Signed-off-by: Sahil Kumar <[email protected]> * test(persistence): add tests for read mapper Signed-off-by: Sahil Kumar <[email protected]> * test(persistence): add tests for user mapper Signed-off-by: Sahil Kumar <[email protected]> * refactor(persistence): remove redundant UsersTable getter from ConnectionEventDao Signed-off-by: Sahil Kumar <[email protected]> * test(persistence): add tests for stream chat persistence client Signed-off-by: Sahil Kumar <[email protected]> * test(persistence): add tests moor chat database Signed-off-by: Sahil Kumar <[email protected]> * test(persistence): add moor schemas for future migration tests Signed-off-by: Sahil Kumar <[email protected]> * test(persistence): add clear queryCache test in channel query dao Signed-off-by: Sahil Kumar <[email protected]> * test(persistence): add getThreadMessagesByParentId along with pagination test in message, pinned message dao. Signed-off-by: Sahil Kumar <[email protected]> * test(persistence): add getMessagesByCid along with pagination test in message, pinned message dao. Signed-off-by: Sahil Kumar <[email protected]> * update ci * apply locale to jiffy * fix test * test(persistence): add getMessagesByCid along with quotedMessage test in message, pinned message dao. Signed-off-by: Sahil Kumar <[email protected]> * test(persistence): add extra checks in getMessagesByCid along with pagination test in message, pinned message dao. Signed-off-by: Sahil Kumar <[email protected]> * test(persistence): add return channel with pagination applies test in channel query dao Signed-off-by: Sahil Kumar <[email protected]> * test(persistence): improve message mapper, pinned message mapper test Signed-off-by: Sahil Kumar <[email protected]> * test(persistence): add client constructor test in stream chat persistence client Signed-off-by: Sahil Kumar <[email protected]> * test(persistence): add coverage:ignore-file for entities and db/shared directory Signed-off-by: Sahil Kumar <[email protected]> * skip pub publish --dry-run for develop branch Signed-off-by: Sahil Kumar <[email protected]> * add remove from coverage script Signed-off-by: Sahil Kumar <[email protected]> * fix Signed-off-by: Sahil Kumar <[email protected]> * fix Signed-off-by: Sahil Kumar <[email protected]> * fix Signed-off-by: Sahil Kumar <[email protected]> * fix Signed-off-by: Sahil Kumar <[email protected]> * fix locale * fix message input _parseExistingMessage * fix(UI-Kit): Show selected attachment file as file in message input widget Signed-off-by: Sahil Kumar <[email protected]> * fix: ws disconnection (#345) * update ws removing custom implementation; fixed disconnection while connecting * add test * feat: Apply team lints to core package (#334) * Add analyzer file to core package * Apply team lint rules to core package * clean up analyzer warnings in stream chat flutter * remove unused line * add ignore * sync analysis options * [Core -> MessageWidget] Fix variable dynamic types Signed-off-by: Sahil Kumar <[email protected]> Co-authored-by: Salvatore Giordano <[email protected]> Co-authored-by: Sahil Kumar <[email protected]> * test: add tests for stream chat flutter core (#354) * test(core): add tests for channels bloc Signed-off-by: Sahil Kumar <[email protected]> * test(core): refactor some tests due to changes in channels bloc Signed-off-by: Sahil Kumar <[email protected]> * test(core): add tests for channel list core Signed-off-by: Sahil Kumar <[email protected]> * test(core): add tests for users bloc, minor improvements Signed-off-by: Sahil Kumar <[email protected]> * test(core): add tests for user list core, minor improvements Signed-off-by: Sahil Kumar <[email protected]> * test(core): add tests for message search bloc, refactor Signed-off-by: Sahil Kumar <[email protected]> * test(core): add tests for message search list core, refactor Signed-off-by: Sahil Kumar <[email protected]> * test(core): add tests for lazy load scroll view Signed-off-by: Sahil Kumar <[email protected]> * test(core): add tests for stream chat core Signed-off-by: Sahil Kumar <[email protected]> * test(core): add tests for message list core Signed-off-by: Sahil Kumar <[email protected]> * test(core): add tests for stream channel Signed-off-by: Sahil Kumar <[email protected]> * Fix merge conflicts Signed-off-by: Sahil Kumar <[email protected]> * flutter format Signed-off-by: Sahil Kumar <[email protected]> * fixes Signed-off-by: Sahil Kumar <[email protected]> * update workflow Signed-off-by: Sahil Kumar <[email protected]> * chore(core): fix analyzer issues Signed-off-by: Sahil Kumar <[email protected]> * chore(ui-kit): fix analyzer issues Signed-off-by: Sahil Kumar <[email protected]> * refactor(ui-kit): update giphy interaction (#361) * refactor(ui-kit): update giphy interaction Signed-off-by: Sahil Kumar <[email protected]> * fix overflow Co-authored-by: Salvatore Giordano <[email protected]> * fix: Fixed sendingbutton.outside case (#355) * fix: Fixed sendingbutton.outside case * fix: Fixed all actionbutton cases * fix review Co-authored-by: Salvatore Giordano <[email protected]> * fix(ui-kit): fix accessibility text size scaling in message widget Signed-off-by: Sahil Kumar <[email protected]> * fix(ui-kit): fix message widget long username overflow Signed-off-by: Sahil Kumar <[email protected]> * fix(ui-kit): fix message input dm checkbox accessibility scaling issue Signed-off-by: Sahil Kumar <[email protected]> * feat: exposed textbuilder callback (#367) * exposed textbuilder callback * exposed textbuilder callback * fixes Signed-off-by: Sahil Kumar <[email protected]> * check if user.mutes is null * check if user.mutes is null * fixes #370: remove all controls on full screen media if message is of type ephemeral (#373) * fix: fix channel list pagination spinner (#375) Signed-off-by: Sahil Kumar <[email protected]> * fix: attachments upload when size exceeds (#377) * fix: Fixed file upload error * fix: Fixed file upload error * fix coverage script Signed-off-by: Sahil Kumar <[email protected]> * fix: message input (#382) * feat: Added mentions suffix builder * feat: Added builders for mentions and theme element for message input expanded button * refactor: refactored PR to suit other style * fix: fixes trailing commas and changes names * doc: added documentation to new elements * doc: added documentation to new elements * bump version * add meta dep to core * sort deps Co-authored-by: Sahil Kumar <[email protected]> Co-authored-by: Neevash Ramdial (Nash) <[email protected]> Co-authored-by: Deven Joshi <[email protected]>
This commit is contained in:
co-authored by
Sahil Kumar
Neevash Ramdial
Deven Joshi
parent
aeb6da8d38
commit
87ca818a9a
@@ -1,3 +1,9 @@
|
||||
## 1.5.2
|
||||
|
||||
- Fix accessibility text size overflows
|
||||
- Updated Giphy attachment ui
|
||||
- Minor fixes and improvements
|
||||
|
||||
## 1.5.1
|
||||
|
||||
- Fixed unread count not updating while the chat is open
|
||||
|
||||
@@ -59,138 +59,57 @@ class GiphyAttachment extends AttachmentWidget {
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
crossAxisAlignment: CrossAxisAlignment.stretch,
|
||||
children: <Widget>[
|
||||
Stack(
|
||||
children: [
|
||||
Padding(
|
||||
padding: const EdgeInsets.all(8.0),
|
||||
child: GestureDetector(
|
||||
onTap: () => onAttachmentTap ?? _onImageTap(context),
|
||||
child: ClipRRect(
|
||||
borderRadius: BorderRadius.only(
|
||||
topLeft: Radius.circular(8),
|
||||
topRight: Radius.circular(8),
|
||||
),
|
||||
child: CachedNetworkImage(
|
||||
height: size?.height,
|
||||
width: size?.width,
|
||||
placeholder: (_, __) {
|
||||
return Container(
|
||||
width: size?.width,
|
||||
height: size?.height,
|
||||
child: Center(
|
||||
child: CircularProgressIndicator(),
|
||||
),
|
||||
);
|
||||
},
|
||||
imageUrl: imageUrl,
|
||||
errorWidget: (context, url, error) {
|
||||
return AttachmentError(size: size);
|
||||
},
|
||||
fit: BoxFit.cover,
|
||||
),
|
||||
),
|
||||
Padding(
|
||||
padding: const EdgeInsets.all(8.0),
|
||||
child: Row(
|
||||
children: [
|
||||
StreamSvgIcon.giphyIcon(),
|
||||
SizedBox(width: 8),
|
||||
Text(
|
||||
'Giphy',
|
||||
style: TextStyle(fontWeight: FontWeight.bold),
|
||||
),
|
||||
),
|
||||
Positioned(
|
||||
bottom: 16,
|
||||
left: 16,
|
||||
child: Material(
|
||||
color: StreamChatTheme.of(context)
|
||||
.colorTheme
|
||||
.black
|
||||
.withOpacity(.5),
|
||||
shape: RoundedRectangleBorder(
|
||||
borderRadius: BorderRadius.circular(12),
|
||||
),
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.symmetric(
|
||||
horizontal: 8.0,
|
||||
vertical: 4.0,
|
||||
),
|
||||
child: Row(
|
||||
children: [
|
||||
StreamSvgIcon.lightning(
|
||||
color:
|
||||
StreamChatTheme.of(context).colorTheme.white,
|
||||
size: 16,
|
||||
),
|
||||
Text(
|
||||
'GIPHY',
|
||||
style: TextStyle(
|
||||
color: StreamChatTheme.of(context)
|
||||
.colorTheme
|
||||
.white,
|
||||
fontWeight: FontWeight.bold,
|
||||
fontSize: 11,
|
||||
),
|
||||
),
|
||||
],
|
||||
SizedBox(width: 8),
|
||||
if (attachment.title != null)
|
||||
Flexible(
|
||||
child: Text(
|
||||
attachment.title,
|
||||
style: TextStyle(
|
||||
color: StreamChatTheme.of(context)
|
||||
.colorTheme
|
||||
.black
|
||||
.withOpacity(0.5),
|
||||
),
|
||||
overflow: TextOverflow.ellipsis,
|
||||
maxLines: 1,
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
],
|
||||
),
|
||||
),
|
||||
if (attachment.title != null)
|
||||
Container(
|
||||
alignment: Alignment.bottomCenter,
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.symmetric(horizontal: 8.0),
|
||||
child: Row(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
children: [
|
||||
Card(
|
||||
color: Colors.white,
|
||||
elevation: 2,
|
||||
shape: CircleBorder(),
|
||||
child: IconButton(
|
||||
padding: const EdgeInsets.all(0),
|
||||
constraints: BoxConstraints.tight(Size(32, 32)),
|
||||
icon: StreamSvgIcon.left(
|
||||
size: 24.0,
|
||||
),
|
||||
splashRadius: 16,
|
||||
onPressed: () {
|
||||
streamChannel.channel.sendAction(message, {
|
||||
'image_action': 'shuffle',
|
||||
});
|
||||
},
|
||||
),
|
||||
Padding(
|
||||
padding: const EdgeInsets.all(2.0),
|
||||
child: GestureDetector(
|
||||
onTap: () => onAttachmentTap ?? _onImageTap(context),
|
||||
child: CachedNetworkImage(
|
||||
height: size?.height,
|
||||
width: size?.width,
|
||||
placeholder: (_, __) {
|
||||
return Container(
|
||||
width: size?.width,
|
||||
height: size?.height,
|
||||
child: Center(
|
||||
child: CircularProgressIndicator(),
|
||||
),
|
||||
Expanded(
|
||||
child: Center(
|
||||
child: Text(
|
||||
'"${attachment.title}"',
|
||||
style: TextStyle(
|
||||
fontStyle: FontStyle.italic,
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
Card(
|
||||
color: Colors.white,
|
||||
elevation: 2,
|
||||
shape: CircleBorder(),
|
||||
child: IconButton(
|
||||
padding: const EdgeInsets.all(0),
|
||||
constraints: BoxConstraints.tight(Size(32, 32)),
|
||||
icon: StreamSvgIcon.right(
|
||||
size: 24.0,
|
||||
),
|
||||
splashRadius: 16,
|
||||
onPressed: () {
|
||||
streamChannel.channel.sendAction(message, {
|
||||
'image_action': 'shuffle',
|
||||
});
|
||||
},
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
);
|
||||
},
|
||||
imageUrl: imageUrl,
|
||||
errorWidget: (context, url, error) {
|
||||
return AttachmentError(size: size);
|
||||
},
|
||||
fit: BoxFit.cover,
|
||||
),
|
||||
),
|
||||
SizedBox(
|
||||
height: 4.0,
|
||||
),
|
||||
Container(
|
||||
color: StreamChatTheme.of(context)
|
||||
@@ -236,6 +155,38 @@ class GiphyAttachment extends AttachmentWidget {
|
||||
.withOpacity(0.2),
|
||||
height: 50.0,
|
||||
),
|
||||
Expanded(
|
||||
child: Container(
|
||||
height: 50,
|
||||
child: TextButton(
|
||||
onPressed: () {
|
||||
streamChannel.channel.sendAction(message, {
|
||||
'image_action': 'shuffle',
|
||||
});
|
||||
},
|
||||
child: Text(
|
||||
'Shuffle',
|
||||
style: StreamChatTheme.of(context)
|
||||
.textTheme
|
||||
.bodyBold
|
||||
.copyWith(
|
||||
color: StreamChatTheme.of(context)
|
||||
.colorTheme
|
||||
.black
|
||||
.withOpacity(0.5),
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
Container(
|
||||
width: 0.5,
|
||||
color: StreamChatTheme.of(context)
|
||||
.colorTheme
|
||||
.black
|
||||
.withOpacity(0.2),
|
||||
height: 50.0,
|
||||
),
|
||||
Expanded(
|
||||
child: Container(
|
||||
height: 50,
|
||||
@@ -261,9 +212,7 @@ class GiphyAttachment extends AttachmentWidget {
|
||||
],
|
||||
),
|
||||
),
|
||||
SizedBox(
|
||||
height: 4.0,
|
||||
),
|
||||
SizedBox(height: 4.0),
|
||||
Align(
|
||||
alignment: Alignment.centerRight,
|
||||
child: Padding(
|
||||
|
||||
@@ -143,7 +143,7 @@ class _ChannelFileDisplayScreenState extends State<ChannelFileDisplayScreen> {
|
||||
}
|
||||
|
||||
return LazyLoadScrollView(
|
||||
onEndOfPage: () => messageSearchBloc.loadMore(
|
||||
onEndOfPage: () => messageSearchBloc.search(
|
||||
filter: {
|
||||
'cid': {
|
||||
r'$in': [StreamChannel.of(context).channel.cid]
|
||||
|
||||
@@ -628,13 +628,14 @@ class _ChannelListViewState extends State<ChannelListView> {
|
||||
),
|
||||
);
|
||||
}
|
||||
return Container(
|
||||
height: 100,
|
||||
padding: EdgeInsets.all(32),
|
||||
child: Center(
|
||||
child: snapshot.data ? CircularProgressIndicator() : Container(),
|
||||
),
|
||||
);
|
||||
return snapshot.data
|
||||
? Center(
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.all(16.0),
|
||||
child: const CircularProgressIndicator(),
|
||||
),
|
||||
)
|
||||
: Offstage();
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
@@ -166,7 +166,7 @@ class _ChannelMediaDisplayScreenState extends State<ChannelMediaDisplayScreen> {
|
||||
}
|
||||
|
||||
return LazyLoadScrollView(
|
||||
onEndOfPage: () => messageSearchBloc.loadMore(
|
||||
onEndOfPage: () => messageSearchBloc.search(
|
||||
filter: {
|
||||
'cid': {
|
||||
r'$in': [StreamChannel.of(context).channel.cid]
|
||||
|
||||
@@ -170,14 +170,14 @@ class ChannelPreview extends StatelessWidget {
|
||||
|
||||
if (lastMessageAt.millisecondsSinceEpoch >=
|
||||
startOfDay.millisecondsSinceEpoch) {
|
||||
stringDate = Jiffy(lastMessageAt.toLocal()).format('HH:mm');
|
||||
stringDate = Jiffy(lastMessageAt.toLocal()).jm;
|
||||
} else if (lastMessageAt.millisecondsSinceEpoch >=
|
||||
startOfDay.subtract(Duration(days: 1)).millisecondsSinceEpoch) {
|
||||
stringDate = 'Yesterday';
|
||||
} else if (startOfDay.difference(lastMessageAt).inDays < 7) {
|
||||
stringDate = Jiffy(lastMessageAt.toLocal()).EEEE;
|
||||
} else {
|
||||
stringDate = Jiffy(lastMessageAt.toLocal()).format('dd/MM/yyyy');
|
||||
stringDate = Jiffy(lastMessageAt.toLocal()).yMd;
|
||||
}
|
||||
|
||||
return Text(
|
||||
|
||||
@@ -28,14 +28,14 @@ class DateDivider extends StatelessWidget {
|
||||
now.subtract(Duration(days: 7)),
|
||||
Units.DAY,
|
||||
)) {
|
||||
dayInfo = createdAt.format('EEEE');
|
||||
dayInfo = createdAt.EEEE;
|
||||
} else if (Jiffy(createdAt).isAfter(
|
||||
Jiffy(now).subtract(years: 1),
|
||||
Units.DAY,
|
||||
)) {
|
||||
dayInfo = createdAt.format('MMMM d');
|
||||
dayInfo = createdAt.MMMd;
|
||||
} else {
|
||||
dayInfo = createdAt.format('MMMM d');
|
||||
dayInfo = createdAt.MMMd;
|
||||
}
|
||||
|
||||
if (uppercase) dayInfo = dayInfo.toUpperCase();
|
||||
|
||||
@@ -97,3 +97,8 @@ extension InputDecorationX on InputDecoration {
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
extension BuildContextX on BuildContext {
|
||||
double get textScaleFactor =>
|
||||
MediaQuery.maybeOf(this)?.textScaleFactor ?? 1.0;
|
||||
}
|
||||
|
||||
@@ -185,21 +185,22 @@ class _FullScreenMediaState extends State<FullScreenMedia>
|
||||
widget.message, StreamChannel.of(context).channel);
|
||||
},
|
||||
),
|
||||
ImageFooter(
|
||||
currentPage: _currentPage,
|
||||
totalPages: widget.mediaAttachments.length,
|
||||
mediaAttachments: widget.mediaAttachments,
|
||||
message: widget.message,
|
||||
mediaSelectedCallBack: (val) {
|
||||
setState(() {
|
||||
_currentPage = val;
|
||||
_pageController.animateToPage(val,
|
||||
duration: Duration(milliseconds: 300),
|
||||
curve: Curves.easeInOut);
|
||||
Navigator.pop(context);
|
||||
});
|
||||
},
|
||||
),
|
||||
if (widget.message.type != 'ephemeral')
|
||||
ImageFooter(
|
||||
currentPage: _currentPage,
|
||||
totalPages: widget.mediaAttachments.length,
|
||||
mediaAttachments: widget.mediaAttachments,
|
||||
message: widget.message,
|
||||
mediaSelectedCallBack: (val) {
|
||||
setState(() {
|
||||
_currentPage = val;
|
||||
_pageController.animateToPage(val,
|
||||
duration: Duration(milliseconds: 300),
|
||||
curve: Curves.easeInOut);
|
||||
Navigator.pop(context);
|
||||
});
|
||||
},
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
@@ -220,7 +221,7 @@ class _FullScreenMediaState extends State<FullScreenMedia>
|
||||
24) {
|
||||
return 'yesterday';
|
||||
} else {
|
||||
return 'on ${Jiffy(dateTime).format("MMM do")}';
|
||||
return 'on ${Jiffy(dateTime).MMMd}';
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -78,6 +78,7 @@ class _ImageFooterState extends State<ImageFooter> {
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final showShareButton = !kIsWeb;
|
||||
return SizedBox.fromSize(
|
||||
size: Size(
|
||||
MediaQuery.of(context).size.width,
|
||||
@@ -91,8 +92,10 @@ class _ImageFooterState extends State<ImageFooter> {
|
||||
child: Row(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
children: [
|
||||
kIsWeb
|
||||
? SizedBox()
|
||||
!showShareButton
|
||||
? Container(
|
||||
width: 48,
|
||||
)
|
||||
: IconButton(
|
||||
icon: StreamSvgIcon.iconShare(
|
||||
size: 24.0,
|
||||
|
||||
@@ -63,38 +63,43 @@ class ImageHeader extends StatelessWidget implements PreferredSizeWidget {
|
||||
backgroundColor:
|
||||
StreamChatTheme.of(context).channelTheme.channelHeaderTheme.color,
|
||||
actions: <Widget>[
|
||||
IconButton(
|
||||
icon: StreamSvgIcon.iconMenuPoint(
|
||||
color: StreamChatTheme.of(context).colorTheme.black,
|
||||
if (message.type != 'ephemeral')
|
||||
IconButton(
|
||||
icon: StreamSvgIcon.iconMenuPoint(
|
||||
color: StreamChatTheme.of(context).colorTheme.black,
|
||||
),
|
||||
onPressed: () {
|
||||
_showMessageActionModalBottomSheet(context);
|
||||
},
|
||||
),
|
||||
onPressed: () {
|
||||
_showMessageActionModalBottomSheet(context);
|
||||
},
|
||||
),
|
||||
],
|
||||
centerTitle: true,
|
||||
title: InkWell(
|
||||
onTap: onTitleTap,
|
||||
child: Container(
|
||||
height: preferredSize.height,
|
||||
width: preferredSize.width,
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.center,
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: <Widget>[
|
||||
Text(
|
||||
userName,
|
||||
style: StreamChatTheme.of(context).textTheme.headlineBold,
|
||||
title: message.type != 'ephemeral'
|
||||
? InkWell(
|
||||
onTap: onTitleTap,
|
||||
child: Container(
|
||||
height: preferredSize.height,
|
||||
width: preferredSize.width,
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.center,
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: <Widget>[
|
||||
Text(
|
||||
userName,
|
||||
style: StreamChatTheme.of(context).textTheme.headlineBold,
|
||||
),
|
||||
Text(
|
||||
sentAt,
|
||||
style: StreamChatTheme.of(context)
|
||||
.channelPreviewTheme
|
||||
.subtitle,
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
Text(
|
||||
sentAt,
|
||||
style: StreamChatTheme.of(context).channelPreviewTheme.subtitle,
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
)
|
||||
: SizedBox(),
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,99 @@
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
import '../stream_chat_flutter.dart';
|
||||
|
||||
/// This widget is used for showing user tiles for mentions
|
||||
/// Use [title], [subtitle], [leading], [trailing] for substituting widgets in respective positions
|
||||
class MentionTile extends StatelessWidget {
|
||||
/// Member to display in the tile
|
||||
final Member member;
|
||||
|
||||
/// Widget to display as title
|
||||
final Widget title;
|
||||
|
||||
/// Widget to display below [title]
|
||||
final Widget subtitle;
|
||||
|
||||
/// Widget at the start of the tile
|
||||
final Widget leading;
|
||||
|
||||
/// Widget at the end of tile
|
||||
final Widget trailing;
|
||||
|
||||
MentionTile(
|
||||
this.member, {
|
||||
this.title,
|
||||
this.subtitle,
|
||||
this.leading,
|
||||
this.trailing,
|
||||
});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Container(
|
||||
height: 56.0,
|
||||
child: Row(
|
||||
crossAxisAlignment: CrossAxisAlignment.center,
|
||||
children: [
|
||||
SizedBox(
|
||||
width: 16.0,
|
||||
),
|
||||
leading ??
|
||||
UserAvatar(
|
||||
constraints: BoxConstraints.tight(
|
||||
Size(
|
||||
40,
|
||||
40,
|
||||
),
|
||||
),
|
||||
user: member.user,
|
||||
),
|
||||
SizedBox(
|
||||
width: 8.0,
|
||||
),
|
||||
Expanded(
|
||||
child: Align(
|
||||
alignment: Alignment.centerLeft,
|
||||
child: Column(
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
title ??
|
||||
Text(
|
||||
'${member.user.name}',
|
||||
maxLines: 1,
|
||||
overflow: TextOverflow.ellipsis,
|
||||
style: StreamChatTheme.of(context).textTheme.bodyBold,
|
||||
),
|
||||
SizedBox(
|
||||
height: 2.0,
|
||||
),
|
||||
subtitle ??
|
||||
Text(
|
||||
'@${member.userId}',
|
||||
maxLines: 1,
|
||||
overflow: TextOverflow.ellipsis,
|
||||
style: StreamChatTheme.of(context)
|
||||
.textTheme
|
||||
.footnoteBold
|
||||
.copyWith(
|
||||
color:
|
||||
StreamChatTheme.of(context).colorTheme.grey,
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
trailing ??
|
||||
Padding(
|
||||
padding: const EdgeInsets.only(right: 18.0, left: 8.0),
|
||||
child: StreamSvgIcon.mentions(
|
||||
color: StreamChatTheme.of(context).colorTheme.accentBlue,
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -16,7 +16,6 @@ import 'package:stream_chat_flutter/src/media_list_view.dart';
|
||||
import 'package:stream_chat_flutter/src/message_list_view.dart';
|
||||
import 'package:stream_chat_flutter/src/stream_chat_theme.dart';
|
||||
import 'package:stream_chat_flutter/src/stream_svg_icon.dart';
|
||||
import 'package:stream_chat_flutter/src/user_avatar.dart';
|
||||
import 'package:stream_chat_flutter/src/video_service.dart';
|
||||
import 'package:stream_chat_flutter_core/stream_chat_flutter_core.dart';
|
||||
import 'package:substring_highlight/substring_highlight.dart';
|
||||
@@ -32,6 +31,13 @@ typedef AttachmentThumbnailBuilder = Widget Function(
|
||||
Attachment,
|
||||
);
|
||||
|
||||
/// Builder function for building a mention tile
|
||||
/// Use [MentionTile] for the default implementation
|
||||
typedef MentionTileBuilder = Widget Function(
|
||||
BuildContext context,
|
||||
Member member,
|
||||
);
|
||||
|
||||
enum ActionsLocation {
|
||||
left,
|
||||
right,
|
||||
@@ -125,6 +131,7 @@ class MessageInput extends StatefulWidget {
|
||||
this.idleSendButton,
|
||||
this.activeSendButton,
|
||||
this.showCommandsButton = true,
|
||||
this.mentionsTileBuilder,
|
||||
}) : super(key: key);
|
||||
|
||||
/// Message to edit
|
||||
@@ -191,6 +198,9 @@ class MessageInput extends StatefulWidget {
|
||||
/// Send button widget in an active state
|
||||
final Widget activeSendButton;
|
||||
|
||||
/// Customize the tile for the mentions overlay
|
||||
final MentionTileBuilder mentionsTileBuilder;
|
||||
|
||||
@override
|
||||
MessageInputState createState() => MessageInputState();
|
||||
|
||||
@@ -319,7 +329,11 @@ class MessageInputState extends State<MessageInput> {
|
||||
),
|
||||
if (widget.parentMessage != null && !widget.hideSendAsDm)
|
||||
Padding(
|
||||
padding: const EdgeInsets.symmetric(horizontal: 8.0),
|
||||
padding: const EdgeInsets.only(
|
||||
right: 12.0,
|
||||
left: 12.0,
|
||||
bottom: 12.0,
|
||||
),
|
||||
child: _buildDmCheckbox(),
|
||||
),
|
||||
_buildFilePickerSection(),
|
||||
@@ -354,68 +368,68 @@ class MessageInputState extends State<MessageInput> {
|
||||
}
|
||||
|
||||
Widget _buildDmCheckbox() {
|
||||
return Container(
|
||||
height: 36,
|
||||
padding: const EdgeInsets.only(
|
||||
left: 12,
|
||||
bottom: 12,
|
||||
top: 8,
|
||||
),
|
||||
child: Row(
|
||||
crossAxisAlignment: CrossAxisAlignment.center,
|
||||
children: [
|
||||
Container(
|
||||
height: 16,
|
||||
width: 16,
|
||||
foregroundDecoration: BoxDecoration(
|
||||
border: _sendAsDm
|
||||
? null
|
||||
: Border.all(
|
||||
color: StreamChatTheme.of(context)
|
||||
.colorTheme
|
||||
.black
|
||||
.withOpacity(.5),
|
||||
width: 2,
|
||||
),
|
||||
return Row(
|
||||
crossAxisAlignment: CrossAxisAlignment.center,
|
||||
children: [
|
||||
Container(
|
||||
height: 16,
|
||||
width: 16,
|
||||
foregroundDecoration: BoxDecoration(
|
||||
border: _sendAsDm
|
||||
? null
|
||||
: Border.all(
|
||||
color: StreamChatTheme.of(context)
|
||||
.colorTheme
|
||||
.black
|
||||
.withOpacity(.5),
|
||||
width: 2,
|
||||
),
|
||||
borderRadius: BorderRadius.circular(3),
|
||||
),
|
||||
child: Center(
|
||||
child: Material(
|
||||
borderRadius: BorderRadius.circular(3),
|
||||
),
|
||||
child: Center(
|
||||
child: Material(
|
||||
borderRadius: BorderRadius.circular(3),
|
||||
color: _sendAsDm
|
||||
? StreamChatTheme.of(context).colorTheme.accentBlue
|
||||
: StreamChatTheme.of(context).colorTheme.white,
|
||||
child: InkWell(
|
||||
onTap: () {
|
||||
setState(() {
|
||||
_sendAsDm = !_sendAsDm;
|
||||
});
|
||||
},
|
||||
child: AnimatedCrossFade(
|
||||
duration: Duration(milliseconds: 300),
|
||||
reverseDuration: Duration(milliseconds: 300),
|
||||
crossFadeState: _sendAsDm
|
||||
? CrossFadeState.showFirst
|
||||
: CrossFadeState.showSecond,
|
||||
firstChild: StreamSvgIcon.check(
|
||||
size: 16.0,
|
||||
color: StreamChatTheme.of(context).colorTheme.white,
|
||||
),
|
||||
secondChild: SizedBox(
|
||||
height: 16,
|
||||
width: 16,
|
||||
),
|
||||
color: _sendAsDm
|
||||
? StreamChatTheme.of(context).colorTheme.accentBlue
|
||||
: StreamChatTheme.of(context).colorTheme.white,
|
||||
child: InkWell(
|
||||
onTap: () {
|
||||
setState(() {
|
||||
_sendAsDm = !_sendAsDm;
|
||||
});
|
||||
},
|
||||
child: AnimatedCrossFade(
|
||||
duration: Duration(milliseconds: 300),
|
||||
reverseDuration: Duration(milliseconds: 300),
|
||||
crossFadeState: _sendAsDm
|
||||
? CrossFadeState.showFirst
|
||||
: CrossFadeState.showSecond,
|
||||
firstChild: StreamSvgIcon.check(
|
||||
size: 16.0,
|
||||
color: StreamChatTheme.of(context).colorTheme.white,
|
||||
),
|
||||
secondChild: SizedBox(
|
||||
height: 16,
|
||||
width: 16,
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
Padding(
|
||||
padding: const EdgeInsets.symmetric(horizontal: 16.0),
|
||||
child: Text('Also send as direct message'),
|
||||
),
|
||||
Padding(
|
||||
padding: const EdgeInsets.symmetric(horizontal: 12.0),
|
||||
child: Text(
|
||||
'Also send as direct message',
|
||||
style: StreamChatTheme.of(context).textTheme.footnote.copyWith(
|
||||
color: StreamChatTheme.of(context)
|
||||
.colorTheme
|
||||
.black
|
||||
.withOpacity(0.5),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
],
|
||||
);
|
||||
}
|
||||
|
||||
@@ -454,7 +468,9 @@ class MessageInputState extends State<MessageInput> {
|
||||
? pi
|
||||
: 0,
|
||||
child: StreamSvgIcon.emptyCircleLeft(
|
||||
color: StreamChatTheme.of(context).colorTheme.accentBlue,
|
||||
color: StreamChatTheme.of(context)
|
||||
.messageInputTheme
|
||||
.expandButtonColor,
|
||||
),
|
||||
),
|
||||
padding: const EdgeInsets.all(0),
|
||||
@@ -491,10 +507,17 @@ class MessageInputState extends State<MessageInput> {
|
||||
|
||||
Expanded _buildTextInput(BuildContext context) {
|
||||
final theme = StreamChatTheme.of(context);
|
||||
final margin = (widget.sendButtonLocation == SendButtonLocation.inside
|
||||
? const EdgeInsets.only(right: 8.0)
|
||||
: EdgeInsets.zero) +
|
||||
(widget.actionsLocation != ActionsLocation.left
|
||||
? const EdgeInsets.only(left: 8.0)
|
||||
: EdgeInsets.zero);
|
||||
return Expanded(
|
||||
child: Center(
|
||||
child: Container(
|
||||
clipBehavior: Clip.antiAlias,
|
||||
margin: margin,
|
||||
decoration: BoxDecoration(
|
||||
borderRadius: theme.messageInputTheme.borderRadius,
|
||||
gradient: _focusNode.hasFocus
|
||||
@@ -656,6 +679,7 @@ class MessageInputState extends State<MessageInput> {
|
||||
Timer _debounce;
|
||||
|
||||
String _previousValue;
|
||||
|
||||
void _onChanged(BuildContext context, String s) {
|
||||
if (s == _previousValue) {
|
||||
return;
|
||||
@@ -1113,6 +1137,7 @@ class MessageInputState extends State<MessageInput> {
|
||||
_showErrorAlert(
|
||||
'The file is too large to upload. The file size limit is 20MB.',
|
||||
);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1301,80 +1326,9 @@ class MessageInputState extends State<MessageInput> {
|
||||
_mentionsOverlay?.remove();
|
||||
_mentionsOverlay = null;
|
||||
},
|
||||
child: Container(
|
||||
height: 56.0,
|
||||
child: Row(
|
||||
crossAxisAlignment:
|
||||
CrossAxisAlignment.center,
|
||||
children: [
|
||||
SizedBox(
|
||||
width: 16.0,
|
||||
),
|
||||
UserAvatar(
|
||||
constraints: BoxConstraints.tight(
|
||||
Size(
|
||||
40,
|
||||
40,
|
||||
),
|
||||
),
|
||||
user: m.user,
|
||||
),
|
||||
SizedBox(
|
||||
width: 8.0,
|
||||
),
|
||||
Expanded(
|
||||
child: Align(
|
||||
alignment: Alignment.centerLeft,
|
||||
child: Column(
|
||||
mainAxisAlignment:
|
||||
MainAxisAlignment.center,
|
||||
crossAxisAlignment:
|
||||
CrossAxisAlignment.start,
|
||||
children: [
|
||||
Text(
|
||||
'${m.user.name}',
|
||||
maxLines: 1,
|
||||
overflow:
|
||||
TextOverflow.ellipsis,
|
||||
style: StreamChatTheme.of(
|
||||
context)
|
||||
.textTheme
|
||||
.bodyBold,
|
||||
),
|
||||
SizedBox(
|
||||
height: 2.0,
|
||||
),
|
||||
Text(
|
||||
'@${m.userId}',
|
||||
maxLines: 1,
|
||||
overflow:
|
||||
TextOverflow.ellipsis,
|
||||
style: StreamChatTheme.of(
|
||||
context)
|
||||
.textTheme
|
||||
.footnoteBold
|
||||
.copyWith(
|
||||
color: StreamChatTheme
|
||||
.of(context)
|
||||
.colorTheme
|
||||
.grey),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
Padding(
|
||||
padding: const EdgeInsets.only(
|
||||
right: 18.0, left: 8.0),
|
||||
child: StreamSvgIcon.mentions(
|
||||
color: StreamChatTheme.of(context)
|
||||
.colorTheme
|
||||
.accentBlue,
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
child: widget.mentionsTileBuilder != null
|
||||
? widget.mentionsTileBuilder(context, m)
|
||||
: MentionTile(m),
|
||||
),
|
||||
);
|
||||
},
|
||||
@@ -1962,12 +1916,6 @@ class MessageInputState extends State<MessageInput> {
|
||||
|
||||
final extraDataMap = <String, dynamic>{};
|
||||
|
||||
if (mimeType?.type == 'video' || mimeType?.type == 'image') {
|
||||
attachmentType = mimeType.type;
|
||||
} else {
|
||||
attachmentType = 'file';
|
||||
}
|
||||
|
||||
if (mimeType?.subtype != null) {
|
||||
extraDataMap['mime_type'] = mimeType.subtype.toLowerCase();
|
||||
}
|
||||
@@ -1982,8 +1930,6 @@ class MessageInputState extends State<MessageInput> {
|
||||
extraData: extraDataMap.isNotEmpty ? extraDataMap : null,
|
||||
);
|
||||
|
||||
_attachments[attachment.id] = attachment;
|
||||
|
||||
if (file.size > _kMaxAttachmentSize) {
|
||||
if (attachmentType == 'Video') {
|
||||
final mediaInfo = await VideoService.compressVideo(file.path);
|
||||
@@ -1992,7 +1938,6 @@ class MessageInputState extends State<MessageInput> {
|
||||
_showErrorAlert(
|
||||
'The file is too large to upload. The file size limit is 20MB. We tried compressing it, but it was not enough.',
|
||||
);
|
||||
_attachments.remove(attachment.id);
|
||||
return;
|
||||
}
|
||||
file = AttachmentFile(
|
||||
@@ -2005,9 +1950,12 @@ class MessageInputState extends State<MessageInput> {
|
||||
_showErrorAlert(
|
||||
'The file is too large to upload. The file size limit is 20MB.',
|
||||
);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
_attachments[attachment.id] = attachment;
|
||||
|
||||
setState(() {
|
||||
_attachments.update(attachment.id, (it) {
|
||||
return it.copyWith(
|
||||
@@ -2233,7 +2181,7 @@ class MessageInputState extends State<MessageInput> {
|
||||
void _parseExistingMessage(Message message) {
|
||||
textEditingController.text = message.text;
|
||||
_messageIsPresent = true;
|
||||
for (final attachment in message.attachments) {
|
||||
for (final attachment in message?.attachments) {
|
||||
_attachments[attachment.id] = attachment.copyWith(
|
||||
uploadState: attachment.uploadState ?? UploadState.success(),
|
||||
);
|
||||
|
||||
@@ -141,6 +141,7 @@ class MessageListView extends StatefulWidget {
|
||||
this.onMessageTap,
|
||||
this.onSystemMessageTap,
|
||||
this.onAttachmentTap,
|
||||
this.textBuilder,
|
||||
}) : super(key: key);
|
||||
|
||||
/// Function used to build a custom message widget
|
||||
@@ -230,9 +231,12 @@ class MessageListView extends StatefulWidget {
|
||||
/// Called when system message is tapped
|
||||
final OnMessageTap onSystemMessageTap;
|
||||
|
||||
// Customize onTap on attachment
|
||||
/// Customize onTap on attachment
|
||||
final void Function(Message message, Attachment attachment) onAttachmentTap;
|
||||
|
||||
/// Customize the MessageWidget textBuilder
|
||||
final void Function(BuildContext context, Message message) textBuilder;
|
||||
|
||||
@override
|
||||
_MessageListViewState createState() => _MessageListViewState();
|
||||
}
|
||||
@@ -839,6 +843,7 @@ class _MessageListViewState extends State<MessageListView> {
|
||||
}
|
||||
FocusScope.of(context).unfocus();
|
||||
},
|
||||
textBuilder: widget.textBuilder,
|
||||
);
|
||||
}
|
||||
|
||||
@@ -1015,6 +1020,7 @@ class _MessageListViewState extends State<MessageListView> {
|
||||
FocusScope.of(context).unfocus();
|
||||
},
|
||||
onAttachmentTap: widget.onAttachmentTap,
|
||||
textBuilder: widget.textBuilder,
|
||||
);
|
||||
|
||||
if (!message.isDeleted &&
|
||||
|
||||
@@ -84,9 +84,9 @@ class MessageSearchItem extends StatelessWidget {
|
||||
if (now.year != createdAt.year ||
|
||||
now.month != createdAt.month ||
|
||||
now.day != createdAt.day) {
|
||||
stringDate = Jiffy(createdAt.toLocal()).format('dd/MM/yyyy');
|
||||
stringDate = Jiffy(createdAt.toLocal()).yMd;
|
||||
} else {
|
||||
stringDate = Jiffy(createdAt.toLocal()).format('HH:mm');
|
||||
stringDate = Jiffy(createdAt.toLocal()).jm;
|
||||
}
|
||||
|
||||
return Text(
|
||||
|
||||
@@ -262,17 +262,13 @@ class _MessageSearchListViewState extends State<MessageSearchListView> {
|
||||
);
|
||||
if (widget.pullToRefresh) {
|
||||
child = RefreshIndicator(
|
||||
onRefresh: () async {
|
||||
_messageSearchListController.loadData();
|
||||
},
|
||||
onRefresh: () => _messageSearchListController.loadData(),
|
||||
child: child,
|
||||
);
|
||||
}
|
||||
|
||||
child = LazyLoadScrollView(
|
||||
onEndOfPage: () async {
|
||||
return _messageSearchListController.paginateData();
|
||||
},
|
||||
onEndOfPage: () => _messageSearchListController.paginateData(),
|
||||
child: child,
|
||||
);
|
||||
|
||||
|
||||
@@ -585,7 +585,8 @@ class _MessageWidgetState extends State<MessageWidget>
|
||||
),
|
||||
],
|
||||
),
|
||||
if (showBottomRow) SizedBox(height: 20.0),
|
||||
if (showBottomRow)
|
||||
SizedBox(height: context.textScaleFactor * 18.0),
|
||||
],
|
||||
),
|
||||
if (showBottomRow)
|
||||
@@ -682,6 +683,8 @@ class _MessageWidgetState extends State<MessageWidget>
|
||||
}
|
||||
};
|
||||
|
||||
const usernameKey = Key('username');
|
||||
|
||||
children.addAll([
|
||||
if (showInChannel || showThreadReplyIndicator) ...[
|
||||
if (showThreadParticipants)
|
||||
@@ -697,7 +700,10 @@ class _MessageWidgetState extends State<MessageWidget>
|
||||
if (showUsername)
|
||||
Text(
|
||||
widget.message.user.name,
|
||||
maxLines: 1,
|
||||
key: usernameKey,
|
||||
style: widget.messageTheme.messageAuthor,
|
||||
overflow: TextOverflow.ellipsis,
|
||||
),
|
||||
if (showTimeStamp)
|
||||
Text(
|
||||
@@ -710,18 +716,17 @@ class _MessageWidgetState extends State<MessageWidget>
|
||||
final showThreadTail = !(hasUrlAttachments || isGiphy || isOnlyEmoji) &&
|
||||
(showThreadReplyIndicator || showInChannel);
|
||||
|
||||
return Flex(
|
||||
direction: Axis.horizontal,
|
||||
clipBehavior: Clip.none,
|
||||
return Row(
|
||||
crossAxisAlignment: CrossAxisAlignment.end,
|
||||
children: [
|
||||
if (showThreadTail)
|
||||
Container(
|
||||
margin: EdgeInsets.only(
|
||||
bottom: widget.messageTheme.replies.fontSize / 2,
|
||||
bottom: context.textScaleFactor *
|
||||
(widget.messageTheme.replies.fontSize / 2),
|
||||
),
|
||||
child: CustomPaint(
|
||||
size: const Size(16, 32),
|
||||
size: Size(16, 32) * context.textScaleFactor,
|
||||
painter: _ThreadReplyPainter(
|
||||
context: context,
|
||||
color: widget.messageTheme.messageBorderColor,
|
||||
@@ -729,16 +734,20 @@ class _MessageWidgetState extends State<MessageWidget>
|
||||
),
|
||||
),
|
||||
...children.map(
|
||||
(child) => Transform(
|
||||
transform: Matrix4.rotationY(widget.reverse ? pi : 0),
|
||||
alignment: Alignment.center,
|
||||
child: Container(
|
||||
height: 16,
|
||||
child: Center(
|
||||
(child) {
|
||||
Widget mappedChild = Transform(
|
||||
transform: Matrix4.rotationY(widget.reverse ? pi : 0),
|
||||
alignment: Alignment.center,
|
||||
child: Container(
|
||||
height: context.textScaleFactor * 14,
|
||||
child: child,
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
if (child.key == usernameKey) {
|
||||
mappedChild = Flexible(child: mappedChild);
|
||||
}
|
||||
return mappedChild;
|
||||
},
|
||||
),
|
||||
].insertBetween(const SizedBox(width: 8.0)),
|
||||
);
|
||||
|
||||
@@ -3,9 +3,11 @@ import 'dart:async';
|
||||
import 'package:flutter/foundation.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_portal/flutter_portal.dart';
|
||||
import 'package:jiffy/jiffy.dart';
|
||||
import 'package:stream_chat_flutter/src/stream_chat_theme.dart';
|
||||
import 'package:stream_chat_flutter/stream_chat_flutter.dart';
|
||||
import 'package:stream_chat_flutter_core/stream_chat_flutter_core.dart';
|
||||
import 'dart:ui' as ui;
|
||||
|
||||
/// Widget used to provide information about the chat to the widget tree
|
||||
///
|
||||
@@ -121,4 +123,11 @@ class StreamChatState extends State<StreamChat> {
|
||||
void initState() {
|
||||
super.initState();
|
||||
}
|
||||
|
||||
@override
|
||||
void didChangeDependencies() {
|
||||
final locale = ui.window.locale;
|
||||
Jiffy.locale(locale.languageCode);
|
||||
super.didChangeDependencies();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -272,6 +272,7 @@ class StreamChatThemeData {
|
||||
sendAnimationDuration: Duration(milliseconds: 300),
|
||||
actionButtonColor: colorTheme.accentBlue,
|
||||
actionButtonIdleColor: colorTheme.grey,
|
||||
expandButtonColor: colorTheme.accentBlue,
|
||||
sendButtonColor: colorTheme.accentBlue,
|
||||
sendButtonIdleColor: colorTheme.greyGainsboro,
|
||||
inputBackground: colorTheme.white,
|
||||
@@ -935,6 +936,9 @@ class MessageInputTheme {
|
||||
/// Background color of [MessageInput] action buttons
|
||||
final Color actionButtonIdleColor;
|
||||
|
||||
/// Background color of [MessageInput] expand button
|
||||
final Color expandButtonColor;
|
||||
|
||||
/// Background color of [MessageInput]
|
||||
final Color inputBackground;
|
||||
|
||||
@@ -966,6 +970,7 @@ class MessageInputTheme {
|
||||
this.activeBorderGradient,
|
||||
this.idleBorderGradient,
|
||||
this.borderRadius,
|
||||
this.expandButtonColor,
|
||||
});
|
||||
|
||||
/// Returns a new [MessageInputTheme] replacing some of its properties
|
||||
@@ -976,6 +981,7 @@ class MessageInputTheme {
|
||||
Color sendButtonColor,
|
||||
Color actionButtonIdleColor,
|
||||
Color sendButtonIdleColor,
|
||||
Color expandButtonColor,
|
||||
TextStyle inputTextStyle,
|
||||
InputDecoration inputDecoration,
|
||||
Gradient activeBorderGradient,
|
||||
@@ -990,6 +996,7 @@ class MessageInputTheme {
|
||||
sendButtonColor: sendButtonColor ?? this.sendButtonColor,
|
||||
actionButtonIdleColor:
|
||||
actionButtonIdleColor ?? this.actionButtonIdleColor,
|
||||
expandButtonColor: expandButtonColor ?? this.expandButtonColor,
|
||||
inputTextStyle: inputTextStyle ?? this.inputTextStyle,
|
||||
sendButtonIdleColor: sendButtonIdleColor ?? this.sendButtonIdleColor,
|
||||
inputDecoration: inputDecoration ?? this.inputDecoration,
|
||||
@@ -1014,6 +1021,7 @@ class MessageInputTheme {
|
||||
activeBorderGradient: other.activeBorderGradient,
|
||||
idleBorderGradient: other.idleBorderGradient,
|
||||
borderRadius: other.borderRadius,
|
||||
expandButtonColor: other.expandButtonColor,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -193,9 +193,7 @@ class _UserListViewState extends State<UserListView>
|
||||
return child;
|
||||
} else {
|
||||
return RefreshIndicator(
|
||||
onRefresh: () async {
|
||||
_userListController.loadData();
|
||||
},
|
||||
onRefresh: () => _userListController.loadData(),
|
||||
child: child,
|
||||
);
|
||||
}
|
||||
@@ -243,9 +241,7 @@ class _UserListViewState extends State<UserListView>
|
||||
child: Text(message),
|
||||
),
|
||||
TextButton(
|
||||
onPressed: () {
|
||||
_userListController.loadData();
|
||||
},
|
||||
onPressed: () => _userListController.loadData(),
|
||||
child: Text('Retry'),
|
||||
),
|
||||
],
|
||||
@@ -300,9 +296,7 @@ class _UserListViewState extends State<UserListView>
|
||||
);
|
||||
|
||||
return LazyLoadScrollView(
|
||||
onEndOfPage: () async {
|
||||
return _userListController.paginateData();
|
||||
},
|
||||
onEndOfPage: () => _userListController.paginateData(),
|
||||
child: child,
|
||||
);
|
||||
}
|
||||
|
||||
@@ -39,4 +39,5 @@ export 'src/channel_media_display_screen.dart';
|
||||
export 'src/info_tile.dart';
|
||||
export 'src/stream_chat.dart';
|
||||
export 'src/connection_status_builder.dart';
|
||||
export 'src/mention_tile.dart';
|
||||
export 'package:stream_chat_flutter_core/stream_chat_flutter_core.dart';
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
name: stream_chat_flutter
|
||||
homepage: https://github.com/GetStream/stream-chat-flutter
|
||||
description: Stream Chat official Flutter SDK. Build your own chat experience using Dart and Flutter.
|
||||
version: 1.5.1
|
||||
version: 1.5.2
|
||||
repository: https://github.com/GetStream/stream-chat-flutter
|
||||
issue_tracker: https://github.com/GetStream/stream-chat-flutter/issues
|
||||
|
||||
@@ -11,7 +11,7 @@ environment:
|
||||
dependencies:
|
||||
flutter:
|
||||
sdk: flutter
|
||||
stream_chat_flutter_core: ^1.5.0
|
||||
stream_chat_flutter_core: ^1.5.1
|
||||
photo_view: ^0.11.0
|
||||
rxdart: ^0.25.0
|
||||
scrollable_positioned_list: ^0.1.8
|
||||
@@ -30,16 +30,13 @@ dependencies:
|
||||
flutter_keyboard_visibility: ^4.0.2
|
||||
video_compress: ^2.1.1
|
||||
visibility_detector: ^0.1.5
|
||||
http_parser: ^3.1.4
|
||||
meta: ^1.2.4
|
||||
lottie: ^0.7.0+1
|
||||
substring_highlight: ^0.1.2
|
||||
flutter_slidable: ^0.5.7
|
||||
clipboard: ^0.1.2+8
|
||||
image_gallery_saver: ^1.6.7
|
||||
share_plus: ^1.2.0
|
||||
photo_manager: ^1.0.0
|
||||
transparent_image: ^1.0.0
|
||||
ezanimation: ^0.4.1
|
||||
synchronized: ^2.1.0
|
||||
characters: ^1.0.0
|
||||
|
||||
@@ -69,7 +69,7 @@ void main() {
|
||||
),
|
||||
));
|
||||
|
||||
expect(find.text('22/06/2020'), findsOneWidget);
|
||||
expect(find.text('6/22/2020'), findsOneWidget);
|
||||
expect(find.text('test name'), findsOneWidget);
|
||||
expect(find.text('1'), findsOneWidget);
|
||||
expect(find.text('hello'), findsOneWidget);
|
||||
|
||||
Reference in New Issue
Block a user