D1APP-99 studio progress

This commit is contained in:
MohammadTaha Basiri 2022-03-17 15:35:15 +03:30
parent 5278238e19
commit 628ebbe271
12 changed files with 248 additions and 166 deletions

View File

@ -64,6 +64,9 @@ class RouteGenerator {
ChangeNotifierProvider<StudioState>( ChangeNotifierProvider<StudioState>(
create: (context) => StudioState(), create: (context) => StudioState(),
), ),
ChangeNotifierProvider<StudioDetailsState>(
create: (context) => StudioDetailsState(),
),
], ],
child: const Home(), child: const Home(),
), ),
@ -103,8 +106,8 @@ class RouteGenerator {
); );
case Routes.studioDetails: case Routes.studioDetails:
return _createRoute( return _createRoute(
ChangeNotifierProvider<StudioDetailsState>( ChangeNotifierProvider<StudioDetailsState>.value(
create: (context) => StudioDetailsState(), value: (settings.arguments as Map<String, dynamic>)['state'],
child: StudioDetails( child: StudioDetails(
pageData: settings.arguments as Map<String, dynamic>, pageData: settings.arguments as Map<String, dynamic>,
), ),

View File

@ -1,3 +1,5 @@
import 'package:didvan/models/requests/studio.dart';
import 'package:didvan/models/studio_details_data.dart';
import 'package:didvan/services/network/request.dart'; import 'package:didvan/services/network/request.dart';
import 'package:didvan/services/network/request_helper.dart'; import 'package:didvan/services/network/request_helper.dart';
import 'package:flutter/foundation.dart'; import 'package:flutter/foundation.dart';
@ -7,8 +9,8 @@ import 'package:just_audio/just_audio.dart';
class MediaService { class MediaService {
static final AudioPlayer audioPlayer = AudioPlayer(); static final AudioPlayer audioPlayer = AudioPlayer();
static String? audioPlayerTag; static String? audioPlayerTag;
static String? audioPlayerTitle; static StudioDetailsData? currentPodcast;
static String? audioPlayerCover; static StudioRequestArgs? podcastPlaylistArgs;
static void init() { static void init() {
audioPlayer.positionStream.listen((event) { audioPlayer.positionStream.listen((event) {
@ -21,6 +23,7 @@ class MediaService {
static Future<void> handleAudioPlayback({ static Future<void> handleAudioPlayback({
required dynamic audioSource, required dynamic audioSource,
bool isVoiceMessage = true,
}) async { }) async {
bool isNetworkAudio = audioSource.runtimeType == String; bool isNetworkAudio = audioSource.runtimeType == String;
String tag; String tag;
@ -40,9 +43,11 @@ class MediaService {
audioPlayerTag = tag; audioPlayerTag = tag;
if (isNetworkAudio) { if (isNetworkAudio) {
await audioPlayer.setUrl( await audioPlayer.setUrl(
RequestHelper.baseUrl + isVoiceMessage
audioSource + ? (RequestHelper.baseUrl +
'?accessToken=${RequestService.token}', audioSource +
'?accessToken=${RequestService.token}')
: audioSource,
); );
} else { } else {
if (kIsWeb) { if (kIsWeb) {
@ -58,6 +63,8 @@ class MediaService {
static Future<void> resetAudioPlayer() async { static Future<void> resetAudioPlayer() async {
audioPlayerTag = null; audioPlayerTag = null;
currentPodcast = null;
podcastPlaylistArgs = null;
MediaService.audioPlayer.stop(); MediaService.audioPlayer.stop();
} }

View File

@ -79,7 +79,7 @@ class ActionSheetUtils {
isScrollControlled: true, isScrollControlled: true,
context: context, context: context,
builder: (context) => Container( builder: (context) => Container(
padding: const EdgeInsets.all(20), padding: data.hasPadding ? const EdgeInsets.all(20) : EdgeInsets.zero,
decoration: BoxDecoration( decoration: BoxDecoration(
color: Theme.of(context).colorScheme.surface, color: Theme.of(context).colorScheme.surface,
borderRadius: const BorderRadius.vertical( borderRadius: const BorderRadius.vertical(
@ -91,6 +91,7 @@ class ActionSheetUtils {
mainAxisSize: MainAxisSize.min, mainAxisSize: MainAxisSize.min,
crossAxisAlignment: CrossAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.start,
children: [ children: [
const SizedBox(height: 20),
Center( Center(
child: Container( child: Container(
height: 3, height: 3,
@ -99,23 +100,24 @@ class ActionSheetUtils {
), ),
), ),
const SizedBox(height: 8), const SizedBox(height: 8),
Row( if (data.title != null)
children: [ Row(
if (data.titleIcon != null) children: [
Icon( if (data.titleIcon != null)
data.titleIcon, Icon(
data.titleIcon,
color: data.titleColor ??
Theme.of(context).colorScheme.title,
),
if (data.titleIcon != null) const SizedBox(width: 8),
DidvanText(
data.title!,
style: Theme.of(context).textTheme.subtitle1,
color: data.titleColor ?? color: data.titleColor ??
Theme.of(context).colorScheme.title, Theme.of(context).colorScheme.title,
), )
if (data.titleIcon != null) const SizedBox(width: 8), ],
DidvanText( ),
data.title,
style: Theme.of(context).textTheme.subtitle1,
color:
data.titleColor ?? Theme.of(context).colorScheme.title,
)
],
),
const SizedBox(height: 28), const SizedBox(height: 28),
data.content, data.content,
const SizedBox(height: 28), const SizedBox(height: 28),
@ -169,30 +171,31 @@ class ActionSheetUtils {
mainAxisSize: MainAxisSize.min, mainAxisSize: MainAxisSize.min,
crossAxisAlignment: CrossAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.start,
children: [ children: [
Row( if (data.title != null)
mainAxisSize: MainAxisSize.min, Row(
children: [ mainAxisSize: MainAxisSize.min,
GestureDetector( children: [
onTap: () => Navigator.of(context).pop(), GestureDetector(
child: Icon( onTap: () => Navigator.of(context).pop(),
data.titleIcon, child: Icon(
size: 20, data.titleIcon,
color: data.titleColor, size: 20,
color: data.titleColor,
),
), ),
), const SizedBox(
const SizedBox( width: 8,
width: 8,
),
Expanded(
child: DidvanText(
data.title,
style: Theme.of(context).textTheme.headline3,
color: data.titleColor,
fontWeight: FontWeight.bold,
), ),
), Expanded(
], child: DidvanText(
), data.title!,
style: Theme.of(context).textTheme.headline3,
color: data.titleColor,
fontWeight: FontWeight.bold,
),
),
],
),
const SizedBox( const SizedBox(
height: 12, height: 12,
), ),

View File

@ -1,7 +1,7 @@
import 'dart:io'; import 'dart:io';
import 'package:didvan/services/media/media.dart'; import 'package:didvan/services/media/media.dart';
import 'package:didvan/views/home/widgets/audio_slider.dart'; import 'package:didvan/views/home/widgets/audio/audio_slider.dart';
import 'package:didvan/views/home/widgets/player_controller_button.dart'; import 'package:didvan/views/home/widgets/player_controller_button.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';

View File

@ -1,8 +1,8 @@
import 'package:didvan/models/tag.dart'; import 'package:didvan/models/tag.dart';
import 'package:didvan/models/view/app_bar_data.dart'; import 'package:didvan/models/view/app_bar_data.dart';
import 'package:didvan/views/home/hashtag/hashtag_state.dart'; import 'package:didvan/views/home/hashtag/hashtag_state.dart';
import 'package:didvan/views/home/widgets/news_overview.dart'; import 'package:didvan/views/home/widgets/overview/news.dart';
import 'package:didvan/views/home/widgets/radar_overview.dart'; import 'package:didvan/views/home/widgets/overview/radar.dart';
import 'package:didvan/views/widgets/didvan/scaffold.dart'; import 'package:didvan/views/widgets/didvan/scaffold.dart';
import 'package:didvan/views/widgets/state_handlers/sliver_state_handler.dart'; import 'package:didvan/views/widgets/state_handlers/sliver_state_handler.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';

View File

@ -6,9 +6,9 @@ import 'package:didvan/views/home/studio/studio_state.dart';
import 'package:didvan/views/home/studio/widgets/slider.dart'; import 'package:didvan/views/home/studio/widgets/slider.dart';
import 'package:didvan/views/home/studio/widgets/tab_bar.dart'; import 'package:didvan/views/home/studio/widgets/tab_bar.dart';
import 'package:didvan/views/home/widgets/logo_app_bar.dart'; import 'package:didvan/views/home/widgets/logo_app_bar.dart';
import 'package:didvan/views/home/widgets/podcast_overview.dart'; import 'package:didvan/views/home/widgets/overview/podcast.dart';
import 'package:didvan/views/home/widgets/overview/video.dart';
import 'package:didvan/views/home/widgets/search_field.dart'; import 'package:didvan/views/home/widgets/search_field.dart';
import 'package:didvan/views/home/widgets/video_overview.dart';
import 'package:didvan/views/widgets/didvan/divider.dart'; import 'package:didvan/views/widgets/didvan/divider.dart';
import 'package:didvan/views/widgets/didvan/icon_button.dart'; import 'package:didvan/views/widgets/didvan/icon_button.dart';
import 'package:didvan/views/widgets/didvan/radial_button.dart'; import 'package:didvan/views/widgets/didvan/radial_button.dart';
@ -25,7 +25,7 @@ class Studio extends StatefulWidget {
} }
class _StudioState extends State<Studio> { class _StudioState extends State<Studio> {
final FocusNode _focusNode = FocusNode(); final _focusNode = FocusNode();
@override @override
void initState() { void initState() {
@ -119,8 +119,6 @@ class _StudioState extends State<Studio> {
: PodcastOverview( : PodcastOverview(
podcast: state.studios[index], podcast: state.studios[index],
onMarkChanged: state.changeMark, onMarkChanged: state.changeMark,
hasUnmarkConfirmation: false,
onCommentsChanged: state.onCommentsChanged,
studioRequestArgs: StudioRequestArgs( studioRequestArgs: StudioRequestArgs(
page: state.page, page: state.page,
order: state.order, order: state.order,

View File

@ -1,12 +1,18 @@
import 'dart:io'; import 'dart:io';
import 'package:didvan/config/design_config.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/studio_details_data.dart'; import 'package:didvan/models/studio_details_data.dart';
import 'package:didvan/models/view/app_bar_data.dart'; import 'package:didvan/models/view/app_bar_data.dart';
import 'package:didvan/services/media/media.dart';
import 'package:didvan/views/home/studio/studio_details/studio_details_state.dart'; import 'package:didvan/views/home/studio/studio_details/studio_details_state.dart';
import 'package:didvan/views/home/widgets/audio_slider.dart'; import 'package:didvan/views/home/widgets/audio/audio_slider.dart';
import 'package:didvan/views/home/widgets/bookmark_button.dart';
import 'package:didvan/views/widgets/didvan/icon_button.dart';
import 'package:didvan/views/widgets/didvan/scaffold.dart'; import 'package:didvan/views/widgets/didvan/scaffold.dart';
import 'package:didvan/views/widgets/didvan/text.dart'; import 'package:didvan/views/widgets/didvan/text.dart';
import 'package:didvan/views/widgets/ink_wrapper.dart';
import 'package:didvan/views/widgets/skeleton_image.dart'; import 'package:didvan/views/widgets/skeleton_image.dart';
import 'package:didvan/views/widgets/state_handlers/state_handler.dart'; import 'package:didvan/views/widgets/state_handlers/state_handler.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
@ -30,15 +36,15 @@ class _StudioDetailsState extends State<StudioDetails> {
double _dwInPortrait = 0; double _dwInPortrait = 0;
double _scaleInPortrait = 1; double _scaleInPortrait = 1;
bool get _isVideo => widget.pageData['isVideo'];
@override @override
void initState() { void initState() {
final state = context.read<StudioDetailsState>(); final state = context.read<StudioDetailsState>();
Future.delayed( Future.delayed(
Duration.zero, Duration.zero,
() => state.getStudioDetails(widget.pageData['id']), () => state.getStudioDetails(widget.pageData['id']),
); );
state.args = widget.pageData['args']; state.args = widget.pageData['args'];
if (Platform.isAndroid) WebView.platform = AndroidWebView(); if (Platform.isAndroid) WebView.platform = AndroidWebView();
super.initState(); super.initState();
@ -96,6 +102,8 @@ class _StudioDetailsState extends State<StudioDetails> {
return true; return true;
}, },
child: DidvanScaffold( child: DidvanScaffold(
backgroundColor: Theme.of(context).colorScheme.surface,
padding: EdgeInsets.zero,
appBarData: _isFullScreen appBarData: _isFullScreen
? null ? null
: AppBarData( : AppBarData(
@ -103,15 +111,14 @@ class _StudioDetailsState extends State<StudioDetails> {
title: state.currentStudio.title, title: state.currentStudio.title,
), ),
children: [ children: [
if (_isVideo) SizedBox(
SizedBox( width: ds.width,
width: ds.width, height: _isFullScreen ? ds.height : ds.width * 9 / 16,
height: _isFullScreen ? ds.height : ds.width * 9 / 16, child: Stack(
child: Stack( children: [
children: [ WebView(
WebView( initialUrl: Uri.dataFromString(
initialUrl: Uri.dataFromString( '''
'''
<html> <html>
<head> <head>
<meta <meta
@ -144,27 +151,25 @@ class _StudioDetailsState extends State<StudioDetails> {
</body> </body>
</html> </html>
''', ''',
mimeType: 'text/html', mimeType: 'text/html',
).toString(), ).toString(),
javascriptMode: JavascriptMode.unrestricted, javascriptMode: JavascriptMode.unrestricted,
), ),
Positioned( Positioned(
right: 42, right: 42,
bottom: 8, bottom: 8,
child: GestureDetector( child: GestureDetector(
onTap: () => _changeFullSceen(!_isFullScreen), onTap: () => _changeFullSceen(!_isFullScreen),
child: Container( child: Container(
color: Colors.transparent, color: Colors.transparent,
width: 24, width: 24,
height: 30, height: 30,
),
), ),
), ),
], ),
), ],
), ),
if (!_isVideo) ),
AudioPlayerWidget(podcast: state.currentStudio),
], ],
), ),
), ),
@ -172,39 +177,3 @@ class _StudioDetailsState extends State<StudioDetails> {
); );
} }
} }
class AudioPlayerWidget extends StatelessWidget {
final StudioDetailsData podcast;
const AudioPlayerWidget({Key? key, required this.podcast}) : super(key: key);
@override
Widget build(BuildContext context) {
return Column(
children: [
Padding(
padding: const EdgeInsets.symmetric(horizontal: 24),
child: Hero(
tag: podcast.media,
child: SkeletonImage(
imageUrl: podcast.image,
aspectRatio: 1 / 1,
),
),
),
const SizedBox(height: 16),
DidvanText(
podcast.title,
style: Theme.of(context).textTheme.bodyText1,
),
const SizedBox(height: 16),
Padding(
padding: const EdgeInsets.symmetric(horizontal: 16),
child: AudioSlider(
tag: podcast.media,
showTimer: true,
),
),
],
);
}
}

View File

@ -6,15 +6,14 @@ import 'package:didvan/models/overview_data.dart';
import 'package:didvan/models/requests/studio.dart'; import 'package:didvan/models/requests/studio.dart';
import 'package:didvan/models/studio_details_data.dart'; import 'package:didvan/models/studio_details_data.dart';
import 'package:didvan/providers/core_provider.dart'; import 'package:didvan/providers/core_provider.dart';
import 'package:didvan/services/media/media.dart';
import 'package:didvan/services/network/request.dart'; import 'package:didvan/services/network/request.dart';
import 'package:didvan/services/network/request_helper.dart'; import 'package:didvan/services/network/request_helper.dart';
class StudioDetailsState extends CoreProvier { class StudioDetailsState extends CoreProvier {
final List<StudioDetailsData?> studios = []; final List<StudioDetailsData?> studios = [];
late Timer _trackingTimer; late int initialIndex;
int _trackingTimerCounter = 0; late StudioRequestArgs args;
late final int initialIndex;
late final StudioRequestArgs args;
bool isFetchingNewItem = false; bool isFetchingNewItem = false;
final List<int> relatedQueue = []; final List<int> relatedQueue = [];
@ -29,25 +28,36 @@ class StudioDetailsState extends CoreProvier {
} }
} }
Future<void> getStudioDetails(int id, {bool? isForward}) async { Future<void> getStudioDetails(int id,
{bool? isForward, StudioRequestArgs? args}) async {
if (args != null) {
this.args = args;
}
if (isForward == null) { if (isForward == null) {
appState = AppState.busy; appState = AppState.busy;
} else { } else {
isFetchingNewItem = true; isFetchingNewItem = true;
notifyListeners(); notifyListeners();
} }
final service = RequestService(RequestHelper.studioDetails(id, args)); final service = RequestService(RequestHelper.studioDetails(id, this.args));
await service.httpGet(); await service.httpGet();
_handleTracking(sendRequest: isForward != null);
if (service.isSuccess) { if (service.isSuccess) {
final result = service.result; final result = service.result;
final studio = StudioDetailsData.fromJson(result['studio']); final studio = StudioDetailsData.fromJson(result['studio']);
if (args.page == 0) { if (this.args.page == 0) {
studios.add(studio); studios.add(studio);
initialIndex = 0; initialIndex = 0;
appState = AppState.idle; appState = AppState.idle;
return; return;
} }
if (this.args.type == 'podcast') {
MediaService.currentPodcast = studio;
MediaService.podcastPlaylistArgs = args;
await MediaService.handleAudioPlayback(
audioSource: studio.media,
isVoiceMessage: false,
);
}
StudioDetailsData? prevStudio; StudioDetailsData? prevStudio;
if (result['prevStudio'].isNotEmpty) { if (result['prevStudio'].isNotEmpty) {
@ -121,21 +131,4 @@ class StudioDetailsState extends CoreProvier {
count; count;
notifyListeners(); notifyListeners();
} }
Future<void> _handleTracking({bool sendRequest = true}) async {
if (!sendRequest) {
_trackingTimer = Timer.periodic(const Duration(seconds: 1), (timer) {
_trackingTimerCounter++;
});
return;
}
//send request
_trackingTimerCounter = 0;
}
@override
void dispose() {
_trackingTimer.cancel();
super.dispose();
}
} }

View File

@ -1,11 +1,21 @@
import 'package:didvan/config/design_config.dart'; import 'package:didvan/config/design_config.dart';
import 'package:didvan/config/theme_data.dart'; import 'package:didvan/config/theme_data.dart';
import 'package:didvan/constants/app_icons.dart'; import 'package:didvan/constants/app_icons.dart';
import 'package:didvan/models/view/action_sheet_data.dart';
import 'package:didvan/routes/routes.dart';
import 'package:didvan/services/media/media.dart'; import 'package:didvan/services/media/media.dart';
import 'package:didvan/utils/action_sheet.dart';
import 'package:didvan/views/home/studio/studio_details/studio_details.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/home/widgets/audio/audio_player_widget.dart';
import 'package:didvan/views/home/widgets/audio/audio_slider.dart';
import 'package:didvan/views/widgets/didvan/icon_button.dart'; import 'package:didvan/views/widgets/didvan/icon_button.dart';
import 'package:didvan/views/widgets/didvan/text.dart'; import 'package:didvan/views/widgets/didvan/text.dart';
import 'package:didvan/views/widgets/skeleton_image.dart'; import 'package:didvan/views/widgets/skeleton_image.dart';
import 'package:expandable_bottom_sheet/expandable_bottom_sheet.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:provider/provider.dart';
class DidvanBNB extends StatelessWidget { class DidvanBNB extends StatelessWidget {
final int currentTabIndex; final int currentTabIndex;
@ -15,6 +25,9 @@ class DidvanBNB extends StatelessWidget {
{Key? key, required this.currentTabIndex, required this.onTabChanged}) {Key? key, required this.currentTabIndex, required this.onTabChanged})
: super(key: key); : super(key: key);
bool get _enablePlayerController =>
MediaService.currentPodcast != null || MediaService.audioPlayer.playing;
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
return StreamBuilder<bool>( return StreamBuilder<bool>(
@ -22,29 +35,89 @@ class DidvanBNB extends StatelessWidget {
builder: (context, snapshot) { builder: (context, snapshot) {
return Stack( return Stack(
children: [ children: [
AnimatedContainer( GestureDetector(
duration: DesignConfig.lowAnimationDuration, onTap: () => _showPlayerBottomSheet(context),
height: snapshot.data == true ? 120 : 72, child: AnimatedContainer(
decoration: BoxDecoration( padding: const EdgeInsets.only(top: 12),
color: DesignConfig.isDark duration: DesignConfig.lowAnimationDuration,
? Theme.of(context).colorScheme.focused height: _enablePlayerController ? 120 : 72,
: Theme.of(context).colorScheme.navigation, decoration: BoxDecoration(
borderRadius: const BorderRadius.vertical( color: DesignConfig.isDark
top: Radius.circular(16), ? Theme.of(context).colorScheme.focused
), : Theme.of(context).colorScheme.navigation,
), borderRadius: const BorderRadius.vertical(
child: Row( top: Radius.circular(16),
children: [
const DidvanIconButton(
icon: DidvanIcons.close_regular,
gestureSize: 24,
onPressed: MediaService.resetAudioPlayer,
), ),
const SizedBox(width: 16), ),
if (MediaService.audioPlayerCover != null) child: !_enablePlayerController
SkeletonImage(imageUrl: MediaService.audioPlayerCover!), ? const SizedBox()
const SizedBox(width: 16), : SizedBox(
], height: 48,
child: Row(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Padding(
padding: const EdgeInsets.only(
right: 12,
left: 16,
),
child: DidvanIconButton(
icon: DidvanIcons.close_regular,
color: DesignConfig.isDark
? null
: Theme.of(context).colorScheme.secondCTA,
gestureSize: 28,
onPressed: MediaService.resetAudioPlayer,
),
),
SkeletonImage(
imageUrl: MediaService.currentPodcast!.image,
width: 32,
height: 32,
),
const SizedBox(width: 16),
Expanded(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
DidvanText(
MediaService.currentPodcast!.title,
color: DesignConfig.isDark
? null
: Theme.of(context)
.colorScheme
.secondCTA,
),
AudioSlider(
disableThumb: true,
tag: MediaService.audioPlayerTag!,
),
],
),
),
Padding(
padding: const EdgeInsets.only(
left: 12,
right: 16,
),
child: DidvanIconButton(
gestureSize: 28,
color: DesignConfig.isDark
? null
: Theme.of(context).colorScheme.secondCTA,
icon: snapshot.data!
? DidvanIcons.pause_solid
: DidvanIcons.play_solid,
onPressed: () {
MediaService.handleAudioPlayback(
audioSource: MediaService.audioPlayerTag,
);
},
),
),
],
),
),
), ),
), ),
Positioned( Positioned(
@ -105,6 +178,31 @@ class DidvanBNB extends StatelessWidget {
); );
}); });
} }
void _showPlayerBottomSheet(BuildContext context) {
final detailsState = context.read<StudioDetailsState>();
showModalBottomSheet(
backgroundColor: Colors.transparent,
context: context,
isScrollControlled: true,
builder: (context) => ChangeNotifierProvider<StudioDetailsState>.value(
value: detailsState,
child: ExpandableBottomSheet(
background: Container(),
persistentHeader: AudioPlayerWidget(
podcast: MediaService.currentPodcast!,
),
expandableContent: Container(
height: 300,
width: double.infinity,
color: Theme.of(context).colorScheme.surface,
alignment: Alignment.center,
child: const DidvanText('!Under Construction'),
),
),
),
);
}
} }
class _NavBarItem extends StatelessWidget { class _NavBarItem extends StatelessWidget {

View File

@ -4,6 +4,7 @@ import 'package:didvan/models/overview_data.dart';
import 'package:didvan/models/requests/studio.dart'; import 'package:didvan/models/requests/studio.dart';
import 'package:didvan/routes/routes.dart'; import 'package:didvan/routes/routes.dart';
import 'package:didvan/utils/date_time.dart'; import 'package:didvan/utils/date_time.dart';
import 'package:didvan/views/home/studio/studio_details/studio_details_state.dart';
import 'package:didvan/views/home/widgets/bookmark_button.dart'; import 'package:didvan/views/home/widgets/bookmark_button.dart';
import 'package:didvan/views/home/widgets/duration_widget.dart'; import 'package:didvan/views/home/widgets/duration_widget.dart';
import 'package:didvan/views/widgets/didvan/card.dart'; import 'package:didvan/views/widgets/didvan/card.dart';
@ -13,6 +14,7 @@ import 'package:didvan/views/widgets/didvan/text.dart';
import 'package:didvan/views/widgets/shimmer_placeholder.dart'; import 'package:didvan/views/widgets/shimmer_placeholder.dart';
import 'package:didvan/views/widgets/skeleton_image.dart'; import 'package:didvan/views/widgets/skeleton_image.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:provider/provider.dart';
class VideoOverview extends StatelessWidget { class VideoOverview extends StatelessWidget {
final OverviewData video; final OverviewData video;
@ -41,6 +43,7 @@ class VideoOverview extends StatelessWidget {
'args': studioRequestArgs, 'args': studioRequestArgs,
'hasUnmarkConfirmation': hasUnmarkConfirmation, 'hasUnmarkConfirmation': hasUnmarkConfirmation,
'isVideo': true, 'isVideo': true,
'state': context.read<StudioDetailsState>(),
}, },
), ),
child: Row( child: Row(

View File

@ -127,6 +127,13 @@ packages:
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "1.0.4+1" version: "1.0.4+1"
expandable_bottom_sheet:
dependency: "direct main"
description:
name: expandable_bottom_sheet
url: "https://pub.dartlang.org"
source: hosted
version: "1.1.1+1"
fake_async: fake_async:
dependency: transitive dependency: transitive
description: description:

View File

@ -63,6 +63,7 @@ dependencies:
firebase_messaging: ^11.2.8 firebase_messaging: ^11.2.8
firebase_core: ^1.13.1 firebase_core: ^1.13.1
webview_flutter: ^3.0.1 webview_flutter: ^3.0.1
expandable_bottom_sheet: ^1.1.1+1
dev_dependencies: dev_dependencies: