bug fixes
This commit is contained in:
parent
a128684f27
commit
873c1f6692
|
|
@ -87,11 +87,6 @@ class _StudioDetailsState extends State<StudioDetails> {
|
||||||
state: state,
|
state: state,
|
||||||
onRetry: () => state.getStudioDetails(state.studio.id),
|
onRetry: () => state.getStudioDetails(state.studio.id),
|
||||||
builder: (context, state) {
|
builder: (context, state) {
|
||||||
if (state.prevStudio == null &&
|
|
||||||
state.nextStudio == null &&
|
|
||||||
state.args.page != 0) {
|
|
||||||
return const SizedBox();
|
|
||||||
}
|
|
||||||
return WillPopScope(
|
return WillPopScope(
|
||||||
onWillPop: () async {
|
onWillPop: () async {
|
||||||
if (_isFullScreen) {
|
if (_isFullScreen) {
|
||||||
|
|
|
||||||
|
|
@ -75,11 +75,6 @@ class _StudioDetailsState extends State<StudioDetails> {
|
||||||
state: state,
|
state: state,
|
||||||
onRetry: () => state.getStudioDetails(state.studio.id),
|
onRetry: () => state.getStudioDetails(state.studio.id),
|
||||||
builder: (context, state) {
|
builder: (context, state) {
|
||||||
if (state.prevStudio == null &&
|
|
||||||
state.nextStudio == null &&
|
|
||||||
state.args.page != 0) {
|
|
||||||
return const SizedBox();
|
|
||||||
}
|
|
||||||
// ignore: undefined_prefixed_name
|
// ignore: undefined_prefixed_name
|
||||||
ui.platformViewRegistry.registerViewFactory(
|
ui.platformViewRegistry.registerViewFactory(
|
||||||
"video",
|
"video",
|
||||||
|
|
|
||||||
|
|
@ -24,6 +24,7 @@ class StudioDetailsState extends CoreProvier {
|
||||||
int _selectedDetailsIndex = 0;
|
int _selectedDetailsIndex = 0;
|
||||||
Timer? timer;
|
Timer? timer;
|
||||||
int timerValue = 10;
|
int timerValue = 10;
|
||||||
|
bool stopOnPodcastEnds = false;
|
||||||
|
|
||||||
int get selectedDetailsIndex => _selectedDetailsIndex;
|
int get selectedDetailsIndex => _selectedDetailsIndex;
|
||||||
set selectedDetailsIndex(int value) {
|
set selectedDetailsIndex(int value) {
|
||||||
|
|
@ -45,6 +46,7 @@ class StudioDetailsState extends CoreProvier {
|
||||||
if (MediaService.currentPodcast?.id == id && this.args.type == 'podcast') {
|
if (MediaService.currentPodcast?.id == id && this.args.type == 'podcast') {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
_getDownloadsList();
|
_getDownloadsList();
|
||||||
_selectedDetailsIndex = 0;
|
_selectedDetailsIndex = 0;
|
||||||
if (isForward != null) {
|
if (isForward != null) {
|
||||||
|
|
@ -61,12 +63,19 @@ class StudioDetailsState extends CoreProvier {
|
||||||
_handlePodcastPlayback(studio);
|
_handlePodcastPlayback(studio);
|
||||||
}
|
}
|
||||||
if (isForward == null) {
|
if (isForward == null) {
|
||||||
|
if (this.args.type == 'podcast') {
|
||||||
|
MediaService.audioPlayerTag = 'podcast';
|
||||||
|
}
|
||||||
appState = AppState.busy;
|
appState = AppState.busy;
|
||||||
}
|
}
|
||||||
final service = RequestService(RequestHelper.studioDetails(id, this.args));
|
final service = RequestService(RequestHelper.studioDetails(id, this.args));
|
||||||
await service.httpGet();
|
await service.httpGet();
|
||||||
nextStudio = null;
|
nextStudio = null;
|
||||||
prevStudio = null;
|
prevStudio = null;
|
||||||
|
if (stopOnPodcastEnds) {
|
||||||
|
timerValue = 10;
|
||||||
|
}
|
||||||
|
stopOnPodcastEnds = false;
|
||||||
if (service.isSuccess) {
|
if (service.isSuccess) {
|
||||||
final result = service.result;
|
final result = service.result;
|
||||||
studio = StudioDetailsData.fromJson(result['studio']);
|
studio = StudioDetailsData.fromJson(result['studio']);
|
||||||
|
|
@ -109,6 +118,10 @@ class StudioDetailsState extends CoreProvier {
|
||||||
final duration = MediaService.audioPlayer.duration ??
|
final duration = MediaService.audioPlayer.duration ??
|
||||||
Duration(seconds: studio.duration);
|
Duration(seconds: studio.duration);
|
||||||
if (event.compareTo(duration) > 0 && nextStudio != null) {
|
if (event.compareTo(duration) > 0 && nextStudio != null) {
|
||||||
|
if (stopOnPodcastEnds) {
|
||||||
|
MediaService.resetAudioPlayer();
|
||||||
|
return;
|
||||||
|
}
|
||||||
getStudioDetails(nextStudio!.id, isForward: true);
|
getStudioDetails(nextStudio!.id, isForward: true);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
|
||||||
|
|
@ -15,6 +15,9 @@ class StudioState extends CoreProvier {
|
||||||
final List<OverviewData> studios = [];
|
final List<OverviewData> studios = [];
|
||||||
final List<SliderData> sliders = [];
|
final List<SliderData> sliders = [];
|
||||||
final List<int> downloadedFileIds = [];
|
final List<int> downloadedFileIds = [];
|
||||||
|
final List<String> downloadQueue = [];
|
||||||
|
|
||||||
|
AppState downloadState = AppState.idle;
|
||||||
|
|
||||||
String search = '';
|
String search = '';
|
||||||
String lastSearch = '';
|
String lastSearch = '';
|
||||||
|
|
@ -147,8 +150,13 @@ class StudioState extends CoreProvier {
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<void> download(String url, String fileName) async {
|
Future<void> download(String url, String fileName) async {
|
||||||
|
downloadState = AppState.busy;
|
||||||
|
downloadQueue.add(url);
|
||||||
|
notifyListeners();
|
||||||
final service = RequestService(url);
|
final service = RequestService(url);
|
||||||
await service.download(fileName, videosSelected ? 'videos' : 'podcasts');
|
await service.download(fileName, videosSelected ? 'videos' : 'podcasts');
|
||||||
|
downloadState = AppState.idle;
|
||||||
|
downloadQueue.remove(url);
|
||||||
notifyListeners();
|
notifyListeners();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -101,6 +101,7 @@ class _StudioSliderState extends State<StudioSlider> {
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
options: CarouselOptions(
|
options: CarouselOptions(
|
||||||
|
autoPlayAnimationDuration: DesignConfig.mediumAnimationDuration,
|
||||||
onPageChanged: (index, reason) => setState(
|
onPageChanged: (index, reason) => setState(
|
||||||
() => selectedIndex = index,
|
() => selectedIndex = index,
|
||||||
),
|
),
|
||||||
|
|
|
||||||
|
|
@ -4,6 +4,7 @@ import 'dart:math';
|
||||||
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/enums.dart';
|
||||||
import 'package:didvan/models/studio_details_data.dart';
|
import 'package:didvan/models/studio_details_data.dart';
|
||||||
import 'package:didvan/models/view/action_sheet_data.dart';
|
import 'package:didvan/models/view/action_sheet_data.dart';
|
||||||
import 'package:didvan/services/media/media.dart';
|
import 'package:didvan/services/media/media.dart';
|
||||||
|
|
@ -12,6 +13,7 @@ import 'package:didvan/views/home/studio/studio_details/studio_details_state.dar
|
||||||
import 'package:didvan/views/home/studio/studio_state.dart';
|
import 'package:didvan/views/home/studio/studio_state.dart';
|
||||||
import 'package:didvan/views/home/widgets/audio/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/home/widgets/bookmark_button.dart';
|
||||||
|
import 'package:didvan/views/widgets/didvan/button.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/ink_wrapper.dart';
|
import 'package:didvan/views/widgets/ink_wrapper.dart';
|
||||||
|
|
@ -64,14 +66,14 @@ class AudioPlayerWidget extends StatelessWidget {
|
||||||
),
|
),
|
||||||
Row(
|
Row(
|
||||||
crossAxisAlignment: CrossAxisAlignment.start,
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
|
||||||
children: [
|
children: [
|
||||||
const SizedBox(),
|
Expanded(
|
||||||
StatefulBuilder(
|
child: Center(
|
||||||
|
child: StatefulBuilder(
|
||||||
builder: (context, setState) => Column(
|
builder: (context, setState) => Column(
|
||||||
children: [
|
children: [
|
||||||
DidvanIconButton(
|
DidvanIconButton(
|
||||||
icon: state.timer == null
|
icon: state.timer == null && !state.stopOnPodcastEnds
|
||||||
? DidvanIcons.sleep_timer_regular
|
? DidvanIcons.sleep_timer_regular
|
||||||
: DidvanIcons.sleep_enabled_regular,
|
: DidvanIcons.sleep_enabled_regular,
|
||||||
color: Theme.of(context).colorScheme.title,
|
color: Theme.of(context).colorScheme.title,
|
||||||
|
|
@ -82,15 +84,21 @@ class AudioPlayerWidget extends StatelessWidget {
|
||||||
),
|
),
|
||||||
if (state.timer != null)
|
if (state.timer != null)
|
||||||
DidvanText(
|
DidvanText(
|
||||||
state.timerValue.toString() + '\'',
|
state.stopOnPodcastEnds
|
||||||
|
? 'پایان پادکست'
|
||||||
|
: '\'' + state.timerValue.toString(),
|
||||||
isEnglishFont: true,
|
isEnglishFont: true,
|
||||||
style: Theme.of(context).textTheme.overline,
|
style: Theme.of(context).textTheme.overline,
|
||||||
color: Theme.of(context).colorScheme.caption,
|
color: Theme.of(context).colorScheme.title,
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
Column(
|
),
|
||||||
|
),
|
||||||
|
Expanded(
|
||||||
|
child: Center(
|
||||||
|
child: Column(
|
||||||
children: [
|
children: [
|
||||||
DidvanIconButton(
|
DidvanIconButton(
|
||||||
color: Theme.of(context).colorScheme.title,
|
color: Theme.of(context).colorScheme.title,
|
||||||
|
|
@ -100,7 +108,8 @@ class AudioPlayerWidget extends StatelessWidget {
|
||||||
MediaService.audioPlayer.seek(
|
MediaService.audioPlayer.seek(
|
||||||
Duration(
|
Duration(
|
||||||
seconds:
|
seconds:
|
||||||
MediaService.audioPlayer.position.inSeconds + 30,
|
MediaService.audioPlayer.position.inSeconds +
|
||||||
|
30,
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
|
|
@ -112,7 +121,11 @@ class AudioPlayerWidget extends StatelessWidget {
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
StreamBuilder<bool>(
|
),
|
||||||
|
),
|
||||||
|
Expanded(
|
||||||
|
child: Center(
|
||||||
|
child: StreamBuilder<bool>(
|
||||||
stream: MediaService.audioPlayer.playingStream,
|
stream: MediaService.audioPlayer.playingStream,
|
||||||
builder: (context, snapshot) {
|
builder: (context, snapshot) {
|
||||||
return _PlayPouseAnimatedIcon(
|
return _PlayPouseAnimatedIcon(
|
||||||
|
|
@ -121,7 +134,11 @@ class AudioPlayerWidget extends StatelessWidget {
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
Column(
|
),
|
||||||
|
),
|
||||||
|
Expanded(
|
||||||
|
child: Center(
|
||||||
|
child: Column(
|
||||||
children: [
|
children: [
|
||||||
DidvanIconButton(
|
DidvanIconButton(
|
||||||
size: 32,
|
size: 32,
|
||||||
|
|
@ -132,7 +149,8 @@ class AudioPlayerWidget extends StatelessWidget {
|
||||||
Duration(
|
Duration(
|
||||||
seconds: max(
|
seconds: max(
|
||||||
0,
|
0,
|
||||||
MediaService.audioPlayer.position.inSeconds - 10,
|
MediaService.audioPlayer.position.inSeconds -
|
||||||
|
10,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
|
|
@ -145,14 +163,20 @@ class AudioPlayerWidget extends StatelessWidget {
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
BookmarkButton(
|
),
|
||||||
|
),
|
||||||
|
Expanded(
|
||||||
|
child: Center(
|
||||||
|
child: BookmarkButton(
|
||||||
gestureSize: 48,
|
gestureSize: 48,
|
||||||
color: Theme.of(context).colorScheme.title,
|
color: Theme.of(context).colorScheme.title,
|
||||||
value: podcast.marked,
|
value: podcast.marked,
|
||||||
onMarkChanged: (value) =>
|
onMarkChanged: (value) => context
|
||||||
context.read<StudioState>().changeMark(podcast.id, value),
|
.read<StudioState>()
|
||||||
|
.changeMark(podcast.id, value),
|
||||||
|
),
|
||||||
|
),
|
||||||
),
|
),
|
||||||
const SizedBox(),
|
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
|
|
@ -163,13 +187,17 @@ class AudioPlayerWidget extends StatelessWidget {
|
||||||
Future<void> _showSleepTimer(StudioDetailsState state, update) async {
|
Future<void> _showSleepTimer(StudioDetailsState state, update) async {
|
||||||
int timerValue = 10;
|
int timerValue = 10;
|
||||||
final controller = FixedExtentScrollController();
|
final controller = FixedExtentScrollController();
|
||||||
|
bool isInit = true;
|
||||||
Future.delayed(
|
Future.delayed(
|
||||||
const Duration(milliseconds: 100),
|
const Duration(milliseconds: 100),
|
||||||
() => controller.animateTo(
|
() async {
|
||||||
50 * (state.timerValue / 5 - 2),
|
await controller.animateTo(
|
||||||
|
state.timerValue * 10,
|
||||||
duration: DesignConfig.lowAnimationDuration,
|
duration: DesignConfig.lowAnimationDuration,
|
||||||
curve: Curves.easeIn,
|
curve: Curves.easeIn,
|
||||||
),
|
);
|
||||||
|
isInit = false;
|
||||||
|
},
|
||||||
);
|
);
|
||||||
await ActionSheetUtils.showBottomSheet(
|
await ActionSheetUtils.showBottomSheet(
|
||||||
data: ActionSheetData(
|
data: ActionSheetData(
|
||||||
|
|
@ -193,16 +221,20 @@ class AudioPlayerWidget extends StatelessWidget {
|
||||||
child: RotatedBox(
|
child: RotatedBox(
|
||||||
quarterTurns: 3,
|
quarterTurns: 3,
|
||||||
child: ListWheelScrollView(
|
child: ListWheelScrollView(
|
||||||
controller: controller,
|
|
||||||
physics: const FixedExtentScrollPhysics(),
|
physics: const FixedExtentScrollPhysics(),
|
||||||
itemExtent: 48,
|
controller: controller,
|
||||||
|
itemExtent: 10,
|
||||||
onSelectedItemChanged: (index) {
|
onSelectedItemChanged: (index) {
|
||||||
final minutes = (index + 2) * 5;
|
if (!isInit) {
|
||||||
|
state.stopOnPodcastEnds = false;
|
||||||
|
}
|
||||||
|
final minutes = index == 0 ? 1 : index;
|
||||||
timerValue = minutes;
|
timerValue = minutes;
|
||||||
setState(() {});
|
setState(() {});
|
||||||
},
|
},
|
||||||
children: [
|
children: [
|
||||||
for (var i = 0; i < 9; i++)
|
for (var i = 0; i < 61; i++) ...[
|
||||||
|
if (i % 5 == 0)
|
||||||
Center(
|
Center(
|
||||||
child: Container(
|
child: Container(
|
||||||
color: Theme.of(context).colorScheme.text,
|
color: Theme.of(context).colorScheme.text,
|
||||||
|
|
@ -210,21 +242,50 @@ class AudioPlayerWidget extends StatelessWidget {
|
||||||
height: 3,
|
height: 3,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
if (i % 5 != 0) const SizedBox(height: 3),
|
||||||
|
],
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
const SizedBox(height: 32),
|
||||||
|
Padding(
|
||||||
|
padding: const EdgeInsets.symmetric(horizontal: 64),
|
||||||
|
child: DidvanButton(
|
||||||
|
style: state.timerValue ==
|
||||||
|
MediaService.audioPlayer.duration?.inMinutes &&
|
||||||
|
state.stopOnPodcastEnds
|
||||||
|
? ButtonStyleMode.primary
|
||||||
|
: ButtonStyleMode.flat,
|
||||||
|
title: 'پایان پادکست',
|
||||||
|
onPressed: () async {
|
||||||
|
state.timerValue =
|
||||||
|
MediaService.audioPlayer.duration!.inMinutes -
|
||||||
|
MediaService.audioPlayer.position.inMinutes;
|
||||||
|
await controller.animateTo(
|
||||||
|
state.timerValue * 10,
|
||||||
|
duration: DesignConfig.lowAnimationDuration,
|
||||||
|
curve: Curves.easeIn,
|
||||||
|
);
|
||||||
|
state.stopOnPodcastEnds = true;
|
||||||
|
setState(() {});
|
||||||
|
},
|
||||||
|
),
|
||||||
|
),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
onConfirmed: () {
|
onConfirmed: () {
|
||||||
|
if (!state.stopOnPodcastEnds) {
|
||||||
state.timer = Timer(
|
state.timer = Timer(
|
||||||
Duration(minutes: timerValue),
|
Duration(minutes: timerValue),
|
||||||
MediaService.audioPlayer.stop,
|
MediaService.audioPlayer.stop,
|
||||||
);
|
);
|
||||||
|
}
|
||||||
state.timerValue = timerValue;
|
state.timerValue = timerValue;
|
||||||
update();
|
update();
|
||||||
},
|
},
|
||||||
|
confrimTitle: 'شروع زمان خواب',
|
||||||
dismissTitle: 'لغو',
|
dismissTitle: 'لغو',
|
||||||
onDismissed: () {
|
onDismissed: () {
|
||||||
state.timer?.cancel();
|
state.timer?.cancel();
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,6 @@
|
||||||
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/enums.dart';
|
||||||
import 'package:didvan/models/overview_data.dart';
|
import 'package:didvan/models/overview_data.dart';
|
||||||
import 'package:didvan/models/requests/studio.dart';
|
import 'package:didvan/models/requests/studio.dart';
|
||||||
import 'package:didvan/utils/date_time.dart';
|
import 'package:didvan/utils/date_time.dart';
|
||||||
|
|
@ -81,6 +82,8 @@ class PodcastOverview extends StatelessWidget {
|
||||||
DurationWidget(duration: podcast.duration!),
|
DurationWidget(duration: podcast.duration!),
|
||||||
const Spacer(),
|
const Spacer(),
|
||||||
if (!kIsWeb) ...[
|
if (!kIsWeb) ...[
|
||||||
|
if (state.downloadState == AppState.idle ||
|
||||||
|
!state.downloadQueue.contains(podcast.media))
|
||||||
DidvanIconButton(
|
DidvanIconButton(
|
||||||
gestureSize: 28,
|
gestureSize: 28,
|
||||||
color: _isDownloaded(state)
|
color: _isDownloaded(state)
|
||||||
|
|
@ -91,8 +94,17 @@ class PodcastOverview extends StatelessWidget {
|
||||||
: DidvanIcons.download_regular,
|
: DidvanIcons.download_regular,
|
||||||
onPressed: _isDownloaded(state)
|
onPressed: _isDownloaded(state)
|
||||||
? () {}
|
? () {}
|
||||||
: () =>
|
: () => state.download(
|
||||||
state.download(podcast.media!, podcast.id.toString()),
|
podcast.media!, podcast.id.toString()),
|
||||||
|
),
|
||||||
|
if (state.downloadState == AppState.busy &&
|
||||||
|
state.downloadQueue.contains(podcast.media))
|
||||||
|
const SizedBox(
|
||||||
|
width: 18,
|
||||||
|
height: 18,
|
||||||
|
child: CircularProgressIndicator(
|
||||||
|
strokeWidth: 2,
|
||||||
|
),
|
||||||
),
|
),
|
||||||
const SizedBox(width: 16),
|
const SizedBox(width: 16),
|
||||||
],
|
],
|
||||||
|
|
|
||||||
|
|
@ -14,6 +14,8 @@ 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:expandable_bottom_sheet/expandable_bottom_sheet.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:flutter_spinkit/flutter_spinkit.dart';
|
||||||
|
import 'package:just_audio/just_audio.dart';
|
||||||
import 'package:provider/provider.dart';
|
import 'package:provider/provider.dart';
|
||||||
|
|
||||||
class DidvanBNB extends StatelessWidget {
|
class DidvanBNB extends StatelessWidget {
|
||||||
|
|
@ -24,24 +26,26 @@ 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 =>
|
bool _enablePlayerController(StudioDetailsState state) =>
|
||||||
MediaService.currentPodcast != null &&
|
MediaService.currentPodcast != null ||
|
||||||
(MediaService.audioPlayerTag?.contains('podcast') ?? false);
|
(MediaService.audioPlayerTag?.contains('podcast') ?? false);
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
final state = context.read<StudioDetailsState>();
|
|
||||||
return StreamBuilder<bool>(
|
return StreamBuilder<bool>(
|
||||||
stream: MediaService.audioPlayer.playingStream,
|
stream: MediaService.audioPlayer.playingStream,
|
||||||
builder: (context, snapshot) {
|
builder: (context, snapshot) {
|
||||||
return Stack(
|
return Stack(
|
||||||
children: [
|
children: [
|
||||||
GestureDetector(
|
GestureDetector(
|
||||||
onTap: () => _showPlayerBottomSheet(context),
|
onTap: () => MediaService.currentPodcast == null
|
||||||
child: AnimatedContainer(
|
? null
|
||||||
|
: _showPlayerBottomSheet(context),
|
||||||
|
child: Consumer<StudioDetailsState>(
|
||||||
|
builder: (context, state, child) => AnimatedContainer(
|
||||||
padding: const EdgeInsets.only(top: 12),
|
padding: const EdgeInsets.only(top: 12),
|
||||||
duration: DesignConfig.lowAnimationDuration,
|
duration: DesignConfig.lowAnimationDuration,
|
||||||
height: _enablePlayerController ? 128 : 72,
|
height: _enablePlayerController(state) ? 128 : 72,
|
||||||
decoration: BoxDecoration(
|
decoration: BoxDecoration(
|
||||||
color: DesignConfig.isDark
|
color: DesignConfig.isDark
|
||||||
? Theme.of(context).colorScheme.focused
|
? Theme.of(context).colorScheme.focused
|
||||||
|
|
@ -50,8 +54,23 @@ class DidvanBNB extends StatelessWidget {
|
||||||
top: Radius.circular(16),
|
top: Radius.circular(16),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
child: !_enablePlayerController
|
alignment: Alignment.topCenter,
|
||||||
|
child: !_enablePlayerController(state)
|
||||||
? const SizedBox()
|
? const SizedBox()
|
||||||
|
: MediaService.currentPodcast == null
|
||||||
|
? SizedBox(
|
||||||
|
height: 32,
|
||||||
|
child: Center(
|
||||||
|
child: SpinKitThreeBounce(
|
||||||
|
size: 18,
|
||||||
|
color: DesignConfig.isDark
|
||||||
|
? null
|
||||||
|
: Theme.of(context)
|
||||||
|
.colorScheme
|
||||||
|
.secondCTA,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
)
|
||||||
: SizedBox(
|
: SizedBox(
|
||||||
height: 56,
|
height: 56,
|
||||||
child: Row(
|
child: Row(
|
||||||
|
|
@ -66,20 +85,25 @@ class DidvanBNB extends StatelessWidget {
|
||||||
icon: DidvanIcons.close_regular,
|
icon: DidvanIcons.close_regular,
|
||||||
color: DesignConfig.isDark
|
color: DesignConfig.isDark
|
||||||
? null
|
? null
|
||||||
: Theme.of(context).colorScheme.secondCTA,
|
: Theme.of(context)
|
||||||
|
.colorScheme
|
||||||
|
.secondCTA,
|
||||||
gestureSize: 28,
|
gestureSize: 28,
|
||||||
onPressed: MediaService.resetAudioPlayer,
|
onPressed:
|
||||||
|
MediaService.resetAudioPlayer,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
SkeletonImage(
|
SkeletonImage(
|
||||||
imageUrl: MediaService.currentPodcast!.image,
|
imageUrl:
|
||||||
|
MediaService.currentPodcast!.image,
|
||||||
width: 32,
|
width: 32,
|
||||||
height: 32,
|
height: 32,
|
||||||
),
|
),
|
||||||
const SizedBox(width: 16),
|
const SizedBox(width: 16),
|
||||||
Expanded(
|
Expanded(
|
||||||
child: Column(
|
child: Column(
|
||||||
crossAxisAlignment: CrossAxisAlignment.start,
|
crossAxisAlignment:
|
||||||
|
CrossAxisAlignment.start,
|
||||||
children: [
|
children: [
|
||||||
DidvanText(
|
DidvanText(
|
||||||
MediaService.currentPodcast!.title,
|
MediaService.currentPodcast!.title,
|
||||||
|
|
@ -96,6 +120,39 @@ class DidvanBNB extends StatelessWidget {
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
StreamBuilder<PlayerState>(
|
||||||
|
stream: MediaService
|
||||||
|
.audioPlayer.playerStateStream,
|
||||||
|
builder: (context, snapshot) {
|
||||||
|
if (state.appState == AppState.busy ||
|
||||||
|
MediaService.audioPlayer.playerState
|
||||||
|
.processingState ==
|
||||||
|
ProcessingState.loading) {
|
||||||
|
return Padding(
|
||||||
|
padding: const EdgeInsets.only(
|
||||||
|
top: 4,
|
||||||
|
left: 16,
|
||||||
|
right: 16,
|
||||||
|
),
|
||||||
|
child: SizedBox(
|
||||||
|
height: 18,
|
||||||
|
width: 18,
|
||||||
|
child: CircularProgressIndicator(
|
||||||
|
strokeWidth: 2,
|
||||||
|
color: Theme.of(context)
|
||||||
|
.colorScheme
|
||||||
|
.secondCTA,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
return const SizedBox();
|
||||||
|
},
|
||||||
|
),
|
||||||
|
if (state.appState != AppState.busy &&
|
||||||
|
MediaService.audioPlayer.playerState
|
||||||
|
.processingState !=
|
||||||
|
ProcessingState.loading)
|
||||||
Padding(
|
Padding(
|
||||||
padding: const EdgeInsets.only(
|
padding: const EdgeInsets.only(
|
||||||
left: 12,
|
left: 12,
|
||||||
|
|
@ -105,18 +162,22 @@ class DidvanBNB extends StatelessWidget {
|
||||||
gestureSize: 28,
|
gestureSize: 28,
|
||||||
color: DesignConfig.isDark
|
color: DesignConfig.isDark
|
||||||
? null
|
? null
|
||||||
: Theme.of(context).colorScheme.secondCTA,
|
: Theme.of(context)
|
||||||
|
.colorScheme
|
||||||
|
.secondCTA,
|
||||||
icon: snapshot.data!
|
icon: snapshot.data!
|
||||||
? DidvanIcons.pause_solid
|
? DidvanIcons.pause_solid
|
||||||
: DidvanIcons.play_solid,
|
: DidvanIcons.play_solid,
|
||||||
onPressed: () {
|
onPressed: () {
|
||||||
MediaService.handleAudioPlayback(
|
MediaService.handleAudioPlayback(
|
||||||
audioSource: state.downloadedFileIds
|
audioSource: state
|
||||||
|
.downloadedFileIds
|
||||||
.contains(state.studio.id)
|
.contains(state.studio.id)
|
||||||
? StorageService.appDocsDir +
|
? StorageService.appDocsDir +
|
||||||
'/podcasts/podcast-${state.studio.id}.mp3'
|
'/podcasts/podcast-${state.studio.id}.mp3'
|
||||||
: state.studio.media,
|
: state.studio.media,
|
||||||
isNetworkAudio: !state.downloadedFileIds
|
isNetworkAudio: !state
|
||||||
|
.downloadedFileIds
|
||||||
.contains(state.studio.id),
|
.contains(state.studio.id),
|
||||||
id: state.studio.id,
|
id: state.studio.id,
|
||||||
isVoiceMessage: false,
|
isVoiceMessage: false,
|
||||||
|
|
@ -129,6 +190,7 @@ class DidvanBNB extends StatelessWidget {
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
),
|
||||||
Positioned(
|
Positioned(
|
||||||
bottom: 0,
|
bottom: 0,
|
||||||
left: 0,
|
left: 0,
|
||||||
|
|
@ -226,19 +288,24 @@ class DidvanBNB extends StatelessWidget {
|
||||||
color: Theme.of(context).colorScheme.surface,
|
color: Theme.of(context).colorScheme.surface,
|
||||||
child: Column(
|
child: Column(
|
||||||
children: [
|
children: [
|
||||||
DidvanIconButton(
|
StatefulBuilder(
|
||||||
|
builder: (context, setState) => DidvanIconButton(
|
||||||
size: 32,
|
size: 32,
|
||||||
icon: DidvanIcons.angle_down_regular,
|
icon: isExpanded
|
||||||
|
? DidvanIcons.angle_down_regular
|
||||||
|
: DidvanIcons.angle_up_regular,
|
||||||
onPressed: () {
|
onPressed: () {
|
||||||
if (!isExpanded) {
|
if (!isExpanded) {
|
||||||
sheetKey.currentState?.expand();
|
sheetKey.currentState?.expand();
|
||||||
isExpanded = true;
|
isExpanded = true;
|
||||||
return;
|
} else {
|
||||||
}
|
|
||||||
isExpanded = false;
|
isExpanded = false;
|
||||||
sheetKey.currentState?.contract();
|
sheetKey.currentState?.contract();
|
||||||
|
}
|
||||||
|
setState(() {});
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
|
),
|
||||||
const SizedBox(height: 16),
|
const SizedBox(height: 16),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
|
|
@ -247,7 +314,13 @@ class DidvanBNB extends StatelessWidget {
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
expandableContent: state.appState == AppState.busy
|
expandableContent: state.appState == AppState.busy
|
||||||
? const SizedBox()
|
? Container(
|
||||||
|
height: MediaQuery.of(context).size.height / 2,
|
||||||
|
alignment: Alignment.center,
|
||||||
|
child: SpinKitSpinningLines(
|
||||||
|
color: Theme.of(context).colorScheme.primary,
|
||||||
|
),
|
||||||
|
)
|
||||||
: StudioDetailsWidget(
|
: StudioDetailsWidget(
|
||||||
studio: detailsState.studio,
|
studio: detailsState.studio,
|
||||||
onCommentsTabSelected: () {
|
onCommentsTabSelected: () {
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue