Merge branch 'feature/new-ui' into feature/mono-repo
This commit is contained in:
@@ -74,7 +74,7 @@ class MyApp extends StatelessWidget {
|
||||
debugShowCheckedModeBanner: false,
|
||||
theme: ThemeData.light(),
|
||||
darkTheme: ThemeData.dark(),
|
||||
themeMode: ThemeMode.dark,
|
||||
themeMode: ThemeMode.system,
|
||||
onGenerateRoute: AppRoutes.generateRoute,
|
||||
initialRoute:
|
||||
client.state.user == null ? Routes.CHOOSE_USER : Routes.HOME,
|
||||
@@ -286,8 +286,86 @@ class _HomePageState extends State<HomePage> {
|
||||
class UserMentionPage extends StatelessWidget {
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Center(
|
||||
child: Text('On Pause Right Now!'),
|
||||
final user = StreamChat.of(context).user;
|
||||
return MessageSearchBloc(
|
||||
child: MessageSearchListView(
|
||||
filters: {
|
||||
'members': {
|
||||
r'$in': [user.id],
|
||||
},
|
||||
},
|
||||
messageFilters: {
|
||||
'mentioned_users.id': {
|
||||
r'$contains': user.id,
|
||||
},
|
||||
},
|
||||
sortOptions: [
|
||||
SortOption(
|
||||
'created_at',
|
||||
direction: SortOption.ASC,
|
||||
),
|
||||
],
|
||||
paginationParams: PaginationParams(limit: 20),
|
||||
showResultCount: false,
|
||||
emptyBuilder: (_, __) {
|
||||
return LayoutBuilder(
|
||||
builder: (context, viewportConstraints) {
|
||||
return SingleChildScrollView(
|
||||
physics: AlwaysScrollableScrollPhysics(),
|
||||
child: ConstrainedBox(
|
||||
constraints: BoxConstraints(
|
||||
minHeight: viewportConstraints.maxHeight,
|
||||
),
|
||||
child: Center(
|
||||
child: Column(
|
||||
children: [
|
||||
Padding(
|
||||
padding: const EdgeInsets.all(24),
|
||||
child: StreamSvgIcon.mentions(
|
||||
size: 96,
|
||||
color: StreamChatTheme.of(context)
|
||||
.colorTheme
|
||||
.greyGainsboro,
|
||||
),
|
||||
),
|
||||
Text(
|
||||
'No mentions exist yet...',
|
||||
style: StreamChatTheme.of(context)
|
||||
.textTheme
|
||||
.body
|
||||
.copyWith(
|
||||
color:
|
||||
StreamChatTheme.of(context).colorTheme.grey,
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
},
|
||||
);
|
||||
},
|
||||
onItemTap: (messageResponse) async {
|
||||
final client = StreamChat.of(context).client;
|
||||
final message = messageResponse.message;
|
||||
final channel = client.channel(
|
||||
messageResponse.channel.type,
|
||||
id: messageResponse.channel.id,
|
||||
);
|
||||
if (channel.state == null) {
|
||||
await channel.watch();
|
||||
}
|
||||
Navigator.pushNamed(
|
||||
context,
|
||||
Routes.CHANNEL_PAGE,
|
||||
arguments: ChannelPageArgs(
|
||||
channel: channel,
|
||||
initialMessage: message,
|
||||
),
|
||||
);
|
||||
},
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -371,7 +449,39 @@ class _ChannelListPageState extends State<ChannelListPage> {
|
||||
direction: SortOption.ASC,
|
||||
),
|
||||
],
|
||||
pullToRefresh: false,
|
||||
paginationParams: PaginationParams(limit: 20),
|
||||
emptyBuilder: (_, query) {
|
||||
return LayoutBuilder(
|
||||
builder: (context, viewportConstraints) {
|
||||
return SingleChildScrollView(
|
||||
physics: AlwaysScrollableScrollPhysics(),
|
||||
child: ConstrainedBox(
|
||||
constraints: BoxConstraints(
|
||||
minHeight:
|
||||
viewportConstraints.maxHeight,
|
||||
),
|
||||
child: Center(
|
||||
child: Column(
|
||||
children: [
|
||||
Padding(
|
||||
padding: const EdgeInsets.all(24),
|
||||
child: StreamSvgIcon.search(
|
||||
size: 96,
|
||||
color: Colors.grey,
|
||||
),
|
||||
),
|
||||
Text(
|
||||
'No results for \"$query\"...',
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
},
|
||||
);
|
||||
},
|
||||
onItemTap: (messageResponse) async {
|
||||
final client = StreamChat.of(context).client;
|
||||
final message = messageResponse.message;
|
||||
@@ -591,6 +701,12 @@ class _ChannelPageState extends State<ChannelPage> {
|
||||
horizontal: 8,
|
||||
vertical: 4,
|
||||
),
|
||||
style: StreamChatTheme.of(context)
|
||||
.textTheme
|
||||
.footnote
|
||||
.copyWith(
|
||||
color:
|
||||
StreamChatTheme.of(context).colorTheme.grey),
|
||||
),
|
||||
),
|
||||
),
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
name: example
|
||||
description: A new Flutter project.
|
||||
version: 1.0.112+115
|
||||
version: 1.0.113+116
|
||||
|
||||
environment:
|
||||
sdk: ">=2.2.2 <3.0.0"
|
||||
|
||||
@@ -22,9 +22,9 @@ import 'package:stream_chat_flutter/src/stream_svg_icon.dart';
|
||||
import 'package:stream_chat_flutter/src/user_avatar.dart';
|
||||
import 'package:substring_highlight/substring_highlight.dart';
|
||||
import 'package:video_compress/video_compress.dart';
|
||||
import 'extension.dart';
|
||||
|
||||
import '../stream_chat_flutter.dart';
|
||||
import 'extension.dart';
|
||||
import 'quoted_message_widget.dart';
|
||||
import 'stream_channel.dart';
|
||||
|
||||
@@ -477,9 +477,7 @@ class MessageInputState extends State<MessageInput> {
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
children: [
|
||||
StreamSvgIcon.lightning(
|
||||
color: StreamChatTheme.of(context)
|
||||
.colorTheme
|
||||
.white,
|
||||
color: Colors.white,
|
||||
size: 16.0,
|
||||
),
|
||||
Text(
|
||||
@@ -488,9 +486,8 @@ class MessageInputState extends State<MessageInput> {
|
||||
.textTheme
|
||||
.footnote
|
||||
.copyWith(
|
||||
color: StreamChatTheme.of(context)
|
||||
.colorTheme
|
||||
.white),
|
||||
color: Colors.white,
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
@@ -673,7 +670,7 @@ class MessageInputState extends State<MessageInput> {
|
||||
if (commands.isNotEmpty)
|
||||
Padding(
|
||||
padding:
|
||||
const EdgeInsets.only(left: 8.0, top: 8.0),
|
||||
const EdgeInsets.only(left: 0.0, top: 8.0),
|
||||
child: Row(
|
||||
children: [
|
||||
Padding(
|
||||
@@ -698,31 +695,51 @@ class MessageInputState extends State<MessageInput> {
|
||||
],
|
||||
),
|
||||
),
|
||||
SizedBox(
|
||||
height: 10.0,
|
||||
),
|
||||
...commands
|
||||
.map(
|
||||
(c) => ListTile(
|
||||
leading: c.name == 'giphy'
|
||||
? _buildGiphyIcon()
|
||||
: null,
|
||||
title: Text.rich(
|
||||
TextSpan(
|
||||
text: '${c.name.capitalize()}',
|
||||
style: TextStyle(
|
||||
fontWeight: FontWeight.bold),
|
||||
(c) => InkWell(
|
||||
onTap: () {
|
||||
_setCommand(c);
|
||||
},
|
||||
child: Container(
|
||||
height: 40.0,
|
||||
child: Row(
|
||||
children: [
|
||||
TextSpan(
|
||||
text: ' /${c.name} ${c.args}',
|
||||
style: TextStyle(
|
||||
fontWeight: FontWeight.w300,
|
||||
SizedBox(
|
||||
width: 16.0,
|
||||
),
|
||||
_buildCommandIcon(c.name),
|
||||
SizedBox(
|
||||
width: 8.0,
|
||||
),
|
||||
Text.rich(
|
||||
TextSpan(
|
||||
text: '${c.name.capitalize()}',
|
||||
style: TextStyle(
|
||||
fontWeight: FontWeight.bold),
|
||||
children: [
|
||||
TextSpan(
|
||||
text: ' /${c.name} ${c.args}',
|
||||
style:
|
||||
StreamChatTheme.of(context)
|
||||
.textTheme
|
||||
.body
|
||||
.copyWith(
|
||||
color: StreamChatTheme
|
||||
.of(context)
|
||||
.colorTheme
|
||||
.grey,
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
//subtitle: Text(c.description),
|
||||
onTap: () {
|
||||
_setCommand(c);
|
||||
},
|
||||
),
|
||||
)
|
||||
.toList(),
|
||||
@@ -957,9 +974,22 @@ class MessageInputState extends State<MessageInput> {
|
||||
'svgs/icon_picture_empty_state.svg',
|
||||
package: 'stream_chat_flutter',
|
||||
height: 140,
|
||||
color:
|
||||
StreamChatTheme.of(context).colorTheme.accentBlue,
|
||||
color: StreamChatTheme.of(context)
|
||||
.colorTheme
|
||||
.greyGainsboro,
|
||||
),
|
||||
Text(
|
||||
'Please enable access to your photos \nand videos so you can share them with friends.',
|
||||
style: StreamChatTheme.of(context)
|
||||
.textTheme
|
||||
.body
|
||||
.copyWith(
|
||||
color: StreamChatTheme.of(context)
|
||||
.colorTheme
|
||||
.grey),
|
||||
textAlign: TextAlign.center,
|
||||
),
|
||||
SizedBox(height: 6.0),
|
||||
Center(
|
||||
child: Text(
|
||||
'Allow access to your gallery',
|
||||
@@ -1083,28 +1113,87 @@ class MessageInputState extends State<MessageInput> {
|
||||
}
|
||||
}
|
||||
|
||||
CircleAvatar _buildGiphyIcon() {
|
||||
if (kIsWeb) {
|
||||
return CircleAvatar(
|
||||
backgroundColor: StreamChatTheme.of(context).colorTheme.black,
|
||||
child: Image.asset(
|
||||
'images/giphy_icon.png',
|
||||
package: 'stream_chat_flutter',
|
||||
width: 24.0,
|
||||
height: 24.0,
|
||||
),
|
||||
radius: 12,
|
||||
);
|
||||
} else {
|
||||
return CircleAvatar(
|
||||
child: SvgPicture.asset(
|
||||
'svgs/giphy_icon.svg',
|
||||
package: 'stream_chat_flutter',
|
||||
width: 24.0,
|
||||
height: 24.0,
|
||||
),
|
||||
radius: 12,
|
||||
);
|
||||
Widget _buildCommandIcon(String iconType) {
|
||||
switch (iconType) {
|
||||
case 'giphy':
|
||||
return CircleAvatar(
|
||||
child: StreamSvgIcon.giphyIcon(
|
||||
size: 24.0,
|
||||
),
|
||||
radius: 12,
|
||||
);
|
||||
break;
|
||||
case 'ban':
|
||||
return CircleAvatar(
|
||||
backgroundColor: StreamChatTheme.of(context).colorTheme.accentBlue,
|
||||
child: StreamSvgIcon.Icon_user_delete(
|
||||
size: 16.0,
|
||||
color: Colors.white,
|
||||
),
|
||||
radius: 12,
|
||||
);
|
||||
break;
|
||||
case 'flag':
|
||||
return CircleAvatar(
|
||||
backgroundColor: StreamChatTheme.of(context).colorTheme.accentBlue,
|
||||
child: StreamSvgIcon.flag(
|
||||
size: 14.0,
|
||||
color: Colors.white,
|
||||
),
|
||||
radius: 12,
|
||||
);
|
||||
break;
|
||||
case 'imgur':
|
||||
return CircleAvatar(
|
||||
backgroundColor: StreamChatTheme.of(context).colorTheme.accentBlue,
|
||||
child: ClipOval(
|
||||
child: StreamSvgIcon.imgur(
|
||||
size: 24.0,
|
||||
),
|
||||
),
|
||||
radius: 12,
|
||||
);
|
||||
break;
|
||||
case 'mute':
|
||||
return CircleAvatar(
|
||||
backgroundColor: StreamChatTheme.of(context).colorTheme.accentBlue,
|
||||
child: StreamSvgIcon.mute(
|
||||
size: 16.0,
|
||||
color: Colors.white,
|
||||
),
|
||||
radius: 12,
|
||||
);
|
||||
break;
|
||||
case 'unban':
|
||||
return CircleAvatar(
|
||||
backgroundColor: StreamChatTheme.of(context).colorTheme.accentBlue,
|
||||
child: StreamSvgIcon.userAdd(
|
||||
size: 16.0,
|
||||
color: Colors.white,
|
||||
),
|
||||
radius: 12,
|
||||
);
|
||||
break;
|
||||
case 'unmute':
|
||||
return CircleAvatar(
|
||||
backgroundColor: StreamChatTheme.of(context).colorTheme.accentBlue,
|
||||
child: StreamSvgIcon.volumeUp(
|
||||
size: 16.0,
|
||||
color: Colors.white,
|
||||
),
|
||||
radius: 12,
|
||||
);
|
||||
break;
|
||||
default:
|
||||
return CircleAvatar(
|
||||
backgroundColor: StreamChatTheme.of(context).colorTheme.accentBlue,
|
||||
child: StreamSvgIcon.lightning(
|
||||
size: 16.0,
|
||||
color: Colors.white,
|
||||
),
|
||||
radius: 12,
|
||||
);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -52,7 +52,7 @@ class MessageSearchBlocState extends State<MessageSearchBloc>
|
||||
Stream<bool> get queryMessagesLoading =>
|
||||
_queryMessagesLoadingController.stream;
|
||||
|
||||
/// Calls [Client.search] updating [queryMessagesLoading] stream
|
||||
/// Calls [Client.search] updating [messageResponses] stream
|
||||
Future<void> search({
|
||||
Map<String, dynamic> filter,
|
||||
Map<String, dynamic> messageFilter,
|
||||
@@ -60,10 +60,30 @@ class MessageSearchBlocState extends State<MessageSearchBloc>
|
||||
String query,
|
||||
PaginationParams pagination,
|
||||
}) async {
|
||||
final client = StreamChat.of(context).client;
|
||||
_messageResponses.add(null);
|
||||
try {
|
||||
final messages = await _search(
|
||||
filter: filter,
|
||||
messageFilter: messageFilter,
|
||||
sort: sort,
|
||||
query: query,
|
||||
pagination: pagination,
|
||||
);
|
||||
_messageResponses.add(messages.results);
|
||||
} catch (err, stk) {
|
||||
_messageResponses.addError(err, stk);
|
||||
}
|
||||
}
|
||||
|
||||
if (client.state?.user == null ||
|
||||
_queryMessagesLoadingController.value == true) {
|
||||
/// Calls [Client.search] updating [queryMessagesLoading] stream
|
||||
Future<void> loadMore({
|
||||
Map<String, dynamic> filter,
|
||||
Map<String, dynamic> messageFilter,
|
||||
List<SortOption> sort,
|
||||
String query,
|
||||
PaginationParams pagination,
|
||||
}) async {
|
||||
if (_queryMessagesLoadingController.value == true) {
|
||||
return;
|
||||
}
|
||||
_queryMessagesLoadingController.add(true);
|
||||
@@ -74,18 +94,18 @@ class MessageSearchBlocState extends State<MessageSearchBloc>
|
||||
|
||||
final oldMessages = List<GetMessageResponse>.from(messageResponses ?? []);
|
||||
|
||||
final messageResponse = await client.search(
|
||||
filter,
|
||||
sort,
|
||||
query,
|
||||
pagination,
|
||||
messageFilters: messageFilter,
|
||||
final messages = await _search(
|
||||
filter: filter,
|
||||
messageFilter: messageFilter,
|
||||
sort: sort,
|
||||
query: query,
|
||||
pagination: pagination,
|
||||
);
|
||||
|
||||
if (clear) {
|
||||
_messageResponses.add(messageResponse.results);
|
||||
_messageResponses.add(messages.results);
|
||||
} else {
|
||||
final temp = oldMessages + messageResponse.results;
|
||||
final temp = oldMessages + messages.results;
|
||||
_messageResponses.add(temp);
|
||||
}
|
||||
|
||||
@@ -95,6 +115,23 @@ class MessageSearchBlocState extends State<MessageSearchBloc>
|
||||
}
|
||||
}
|
||||
|
||||
Future<SearchMessagesResponse> _search({
|
||||
Map<String, dynamic> filter,
|
||||
Map<String, dynamic> messageFilter,
|
||||
List<SortOption> sort,
|
||||
String query,
|
||||
PaginationParams pagination,
|
||||
}) {
|
||||
final client = StreamChat.of(context).client;
|
||||
return client.search(
|
||||
filter,
|
||||
sort,
|
||||
query,
|
||||
pagination,
|
||||
messageFilters: messageFilter,
|
||||
);
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
super.build(context);
|
||||
|
||||
@@ -51,16 +51,18 @@ class MessageSearchListView extends StatefulWidget {
|
||||
/// Instantiate a new MessageSearchListView
|
||||
const MessageSearchListView({
|
||||
Key key,
|
||||
@required this.messageQuery,
|
||||
@required this.filters,
|
||||
this.messageQuery,
|
||||
this.filters,
|
||||
this.sortOptions,
|
||||
this.paginationParams,
|
||||
this.messageFilters,
|
||||
this.emptyBuilder,
|
||||
this.errorBuilder,
|
||||
this.separatorBuilder,
|
||||
this.itemBuilder,
|
||||
this.onItemTap,
|
||||
this.showResultCount = true,
|
||||
this.pullToRefresh = true,
|
||||
}) : super(key: key);
|
||||
|
||||
/// Message String to search on
|
||||
@@ -83,6 +85,11 @@ class MessageSearchListView extends StatefulWidget {
|
||||
/// message_limit: how many messages should be included to each channel
|
||||
final PaginationParams paginationParams;
|
||||
|
||||
/// The message query filters to use.
|
||||
/// You can query on any of the custom fields you've defined on the [Channel].
|
||||
/// You can also filter other built-in channel fields.
|
||||
final Map<String, dynamic> messageFilters;
|
||||
|
||||
/// Builder used to create a custom item preview
|
||||
final MessageSearchItemBuilder itemBuilder;
|
||||
|
||||
@@ -101,6 +108,9 @@ class MessageSearchListView extends StatefulWidget {
|
||||
/// Set it to false to hide total results text
|
||||
final bool showResultCount;
|
||||
|
||||
/// Set it to false to disable the pull-to-refresh widget
|
||||
final bool pullToRefresh;
|
||||
|
||||
@override
|
||||
_MessageSearchListViewState createState() => _MessageSearchListViewState();
|
||||
}
|
||||
@@ -115,6 +125,7 @@ class _MessageSearchListViewState extends State<MessageSearchListView> {
|
||||
sort: widget.sortOptions,
|
||||
query: widget.messageQuery,
|
||||
pagination: widget.paginationParams,
|
||||
messageFilter: widget.messageFilters,
|
||||
);
|
||||
}
|
||||
|
||||
@@ -127,9 +138,7 @@ class _MessageSearchListViewState extends State<MessageSearchListView> {
|
||||
Widget _separatorBuilder(BuildContext context, int index) {
|
||||
return Container(
|
||||
height: 1,
|
||||
color: Theme.of(context).brightness == Brightness.dark
|
||||
? StreamChatTheme.of(context).colorTheme.white.withOpacity(0.1)
|
||||
: StreamChatTheme.of(context).colorTheme.black.withOpacity(0.1),
|
||||
color: StreamChatTheme.of(context).colorTheme.greyWhisper,
|
||||
);
|
||||
}
|
||||
|
||||
@@ -205,9 +214,7 @@ class _MessageSearchListViewState extends State<MessageSearchListView> {
|
||||
children: [
|
||||
WidgetSpan(
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.only(
|
||||
right: 2.0,
|
||||
),
|
||||
padding: const EdgeInsets.only(right: 2.0),
|
||||
child: Icon(Icons.error_outline),
|
||||
),
|
||||
),
|
||||
@@ -217,18 +224,17 @@ class _MessageSearchListViewState extends State<MessageSearchListView> {
|
||||
style: Theme.of(context).textTheme.headline6,
|
||||
),
|
||||
Padding(
|
||||
padding: const EdgeInsets.only(
|
||||
top: 16.0,
|
||||
),
|
||||
padding: const EdgeInsets.only(top: 16.0),
|
||||
child: Text(message),
|
||||
),
|
||||
FlatButton(
|
||||
RaisedButton(
|
||||
onPressed: () {
|
||||
messageSearchBloc.search(
|
||||
filter: widget.filters,
|
||||
sort: widget.sortOptions,
|
||||
query: widget.messageQuery,
|
||||
pagination: widget.paginationParams,
|
||||
messageFilter: widget.messageFilters,
|
||||
);
|
||||
},
|
||||
child: Text('Retry'),
|
||||
@@ -279,32 +285,46 @@ class _MessageSearchListViewState extends State<MessageSearchListView> {
|
||||
);
|
||||
}
|
||||
|
||||
Widget child;
|
||||
Widget child = ListView.separated(
|
||||
physics: AlwaysScrollableScrollPhysics(),
|
||||
itemCount: items.isNotEmpty ? items.length + 1 : items.length,
|
||||
separatorBuilder: (_, index) {
|
||||
if (widget.separatorBuilder != null) {
|
||||
return widget.separatorBuilder(context, index);
|
||||
}
|
||||
return _separatorBuilder(context, index);
|
||||
},
|
||||
itemBuilder: (context, index) {
|
||||
if (index < items.length) {
|
||||
return _listItemBuilder(context, items[index]);
|
||||
}
|
||||
return _buildQueryProgressIndicator(context, messageSearchBloc);
|
||||
},
|
||||
);
|
||||
if (widget.pullToRefresh) {
|
||||
child = RefreshIndicator(
|
||||
onRefresh: () async => messageSearchBloc.search(
|
||||
filter: widget.filters,
|
||||
sort: widget.sortOptions,
|
||||
query: widget.messageQuery,
|
||||
pagination: widget.paginationParams,
|
||||
messageFilter: widget.messageFilters,
|
||||
),
|
||||
child: child,
|
||||
);
|
||||
}
|
||||
|
||||
child = LazyLoadScrollView(
|
||||
onEndOfPage: () => messageSearchBloc.search(
|
||||
onEndOfPage: () => messageSearchBloc.loadMore(
|
||||
filter: widget.filters,
|
||||
sort: widget.sortOptions,
|
||||
pagination: widget.paginationParams.copyWith(
|
||||
offset: messageSearchBloc.messageResponses?.length ?? 0,
|
||||
),
|
||||
query: widget.messageQuery,
|
||||
messageFilter: widget.messageFilters,
|
||||
),
|
||||
child: ListView.separated(
|
||||
physics: AlwaysScrollableScrollPhysics(),
|
||||
itemCount: items.isNotEmpty ? items.length + 1 : items.length,
|
||||
separatorBuilder: (_, index) {
|
||||
if (widget.separatorBuilder != null) {
|
||||
return widget.separatorBuilder(context, index);
|
||||
}
|
||||
return _separatorBuilder(context, index);
|
||||
},
|
||||
itemBuilder: (context, index) {
|
||||
if (index < items.length) {
|
||||
return _listItemBuilder(context, items[index]);
|
||||
}
|
||||
return _buildQueryProgressIndicator(context, messageSearchBloc);
|
||||
},
|
||||
),
|
||||
child: child,
|
||||
);
|
||||
|
||||
if (widget.showResultCount) {
|
||||
@@ -344,13 +364,16 @@ class _MessageSearchListViewState extends State<MessageSearchListView> {
|
||||
jsonEncode(widget.sortOptions) != jsonEncode(oldWidget.sortOptions) ||
|
||||
widget.paginationParams?.toJson()?.toString() !=
|
||||
oldWidget.paginationParams?.toJson()?.toString() ||
|
||||
widget.messageQuery?.toString() != oldWidget.messageQuery?.toString()) {
|
||||
widget.messageQuery?.toString() != oldWidget.messageQuery?.toString() ||
|
||||
widget.messageFilters?.toString() !=
|
||||
oldWidget.messageFilters?.toString()) {
|
||||
final messageSearchBloc = MessageSearchBloc.of(context);
|
||||
messageSearchBloc.search(
|
||||
filter: widget.filters,
|
||||
sort: widget.sortOptions,
|
||||
query: widget.messageQuery,
|
||||
pagination: widget.paginationParams,
|
||||
messageFilter: widget.messageFilters,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -829,4 +829,52 @@ class StreamSvgIcon extends StatelessWidget {
|
||||
height: size,
|
||||
);
|
||||
}
|
||||
|
||||
factory StreamSvgIcon.giphyIcon({
|
||||
double size,
|
||||
Color color,
|
||||
}) {
|
||||
return StreamSvgIcon(
|
||||
assetName: 'giphy_icon.svg',
|
||||
color: color,
|
||||
width: size,
|
||||
height: size,
|
||||
);
|
||||
}
|
||||
|
||||
factory StreamSvgIcon.imgur({
|
||||
double size,
|
||||
Color color,
|
||||
}) {
|
||||
return StreamSvgIcon(
|
||||
assetName: 'imgur.svg',
|
||||
color: color,
|
||||
width: size,
|
||||
height: size,
|
||||
);
|
||||
}
|
||||
|
||||
factory StreamSvgIcon.volumeUp({
|
||||
double size,
|
||||
Color color,
|
||||
}) {
|
||||
return StreamSvgIcon(
|
||||
assetName: 'volume-up.svg',
|
||||
color: color,
|
||||
width: size,
|
||||
height: size,
|
||||
);
|
||||
}
|
||||
|
||||
factory StreamSvgIcon.flag({
|
||||
double size,
|
||||
Color color,
|
||||
}) {
|
||||
return StreamSvgIcon(
|
||||
assetName: 'flag.svg',
|
||||
color: color,
|
||||
width: size,
|
||||
height: size,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -54,7 +54,7 @@ class TypingIndicator extends StatelessWidget {
|
||||
height: 4,
|
||||
),
|
||||
Text(
|
||||
' ${snapshot.data.map((u) => u.name).join(',')} ${snapshot.data.length == 1 ? 'is' : 'are'} typing',
|
||||
' ${snapshot.data[0].name}${snapshot.data.length == 1 ? '' : ' and ${snapshot.data.length - 1} more'} ${snapshot.data.length == 1 ? 'is' : 'are'} typing',
|
||||
maxLines: 1,
|
||||
style: style,
|
||||
),
|
||||
|
||||
@@ -34,10 +34,10 @@ class UrlAttachment extends StatelessWidget {
|
||||
margin: EdgeInsets.symmetric(horizontal: 8.0),
|
||||
child: Stack(
|
||||
children: [
|
||||
Center(
|
||||
child: CachedNetworkImage(
|
||||
imageUrl: urlAttachment.imageUrl,
|
||||
),
|
||||
CachedNetworkImage(
|
||||
width: double.infinity,
|
||||
imageUrl: urlAttachment.imageUrl,
|
||||
fit: BoxFit.cover,
|
||||
),
|
||||
Positioned(
|
||||
left: 0.0,
|
||||
|
||||
@@ -0,0 +1,3 @@
|
||||
<svg width="15" height="14" viewBox="0 0 15 14" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M2.83329 9.91667V12.8333H1.66663V1.75H12.8305C12.8816 1.74991 12.9318 1.76327 12.9762 1.78873C13.0205 1.81418 13.0574 1.85084 13.0831 1.89504C13.1088 1.93924 13.1224 1.98941 13.1226 2.04054C13.1228 2.09166 13.1096 2.14194 13.0842 2.18633L11 5.83333L13.0842 9.48033C13.1096 9.52473 13.1228 9.57501 13.1226 9.62613C13.1224 9.67726 13.1088 9.72743 13.0831 9.77163C13.0574 9.81582 13.0205 9.85249 12.9762 9.87794C12.9318 9.9034 12.8816 9.91675 12.8305 9.91667H2.83329ZM2.83329 2.91667V8.75H11.3231L9.65596 5.83333L11.3231 2.91667H2.83329Z" fill="white"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 663 B |
@@ -0,0 +1,8 @@
|
||||
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M12 24C18.6274 24 24 18.6274 24 12C24 5.37258 18.6274 0 12 0C5.37258 0 0 5.37258 0 12C0 18.6274 5.37258 24 12 24Z" fill="black"/>
|
||||
<rect x="7" y="7" width="1" height="10" fill="#00FF99"/>
|
||||
<rect x="16" y="10" width="1" height="8" fill="#9D34FF"/>
|
||||
<rect x="7" y="6" width="7" height="1" fill="#FFFF9C"/>
|
||||
<rect x="7" y="17" width="9" height="1" fill="#00CCFF"/>
|
||||
<path d="M14 6H15V7.5H16V9H17V10H14V6Z" fill="#FF6666"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 527 B |
@@ -0,0 +1,12 @@
|
||||
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<g clip-path="url(#clip0)">
|
||||
<path d="M21.2497 23.9754H2.80034C1.25039 23.9754 1.24507e-05 22.7251 1.24507e-05 21.2251V2.77578C-0.00107673 2.41437 0.0693054 2.05631 0.20711 1.72219C0.344914 1.38808 0.547421 1.08451 0.80298 0.828954C1.05854 0.573395 1.36211 0.370889 1.69622 0.233084C2.03033 0.09528 2.38839 0.0248978 2.74981 0.025987H21.1992C22.7496 -0.024028 24 1.22583 24 2.72577V21.1751C24 22.7256 22.7501 23.9754 21.2497 23.9754Z" fill="#08142D"/>
|
||||
<path d="M12.9354 17.0527C12.9354 17.7155 12.8249 18.2059 12.6042 18.5235C12.3838 18.8411 12.0445 19 11.5863 19C11.1225 19 10.7776 18.8395 10.5513 18.5195C10.325 18.1991 10.212 17.7102 10.212 17.0527V11.6752C10.212 11.0178 10.3238 10.5307 10.5473 10.2128C10.7705 9.89496 11.1166 9.73634 11.5863 9.73634C12.0445 9.73634 12.3838 9.89496 12.6045 10.2128C12.8252 10.5307 12.9354 11.0178 12.9354 11.6752V17.0527Z" fill="white"/>
|
||||
<path d="M10 6.54932C10 6.12404 10.1552 5.75961 10.4663 5.4557C10.7773 5.1518 11.1507 5 11.5863 5C12.0159 5 12.3841 5.15211 12.6889 5.4557C12.9947 5.75961 13.1471 6.12404 13.1471 6.54932C13.1471 6.98019 12.9956 7.34494 12.6932 7.64326C12.3906 7.94126 12.0218 8.09027 11.5863 8.09027C11.1396 8.09027 10.7636 7.94126 10.4582 7.64326C10.1527 7.34463 10 6.98019 10 6.54932Z" fill="#5BBF8C"/>
|
||||
</g>
|
||||
<defs>
|
||||
<clipPath id="clip0">
|
||||
<rect width="24" height="24" rx="12" fill="white"/>
|
||||
</clipPath>
|
||||
</defs>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 1.4 KiB |
@@ -0,0 +1,3 @@
|
||||
<svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M6.66663 4.81334L4.40196 6.66667H1.99996V9.33334H4.40196L6.66663 11.1867V4.81334ZM3.92596 10.6667H1.33329C1.15648 10.6667 0.986912 10.5964 0.861888 10.4714C0.736864 10.3464 0.666626 10.1768 0.666626 10V6C0.666626 5.82319 0.736864 5.65362 0.861888 5.5286C0.986912 5.40358 1.15648 5.33334 1.33329 5.33334H3.92596L7.45529 2.44534C7.50413 2.4053 7.56333 2.37996 7.626 2.37227C7.68868 2.36457 7.75225 2.37484 7.80932 2.40187C7.86639 2.4289 7.91461 2.47159 7.94836 2.52496C7.98211 2.57833 8 2.64019 7.99996 2.70334V13.2967C8 13.3598 7.98211 13.4217 7.94836 13.475C7.91461 13.5284 7.86639 13.5711 7.80932 13.5981C7.75225 13.6252 7.68868 13.6354 7.626 13.6277C7.56333 13.62 7.50413 13.5947 7.45529 13.5547L3.92663 10.6667H3.92596ZM12.9373 13.4227L11.9933 12.4787C12.6253 11.9163 13.1309 11.2264 13.4768 10.4545C13.8227 9.68248 14.001 8.84594 14 8C14.0008 7.11073 13.8035 6.23244 13.4225 5.42892C13.0415 4.6254 12.4863 3.91683 11.7973 3.35467L12.744 2.408C13.5563 3.0957 14.2088 3.95233 14.656 4.91813C15.1032 5.88394 15.3343 6.93568 15.3333 8C15.3333 10.1487 14.4093 12.0813 12.9373 13.4227ZM10.5753 11.0607L9.62729 10.1127C9.95094 9.8638 10.213 9.54383 10.3932 9.17749C10.5735 8.81115 10.667 8.40827 10.6666 8C10.6666 7.04667 10.1666 6.21 9.41329 5.73867L10.3726 4.77934C10.8776 5.1508 11.288 5.6359 11.5707 6.19542C11.8535 6.75493 12.0005 7.37313 12 8C12 9.228 11.4466 10.3267 10.5753 11.0607Z" fill="white"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 1.5 KiB |
Reference in New Issue
Block a user