2022-01-02 19:12:39 -05:00
|
|
|
import 'package:flutter/material.dart';
|
2022-06-27 23:23:09 -04:00
|
|
|
import 'package:flutter/services.dart';
|
2022-01-05 09:38:05 -05:00
|
|
|
import 'package:flutter_mobx/flutter_mobx.dart';
|
2022-08-31 14:11:45 -04:00
|
|
|
import 'package:frosty/constants.dart';
|
2022-01-05 09:38:05 -05:00
|
|
|
import 'package:frosty/models/channel.dart';
|
2022-08-31 14:11:45 -04:00
|
|
|
import 'package:frosty/screens/channel/channel.dart';
|
|
|
|
|
import 'package:frosty/screens/home/search/search_store.dart';
|
2022-06-28 10:32:16 -04:00
|
|
|
import 'package:frosty/widgets/alert_message.dart';
|
2022-02-09 17:54:43 -05:00
|
|
|
import 'package:frosty/widgets/block_report_modal.dart';
|
2022-01-05 09:38:05 -05:00
|
|
|
import 'package:frosty/widgets/loading_indicator.dart';
|
2022-01-02 19:12:39 -05:00
|
|
|
import 'package:frosty/widgets/profile_picture.dart';
|
2023-01-18 05:34:54 -05:00
|
|
|
import 'package:frosty/widgets/uptime.dart';
|
2022-01-05 09:38:05 -05:00
|
|
|
import 'package:mobx/mobx.dart';
|
2022-01-02 19:12:39 -05:00
|
|
|
|
2022-05-12 04:58:03 -04:00
|
|
|
class SearchResultsChannels extends StatefulWidget {
|
2022-01-02 19:12:39 -05:00
|
|
|
final SearchStore searchStore;
|
2022-01-05 09:38:05 -05:00
|
|
|
final String query;
|
2022-01-02 19:12:39 -05:00
|
|
|
|
2022-01-05 09:38:05 -05:00
|
|
|
const SearchResultsChannels({
|
|
|
|
|
Key? key,
|
|
|
|
|
required this.searchStore,
|
|
|
|
|
required this.query,
|
|
|
|
|
}) : super(key: key);
|
2022-01-02 19:12:39 -05:00
|
|
|
|
2022-05-12 04:58:03 -04:00
|
|
|
@override
|
|
|
|
|
State<SearchResultsChannels> createState() => _SearchResultsChannelsState();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
class _SearchResultsChannelsState extends State<SearchResultsChannels> {
|
2022-01-05 09:38:05 -05:00
|
|
|
Future<void> _handleSearch(BuildContext context, String search) async {
|
|
|
|
|
try {
|
2022-05-12 04:58:03 -04:00
|
|
|
final channelInfo = await widget.searchStore.searchChannel(search);
|
|
|
|
|
|
|
|
|
|
if (!mounted) return;
|
2022-01-05 09:38:05 -05:00
|
|
|
Navigator.push(
|
|
|
|
|
context,
|
|
|
|
|
MaterialPageRoute(
|
2022-01-10 17:34:01 -05:00
|
|
|
builder: (context) => VideoChat(
|
2022-01-25 15:43:26 -05:00
|
|
|
userId: channelInfo.broadcasterId,
|
|
|
|
|
userName: channelInfo.broadcasterName,
|
|
|
|
|
userLogin: channelInfo.broadcasterLogin,
|
2022-01-02 19:12:39 -05:00
|
|
|
),
|
2022-01-05 09:38:05 -05:00
|
|
|
),
|
|
|
|
|
);
|
2022-06-28 10:32:16 -04:00
|
|
|
} catch (error) {
|
2022-01-15 13:16:43 -05:00
|
|
|
final snackBar = SnackBar(
|
2023-10-22 18:38:32 -04:00
|
|
|
content: AlertMessage(
|
|
|
|
|
message: error.toString(),
|
|
|
|
|
centered: false,
|
|
|
|
|
),
|
2022-01-05 09:38:05 -05:00
|
|
|
);
|
2022-06-28 10:32:16 -04:00
|
|
|
|
2022-01-05 09:38:05 -05:00
|
|
|
ScaffoldMessenger.of(context).showSnackBar(snackBar);
|
2022-01-02 19:12:39 -05:00
|
|
|
}
|
2022-01-05 09:38:05 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@override
|
|
|
|
|
Widget build(BuildContext context) {
|
|
|
|
|
return Observer(
|
|
|
|
|
builder: (context) {
|
2022-05-12 04:58:03 -04:00
|
|
|
final future = widget.searchStore.channelFuture;
|
2022-01-02 19:12:39 -05:00
|
|
|
|
2022-01-05 14:33:01 -05:00
|
|
|
switch (future!.status) {
|
2022-01-05 09:38:05 -05:00
|
|
|
case FutureStatus.pending:
|
|
|
|
|
return const SliverToBoxAdapter(
|
|
|
|
|
child: LoadingIndicator(
|
2022-06-28 10:32:16 -04:00
|
|
|
subtitle: 'Loading channels...',
|
2022-01-05 09:38:05 -05:00
|
|
|
),
|
|
|
|
|
);
|
|
|
|
|
case FutureStatus.rejected:
|
|
|
|
|
return const SliverToBoxAdapter(
|
2022-06-28 10:32:16 -04:00
|
|
|
child: SizedBox(
|
|
|
|
|
height: 100.0,
|
2023-01-18 05:34:54 -05:00
|
|
|
child: AlertMessage(message: 'Failed to get channels'),
|
2022-01-08 09:34:54 -05:00
|
|
|
),
|
2022-01-05 09:38:05 -05:00
|
|
|
);
|
|
|
|
|
case FutureStatus.fulfilled:
|
2023-04-29 11:34:28 -04:00
|
|
|
final results = (future.result as List<ChannelQuery>).where(
|
2023-10-22 18:38:32 -04:00
|
|
|
(channel) => !widget.searchStore.authStore.user.blockedUsers
|
|
|
|
|
.map((blockedUser) => blockedUser.userId)
|
|
|
|
|
.contains(channel.id),
|
|
|
|
|
);
|
2022-01-05 09:38:05 -05:00
|
|
|
|
|
|
|
|
return SliverList(
|
2023-01-18 05:34:54 -05:00
|
|
|
delegate: SliverChildListDelegate.fixed(
|
|
|
|
|
[
|
|
|
|
|
...results.map(
|
|
|
|
|
(channel) {
|
2023-04-29 11:34:28 -04:00
|
|
|
final displayName = regexEnglish
|
|
|
|
|
.hasMatch(channel.displayName)
|
2023-01-18 05:34:54 -05:00
|
|
|
? channel.displayName
|
|
|
|
|
: '${channel.displayName} (${channel.broadcasterLogin})';
|
2022-02-09 17:54:43 -05:00
|
|
|
|
2023-10-22 18:38:32 -04:00
|
|
|
return InkWell(
|
2023-01-18 05:34:54 -05:00
|
|
|
onTap: () => Navigator.push(
|
|
|
|
|
context,
|
|
|
|
|
MaterialPageRoute(
|
|
|
|
|
builder: (context) => VideoChat(
|
|
|
|
|
userId: channel.id,
|
|
|
|
|
userName: channel.displayName,
|
|
|
|
|
userLogin: channel.broadcasterLogin,
|
|
|
|
|
),
|
2022-02-09 17:54:43 -05:00
|
|
|
),
|
|
|
|
|
),
|
2023-01-18 05:34:54 -05:00
|
|
|
onLongPress: () {
|
|
|
|
|
HapticFeedback.lightImpact();
|
2022-06-27 23:23:09 -04:00
|
|
|
|
2023-01-18 05:34:54 -05:00
|
|
|
showModalBottomSheet(
|
|
|
|
|
context: context,
|
|
|
|
|
builder: (context) => BlockReportModal(
|
|
|
|
|
authStore: widget.searchStore.authStore,
|
|
|
|
|
name: displayName,
|
|
|
|
|
userLogin: channel.broadcasterLogin,
|
|
|
|
|
userId: channel.id,
|
|
|
|
|
),
|
|
|
|
|
);
|
|
|
|
|
},
|
2023-10-22 18:38:32 -04:00
|
|
|
child: ListTile(
|
|
|
|
|
title: Text(displayName),
|
2023-04-29 11:34:28 -04:00
|
|
|
leading: ProfilePicture(
|
2023-10-22 18:38:32 -04:00
|
|
|
userLogin: channel.broadcasterLogin,
|
|
|
|
|
radius: 16,
|
|
|
|
|
),
|
2023-01-18 05:34:54 -05:00
|
|
|
subtitle: channel.isLive
|
|
|
|
|
? Row(
|
|
|
|
|
children: [
|
|
|
|
|
const Icon(
|
|
|
|
|
Icons.circle,
|
|
|
|
|
color: Colors.red,
|
|
|
|
|
size: 10,
|
2022-06-29 16:37:43 -04:00
|
|
|
),
|
2023-01-18 05:34:54 -05:00
|
|
|
const SizedBox(width: 5),
|
|
|
|
|
Uptime(startTime: channel.startedAt),
|
|
|
|
|
],
|
|
|
|
|
)
|
|
|
|
|
: null,
|
|
|
|
|
),
|
|
|
|
|
);
|
|
|
|
|
},
|
|
|
|
|
),
|
2023-10-22 18:38:32 -04:00
|
|
|
ListTile(
|
|
|
|
|
title: Text('Go to channel "${widget.query}"'),
|
2023-01-18 05:34:54 -05:00
|
|
|
onTap: () => _handleSearch(context, widget.query),
|
|
|
|
|
trailing: const Icon(Icons.chevron_right_rounded),
|
2023-10-22 18:38:32 -04:00
|
|
|
),
|
2023-01-18 05:34:54 -05:00
|
|
|
],
|
|
|
|
|
),
|
2022-01-05 09:38:05 -05:00
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
},
|
2022-01-02 19:12:39 -05:00
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
}
|