Add ability to block and report in search results
This commit is contained in:
parent
97a742f74c
commit
8eeed4e716
7 changed files with 103 additions and 60 deletions
|
|
@ -37,7 +37,7 @@ abstract class _UserStoreBase with Store {
|
|||
final success = await twitchApi.blockUser(userId: targetId, headers: headers);
|
||||
// Add a slight delay between requests, otherwise the blocked list won't properly update.
|
||||
// Weird behavior, might be something to do with PUT request and time to create and update resource?
|
||||
await Future.delayed(const Duration(milliseconds: 200));
|
||||
await Future.delayed(const Duration(milliseconds: 300));
|
||||
if (success) await refreshBlockedUsers(headers: headers);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -31,7 +31,7 @@ class ChatDetails extends StatelessWidget {
|
|||
chatDetails: chatDetails,
|
||||
userLogin: userLogin,
|
||||
),
|
||||
)
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
|
|
|
|||
|
|
@ -126,8 +126,8 @@ class _ChattersListState extends State<ChattersList> {
|
|||
),
|
||||
),
|
||||
...chatDetailStore.filteredUsers.expandIndexed(
|
||||
(index, type) => [
|
||||
if (type.isNotEmpty) ...[
|
||||
(index, users) => [
|
||||
if (users.isNotEmpty) ...[
|
||||
SliverPadding(
|
||||
padding: const EdgeInsets.only(left: 10.0, right: 10.0, top: 20.0),
|
||||
sliver: SliverToBoxAdapter(
|
||||
|
|
@ -141,8 +141,8 @@ class _ChattersListState extends State<ChattersList> {
|
|||
padding: const EdgeInsets.only(left: 10.0, right: 10.0, top: 5.0),
|
||||
sliver: SliverList(
|
||||
delegate: SliverChildBuilderDelegate(
|
||||
(context, index) => Text(type[index]),
|
||||
childCount: type.length,
|
||||
(context, index) => Text(users[index]),
|
||||
childCount: users.length,
|
||||
),
|
||||
),
|
||||
),
|
||||
|
|
|
|||
|
|
@ -4,6 +4,7 @@ import 'package:frosty/constants/constants.dart';
|
|||
import 'package:frosty/models/channel.dart';
|
||||
import 'package:frosty/screens/channel/video_chat.dart';
|
||||
import 'package:frosty/screens/home/stores/search_store.dart';
|
||||
import 'package:frosty/widgets/block_report_modal.dart';
|
||||
import 'package:frosty/widgets/loading_indicator.dart';
|
||||
import 'package:frosty/widgets/profile_picture.dart';
|
||||
import 'package:mobx/mobx.dart';
|
||||
|
|
@ -60,42 +61,56 @@ class SearchResultsChannels extends StatelessWidget {
|
|||
),
|
||||
);
|
||||
case FutureStatus.fulfilled:
|
||||
final List<ChannelQuery> results = future.result;
|
||||
final results = (future.result as List<ChannelQuery>)
|
||||
.where((channel) => !searchStore.authStore.user.blockedUsers.map((blockedUser) => blockedUser.userId).contains(channel.id));
|
||||
|
||||
return SliverList(
|
||||
delegate: SliverChildListDelegate.fixed([
|
||||
...results.map(
|
||||
(channel) => ListTile(
|
||||
title: Text(
|
||||
regexEnglish.hasMatch(channel.displayName) ? channel.displayName : channel.displayName + ' (${channel.broadcasterLogin})'),
|
||||
leading: ProfilePicture(userLogin: channel.broadcasterLogin),
|
||||
trailing: channel.isLive
|
||||
? ClipRRect(
|
||||
borderRadius: BorderRadius.circular(5.0),
|
||||
child: Container(
|
||||
color: const Color(0xFFF44336),
|
||||
padding: const EdgeInsets.all(10.0),
|
||||
child: const Text(
|
||||
'LIVE',
|
||||
style: TextStyle(fontWeight: FontWeight.bold),
|
||||
(channel) {
|
||||
final displayName =
|
||||
regexEnglish.hasMatch(channel.displayName) ? channel.displayName : channel.displayName + ' (${channel.broadcasterLogin})';
|
||||
|
||||
return ListTile(
|
||||
title: Text(displayName),
|
||||
leading: ProfilePicture(userLogin: channel.broadcasterLogin),
|
||||
trailing: channel.isLive
|
||||
? ClipRRect(
|
||||
borderRadius: BorderRadius.circular(5.0),
|
||||
child: Container(
|
||||
color: const Color(0xFFF44336),
|
||||
padding: const EdgeInsets.all(10.0),
|
||||
child: const Text(
|
||||
'LIVE',
|
||||
style: TextStyle(fontWeight: FontWeight.bold),
|
||||
),
|
||||
),
|
||||
),
|
||||
)
|
||||
: null,
|
||||
subtitle: channel.isLive
|
||||
? Text('Uptime: ${DateTime.now().difference(DateTime.parse(channel.startedAt)).toString().split('.')[0]}')
|
||||
: null,
|
||||
onTap: () => Navigator.push(
|
||||
context,
|
||||
MaterialPageRoute(
|
||||
builder: (context) => VideoChat(
|
||||
userId: channel.id,
|
||||
userName: channel.displayName,
|
||||
userLogin: channel.broadcasterLogin,
|
||||
)
|
||||
: null,
|
||||
subtitle: channel.isLive
|
||||
? Text('Uptime: ${DateTime.now().difference(DateTime.parse(channel.startedAt)).toString().split('.')[0]}')
|
||||
: null,
|
||||
onTap: () => Navigator.push(
|
||||
context,
|
||||
MaterialPageRoute(
|
||||
builder: (context) => VideoChat(
|
||||
userId: channel.id,
|
||||
userName: channel.displayName,
|
||||
userLogin: channel.broadcasterLogin,
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
onLongPress: () => showModalBottomSheet(
|
||||
context: context,
|
||||
builder: (context) => BlockReportModal(
|
||||
authStore: searchStore.authStore,
|
||||
name: displayName,
|
||||
userLogin: channel.broadcasterLogin,
|
||||
userId: channel.id,
|
||||
),
|
||||
),
|
||||
);
|
||||
},
|
||||
),
|
||||
ListTile(
|
||||
title: Text('Go to channel "$query"'),
|
||||
|
|
|
|||
|
|
@ -4,10 +4,9 @@ import 'package:frosty/constants/constants.dart';
|
|||
import 'package:frosty/models/stream.dart';
|
||||
import 'package:frosty/screens/channel/video_chat.dart';
|
||||
import 'package:frosty/screens/home/stores/list_store.dart';
|
||||
import 'package:frosty/widgets/block_button.dart';
|
||||
import 'package:frosty/widgets/block_report_modal.dart';
|
||||
import 'package:frosty/widgets/loading_indicator.dart';
|
||||
import 'package:frosty/widgets/profile_picture.dart';
|
||||
import 'package:frosty/widgets/report_button.dart';
|
||||
import 'package:intl/intl.dart';
|
||||
|
||||
/// A tappable card widget that displays a stream's thumbnail and details.
|
||||
|
|
@ -56,28 +55,11 @@ class StreamCard extends StatelessWidget {
|
|||
),
|
||||
onLongPress: () => showModalBottomSheet(
|
||||
context: context,
|
||||
builder: (context) => Column(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: [
|
||||
Container(
|
||||
padding: const EdgeInsets.symmetric(horizontal: 10.0),
|
||||
width: double.infinity,
|
||||
child: BlockButton(
|
||||
authStore: listStore.authStore,
|
||||
targetUser: streamerName,
|
||||
targetUserId: streamInfo.userId,
|
||||
simple: false,
|
||||
),
|
||||
),
|
||||
Container(
|
||||
padding: const EdgeInsets.symmetric(horizontal: 10.0),
|
||||
width: double.infinity,
|
||||
child: ReportButton(
|
||||
userLogin: streamInfo.userLogin,
|
||||
name: streamerName,
|
||||
),
|
||||
),
|
||||
],
|
||||
builder: (context) => BlockReportModal(
|
||||
authStore: listStore.authStore,
|
||||
name: streamerName,
|
||||
userLogin: streamInfo.userLogin,
|
||||
userId: streamInfo.userId,
|
||||
),
|
||||
),
|
||||
child: Padding(
|
||||
|
|
|
|||
|
|
@ -27,7 +27,7 @@ class BlockButton extends StatelessWidget {
|
|||
builder: (context) => AlertDialog(
|
||||
title: isBlocked ? const Text('Unblock') : const Text('Block'),
|
||||
content: Text(
|
||||
'Are you sure you want to ${isBlocked ? 'unblock $targetUser?' : 'block $targetUser? This will hide them from channel lists and chat messages.'}'),
|
||||
'Are you sure you want to ${isBlocked ? 'unblock $targetUser?' : 'block $targetUser? This will remove them from channel lists, search results, and chat messages.'}'),
|
||||
actions: [
|
||||
TextButton(
|
||||
onPressed: Navigator.of(context).pop,
|
||||
|
|
|
|||
46
lib/widgets/block_report_modal.dart
Normal file
46
lib/widgets/block_report_modal.dart
Normal file
|
|
@ -0,0 +1,46 @@
|
|||
import 'package:flutter/widgets.dart';
|
||||
import 'package:frosty/core/auth/auth_store.dart';
|
||||
import 'package:frosty/widgets/block_button.dart';
|
||||
import 'package:frosty/widgets/report_button.dart';
|
||||
|
||||
class BlockReportModal extends StatelessWidget {
|
||||
final AuthStore authStore;
|
||||
final String name;
|
||||
final String userLogin;
|
||||
final String userId;
|
||||
|
||||
const BlockReportModal({
|
||||
Key? key,
|
||||
required this.authStore,
|
||||
required this.name,
|
||||
required this.userLogin,
|
||||
required this.userId,
|
||||
}) : super(key: key);
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Column(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: [
|
||||
Container(
|
||||
padding: const EdgeInsets.symmetric(horizontal: 10.0),
|
||||
width: double.infinity,
|
||||
child: BlockButton(
|
||||
authStore: authStore,
|
||||
targetUser: name,
|
||||
targetUserId: userId,
|
||||
simple: false,
|
||||
),
|
||||
),
|
||||
Container(
|
||||
padding: const EdgeInsets.symmetric(horizontal: 10.0),
|
||||
width: double.infinity,
|
||||
child: ReportButton(
|
||||
userLogin: userLogin,
|
||||
name: name,
|
||||
),
|
||||
),
|
||||
],
|
||||
);
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue