Merge branches 'feature/new-ui' and 'qa2-fixes' of github.com:GetStream/stream-chat-flutter into qa2-fixes
This commit is contained in:
@@ -5,39 +5,27 @@
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
<testcase classname="fastlane.lanes" name="0: Verifying fastlane version" time="0.00047">
|
<testcase classname="fastlane.lanes" name="0: Verifying fastlane version" time="0.000341">
|
||||||
|
|
||||||
</testcase>
|
</testcase>
|
||||||
|
|
||||||
|
|
||||||
<testcase classname="fastlane.lanes" name="1: default_platform" time="0.000176">
|
<testcase classname="fastlane.lanes" name="1: default_platform" time="0.000173">
|
||||||
|
|
||||||
</testcase>
|
</testcase>
|
||||||
|
|
||||||
|
|
||||||
<testcase classname="fastlane.lanes" name="2: is_ci" time="0.000168">
|
<testcase classname="fastlane.lanes" name="2: is_ci" time="0.000178">
|
||||||
|
|
||||||
</testcase>
|
</testcase>
|
||||||
|
|
||||||
|
|
||||||
<testcase classname="fastlane.lanes" name="3: Switch to ios match_me lane" time="0.000157">
|
<testcase classname="fastlane.lanes" name="3: is_ci" time="0.0002">
|
||||||
|
|
||||||
</testcase>
|
</testcase>
|
||||||
|
|
||||||
|
|
||||||
<testcase classname="fastlane.lanes" name="4: is_ci" time="0.000161">
|
<testcase classname="fastlane.lanes" name="4: match" time="41.729101">
|
||||||
|
|
||||||
</testcase>
|
|
||||||
|
|
||||||
|
|
||||||
<testcase classname="fastlane.lanes" name="5: match" time="32.299713">
|
|
||||||
|
|
||||||
</testcase>
|
|
||||||
|
|
||||||
|
|
||||||
<testcase classname="fastlane.lanes" name="6: gym" time="9.737819">
|
|
||||||
|
|
||||||
<failure message="/Library/Ruby/Gems/2.6.0/gems/fastlane-2.162.0/fastlane/lib/fastlane/actions/actions_helper.rb:67:in `execute_action' /Library/Ruby/Gems/2.6.0/gems/fastlane-2.162.0/fastlane/lib/fastlane/runner.rb:255:in `block in execute_action' /Library/Ruby/Gems/2.6.0/gems/fastlane-2.162.0/fastlane/lib/fastlane/runner.rb:229:in `chdir' /Library/Ruby/Gems/2.6.0/gems/fastlane-2.162.0/fastlane/lib/fastlane/runner.rb:229:in `execute_action' /Library/Ruby/Gems/2.6.0/gems/fastlane-2.162.0/fastlane/lib/fastlane/runner.rb:157:in `trigger_action_by_name' /Library/Ruby/Gems/2.6.0/gems/fastlane-2.162.0/fastlane/lib/fastlane/fast_file.rb:159:in `method_missing' Fastfile:28:in `block (2 levels) in parsing_binding' /Library/Ruby/Gems/2.6.0/gems/fastlane-2.162.0/fastlane/lib/fastlane/lane.rb:33:in `call' /Library/Ruby/Gems/2.6.0/gems/fastlane-2.162.0/fastlane/lib/fastlane/runner.rb:49:in `block in execute' /Library/Ruby/Gems/2.6.0/gems/fastlane-2.162.0/fastlane/lib/fastlane/runner.rb:45:in `chdir' /Library/Ruby/Gems/2.6.0/gems/fastlane-2.162.0/fastlane/lib/fastlane/runner.rb:45:in `execute' /Library/Ruby/Gems/2.6.0/gems/fastlane-2.162.0/fastlane/lib/fastlane/lane_manager.rb:47:in `cruise_lane' /Library/Ruby/Gems/2.6.0/gems/fastlane-2.162.0/fastlane/lib/fastlane/command_line_handler.rb:36:in `handle' /Library/Ruby/Gems/2.6.0/gems/fastlane-2.162.0/fastlane/lib/fastlane/commands_generator.rb:108:in `block (2 levels) in run' /Library/Ruby/Gems/2.6.0/gems/commander-fastlane-4.4.6/lib/commander/command.rb:178:in `call' /Library/Ruby/Gems/2.6.0/gems/commander-fastlane-4.4.6/lib/commander/command.rb:153:in `run' /Library/Ruby/Gems/2.6.0/gems/commander-fastlane-4.4.6/lib/commander/runner.rb:476:in `run_active_command' /Library/Ruby/Gems/2.6.0/gems/fastlane-2.162.0/fastlane_core/lib/fastlane_core/ui/fastlane_runner.rb:76:in `run!' /Library/Ruby/Gems/2.6.0/gems/commander-fastlane-4.4.6/lib/commander/delegates.rb:15:in `run!' /Library/Ruby/Gems/2.6.0/gems/fastlane-2.162.0/fastlane/lib/fastlane/commands_generator.rb:352:in `run' /Library/Ruby/Gems/2.6.0/gems/fastlane-2.162.0/fastlane/lib/fastlane/commands_generator.rb:41:in `start' /Library/Ruby/Gems/2.6.0/gems/fastlane-2.162.0/fastlane/lib/fastlane/cli_tools_distributor.rb:119:in `take_off' /Library/Ruby/Gems/2.6.0/gems/fastlane-2.162.0/bin/fastlane:23:in `<top (required)>' /usr/local/bin/fastlane:23:in `load' /usr/local/bin/fastlane:23:in `<top (required)>' /Library/Ruby/Gems/2.6.0/gems/bundler-2.0.2/lib/bundler/cli/exec.rb:74:in `load' /Library/Ruby/Gems/2.6.0/gems/bundler-2.0.2/lib/bundler/cli/exec.rb:74:in `kernel_load' /Library/Ruby/Gems/2.6.0/gems/bundler-2.0.2/lib/bundler/cli/exec.rb:28:in `run' /Library/Ruby/Gems/2.6.0/gems/bundler-2.0.2/lib/bundler/cli.rb:465:in `exec' /Library/Ruby/Gems/2.6.0/gems/bundler-2.0.2/lib/bundler/vendor/thor/lib/thor/command.rb:27:in `run' /Library/Ruby/Gems/2.6.0/gems/bundler-2.0.2/lib/bundler/vendor/thor/lib/thor/invocation.rb:126:in `invoke_command' /Library/Ruby/Gems/2.6.0/gems/bundler-2.0.2/lib/bundler/vendor/thor/lib/thor.rb:387:in `dispatch' /Library/Ruby/Gems/2.6.0/gems/bundler-2.0.2/lib/bundler/cli.rb:27:in `dispatch' /Library/Ruby/Gems/2.6.0/gems/bundler-2.0.2/lib/bundler/vendor/thor/lib/thor/base.rb:466:in `start' /Library/Ruby/Gems/2.6.0/gems/bundler-2.0.2/lib/bundler/cli.rb:18:in `start' /Library/Ruby/Gems/2.6.0/gems/bundler-2.0.2/exe/bundle:30:in `block in <top (required)>' /Library/Ruby/Gems/2.6.0/gems/bundler-2.0.2/lib/bundler/friendly_errors.rb:124:in `with_friendly_errors' /Library/Ruby/Gems/2.6.0/gems/bundler-2.0.2/exe/bundle:22:in `<top (required)>' /usr/local/bin/bundle:23:in `load' /usr/local/bin/bundle:23:in `<main>' Error building the application - see the log above" />
|
|
||||||
|
|
||||||
</testcase>
|
</testcase>
|
||||||
|
|
||||||
|
|||||||
+118
-2
@@ -283,8 +283,86 @@ class _HomePageState extends State<HomePage> {
|
|||||||
class UserMentionPage extends StatelessWidget {
|
class UserMentionPage extends StatelessWidget {
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
return Center(
|
final user = StreamChat.of(context).user;
|
||||||
child: Text('On Pause Right Now!'),
|
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,
|
||||||
|
),
|
||||||
|
);
|
||||||
|
},
|
||||||
|
),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -368,7 +446,39 @@ class _ChannelListPageState extends State<ChannelListPage> {
|
|||||||
direction: SortOption.ASC,
|
direction: SortOption.ASC,
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
|
pullToRefresh: false,
|
||||||
paginationParams: PaginationParams(limit: 20),
|
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 {
|
onItemTap: (messageResponse) async {
|
||||||
final client = StreamChat.of(context).client;
|
final client = StreamChat.of(context).client;
|
||||||
final message = messageResponse.message;
|
final message = messageResponse.message;
|
||||||
@@ -588,6 +698,12 @@ class _ChannelPageState extends State<ChannelPage> {
|
|||||||
horizontal: 8,
|
horizontal: 8,
|
||||||
vertical: 4,
|
vertical: 4,
|
||||||
),
|
),
|
||||||
|
style: StreamChatTheme.of(context)
|
||||||
|
.textTheme
|
||||||
|
.footnote
|
||||||
|
.copyWith(
|
||||||
|
color:
|
||||||
|
StreamChatTheme.of(context).colorTheme.grey),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
|||||||
@@ -974,9 +974,22 @@ class MessageInputState extends State<MessageInput> {
|
|||||||
'svgs/icon_picture_empty_state.svg',
|
'svgs/icon_picture_empty_state.svg',
|
||||||
package: 'stream_chat_flutter',
|
package: 'stream_chat_flutter',
|
||||||
height: 140,
|
height: 140,
|
||||||
color:
|
color: StreamChatTheme.of(context)
|
||||||
StreamChatTheme.of(context).colorTheme.accentBlue,
|
.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(
|
Center(
|
||||||
child: Text(
|
child: Text(
|
||||||
'Allow access to your gallery',
|
'Allow access to your gallery',
|
||||||
|
|||||||
@@ -52,7 +52,7 @@ class MessageSearchBlocState extends State<MessageSearchBloc>
|
|||||||
Stream<bool> get queryMessagesLoading =>
|
Stream<bool> get queryMessagesLoading =>
|
||||||
_queryMessagesLoadingController.stream;
|
_queryMessagesLoadingController.stream;
|
||||||
|
|
||||||
/// Calls [Client.search] updating [queryMessagesLoading] stream
|
/// Calls [Client.search] updating [messageResponses] stream
|
||||||
Future<void> search({
|
Future<void> search({
|
||||||
Map<String, dynamic> filter,
|
Map<String, dynamic> filter,
|
||||||
Map<String, dynamic> messageFilter,
|
Map<String, dynamic> messageFilter,
|
||||||
@@ -60,10 +60,30 @@ class MessageSearchBlocState extends State<MessageSearchBloc>
|
|||||||
String query,
|
String query,
|
||||||
PaginationParams pagination,
|
PaginationParams pagination,
|
||||||
}) async {
|
}) 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 ||
|
/// Calls [Client.search] updating [queryMessagesLoading] stream
|
||||||
_queryMessagesLoadingController.value == true) {
|
Future<void> loadMore({
|
||||||
|
Map<String, dynamic> filter,
|
||||||
|
Map<String, dynamic> messageFilter,
|
||||||
|
List<SortOption> sort,
|
||||||
|
String query,
|
||||||
|
PaginationParams pagination,
|
||||||
|
}) async {
|
||||||
|
if (_queryMessagesLoadingController.value == true) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
_queryMessagesLoadingController.add(true);
|
_queryMessagesLoadingController.add(true);
|
||||||
@@ -74,18 +94,18 @@ class MessageSearchBlocState extends State<MessageSearchBloc>
|
|||||||
|
|
||||||
final oldMessages = List<GetMessageResponse>.from(messageResponses ?? []);
|
final oldMessages = List<GetMessageResponse>.from(messageResponses ?? []);
|
||||||
|
|
||||||
final messageResponse = await client.search(
|
final messages = await _search(
|
||||||
filter,
|
filter: filter,
|
||||||
sort,
|
messageFilter: messageFilter,
|
||||||
query,
|
sort: sort,
|
||||||
pagination,
|
query: query,
|
||||||
messageFilters: messageFilter,
|
pagination: pagination,
|
||||||
);
|
);
|
||||||
|
|
||||||
if (clear) {
|
if (clear) {
|
||||||
_messageResponses.add(messageResponse.results);
|
_messageResponses.add(messages.results);
|
||||||
} else {
|
} else {
|
||||||
final temp = oldMessages + messageResponse.results;
|
final temp = oldMessages + messages.results;
|
||||||
_messageResponses.add(temp);
|
_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
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
super.build(context);
|
super.build(context);
|
||||||
|
|||||||
@@ -51,16 +51,18 @@ class MessageSearchListView extends StatefulWidget {
|
|||||||
/// Instantiate a new MessageSearchListView
|
/// Instantiate a new MessageSearchListView
|
||||||
const MessageSearchListView({
|
const MessageSearchListView({
|
||||||
Key key,
|
Key key,
|
||||||
@required this.messageQuery,
|
this.messageQuery,
|
||||||
@required this.filters,
|
this.filters,
|
||||||
this.sortOptions,
|
this.sortOptions,
|
||||||
this.paginationParams,
|
this.paginationParams,
|
||||||
|
this.messageFilters,
|
||||||
this.emptyBuilder,
|
this.emptyBuilder,
|
||||||
this.errorBuilder,
|
this.errorBuilder,
|
||||||
this.separatorBuilder,
|
this.separatorBuilder,
|
||||||
this.itemBuilder,
|
this.itemBuilder,
|
||||||
this.onItemTap,
|
this.onItemTap,
|
||||||
this.showResultCount = true,
|
this.showResultCount = true,
|
||||||
|
this.pullToRefresh = true,
|
||||||
}) : super(key: key);
|
}) : super(key: key);
|
||||||
|
|
||||||
/// Message String to search on
|
/// Message String to search on
|
||||||
@@ -83,6 +85,11 @@ class MessageSearchListView extends StatefulWidget {
|
|||||||
/// message_limit: how many messages should be included to each channel
|
/// message_limit: how many messages should be included to each channel
|
||||||
final PaginationParams paginationParams;
|
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
|
/// Builder used to create a custom item preview
|
||||||
final MessageSearchItemBuilder itemBuilder;
|
final MessageSearchItemBuilder itemBuilder;
|
||||||
|
|
||||||
@@ -101,6 +108,9 @@ class MessageSearchListView extends StatefulWidget {
|
|||||||
/// Set it to false to hide total results text
|
/// Set it to false to hide total results text
|
||||||
final bool showResultCount;
|
final bool showResultCount;
|
||||||
|
|
||||||
|
/// Set it to false to disable the pull-to-refresh widget
|
||||||
|
final bool pullToRefresh;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
_MessageSearchListViewState createState() => _MessageSearchListViewState();
|
_MessageSearchListViewState createState() => _MessageSearchListViewState();
|
||||||
}
|
}
|
||||||
@@ -115,6 +125,7 @@ class _MessageSearchListViewState extends State<MessageSearchListView> {
|
|||||||
sort: widget.sortOptions,
|
sort: widget.sortOptions,
|
||||||
query: widget.messageQuery,
|
query: widget.messageQuery,
|
||||||
pagination: widget.paginationParams,
|
pagination: widget.paginationParams,
|
||||||
|
messageFilter: widget.messageFilters,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -127,9 +138,7 @@ class _MessageSearchListViewState extends State<MessageSearchListView> {
|
|||||||
Widget _separatorBuilder(BuildContext context, int index) {
|
Widget _separatorBuilder(BuildContext context, int index) {
|
||||||
return Container(
|
return Container(
|
||||||
height: 1,
|
height: 1,
|
||||||
color: Theme.of(context).brightness == Brightness.dark
|
color: StreamChatTheme.of(context).colorTheme.greyWhisper,
|
||||||
? StreamChatTheme.of(context).colorTheme.white.withOpacity(0.1)
|
|
||||||
: StreamChatTheme.of(context).colorTheme.black.withOpacity(0.1),
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -205,9 +214,7 @@ class _MessageSearchListViewState extends State<MessageSearchListView> {
|
|||||||
children: [
|
children: [
|
||||||
WidgetSpan(
|
WidgetSpan(
|
||||||
child: Padding(
|
child: Padding(
|
||||||
padding: const EdgeInsets.only(
|
padding: const EdgeInsets.only(right: 2.0),
|
||||||
right: 2.0,
|
|
||||||
),
|
|
||||||
child: Icon(Icons.error_outline),
|
child: Icon(Icons.error_outline),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
@@ -217,18 +224,17 @@ class _MessageSearchListViewState extends State<MessageSearchListView> {
|
|||||||
style: Theme.of(context).textTheme.headline6,
|
style: Theme.of(context).textTheme.headline6,
|
||||||
),
|
),
|
||||||
Padding(
|
Padding(
|
||||||
padding: const EdgeInsets.only(
|
padding: const EdgeInsets.only(top: 16.0),
|
||||||
top: 16.0,
|
|
||||||
),
|
|
||||||
child: Text(message),
|
child: Text(message),
|
||||||
),
|
),
|
||||||
FlatButton(
|
RaisedButton(
|
||||||
onPressed: () {
|
onPressed: () {
|
||||||
messageSearchBloc.search(
|
messageSearchBloc.search(
|
||||||
filter: widget.filters,
|
filter: widget.filters,
|
||||||
sort: widget.sortOptions,
|
sort: widget.sortOptions,
|
||||||
query: widget.messageQuery,
|
query: widget.messageQuery,
|
||||||
pagination: widget.paginationParams,
|
pagination: widget.paginationParams,
|
||||||
|
messageFilter: widget.messageFilters,
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
child: Text('Retry'),
|
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(
|
child = LazyLoadScrollView(
|
||||||
onEndOfPage: () => messageSearchBloc.search(
|
onEndOfPage: () => messageSearchBloc.loadMore(
|
||||||
filter: widget.filters,
|
filter: widget.filters,
|
||||||
sort: widget.sortOptions,
|
sort: widget.sortOptions,
|
||||||
pagination: widget.paginationParams.copyWith(
|
pagination: widget.paginationParams.copyWith(
|
||||||
offset: messageSearchBloc.messageResponses?.length ?? 0,
|
offset: messageSearchBloc.messageResponses?.length ?? 0,
|
||||||
),
|
),
|
||||||
query: widget.messageQuery,
|
query: widget.messageQuery,
|
||||||
|
messageFilter: widget.messageFilters,
|
||||||
),
|
),
|
||||||
child: ListView.separated(
|
child: child,
|
||||||
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.showResultCount) {
|
if (widget.showResultCount) {
|
||||||
@@ -344,13 +364,16 @@ class _MessageSearchListViewState extends State<MessageSearchListView> {
|
|||||||
jsonEncode(widget.sortOptions) != jsonEncode(oldWidget.sortOptions) ||
|
jsonEncode(widget.sortOptions) != jsonEncode(oldWidget.sortOptions) ||
|
||||||
widget.paginationParams?.toJson()?.toString() !=
|
widget.paginationParams?.toJson()?.toString() !=
|
||||||
oldWidget.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);
|
final messageSearchBloc = MessageSearchBloc.of(context);
|
||||||
messageSearchBloc.search(
|
messageSearchBloc.search(
|
||||||
filter: widget.filters,
|
filter: widget.filters,
|
||||||
sort: widget.sortOptions,
|
sort: widget.sortOptions,
|
||||||
query: widget.messageQuery,
|
query: widget.messageQuery,
|
||||||
pagination: widget.paginationParams,
|
pagination: widget.paginationParams,
|
||||||
|
messageFilter: widget.messageFilters,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -54,7 +54,7 @@ class TypingIndicator extends StatelessWidget {
|
|||||||
height: 4,
|
height: 4,
|
||||||
),
|
),
|
||||||
Text(
|
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,
|
maxLines: 1,
|
||||||
style: style,
|
style: style,
|
||||||
),
|
),
|
||||||
|
|||||||
@@ -30,10 +30,10 @@ class UrlAttachment extends StatelessWidget {
|
|||||||
margin: EdgeInsets.symmetric(horizontal: 8.0),
|
margin: EdgeInsets.symmetric(horizontal: 8.0),
|
||||||
child: Stack(
|
child: Stack(
|
||||||
children: [
|
children: [
|
||||||
Center(
|
CachedNetworkImage(
|
||||||
child: CachedNetworkImage(
|
width: double.infinity,
|
||||||
imageUrl: urlAttachment.imageUrl,
|
imageUrl: urlAttachment.imageUrl,
|
||||||
),
|
fit: BoxFit.cover,
|
||||||
),
|
),
|
||||||
Positioned(
|
Positioned(
|
||||||
left: 0.0,
|
left: 0.0,
|
||||||
|
|||||||
Reference in New Issue
Block a user