diff --git a/android/app/build.gradle b/android/app/build.gradle index 6ba8c9e..44b61c9 100644 --- a/android/app/build.gradle +++ b/android/app/build.gradle @@ -32,7 +32,7 @@ if (keystorePropertiesFile.exists()) { } android { - compileSdkVersion 31 + compileSdkVersion 33 compileOptions { diff --git a/lib/constants/assets.dart b/lib/constants/assets.dart index f582dff..5cffd24 100644 --- a/lib/constants/assets.dart +++ b/lib/constants/assets.dart @@ -3,57 +3,56 @@ import 'package:flutter/cupertino.dart'; class Assets { static const String _basePath = 'lib/assets'; - static const String _baseImagesPath = _basePath + '/images'; - static const String _baseCategoriesPath = _baseImagesPath + '/categories'; - static const String _baseThemesPath = _baseImagesPath + '/themes'; - static const String _baseEmptyStatesPath = _baseImagesPath + '/empty_states'; - static const String _baseAnimationsPath = _basePath + '/animations'; - static const String _baseRecordsPath = _baseImagesPath + '/records'; - static const String _baseLogosPath = _baseImagesPath + '/logos'; + static const String _baseImagesPath = '$_basePath/images'; + static const String _baseCategoriesPath = '$_baseImagesPath/categories'; + static const String _baseThemesPath = '$_baseImagesPath/themes'; + static const String _baseEmptyStatesPath = '$_baseImagesPath/empty_states'; + static const String _baseAnimationsPath = '$_basePath/animations'; + static const String _baseRecordsPath = '$_baseImagesPath/records'; + static const String _baseLogosPath = '$_baseImagesPath/logos'; static String get verticalLogoWithText => - _baseLogosPath + '/logo-vertical-$_themeSuffix.svg'; + '$_baseLogosPath/logo-vertical-$_themeSuffix.svg'; static String get horizontalLogoWithText => - _baseLogosPath + '/logo-horizontal-$_themeSuffix.svg'; - static String get studioLogo => _baseLogosPath + '/studio-$_themeSuffix.svg'; + '$_baseLogosPath/logo-horizontal-$_themeSuffix.svg'; + static String get studioLogo => '$_baseLogosPath/studio-$_themeSuffix.svg'; static String get logoLoadingAnimation => - _baseAnimationsPath + '/indicator-$_themeSuffix.riv'; + '$_baseAnimationsPath/indicator-$_themeSuffix.riv'; static String get businessCategoryIcon => - _baseCategoriesPath + '/business-$_themeSuffix.svg'; + '$_baseCategoriesPath/business-$_themeSuffix.svg'; static String get economicCategoryIcon => - _baseCategoriesPath + '/economic-$_themeSuffix.svg'; + '$_baseCategoriesPath/economic-$_themeSuffix.svg'; static String get enviromentalCategoryIcon => - _baseCategoriesPath + '/enviromental-$_themeSuffix.svg'; + '$_baseCategoriesPath/enviromental-$_themeSuffix.svg'; static String get politicalCategoryIcon => - _baseCategoriesPath + '/political-$_themeSuffix.svg'; + '$_baseCategoriesPath/political-$_themeSuffix.svg'; static String get socialCategoryIcon => - _baseCategoriesPath + '/social-$_themeSuffix.svg'; + '$_baseCategoriesPath/social-$_themeSuffix.svg'; static String get techCategoryIcon => - _baseCategoriesPath + '/tech-$_themeSuffix.svg'; + '$_baseCategoriesPath/tech-$_themeSuffix.svg'; static String get steelCategoryIcon => - _baseCategoriesPath + '/steel-$_themeSuffix.svg'; + '$_baseCategoriesPath/steel-$_themeSuffix.svg'; static String get stockCategoryIcon => - _baseCategoriesPath + '/stock-$_themeSuffix.svg'; + '$_baseCategoriesPath/stock-$_themeSuffix.svg'; static String get globCategoryIcon => - _baseCategoriesPath + '/glob-$_themeSuffix.svg'; + '$_baseCategoriesPath/glob-$_themeSuffix.svg'; static String get emptyBookmark => - _baseEmptyStatesPath + '/bookmark-$_themeSuffix.svg'; + '$_baseEmptyStatesPath/bookmark-$_themeSuffix.svg'; static String get emptyChart => - _baseEmptyStatesPath + '/chart-$_themeSuffix.svg'; - static String get emptyChat => - _baseEmptyStatesPath + '/chat-$_themeSuffix.svg'; + '$_baseEmptyStatesPath/chart-$_themeSuffix.svg'; + static String get emptyChat => '$_baseEmptyStatesPath/chat-$_themeSuffix.svg'; static String get emptyConnection => - _baseEmptyStatesPath + '/connection-$_themeSuffix.svg'; + '$_baseEmptyStatesPath/connection-$_themeSuffix.svg'; static String get emptyResult => - _baseEmptyStatesPath + '/result-$_themeSuffix.svg'; + '$_baseEmptyStatesPath/result-$_themeSuffix.svg'; - static const String lightTheme = _baseThemesPath + '/theme-light.svg'; - static const String darkTheme = _baseThemesPath + '/theme-dark.svg'; + static const String lightTheme = '$_baseThemesPath/theme-light.svg'; + static const String darkTheme = '$_baseThemesPath/theme-dark.svg'; - static String get record => _baseRecordsPath + '/record-$_themeSuffix.svg'; + static String get record => '$_baseRecordsPath/record-$_themeSuffix.svg'; static String get _themeSuffix => DesignConfig.brightness == Brightness.dark ? 'dark' : 'light'; diff --git a/lib/models/news_details_data.dart b/lib/models/news_details_data.dart index 0a1a68b..590ad5a 100644 --- a/lib/models/news_details_data.dart +++ b/lib/models/news_details_data.dart @@ -14,6 +14,7 @@ class NewsDetailsData { final List tags; final List contents; final List relatedContents = []; + bool relatedContentsIsEmpty; NewsDetailsData({ required this.id, @@ -26,6 +27,7 @@ class NewsDetailsData { required this.tags, required this.contents, required this.order, + this.relatedContentsIsEmpty = false, }); factory NewsDetailsData.fromJson(Map json) { diff --git a/lib/models/radar_details_data.dart b/lib/models/radar_details_data.dart index a41bb1e..1bfb83c 100644 --- a/lib/models/radar_details_data.dart +++ b/lib/models/radar_details_data.dart @@ -11,6 +11,7 @@ class RadarDetailsData { final int timeToRead; final String createdAt; final String? podcast; + final int? duration; final bool forManagers; final bool marked; int comments; @@ -19,6 +20,7 @@ class RadarDetailsData { final List categories; final int order; final List relatedContents = []; + bool relatedContentsIsEmpty; RadarDetailsData({ required this.id, @@ -34,6 +36,8 @@ class RadarDetailsData { required this.contents, required this.categories, required this.order, + required this.duration, + this.relatedContentsIsEmpty = false, }); factory RadarDetailsData.fromJson(Map json) { @@ -59,6 +63,7 @@ class RadarDetailsData { (cat) => CategoryData.fromJson(cat), ), ), + duration: json['duration'], ); } diff --git a/lib/models/studio_details_data.dart b/lib/models/studio_details_data.dart index 334b4b2..911ae62 100644 --- a/lib/models/studio_details_data.dart +++ b/lib/models/studio_details_data.dart @@ -11,6 +11,7 @@ class StudioDetailsData { final String? iframe; final String createdAt; final int order; + bool relatedContentsIsEmpty; bool marked; int comments; final List tags; @@ -29,6 +30,7 @@ class StudioDetailsData { required this.marked, required this.comments, required this.tags, + this.relatedContentsIsEmpty = false, }); factory StudioDetailsData.fromJson(Map json) { diff --git a/lib/services/media/media.dart b/lib/services/media/media.dart index 2342acd..cb4813f 100644 --- a/lib/services/media/media.dart +++ b/lib/services/media/media.dart @@ -25,9 +25,10 @@ class MediaService { void Function(bool isNext)? onTrackChanged, }) async { String tag; - tag = '${isVoiceMessage ? 'message' : 'podcast'}-$id'; + tag = + '${currentPodcast?.description == 'radar' ? 'radar' : isVoiceMessage ? 'message' : 'podcast'}-$id'; if (!isVoiceMessage && MediaProvider.downloadedItemIds.contains(id)) { - audioSource = StorageService.appDocsDir + '/podcasts/podcast-$id.mp3'; + audioSource = '${StorageService.appDocsDir}/podcasts/podcast-$id.mp3'; isNetworkAudio = false; } if (audioPlayerTag == tag) { @@ -52,7 +53,7 @@ class MediaService { ? null : Metas( artist: 'استودیو دیدوان', - title: currentPodcast!.title, + title: currentPodcast?.title ?? '', ), ); } else { @@ -62,7 +63,7 @@ class MediaService { ? null : Metas( artist: 'استودیو دیدوان', - title: currentPodcast!.title, + title: currentPodcast?.title ?? '', ), ); } diff --git a/lib/services/network/request_helper.dart b/lib/services/network/request_helper.dart index ab0336e..e964e1e 100644 --- a/lib/services/network/request_helper.dart +++ b/lib/services/network/request_helper.dart @@ -4,44 +4,41 @@ import 'package:didvan/models/requests/studio.dart'; class RequestHelper { static const String baseUrl = 'https://api.didvan.app'; - static const String _baseUserUrl = baseUrl + '/user'; - static const String _baseRadarUrl = baseUrl + '/radar'; - static const String _baseNewsUrl = baseUrl + '/news'; - static const String _baseStudioUrl = baseUrl + '/studio'; - static const String _baseStatisticUrl = baseUrl + '/statistic'; - static const String _baseDirectUrl = _baseUserUrl + '/direct'; + static const String _baseUserUrl = '$baseUrl/user'; + static const String _baseRadarUrl = '$baseUrl/radar'; + static const String _baseNewsUrl = '$baseUrl/news'; + static const String _baseStudioUrl = '$baseUrl/studio'; + static const String _baseStatisticUrl = '$baseUrl/statistic'; + static const String _baseDirectUrl = '$_baseUserUrl/direct'; - static const String confirmUsername = _baseUserUrl + '/confirmUsername'; - static const String changePassword = _baseUserUrl + '/changePassword'; - static const String login = _baseUserUrl + '/login'; - static const String directs = _baseUserUrl + '/direct'; - static const String userInfo = _baseUserUrl + '/info'; - static const String firebaseToken = _baseUserUrl + '/firebaseToken'; - static const String silenceInterval = _baseUserUrl + '/silenceInterval'; - static const String updateProfilePhoto = _baseUserUrl + '/profile/photo'; - static const String checkUsername = _baseUserUrl + '/CheckUsername'; - static const String updateProfile = _baseUserUrl + '/profile/edit'; - static const String otp = _baseUserUrl + '/otp'; + static const String confirmUsername = '$_baseUserUrl/confirmUsername'; + static const String changePassword = '$_baseUserUrl/changePassword'; + static const String login = '$_baseUserUrl/login'; + static const String directs = '$_baseUserUrl/direct'; + static const String userInfo = '$_baseUserUrl/info'; + static const String firebaseToken = '$_baseUserUrl/firebaseToken'; + static const String silenceInterval = '$_baseUserUrl/silenceInterval'; + static const String updateProfilePhoto = '$_baseUserUrl/profile/photo'; + static const String checkUsername = '$_baseUserUrl/CheckUsername'; + static const String updateProfile = '$_baseUserUrl/profile/edit'; + static const String otp = '$_baseUserUrl/otp'; static String bookmarks({ required int page, String? search, String? type, String? studioType, }) => - _baseUserUrl + - '/marked/${type ?? ''}' + - _urlConcatGenerator([ - MapEntry('page', page), - MapEntry('type', studioType), - MapEntry('search', search), - ]); + '$_baseUserUrl/marked/${type ?? ''}${_urlConcatGenerator([ + MapEntry('page', page), + MapEntry('type', studioType), + MapEntry('search', search), + ])}'; - static const String directTypes = baseUrl + '/direct/types'; - static String direct(int id) => _baseDirectUrl + '/$id'; - static String sendDirectMessage(int id) => - _baseDirectUrl + '/$id/sendMessage'; + static const String directTypes = '$baseUrl/direct/types'; + static String direct(int id) => '$_baseDirectUrl/$id'; + static String sendDirectMessage(int id) => '$_baseDirectUrl/$id/sendMessage'; static String deleteDirect(int id, int messageId) => - _baseDirectUrl + '/$id/message/$messageId'; + '$_baseDirectUrl/$id/message/$messageId'; static String tag({ required List ids, String? type, @@ -49,26 +46,22 @@ class RequestHelper { int? page, int? limit, }) => - baseUrl + - '/tag' + - _urlConcatGenerator([ - MapEntry('page', page), - MapEntry('limit', limit ?? '3'), - MapEntry('type', type), - MapEntry('id', itemId ?? '1'), - MapEntry('tags', _urlListConcatGenerator(ids)), - ]); + '$baseUrl/tag${_urlConcatGenerator([ + MapEntry('page', page), + MapEntry('limit', limit ?? '3'), + MapEntry('type', type), + MapEntry('id', itemId ?? '1'), + MapEntry('tags', _urlListConcatGenerator(ids)), + ])}'; static String radarDetails(int id, RadarRequestArgs args) => - _baseRadarUrl + - '/$id' + - _urlConcatGenerator([ - MapEntry('page', args.page), - MapEntry('start', args.startDate), - MapEntry('end', args.endDate), - MapEntry('search', args.search), - MapEntry('categories', _urlListConcatGenerator(args.categories)), - ]); + '$_baseRadarUrl/$id${_urlConcatGenerator([ + MapEntry('page', args.page), + MapEntry('start', args.startDate), + MapEntry('end', args.endDate), + MapEntry('search', args.search), + MapEntry('categories', _urlListConcatGenerator(args.categories)), + ])}'; static String radarOverviews({required RadarRequestArgs args}) => _baseRadarUrl + _urlConcatGenerator([ @@ -80,14 +73,12 @@ class RequestHelper { ]); static String newsDetails(int id, NewsRequestArgs args) => - _baseNewsUrl + - '/$id' + - _urlConcatGenerator([ - MapEntry('page', args.page), - MapEntry('start', args.startDate), - MapEntry('end', args.endDate), - MapEntry('search', args.search), - ]); + '$_baseNewsUrl/$id${_urlConcatGenerator([ + MapEntry('page', args.page), + MapEntry('start', args.startDate), + MapEntry('end', args.endDate), + MapEntry('search', args.search), + ])}'; static String newsOverviews({required NewsRequestArgs args}) => _baseNewsUrl + _urlConcatGenerator([ @@ -98,19 +89,15 @@ class RequestHelper { ]); static String studioSlider(String type) => - _baseStudioUrl + - '/slider' + - _urlConcatGenerator([MapEntry('type', type)]); + '$_baseStudioUrl/slider${_urlConcatGenerator([MapEntry('type', type)])}'; static String studioDetails(int id, StudioRequestArgs args) => - _baseStudioUrl + - '/$id' + - _urlConcatGenerator([ - MapEntry('page', args.page), - MapEntry('type', args.type), - MapEntry('order', args.order), - MapEntry('search', args.search), - MapEntry('asc', args.asc), - ]); + '$_baseStudioUrl/$id${_urlConcatGenerator([ + MapEntry('page', args.page), + MapEntry('type', args.type), + MapEntry('order', args.order), + MapEntry('search', args.search), + MapEntry('asc', args.asc), + ])}'; static String studioOverviews({required StudioRequestArgs args}) => _baseStudioUrl + _urlConcatGenerator([ @@ -130,23 +117,19 @@ class RequestHelper { String label, String period, ) => - _baseStatisticUrl + - '/$label' + - _urlConcatGenerator([ - MapEntry('period', period), - ]); + '$_baseStatisticUrl/$label${_urlConcatGenerator([ + MapEntry('period', period), + ])}'; - static String mark(int id, String type) => baseUrl + '/$type/$id/mark'; - static String tracking(int id, String type) => - baseUrl + '/$type/$id/tracking'; - static String comments(int id, String type) => - baseUrl + '/$type/$id/comments'; + static String mark(int id, String type) => '$baseUrl/$type/$id/mark'; + static String tracking(int id, String type) => '$baseUrl/$type/$id/tracking'; + static String comments(int id, String type) => '$baseUrl/$type/$id/comments'; static String feedback(int id, int commentId, String type) => - baseUrl + '/$type/$id/comments/$commentId/feedback'; + '$baseUrl/$type/$id/comments/$commentId/feedback'; static String addComment(int id, String type) => - baseUrl + '/$type/$id/comments/add'; - static String deleteComment(int id) => baseUrl + '/comment/$id'; - static String reportComment(int id) => baseUrl + '/comment/$id/report'; + '$baseUrl/$type/$id/comments/add'; + static String deleteComment(int id) => '$baseUrl/comment/$id'; + static String reportComment(int id) => '$baseUrl/comment/$id/report'; static String _urlConcatGenerator(List> additions) { String result = ''; @@ -156,7 +139,7 @@ class RequestHelper { if (additions.isNotEmpty) { result += '?'; for (var i = 0; i < additions.length; i++) { - result += (additions[i].key + '=' + additions[i].value!.toString()); + result += ('${additions[i].key}=${additions[i].value!}'); if (i != additions.length - 1) { result += '&'; } diff --git a/lib/views/home/direct/widgets/audio_widget.dart b/lib/views/home/direct/widgets/audio_widget.dart index 5f1c8bd..f116b32 100644 --- a/lib/views/home/direct/widgets/audio_widget.dart +++ b/lib/views/home/direct/widgets/audio_widget.dart @@ -1,7 +1,9 @@ import 'dart:io'; +import 'package:assets_audio_player/assets_audio_player.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/services/media/media.dart'; import 'package:didvan/views/home/widgets/audio/audio_slider.dart'; import 'package:didvan/views/widgets/didvan/icon_button.dart'; @@ -11,11 +13,13 @@ class AudioWidget extends StatelessWidget { final String? audioUrl; final File? audioFile; final int id; + final StudioDetailsData? audioMetaData; const AudioWidget({ Key? key, this.audioUrl, this.audioFile, required this.id, + this.audioMetaData, }) : super(key: key); @override @@ -24,16 +28,20 @@ class AudioWidget extends StatelessWidget { stream: MediaService.audioPlayer.isPlaying, builder: (context, snapshot) { return Row( + crossAxisAlignment: CrossAxisAlignment.start, children: [ Expanded( child: AudioSlider( - tag: 'message-$id', + tag: audioMetaData != null ? 'radar-$id' : 'message-$id', + duration: audioMetaData?.duration, + showTimer: true, ), ), _AudioControllerButton( audioFile: audioFile, audioUrl: audioUrl, id: id, + audioMetaData: audioMetaData, ), ], ); @@ -46,28 +54,46 @@ class _AudioControllerButton extends StatelessWidget { final String? audioUrl; final File? audioFile; final int id; + final StudioDetailsData? audioMetaData; - const _AudioControllerButton( - {Key? key, this.audioUrl, this.audioFile, required this.id}) - : super(key: key); + const _AudioControllerButton({ + Key? key, + this.audioUrl, + this.audioFile, + required this.id, + this.audioMetaData, + }) : super(key: key); - bool get _nowPlaying => MediaService.audioPlayerTag == 'message-$id'; + bool get _nowPlaying => + MediaService.audioPlayerTag == + (audioMetaData != null ? 'radar-$id' : 'message-$id'); @override Widget build(BuildContext context) { - return DidvanIconButton( - icon: MediaService.audioPlayer.isPlaying.value && _nowPlaying - ? DidvanIcons.pause_circle_solid - : DidvanIcons.play_circle_solid, - color: Theme.of(context).colorScheme.focusedBorder, - onPressed: () { - MediaService.handleAudioPlayback( - audioSource: audioFile?.path ?? audioUrl, - id: id, - isNetworkAudio: audioFile == null, - isVoiceMessage: true, - ); - }, - ); + return StreamBuilder( + stream: MediaService.audioPlayer.onReadyToPlay, + builder: (context, snapshot) { + return DidvanIconButton( + icon: MediaService.audioPlayer.isPlaying.value && _nowPlaying + ? DidvanIcons.pause_circle_solid + : DidvanIcons.play_circle_solid, + gestureSize: 36, + color: Theme.of(context).colorScheme.focusedBorder, + onPressed: () async { + if (snapshot.data == null && _nowPlaying) { + return; + } + if (audioMetaData != null) { + MediaService.currentPodcast = audioMetaData; + } + MediaService.handleAudioPlayback( + audioSource: audioFile?.path ?? audioUrl, + id: id, + isNetworkAudio: audioFile == null, + isVoiceMessage: audioMetaData == null, + ); + }, + ); + }); } } diff --git a/lib/views/home/news/news_details/news_details_state.dart b/lib/views/home/news/news_details/news_details_state.dart index 2f07cd2..72d13cd 100644 --- a/lib/views/home/news/news_details/news_details_state.dart +++ b/lib/views/home/news/news_details/news_details_state.dart @@ -72,6 +72,9 @@ class NewsDetailsState extends CoreProvier { _currentIndex--; } isFetchingNewItem = false; + if (currentNews.contents.length == 1) { + getRelatedContents(); + } appState = AppState.idle; return; } @@ -108,7 +111,10 @@ class NewsDetailsState extends CoreProvier { } Future getRelatedContents() async { - if (currentNews.relatedContents.isNotEmpty) return; + if (currentNews.relatedContents.isNotEmpty && + currentNews.relatedContentsIsEmpty) { + return; + } relatedQueue.add(currentNews.id); final service = RequestService(RequestHelper.tag( ids: currentNews.tags.map((tag) => tag.id).toList(), @@ -125,8 +131,19 @@ class NewsDetailsState extends CoreProvier { .relatedContents .add(OverviewData.fromJson(relateds[i])); } - notifyListeners(); + if (relateds.isEmpty) { + news + .where((element) => element != null) + .firstWhere((element) => element!.id == currentNews.id) + ?.relatedContentsIsEmpty = true; + } + } else { + news + .where((element) => element != null) + .firstWhere((element) => element!.id == currentNews.id) + ?.relatedContentsIsEmpty = true; } + notifyListeners(); } @override diff --git a/lib/views/home/radar/radar_details/radar_details.dart b/lib/views/home/radar/radar_details/radar_details.dart index 5626d3a..9e36cce 100644 --- a/lib/views/home/radar/radar_details/radar_details.dart +++ b/lib/views/home/radar/radar_details/radar_details.dart @@ -1,3 +1,4 @@ +import 'package:didvan/models/enums.dart'; import 'package:didvan/models/requests/radar.dart'; import 'package:didvan/views/home/radar/radar_details/radar_details_state.dart'; import 'package:didvan/views/home/widgets/floating_navigation_bar.dart'; diff --git a/lib/views/home/radar/radar_details/radar_details_state.dart b/lib/views/home/radar/radar_details/radar_details_state.dart index e0c9a2f..78fe722 100644 --- a/lib/views/home/radar/radar_details/radar_details_state.dart +++ b/lib/views/home/radar/radar_details/radar_details_state.dart @@ -81,6 +81,9 @@ class RadarDetailsState extends CoreProvier { _currentIndex--; } isFetchingNewItem = false; + if (currentRadar.contents.length == 1) { + getRelatedContents(); + } appState = AppState.idle; return; } @@ -91,7 +94,10 @@ class RadarDetailsState extends CoreProvier { } Future getRelatedContents() async { - if (currentRadar.relatedContents.isNotEmpty) return; + if (currentRadar.relatedContents.isNotEmpty && + currentRadar.relatedContentsIsEmpty) { + return; + } relatedQueue.add(currentRadar.id); final service = RequestService(RequestHelper.tag( ids: currentRadar.tags.map((tag) => tag.id).toList(), @@ -108,8 +114,19 @@ class RadarDetailsState extends CoreProvier { .relatedContents .add(OverviewData.fromJson(relateds[i])); } - notifyListeners(); + if (relateds.isEmpty) { + radars + .where((element) => element != null) + .firstWhere((element) => element!.id == currentRadar.id) + ?.relatedContentsIsEmpty = true; + } + } else { + radars + .where((element) => element != null) + .firstWhere((element) => element!.id == currentRadar.id) + ?.relatedContentsIsEmpty = true; } + notifyListeners(); } bool exists(RadarDetailsData? radar) => diff --git a/lib/views/home/settings/profile/widgets/profile_photo.dart b/lib/views/home/settings/profile/widgets/profile_photo.dart index 865d898..3984ee0 100644 --- a/lib/views/home/settings/profile/widgets/profile_photo.dart +++ b/lib/views/home/settings/profile/widgets/profile_photo.dart @@ -138,17 +138,19 @@ class _ProfilePhotoState extends State { return; } final pickedFile = await MediaService.pickImage(source: source); - File? file; + dynamic file; if (pickedFile != null && !kIsWeb) { file = await ImageCropper().cropImage( sourcePath: pickedFile.path, aspectRatio: const CropAspectRatio(ratioX: 1, ratioY: 1), - iosUiSettings: const IOSUiSettings( - title: 'برش تصویر', - doneButtonTitle: 'تایید', - cancelButtonTitle: 'بازگشت', - ), - androidUiSettings: const AndroidUiSettings(toolbarTitle: 'برش تصویر'), + uiSettings: [ + IOSUiSettings( + title: 'برش تصویر', + doneButtonTitle: 'تایید', + cancelButtonTitle: 'بازگشت', + ), + AndroidUiSettings(toolbarTitle: 'برش تصویر') + ], compressQuality: 30, ); if (file == null) return; diff --git a/lib/views/home/studio/studio.dart b/lib/views/home/studio/studio.dart index e4260d8..20c825d 100644 --- a/lib/views/home/studio/studio.dart +++ b/lib/views/home/studio/studio.dart @@ -126,7 +126,7 @@ class _StudioState extends State { emptyState: EmptyResult( onNewSearch: () => _focusNode.requestFocus(), ), - centerEmptyState: true, + centerEmptyState: false, enableEmptyState: state.studios.isEmpty, placeholder: state.videosSelected ? VideoOverview.placeHolder 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 190418e..d1e810f 100644 --- a/lib/views/home/studio/studio_details/studio_details_state.dart +++ b/lib/views/home/studio/studio_details/studio_details_state.dart @@ -14,7 +14,7 @@ class StudioDetailsState extends CoreProvier { StudioDetailsData? nextStudio; StudioDetailsData? prevStudio; late int initialIndex; - late StudioRequestArgs args; + StudioRequestArgs? args; StudioRequestArgs? podcastArgs; final List relatedQueue = []; bool _positionListenerActivated = false; @@ -45,11 +45,11 @@ class StudioDetailsState extends CoreProvier { if (args != null) { this.args = args; } - if (this.args.type == 'podcast') { + if (this.args?.type == 'podcast') { podcastArgs = this.args; } if (MediaService.currentPodcast?.id == id && - this.args.type == 'podcast' && + this.args?.type == 'podcast' && !fetchOnly) { return; } @@ -68,7 +68,7 @@ class StudioDetailsState extends CoreProvier { _handlePodcastPlayback(studio); } if (isForward == null) { - if (this.args.type == 'podcast') { + if (this.args?.type == 'podcast') { MediaService.audioPlayerTag = 'podcast-${MediaService.currentPodcast?.id ?? ''}'; } @@ -77,7 +77,12 @@ class StudioDetailsState extends CoreProvier { alongSideState = AppState.busy; notifyListeners(); } - final service = RequestService(RequestHelper.studioDetails(id, this.args)); + final service = RequestService( + RequestHelper.studioDetails( + id, + this.args ?? const StudioRequestArgs(page: 0), + ), + ); await service.httpGet(); nextStudio = null; prevStudio = null; @@ -91,10 +96,10 @@ class StudioDetailsState extends CoreProvier { } final result = service.result; studio = StudioDetailsData.fromJson(result['studio']); - if (result['nextStudio'].isNotEmpty && this.args.page != 0) { + if (result['nextStudio'].isNotEmpty && this.args?.page != 0) { nextStudio = StudioDetailsData.fromJson(result['nextStudio']); } - if (result['prevStudio'].isNotEmpty && this.args.page != 0) { + if (result['prevStudio'].isNotEmpty && this.args?.page != 0) { prevStudio = StudioDetailsData.fromJson(result['prevStudio']); } if (isForward == null && !fetchOnly) { @@ -113,7 +118,7 @@ class StudioDetailsState extends CoreProvier { } Future _handlePodcastPlayback(StudioDetailsData studio) async { - if (args.type == 'podcast') { + if (args?.type == 'podcast') { MediaService.currentPodcast = studio; MediaService.podcastPlaylistArgs = args; await MediaService.handleAudioPlayback( @@ -156,7 +161,7 @@ class StudioDetailsState extends CoreProvier { final service = RequestService(RequestHelper.tag( ids: studio.tags.map((tag) => tag.id).toList(), itemId: studio.id, - type: args.type, + type: args?.type, )); await service.httpGet(); if (service.isSuccess) { @@ -164,8 +169,13 @@ class StudioDetailsState extends CoreProvier { for (var i = 0; i < relateds.length; i++) { studio.relatedContents.add(OverviewData.fromJson(relateds[i])); } - notifyListeners(); + if (relateds.isEmpty) { + studio.relatedContentsIsEmpty = true; + } + } else { + studio.relatedContentsIsEmpty = true; } + notifyListeners(); } void onCommentsChanged(int count) { diff --git a/lib/views/home/studio/studio_details/widgets/studio_details_widget.dart b/lib/views/home/studio/studio_details/widgets/studio_details_widget.dart index 42e4141..0ff34fb 100644 --- a/lib/views/home/studio/studio_details/widgets/studio_details_widget.dart +++ b/lib/views/home/studio/studio_details/widgets/studio_details_widget.dart @@ -71,7 +71,7 @@ class StudioDetailsWidget extends StatelessWidget { direction: TextDirection.rtl, textAlign: TextAlign.right, lineHeight: LineHeight.percent(135), - margin: EdgeInsets.zero, + margin: const Margins(), padding: EdgeInsets.zero, ), }, @@ -144,7 +144,8 @@ class StudioDetailsWidget extends StatelessWidget { } return Column( children: [ - if (state.studio.relatedContents.isEmpty) + if (state.studio.relatedContents.isEmpty && + !state.studio.relatedContentsIsEmpty) for (var i = 0; i < 3; i++) Padding( padding: const EdgeInsets.only( diff --git a/lib/views/widgets/didvan/bnb.dart b/lib/views/widgets/didvan/bnb.dart index 0b8bf72..3a6d2d9 100644 --- a/lib/views/widgets/didvan/bnb.dart +++ b/lib/views/widgets/didvan/bnb.dart @@ -112,7 +112,8 @@ class _PlayerNavBar extends StatelessWidget { return StreamBuilder( stream: MediaService.audioPlayer.isPlaying, builder: (context, snapshot) => GestureDetector( - onTap: () => MediaService.currentPodcast == null + onTap: () => MediaService.currentPodcast == null || + MediaService.currentPodcast?.description == 'radar' ? null : _showPlayerBottomSheet(context), child: Consumer( @@ -203,7 +204,9 @@ class _PlayerNavBar extends StatelessWidget { stream: MediaService.audioPlayer.onReadyToPlay, builder: (context, snapshot) { if (snapshot.data == null || - state.appState == AppState.busy) { + state.appState == AppState.busy && + MediaService.currentPodcast?.description != + 'radar') { return Padding( padding: const EdgeInsets.only( top: 4, @@ -226,7 +229,8 @@ class _PlayerNavBar extends StatelessWidget { }, ), if (state.appState != AppState.busy && - snapshot.data != null) + snapshot.data != null || + MediaService.currentPodcast?.description == 'radar') Padding( padding: const EdgeInsets.only( left: 12, @@ -241,7 +245,7 @@ class _PlayerNavBar extends StatelessWidget { ? DidvanIcons.pause_solid : DidvanIcons.play_solid, onPressed: () { - if (state.args.type == 'video') { + if (state.args?.type == 'video') { state.getStudioDetails( MediaService.currentPodcast!.id, args: state.podcastArgs, @@ -270,7 +274,7 @@ class _PlayerNavBar extends StatelessWidget { final sheetKey = GlobalKey(); bool isExpanded = false; final detailsState = context.read(); - if (detailsState.args.type == 'video') { + if (detailsState.args?.type == 'video') { detailsState.getStudioDetails( MediaService.currentPodcast!.id, args: detailsState.podcastArgs, diff --git a/lib/views/widgets/didvan/page_view.dart b/lib/views/widgets/didvan/page_view.dart index 6de7ca9..a0b7b66 100644 --- a/lib/views/widgets/didvan/page_view.dart +++ b/lib/views/widgets/didvan/page_view.dart @@ -4,9 +4,12 @@ import 'package:didvan/config/theme_data.dart'; import 'package:didvan/constants/app_icons.dart'; import 'package:didvan/models/requests/news.dart'; import 'package:didvan/models/requests/radar.dart'; +import 'package:didvan/models/studio_details_data.dart'; import 'package:didvan/routes/routes.dart'; import 'package:didvan/utils/action_sheet.dart'; import 'package:didvan/utils/date_time.dart'; +import 'package:didvan/views/home/direct/widgets/audio_widget.dart'; +import 'package:didvan/views/home/widgets/audio/audio_slider.dart'; import 'package:didvan/views/home/widgets/overview/multitype.dart'; import 'package:didvan/views/home/widgets/tag_item.dart'; import 'package:didvan/views/widgets/animated_visibility.dart'; @@ -108,6 +111,44 @@ class _DidvanPageViewState extends State { const EdgeInsets.symmetric(horizontal: 16), child: _subtitle(item), ), + if (widget.isRadar && item.podcast != null) + Container( + padding: const EdgeInsets.all(12) + .copyWith(left: 0, bottom: 4), + margin: const EdgeInsets.all(12), + decoration: BoxDecoration( + border: Border.all( + color: Theme.of(context).colorScheme.hint, + ), + borderRadius: DesignConfig.lowBorderRadius, + color: Theme.of(context).backgroundColor, + ), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + const DidvanText('این مطلب را بشنوید:'), + const SizedBox(height: 8), + AudioWidget( + id: item.id, + audioUrl: item.podcast, + audioMetaData: StudioDetailsData( + id: item.id, + link: item.podcast, + createdAt: item.createdAt, + order: 0, + marked: item.marked, + comments: 0, + tags: [], + iframe: '', + duration: item.duration, + title: item.title, + image: item.image, + description: 'radar', + ), + ), + ], + ), + ), for (var i = 0; i < item.contents.length; i++) Padding( padding: const EdgeInsets.symmetric( @@ -146,7 +187,8 @@ class _DidvanPageViewState extends State { padding: EdgeInsets.symmetric(horizontal: 16.0), child: ItemTitle(title: 'مطالب مشابه'), ), - if (item.relatedContents.isEmpty) + if (item.relatedContents.isEmpty && + !item.relatedContentsIsEmpty) for (var i = 0; i < 3; i++) Padding( padding: const EdgeInsets.only( @@ -178,9 +220,9 @@ class _DidvanPageViewState extends State { ), ), Positioned( - child: _BackButton(scrollController: widget.scrollController), right: 24, top: 24 + deviceTopPadding, + child: _BackButton(scrollController: widget.scrollController), ), ], ); @@ -272,7 +314,7 @@ class _DidvanPageViewState extends State { direction: TextDirection.rtl, textAlign: TextAlign.right, lineHeight: LineHeight.percent(135), - margin: EdgeInsets.zero, + margin: const Margins(), padding: EdgeInsets.zero, ), 'a': Style( diff --git a/lib/views/widgets/didvan/switch.dart b/lib/views/widgets/didvan/switch.dart index 8f592e0..c1b0bee 100644 --- a/lib/views/widgets/didvan/switch.dart +++ b/lib/views/widgets/didvan/switch.dart @@ -16,7 +16,7 @@ class DidvanSwitch extends StatefulWidget { }) : super(key: key); @override - _DidvanSwitchState createState() => _DidvanSwitchState(); + State createState() => _DidvanSwitchState(); } class _DidvanSwitchState extends State { diff --git a/pubspec.lock b/pubspec.lock index 779d0e6..4d8022b 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -1,34 +1,41 @@ # Generated by pub # See https://dart.dev/tools/pub/glossary#lockfile packages: + _flutterfire_internals: + dependency: transitive + description: + name: _flutterfire_internals + url: "https://pub.dartlang.org" + source: hosted + version: "1.0.9" assets_audio_player: dependency: "direct main" description: name: assets_audio_player url: "https://pub.dartlang.org" source: hosted - version: "3.0.5" + version: "3.0.6" assets_audio_player_web: dependency: transitive description: name: assets_audio_player_web url: "https://pub.dartlang.org" source: hosted - version: "3.0.5" + version: "3.0.6" async: dependency: transitive description: name: async url: "https://pub.dartlang.org" source: hosted - version: "2.8.2" + version: "2.9.0" audio_video_progress_bar: dependency: "direct main" description: name: audio_video_progress_bar url: "https://pub.dartlang.org" source: hosted - version: "0.10.0" + version: "0.11.0" better_player: dependency: "direct main" description: @@ -56,21 +63,21 @@ packages: name: cached_network_image url: "https://pub.dartlang.org" source: hosted - version: "3.2.1" + version: "3.2.3" cached_network_image_platform_interface: dependency: transitive description: name: cached_network_image_platform_interface url: "https://pub.dartlang.org" source: hosted - version: "1.0.0" + version: "2.0.0" cached_network_image_web: dependency: transitive description: name: cached_network_image_web url: "https://pub.dartlang.org" source: hosted - version: "1.0.1" + version: "1.0.2" carousel_slider: dependency: "direct main" description: @@ -84,7 +91,7 @@ packages: name: characters url: "https://pub.dartlang.org" source: hosted - version: "1.2.0" + version: "1.2.1" charcode: dependency: transitive description: @@ -98,7 +105,21 @@ packages: name: clock url: "https://pub.dartlang.org" source: hosted - version: "1.1.0" + version: "1.1.1" + cloud_firestore_platform_interface: + dependency: transitive + description: + name: cloud_firestore_platform_interface + url: "https://pub.dartlang.org" + source: hosted + version: "5.9.0" + cloud_firestore_web: + dependency: transitive + description: + name: cloud_firestore_web + url: "https://pub.dartlang.org" + source: hosted + version: "3.1.0" collection: dependency: transitive description: @@ -112,7 +133,7 @@ packages: name: cross_file url: "https://pub.dartlang.org" source: hosted - version: "0.3.3+1" + version: "0.3.3+2" crypto: dependency: transitive description: @@ -140,14 +161,14 @@ packages: name: day_night_time_picker url: "https://pub.dartlang.org" source: hosted - version: "1.1.2" + version: "1.1.3" equatable: dependency: transitive description: name: equatable url: "https://pub.dartlang.org" source: hosted - version: "2.0.3" + version: "2.0.5" expandable_bottom_sheet: dependency: "direct main" description: @@ -161,7 +182,7 @@ packages: name: fake_async url: "https://pub.dartlang.org" source: hosted - version: "1.3.0" + version: "1.3.1" ffi: dependency: transitive description: @@ -175,56 +196,56 @@ packages: name: file url: "https://pub.dartlang.org" source: hosted - version: "6.1.2" + version: "6.1.4" firebase_core: dependency: "direct main" description: name: firebase_core url: "https://pub.dartlang.org" source: hosted - version: "1.19.2" + version: "2.3.0" firebase_core_platform_interface: dependency: transitive description: name: firebase_core_platform_interface url: "https://pub.dartlang.org" source: hosted - version: "4.4.3" + version: "4.5.2" firebase_core_web: dependency: transitive description: name: firebase_core_web url: "https://pub.dartlang.org" source: hosted - version: "1.7.0" + version: "2.0.1" firebase_messaging: dependency: "direct main" description: name: firebase_messaging url: "https://pub.dartlang.org" source: hosted - version: "11.4.4" + version: "14.1.3" firebase_messaging_platform_interface: dependency: transitive description: name: firebase_messaging_platform_interface url: "https://pub.dartlang.org" source: hosted - version: "3.5.4" + version: "4.2.7" firebase_messaging_web: dependency: transitive description: name: firebase_messaging_web url: "https://pub.dartlang.org" source: hosted - version: "2.4.4" + version: "3.2.8" fl_chart: dependency: "direct main" description: name: fl_chart url: "https://pub.dartlang.org" source: hosted - version: "0.50.6" + version: "0.55.2" flutter: dependency: "direct main" description: flutter @@ -250,14 +271,14 @@ packages: name: flutter_html url: "https://pub.dartlang.org" source: hosted - version: "3.0.0-alpha.5" + version: "3.0.0-alpha.6" flutter_lints: dependency: "direct dev" description: name: flutter_lints url: "https://pub.dartlang.org" source: hosted - version: "1.0.4" + version: "2.0.1" flutter_localizations: dependency: "direct main" description: flutter @@ -276,42 +297,42 @@ packages: name: flutter_secure_storage url: "https://pub.dartlang.org" source: hosted - version: "5.0.2" + version: "6.1.0" flutter_secure_storage_linux: dependency: transitive description: name: flutter_secure_storage_linux url: "https://pub.dartlang.org" source: hosted - version: "1.1.0" + version: "1.1.2" flutter_secure_storage_macos: dependency: transitive description: name: flutter_secure_storage_macos url: "https://pub.dartlang.org" source: hosted - version: "1.1.0" + version: "1.1.2" flutter_secure_storage_platform_interface: dependency: transitive description: name: flutter_secure_storage_platform_interface url: "https://pub.dartlang.org" source: hosted - version: "1.0.0" + version: "1.0.1" flutter_secure_storage_web: dependency: transitive description: name: flutter_secure_storage_web url: "https://pub.dartlang.org" source: hosted - version: "1.0.2" + version: "1.1.1" flutter_secure_storage_windows: dependency: transitive description: name: flutter_secure_storage_windows url: "https://pub.dartlang.org" source: hosted - version: "1.1.2" + version: "1.1.3" flutter_spinkit: dependency: "direct main" description: @@ -325,7 +346,7 @@ packages: name: flutter_svg url: "https://pub.dartlang.org" source: hosted - version: "1.1.1+1" + version: "1.1.6" flutter_test: dependency: "direct dev" description: flutter @@ -356,77 +377,91 @@ packages: name: fwfh_text_style url: "https://pub.dartlang.org" source: hosted - version: "2.7.3+2" + version: "2.22.08+1" graphs: dependency: transitive description: name: graphs url: "https://pub.dartlang.org" source: hosted - version: "2.1.0" + version: "2.2.0" html: dependency: transitive description: name: html url: "https://pub.dartlang.org" source: hosted - version: "0.15.0" + version: "0.15.1" http: dependency: transitive description: name: http url: "https://pub.dartlang.org" source: hosted - version: "0.13.4" + version: "0.13.5" http_parser: dependency: transitive description: name: http_parser url: "https://pub.dartlang.org" source: hosted - version: "4.0.1" + version: "4.0.2" image_cropper: dependency: "direct main" description: name: image_cropper url: "https://pub.dartlang.org" source: hosted - version: "1.5.1" + version: "3.0.1" + image_cropper_for_web: + dependency: transitive + description: + name: image_cropper_for_web + url: "https://pub.dartlang.org" + source: hosted + version: "1.0.3" + image_cropper_platform_interface: + dependency: transitive + description: + name: image_cropper_platform_interface + url: "https://pub.dartlang.org" + source: hosted + version: "3.0.3" image_picker: dependency: "direct main" description: name: image_picker url: "https://pub.dartlang.org" source: hosted - version: "0.8.5+3" + version: "0.8.6" image_picker_android: dependency: transitive description: name: image_picker_android url: "https://pub.dartlang.org" source: hosted - version: "0.8.5+1" + version: "0.8.5+3" image_picker_for_web: dependency: transitive description: name: image_picker_for_web url: "https://pub.dartlang.org" source: hosted - version: "2.1.8" + version: "2.1.10" image_picker_ios: dependency: transitive description: name: image_picker_ios url: "https://pub.dartlang.org" source: hosted - version: "0.8.5+6" + version: "0.8.6+1" image_picker_platform_interface: dependency: transitive description: name: image_picker_platform_interface url: "https://pub.dartlang.org" source: hosted - version: "2.5.0" + version: "2.6.2" intl: dependency: transitive description: @@ -447,28 +482,28 @@ packages: name: lints url: "https://pub.dartlang.org" source: hosted - version: "1.0.1" + version: "2.0.1" matcher: dependency: transitive description: name: matcher url: "https://pub.dartlang.org" source: hosted - version: "0.12.11" + version: "0.12.12" material_color_utilities: dependency: transitive description: name: material_color_utilities url: "https://pub.dartlang.org" source: hosted - version: "0.1.4" + version: "0.1.5" meta: dependency: transitive description: name: meta url: "https://pub.dartlang.org" source: hosted - version: "1.7.0" + version: "1.8.0" nested: dependency: transitive description: @@ -482,7 +517,7 @@ packages: name: numerus url: "https://pub.dartlang.org" source: hosted - version: "1.1.1" + version: "2.0.0" octo_image: dependency: transitive description: @@ -496,21 +531,21 @@ packages: name: path url: "https://pub.dartlang.org" source: hosted - version: "1.8.1" + version: "1.8.2" path_drawing: dependency: transitive description: name: path_drawing url: "https://pub.dartlang.org" source: hosted - version: "1.0.0" + version: "1.0.1" path_parsing: dependency: transitive description: name: path_parsing url: "https://pub.dartlang.org" source: hosted - version: "1.0.0" + version: "1.0.1" path_provider: dependency: "direct main" description: @@ -524,14 +559,14 @@ packages: name: path_provider_android url: "https://pub.dartlang.org" source: hosted - version: "2.0.16" + version: "2.0.22" path_provider_ios: dependency: transitive description: name: path_provider_ios url: "https://pub.dartlang.org" source: hosted - version: "2.0.10" + version: "2.0.11" path_provider_linux: dependency: transitive description: @@ -552,14 +587,14 @@ packages: name: path_provider_platform_interface url: "https://pub.dartlang.org" source: hosted - version: "2.0.4" + version: "2.0.5" path_provider_windows: dependency: transitive description: name: path_provider_windows url: "https://pub.dartlang.org" source: hosted - version: "2.1.0" + version: "2.1.3" pedantic: dependency: transitive description: @@ -573,35 +608,35 @@ packages: name: permission_handler url: "https://pub.dartlang.org" source: hosted - version: "9.2.0" + version: "10.2.0" permission_handler_android: dependency: transitive description: name: permission_handler_android url: "https://pub.dartlang.org" source: hosted - version: "9.0.2+1" + version: "10.2.0" permission_handler_apple: dependency: transitive description: name: permission_handler_apple url: "https://pub.dartlang.org" source: hosted - version: "9.0.4" + version: "9.0.7" permission_handler_platform_interface: dependency: transitive description: name: permission_handler_platform_interface url: "https://pub.dartlang.org" source: hosted - version: "3.7.0" + version: "3.9.0" permission_handler_windows: dependency: transitive description: name: permission_handler_windows url: "https://pub.dartlang.org" source: hosted - version: "0.1.0" + version: "0.1.2" persian_datetime_picker: dependency: "direct main" description: @@ -622,7 +657,7 @@ packages: name: petitparser url: "https://pub.dartlang.org" source: hosted - version: "5.0.0" + version: "5.1.0" pin_code_fields: dependency: "direct main" description: @@ -643,7 +678,7 @@ packages: name: plugin_platform_interface url: "https://pub.dartlang.org" source: hosted - version: "2.1.2" + version: "2.1.3" process: dependency: transitive description: @@ -657,42 +692,63 @@ packages: name: provider url: "https://pub.dartlang.org" source: hosted - version: "6.0.3" + version: "6.0.4" record: dependency: "direct main" description: name: record url: "https://pub.dartlang.org" source: hosted - version: "3.0.4" + version: "4.4.3" + record_linux: + dependency: transitive + description: + name: record_linux + url: "https://pub.dartlang.org" + source: hosted + version: "0.3.4" + record_macos: + dependency: transitive + description: + name: record_macos + url: "https://pub.dartlang.org" + source: hosted + version: "0.2.2" record_platform_interface: dependency: transitive description: name: record_platform_interface url: "https://pub.dartlang.org" source: hosted - version: "0.2.0" + version: "0.5.0" record_web: dependency: "direct main" description: name: record_web url: "https://pub.dartlang.org" source: hosted - version: "0.2.1" + version: "0.5.0" + record_windows: + dependency: transitive + description: + name: record_windows + url: "https://pub.dartlang.org" + source: hosted + version: "0.6.2" rive: dependency: "direct main" description: name: rive url: "https://pub.dartlang.org" source: hosted - version: "0.7.33" + version: "0.9.1" rxdart: dependency: transitive description: name: rxdart url: "https://pub.dartlang.org" source: hosted - version: "0.27.5" + version: "0.27.7" skeleton_text: dependency: "direct main" description: @@ -711,21 +767,21 @@ packages: name: source_span url: "https://pub.dartlang.org" source: hosted - version: "1.8.2" + version: "1.9.0" sqflite: dependency: transitive description: name: sqflite url: "https://pub.dartlang.org" source: hosted - version: "2.0.3" + version: "2.2.1" sqflite_common: dependency: transitive description: name: sqflite_common url: "https://pub.dartlang.org" source: hosted - version: "2.2.1+1" + version: "2.4.0+2" stack_trace: dependency: transitive description: @@ -746,28 +802,28 @@ packages: name: string_scanner url: "https://pub.dartlang.org" source: hosted - version: "1.1.0" + version: "1.1.1" synchronized: dependency: transitive description: name: synchronized url: "https://pub.dartlang.org" source: hosted - version: "3.0.0+2" + version: "3.0.0+3" term_glyph: dependency: transitive description: name: term_glyph url: "https://pub.dartlang.org" source: hosted - version: "1.2.0" + version: "1.2.1" test_api: dependency: transitive description: name: test_api url: "https://pub.dartlang.org" source: hosted - version: "0.4.9" + version: "0.4.12" typed_data: dependency: transitive description: @@ -795,14 +851,14 @@ packages: name: url_launcher url: "https://pub.dartlang.org" source: hosted - version: "6.1.5" + version: "6.1.7" url_launcher_android: dependency: transitive description: name: url_launcher_android url: "https://pub.dartlang.org" source: hosted - version: "6.0.17" + version: "6.0.22" url_launcher_ios: dependency: transitive description: @@ -830,14 +886,14 @@ packages: name: url_launcher_platform_interface url: "https://pub.dartlang.org" source: hosted - version: "2.1.0" + version: "2.1.1" url_launcher_web: dependency: transitive description: name: url_launcher_web url: "https://pub.dartlang.org" source: hosted - version: "2.0.12" + version: "2.0.13" url_launcher_windows: dependency: transitive description: @@ -851,7 +907,7 @@ packages: name: uuid url: "https://pub.dartlang.org" source: hosted - version: "3.0.6" + version: "3.0.7" vector_math: dependency: transitive description: @@ -900,7 +956,7 @@ packages: name: wakelock_windows url: "https://pub.dartlang.org" source: hosted - version: "0.2.0" + version: "0.2.1" webview_flutter: dependency: "direct main" description: @@ -914,35 +970,35 @@ packages: name: webview_flutter_android url: "https://pub.dartlang.org" source: hosted - version: "2.8.14" + version: "2.10.4" webview_flutter_platform_interface: dependency: transitive description: name: webview_flutter_platform_interface url: "https://pub.dartlang.org" source: hosted - version: "1.9.1" + version: "1.9.5" webview_flutter_wkwebview: dependency: transitive description: name: webview_flutter_wkwebview url: "https://pub.dartlang.org" source: hosted - version: "2.9.1" + version: "2.9.5" win32: dependency: transitive description: name: win32 url: "https://pub.dartlang.org" source: hosted - version: "2.7.0" + version: "3.1.2" xdg_directories: dependency: transitive description: name: xdg_directories url: "https://pub.dartlang.org" source: hosted - version: "0.2.0+1" + version: "0.2.0+2" xml: dependency: transitive description: @@ -951,5 +1007,5 @@ packages: source: hosted version: "6.1.0" sdks: - dart: ">=2.17.0 <3.0.0" - flutter: ">=3.0.0" + dart: ">=2.18.0 <3.0.0" + flutter: ">=3.3.0" diff --git a/pubspec.yaml b/pubspec.yaml index e85b8ed..6c1ac73 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -37,7 +37,7 @@ dependencies: cupertino_icons: ^1.0.2 provider: ^6.0.1 pin_code_fields: ^7.3.0 - rive: ^0.7.33 + rive: ^0.9.1 image_picker: ^0.8.4+4 day_night_time_picker: ^1.0.5 path_provider: ^2.0.8 @@ -48,24 +48,24 @@ dependencies: carousel_slider: ^4.0.0 flutter_vibrate: ^1.3.0 universal_html: ^2.0.8 - record: ^3.0.2 - record_web: ^0.2.1 + record: ^4.4.3 + record_web: ^0.5.0 persian_datetime_picker: ^2.4.0 persian_number_utility: ^1.1.1 bot_toast: ^4.0.1 - flutter_secure_storage: ^5.0.2 + flutter_secure_storage: ^6.1.0 flutter_html: ^3.0.0-alpha.2 url_launcher: ^6.0.18 - audio_video_progress_bar: ^0.10.0 - image_cropper: ^1.5.0 - firebase_messaging: ^11.2.8 - firebase_core: ^1.13.1 + audio_video_progress_bar: ^0.11.0 + image_cropper: ^3.0.1 + firebase_messaging: ^14.1.3 + firebase_core: ^2.3.0 webview_flutter: ^3.0.1 expandable_bottom_sheet: ^1.1.1+1 - permission_handler: ^9.2.0 + permission_handler: ^10.2.0 better_player: ^0.0.81 assets_audio_player: ^3.0.4+1 - fl_chart: ^0.50.1 + fl_chart: ^0.55.2 dev_dependencies: flutter_test: @@ -76,7 +76,7 @@ dev_dependencies: # activated in the `analysis_options.yaml` file located at the root of your # package. See that file for information about deactivating specific lint # rules and activating additional ones. - flutter_lints: ^1.0.0 + flutter_lints: ^2.0.1 # For information on the generic Dart part of this file, see the # following page: https://dart.dev/tools/pub/pubspec