didvan-app/lib/views/home/studio/widgets/slider.dart

181 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/home/studio/studio_details/studio_details_state.dart';
import 'package:didvan/views/home/studio/studio_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<StudioState>();
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: (state.videosSelected
? Theme.of(context)
.colorScheme
.secondaryDisabled
: Theme.of(context).colorScheme.focused)
.withOpacity(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.caption,
),
),
),
Container(
height: 52,
width: 52,
decoration: BoxDecoration(
shape: BoxShape.circle,
color: Theme.of(context)
.colorScheme
.secondary
.withOpacity(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);
Color _color(BuildContext context) {
if (isVideo) {
return Theme.of(context).colorScheme.secondary;
}
return Theme.of(context).colorScheme.focusedBorder;
}
@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: _color(context),
),
shape: BoxShape.circle,
color: isCurrentIndex ? _color(context) : null,
),
);
}
}