176 lines
6.6 KiB
Dart
176 lines
6.6 KiB
Dart
import 'package:carousel_slider/carousel_slider.dart';
|
|
import 'package:didvan/config/design_config.dart';
|
|
import 'package:didvan/config/theme_data.dart';
|
|
import 'package:didvan/constants/app_icons.dart';
|
|
import 'package:didvan/models/enums.dart';
|
|
import 'package:didvan/models/requests/studio.dart';
|
|
import 'package:didvan/routes/routes.dart';
|
|
import 'package:didvan/views/podcasts/studio_details/studio_details_state.dart';
|
|
import 'package:didvan/views/podcasts/podcasts_state.dart';
|
|
import 'package:didvan/views/widgets/didvan/text.dart';
|
|
import 'package:didvan/views/widgets/shimmer_placeholder.dart';
|
|
import 'package:didvan/views/widgets/skeleton_image.dart';
|
|
import 'package:flutter/material.dart';
|
|
import 'package:provider/provider.dart';
|
|
|
|
class StudioSlider extends StatefulWidget {
|
|
const StudioSlider({Key? key}) : super(key: key);
|
|
|
|
@override
|
|
State<StudioSlider> createState() => _StudioSliderState();
|
|
}
|
|
|
|
class _StudioSliderState extends State<StudioSlider> {
|
|
int selectedIndex = 0;
|
|
|
|
@override
|
|
Widget build(BuildContext context) {
|
|
final state = context.watch<PodcastsState>();
|
|
return Column(
|
|
children: [
|
|
CarouselSlider(
|
|
items: [
|
|
if (state.appState == AppState.busy)
|
|
const Padding(
|
|
padding: EdgeInsets.symmetric(horizontal: 4),
|
|
child: ShimmerPlaceholder(),
|
|
),
|
|
if (state.appState == AppState.idle)
|
|
for (var i = 0; i < state.sliders.length; i++)
|
|
Padding(
|
|
padding: const EdgeInsets.symmetric(horizontal: 4),
|
|
child: GestureDetector(
|
|
onTap: () {
|
|
if (state.videosSelected) {
|
|
Navigator.of(context)
|
|
.pushNamed(Routes.studioDetails, arguments: {
|
|
'onMarkChanged': state.changeMark,
|
|
'id': state.sliders[i].id,
|
|
'args':
|
|
const StudioRequestArgs(page: 0, type: 'video'),
|
|
'hasUnmarkConfirmation': false,
|
|
'isVideo': true,
|
|
});
|
|
return;
|
|
}
|
|
context.read<StudioDetailsState>().getStudioDetails(
|
|
state.sliders[i].id,
|
|
args: const StudioRequestArgs(
|
|
page: 0,
|
|
type: 'podcast',
|
|
),
|
|
);
|
|
},
|
|
child: Stack(
|
|
alignment: Alignment.center,
|
|
children: [
|
|
SkeletonImage(
|
|
borderRadius: DesignConfig.mediumBorderRadius,
|
|
imageUrl: state.sliders[i].image,
|
|
width: double.infinity,
|
|
height: double.infinity,
|
|
),
|
|
Positioned(
|
|
bottom: 0,
|
|
left: 0,
|
|
right: 0,
|
|
child: Container(
|
|
padding: const EdgeInsets.symmetric(
|
|
vertical: 4,
|
|
horizontal: 8,
|
|
),
|
|
decoration: BoxDecoration(
|
|
color: Theme.of(context)
|
|
.colorScheme
|
|
.focused
|
|
.withValues(alpha: 0.9),
|
|
borderRadius: const BorderRadius.vertical(
|
|
bottom: Radius.circular(10),
|
|
),
|
|
),
|
|
child: DidvanText(
|
|
state.sliders[i].title,
|
|
color: Theme.of(context).colorScheme.title,
|
|
style: Theme.of(context).textTheme.bodySmall,
|
|
),
|
|
),
|
|
),
|
|
if (state.videosSelected)
|
|
Container(
|
|
height: 52,
|
|
width: 52,
|
|
decoration: BoxDecoration(
|
|
shape: BoxShape.circle,
|
|
color: (state.videosSelected
|
|
? Theme.of(context).colorScheme.secondary
|
|
: Theme.of(context)
|
|
.colorScheme
|
|
.focusedBorder)
|
|
.withValues(alpha: 0.7),
|
|
),
|
|
child: Icon(
|
|
DidvanIcons.play_solid,
|
|
color: Theme.of(context).colorScheme.white,
|
|
size: 48,
|
|
),
|
|
),
|
|
],
|
|
),
|
|
),
|
|
),
|
|
],
|
|
options: CarouselOptions(
|
|
autoPlayAnimationDuration: DesignConfig.mediumAnimationDuration,
|
|
onPageChanged: (index, reason) => setState(
|
|
() => selectedIndex = index,
|
|
),
|
|
viewportFraction: 0.94,
|
|
aspectRatio: 16 / 9,
|
|
autoPlay: state.appState == AppState.idle,
|
|
),
|
|
),
|
|
const SizedBox(height: 16),
|
|
Row(
|
|
mainAxisAlignment: MainAxisAlignment.center,
|
|
children: [
|
|
for (var i = 0; i < state.sliders.length; i++)
|
|
_SliderIndicator(
|
|
isCurrentIndex: selectedIndex == i,
|
|
isVideo: state.videosSelected,
|
|
),
|
|
],
|
|
),
|
|
const SizedBox(height: 16),
|
|
],
|
|
);
|
|
}
|
|
}
|
|
|
|
class _SliderIndicator extends StatelessWidget {
|
|
final bool isCurrentIndex;
|
|
final bool isVideo;
|
|
const _SliderIndicator({
|
|
Key? key,
|
|
required this.isCurrentIndex,
|
|
required this.isVideo,
|
|
}) : super(key: key);
|
|
|
|
@override
|
|
Widget build(BuildContext context) {
|
|
return AnimatedContainer(
|
|
duration: DesignConfig.lowAnimationDuration,
|
|
height: 8,
|
|
width: 8,
|
|
margin: const EdgeInsets.only(left: 4),
|
|
decoration: BoxDecoration(
|
|
border: Border.all(
|
|
color: Theme.of(context).colorScheme.focusedBorder,
|
|
),
|
|
shape: BoxShape.circle,
|
|
color:
|
|
isCurrentIndex ? Theme.of(context).colorScheme.focusedBorder : null,
|
|
),
|
|
);
|
|
}
|
|
}
|