diff --git a/ios/Podfile.lock b/ios/Podfile.lock index 55fa4cf..89b36ba 100644 --- a/ios/Podfile.lock +++ b/ios/Podfile.lock @@ -88,6 +88,8 @@ PODS: - TOCropViewController (2.6.1) - url_launcher_ios (0.0.1): - Flutter + - webview_flutter_wkwebview (0.0.1): + - Flutter DEPENDENCIES: - audio_session (from `.symlinks/plugins/audio_session/ios`) @@ -103,6 +105,7 @@ DEPENDENCIES: - record (from `.symlinks/plugins/record/ios`) - sqflite (from `.symlinks/plugins/sqflite/ios`) - url_launcher_ios (from `.symlinks/plugins/url_launcher_ios/ios`) + - webview_flutter_wkwebview (from `.symlinks/plugins/webview_flutter_wkwebview/ios`) SPEC REPOS: trunk: @@ -145,6 +148,8 @@ EXTERNAL SOURCES: :path: ".symlinks/plugins/sqflite/ios" url_launcher_ios: :path: ".symlinks/plugins/url_launcher_ios/ios" + webview_flutter_wkwebview: + :path: ".symlinks/plugins/webview_flutter_wkwebview/ios" SPEC CHECKSUMS: audio_session: 4f3e461722055d21515cf3261b64c973c062f345 @@ -171,6 +176,7 @@ SPEC CHECKSUMS: sqflite: 6d358c025f5b867b29ed92fc697fd34924e11904 TOCropViewController: edfd4f25713d56905ad1e0b9f5be3fbe0f59c863 url_launcher_ios: 02f1989d4e14e998335b02b67a7590fa34f971af + webview_flutter_wkwebview: 005fbd90c888a42c5690919a1527ecc6649e1162 PODFILE CHECKSUM: fe0e1ee7f3d1f7d00b11b474b62dd62134535aea diff --git a/lib/views/home/studio/studio_details/studio_details.dart b/lib/views/home/studio/studio_details/studio_details.dart index 9d72d2b..20ce528 100644 --- a/lib/views/home/studio/studio_details/studio_details.dart +++ b/lib/views/home/studio/studio_details/studio_details.dart @@ -1,19 +1,9 @@ import 'dart:io'; 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/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/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/text.dart'; -import 'package:didvan/views/widgets/ink_wrapper.dart'; -import 'package:didvan/views/widgets/skeleton_image.dart'; import 'package:didvan/views/widgets/state_handlers/state_handler.dart'; import 'package:flutter/material.dart'; import 'package:flutter/services.dart'; @@ -117,6 +107,7 @@ class _StudioDetailsState extends State { child: Stack( children: [ WebView( + allowsInlineMediaPlayback: true, initialUrl: Uri.dataFromString( ''' diff --git a/lib/views/home/studio/studio_details/studio_details_state.dart b/lib/views/home/studio/studio_details/studio_details_state.dart index 9f50e72..0a6205b 100644 --- a/lib/views/home/studio/studio_details/studio_details_state.dart +++ b/lib/views/home/studio/studio_details/studio_details_state.dart @@ -14,12 +14,19 @@ class StudioDetailsState extends CoreProvier { final List studios = []; late int initialIndex; late StudioRequestArgs args; + int _selectedDetailsIndex = 0; bool isFetchingNewItem = false; final List relatedQueue = []; int _currentIndex = 0; int get currentIndex => _currentIndex; + int get selectedDetailsIndex => _selectedDetailsIndex; + set selectedDetailsIndex(int value) { + _selectedDetailsIndex = value; + notifyListeners(); + } + StudioDetailsData get currentStudio { try { return studios[_currentIndex]!; diff --git a/lib/views/home/studio/studio_details/widgets/studio_details.dart b/lib/views/home/studio/studio_details/widgets/studio_details.dart new file mode 100644 index 0000000..059b4cc --- /dev/null +++ b/lib/views/home/studio/studio_details/widgets/studio_details.dart @@ -0,0 +1,97 @@ +import 'package:didvan/config/theme_data.dart'; +import 'package:didvan/constants/app_icons.dart'; +import 'package:didvan/views/home/studio/studio_details/studio_details_state.dart'; +import 'package:didvan/views/widgets/didvan/text.dart'; +import 'package:didvan/views/widgets/state_handlers/state_handler.dart'; +import 'package:flutter/material.dart'; +import 'package:provider/provider.dart'; + +class StudioDetailsWidget extends StatelessWidget { + const StudioDetailsWidget({Key? key}) : super(key: key); + + @override + Widget build(BuildContext context) { + return Consumer( + builder: (context, state, child) => StateHandler( + onRetry: () {}, + state: state, + builder: (context, state) => Container( + color: Theme.of(context).colorScheme.surface, + child: Column( + children: [ + Row( + mainAxisAlignment: MainAxisAlignment.spaceAround, + children: [ + _TabItem( + icon: DidvanIcons.description_solid, + title: 'توضیحات', + onTap: () => state.selectedDetailsIndex = 0, + isSelected: state.selectedDetailsIndex == 0, + ), + _TabItem( + icon: DidvanIcons.chats_solid, + title: 'نظرات', + onTap: () => state.selectedDetailsIndex = 1, + isSelected: state.selectedDetailsIndex == 1, + ), + _TabItem( + icon: DidvanIcons.puzzle_solid, + title: 'مطالب مرتبط', + onTap: () => state.selectedDetailsIndex = 2, + isSelected: state.selectedDetailsIndex == 2, + ), + ], + ), + const SizedBox(height: 16), + ], + ), + ), + ), + ); + } +} + +class _TabItem extends StatelessWidget { + final IconData icon; + final String title; + final VoidCallback onTap; + final bool isSelected; + const _TabItem({ + Key? key, + required this.icon, + required this.title, + required this.onTap, + required this.isSelected, + }) : super(key: key); + + Color? _color(context) => + isSelected ? Theme.of(context).colorScheme.focusedBorder : null; + + @override + Widget build(BuildContext context) { + return GestureDetector( + onTap: onTap, + child: Container( + color: Colors.transparent, + child: Column( + children: [ + Icon( + icon, + color: _color(context), + ), + Container( + width: 64, + height: 1, + color: _color(context), + ), + DidvanText( + title, + color: _color(context), + style: Theme.of(context).textTheme.caption, + ) + ], + ), + ), + ); + } +} diff --git a/lib/views/home/widgets/audio/audio_player_widget.dart b/lib/views/home/widgets/audio/audio_player_widget.dart index f8b0a69..d369b10 100644 --- a/lib/views/home/widgets/audio/audio_player_widget.dart +++ b/lib/views/home/widgets/audio/audio_player_widget.dart @@ -104,11 +104,6 @@ class AudioPlayerWidget extends StatelessWidget { ), ], ), - DidvanIconButton( - size: 32, - icon: DidvanIcons.angle_down_regular, - onPressed: Navigator.of(context).pop, - ), ], ), ); diff --git a/lib/views/home/widgets/bnb.dart b/lib/views/home/widgets/bnb.dart index 33bec5d..a7651be 100644 --- a/lib/views/home/widgets/bnb.dart +++ b/lib/views/home/widgets/bnb.dart @@ -1,13 +1,9 @@ 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/view/action_sheet_data.dart'; -import 'package:didvan/routes/routes.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/studio/studio_details/widgets/studio_details.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'; @@ -180,6 +176,8 @@ class DidvanBNB extends StatelessWidget { } void _showPlayerBottomSheet(BuildContext context) { + final sheetKey = GlobalKey(); + bool isExpanded = false; final detailsState = context.read(); showModalBottomSheet( backgroundColor: Colors.transparent, @@ -188,17 +186,39 @@ class DidvanBNB extends StatelessWidget { builder: (context) => ChangeNotifierProvider.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'), + key: sheetKey, + background: const SizedBox(), + persistentHeader: Column( + crossAxisAlignment: CrossAxisAlignment.center, + children: [ + AudioPlayerWidget( + podcast: MediaService.currentPodcast!, + ), + Container( + width: MediaQuery.of(context).size.width, + color: Theme.of(context).colorScheme.surface, + child: Column( + children: [ + DidvanIconButton( + size: 32, + icon: DidvanIcons.angle_down_regular, + onPressed: () { + if (!isExpanded) { + sheetKey.currentState?.expand(); + isExpanded = true; + return; + } + isExpanded = false; + sheetKey.currentState?.contract(); + }, + ), + const SizedBox(height: 16), + ], + ), + ), + ], ), + expandableContent: const StudioDetailsWidget(), ), ), ); diff --git a/lib/views/home/widgets/overview/podcast.dart b/lib/views/home/widgets/overview/podcast.dart index 1669c0a..1a243df 100644 --- a/lib/views/home/widgets/overview/podcast.dart +++ b/lib/views/home/widgets/overview/podcast.dart @@ -2,8 +2,6 @@ import 'package:didvan/config/theme_data.dart'; import 'package:didvan/constants/app_icons.dart'; import 'package:didvan/models/overview_data.dart'; import 'package:didvan/models/requests/studio.dart'; -import 'package:didvan/routes/routes.dart'; -import 'package:didvan/services/media/media.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';