didvan-app/lib/views/home/media/podcast_tab_page.dart

313 lines
11 KiB
Dart

// ignore_for_file: deprecated_member_use
import 'dart:async';
import 'package:didvan/config/design_config.dart';
import 'package:didvan/models/requests/studio.dart';
import 'package:didvan/routes/routes.dart';
import 'package:didvan/services/media/media.dart';
import 'package:didvan/views/home/media/widgets/featured_podcast_card.dart';
import 'package:didvan/views/home/media/widgets/podcast_list_card.dart';
import 'package:didvan/views/podcasts/podcasts_state.dart';
import 'package:didvan/views/widgets/item_title.dart';
import 'package:didvan/views/widgets/state_handlers/empty_result.dart';
import 'package:didvan/views/widgets/state_handlers/state_handler.dart';
import 'package:flutter/material.dart';
import 'package:flutter_svg/svg.dart';
import 'package:provider/provider.dart';
class PodcastTabPage extends StatefulWidget {
const PodcastTabPage({super.key});
@override
State<PodcastTabPage> createState() => _PodcastTabPageState();
}
class _PodcastTabPageState extends State<PodcastTabPage> {
int _currentFeaturedIndex = 0;
Timer? _rotationTimer;
bool _isPlaying = false;
@override
void initState() {
super.initState();
Future.microtask(() {
context.read<PodcastsState>().init(true);
context.read<PodcastsState>().getStudios(page: 1);
});
}
void _startRotation() {
_rotationTimer?.cancel();
_rotationTimer = Timer.periodic(const Duration(seconds: 5), (timer) {
final state = context.read<PodcastsState>();
if (state.studios.isNotEmpty && mounted && !_isPlaying) {
setState(() {
_currentFeaturedIndex =
(_currentFeaturedIndex + 1) % state.studios.length;
});
}
});
}
void _onPlayStateChanged(bool isPlaying) {
setState(() {
_isPlaying = isPlaying;
});
}
void _showSortDialog() {
final state = context.read<PodcastsState>();
showModalBottomSheet(
backgroundColor: DesignConfig.isDark
? const Color.fromARGB(255, 30, 30, 30)
: Colors.white,
context: context,
builder: (context) {
return Container(
padding: const EdgeInsets.all(16),
child: Column(
mainAxisSize: MainAxisSize.min,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Padding(
padding:
const EdgeInsets.only(bottom: 8.0, right: 16.0, top: 8.0),
child: Row(
children: [
SvgPicture.asset('lib/assets/icons/Sort Regular.svg'),
const SizedBox(
width: 5,
),
Text(
'مرتب‌سازی',
style: Theme.of(context)
.textTheme
.titleMedium
?.copyWith(fontWeight: FontWeight.bold),
),
],
),
),
ListTile(
title: const Text('جدیدترین‌ها'),
leading: Radio<int>(
value: 0,
groupValue: state.selectedSortTypeIndex,
onChanged: (int? value) {
if (value != null) {
state.selectedSortTypeIndex = value;
state.getStudios(page: 1);
Navigator.pop(context);
}
},
activeColor: const Color.fromARGB(255, 178, 4, 54),
),
onTap: () {
state.selectedSortTypeIndex = 0;
state.getStudios(page: 1);
Navigator.pop(context);
},
),
ListTile(
title: const Text('قدیمی‌ترین‌ها'),
leading: Radio<int>(
value: 1,
groupValue: state.selectedSortTypeIndex,
onChanged: (int? value) {
if (value != null) {
state.selectedSortTypeIndex = value;
state.getStudios(page: 1);
Navigator.pop(context);
}
},
activeColor: const Color.fromARGB(255, 178, 4, 54),
),
onTap: () {
state.selectedSortTypeIndex = 1;
state.getStudios(page: 1);
Navigator.pop(context);
},
),
ListTile(
title: const Text('پربازدیدترین‌ها'),
leading: Radio<int>(
value: 2,
groupValue: state.selectedSortTypeIndex,
onChanged: (int? value) {
if (value != null) {
state.selectedSortTypeIndex = value;
state.getStudios(page: 1);
Navigator.pop(context);
}
},
activeColor: const Color.fromARGB(255, 178, 4, 54),
),
onTap: () {
state.selectedSortTypeIndex = 2;
state.getStudios(page: 1);
Navigator.pop(context);
},
),
ListTile(
title: const Text('پربحث‌ترین‌ها'),
leading: Radio<int>(
value: 3,
groupValue: state.selectedSortTypeIndex,
onChanged: (int? value) {
if (value != null) {
state.selectedSortTypeIndex = value;
state.getStudios(page: 1);
Navigator.pop(context);
}
},
activeColor: const Color.fromARGB(255, 178, 4, 54),
),
onTap: () {
state.selectedSortTypeIndex = 3;
state.getStudios(page: 1);
Navigator.pop(context);
},
),
],
),
);
},
);
}
void _navigateToDetails(int index) {
final state = context.read<PodcastsState>();
final item = state.studios[index];
Navigator.pushNamed(
context,
Routes.studioDetails,
arguments: {
'id': item.id,
'type': item.type,
'onMarkChanged': (int id, bool value, [bool shouldUpdate = true]) {
context.read<PodcastsState>().changeMark(id, value, shouldUpdate);
},
'args': StudioRequestArgs(
page: state.page,
type: state.type,
search: state.search,
order: state.order,
asc: state.selectedSortTypeIndex == 1,
endDate: state.endDate?.split(' ').first,
startDate: state.startDate?.split(' ').first,
),
},
);
}
@override
void dispose() {
_rotationTimer?.cancel();
if (MediaService.isPlayingFromFeaturedCard &&
MediaService.audioPlayer.playing) {
MediaService.audioPlayer.pause();
}
super.dispose();
}
@override
Widget build(BuildContext context) {
final state = context.watch<PodcastsState>();
return StateHandler<PodcastsState>(
state: state,
emptyState: EmptyResult(
onNewSearch: () {},
),
enableEmptyState: state.studios.isEmpty,
builder: (context, state) {
if (state.studios.isEmpty) {
return const SizedBox.shrink();
}
if (_rotationTimer == null || !_rotationTimer!.isActive) {
WidgetsBinding.instance.addPostFrameCallback((_) {
_startRotation();
});
}
return SingleChildScrollView(
child: Column(
children: [
AnimatedSwitcher(
duration: const Duration(milliseconds: 500),
transitionBuilder: (Widget child, Animation<double> animation) {
return FadeTransition(opacity: animation, child: child);
},
child: FeaturedPodcastCard(
key: ValueKey<int?>(state.studios[_currentFeaturedIndex].id),
podcast: state.studios[_currentFeaturedIndex],
onTap: () => _navigateToDetails(_currentFeaturedIndex),
onPlayStateChanged: _onPlayStateChanged,
),
),
if (state.studios.length > 1)
Padding(
padding:
const EdgeInsets.symmetric(horizontal: 16, vertical: 4),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
ItemTitle(
title: 'همه پادکست‌ها',
color: DesignConfig.isDark
? const Color.fromARGB(255, 0, 90, 119)
: const Color.fromARGB(255, 0, 53, 70),
style: const TextStyle(
fontWeight: FontWeight.bold, fontSize: 18),
),
Row(
children: [
GestureDetector(
onTap: _showSortDialog,
child: Text(
state.orderString,
style: TextStyle(
color: DesignConfig.isDark
? const Color.fromARGB(255, 0, 90, 119)
: const Color.fromARGB(255, 0, 53, 70)),
)),
IconButton(
onPressed: _showSortDialog,
icon: SvgPicture.asset(
'lib/assets/icons/sort2.svg',
color: DesignConfig.isDark
? const Color.fromARGB(255, 0, 90, 119)
: null)),
],
),
],
),
),
if (state.studios.length > 1)
ListView.builder(
itemCount: state.studios.length,
shrinkWrap: true,
physics: const NeverScrollableScrollPhysics(),
itemBuilder: (context, index) {
final podcast = state.studios[index];
// NEW: بررسی اینکه آیا این آیتم، آخرین آیتم در لیست است
final bool isLast = index == state.studios.length - 1;
return PodcastListCard(
podcast: podcast,
onTap: () => _navigateToDetails(index),
isLastItem: isLast, // NEW: ارسال پارامتر به ویجت کارت
);
},
),
],
),
);
},
onRetry: () => context.read<PodcastsState>().getStudios(page: 1),
);
}
}