bug fixes + radar podcasts

This commit is contained in:
MohammadTaha Basiri 2022-12-03 09:26:47 +03:30
parent 931c268c25
commit b1ce815c66
20 changed files with 433 additions and 265 deletions

View File

@ -32,7 +32,7 @@ if (keystorePropertiesFile.exists()) {
} }
android { android {
compileSdkVersion 31 compileSdkVersion 33
compileOptions { compileOptions {

View File

@ -3,57 +3,56 @@ import 'package:flutter/cupertino.dart';
class Assets { class Assets {
static const String _basePath = 'lib/assets'; static const String _basePath = 'lib/assets';
static const String _baseImagesPath = _basePath + '/images'; static const String _baseImagesPath = '$_basePath/images';
static const String _baseCategoriesPath = _baseImagesPath + '/categories'; static const String _baseCategoriesPath = '$_baseImagesPath/categories';
static const String _baseThemesPath = _baseImagesPath + '/themes'; static const String _baseThemesPath = '$_baseImagesPath/themes';
static const String _baseEmptyStatesPath = _baseImagesPath + '/empty_states'; static const String _baseEmptyStatesPath = '$_baseImagesPath/empty_states';
static const String _baseAnimationsPath = _basePath + '/animations'; static const String _baseAnimationsPath = '$_basePath/animations';
static const String _baseRecordsPath = _baseImagesPath + '/records'; static const String _baseRecordsPath = '$_baseImagesPath/records';
static const String _baseLogosPath = _baseImagesPath + '/logos'; static const String _baseLogosPath = '$_baseImagesPath/logos';
static String get verticalLogoWithText => static String get verticalLogoWithText =>
_baseLogosPath + '/logo-vertical-$_themeSuffix.svg'; '$_baseLogosPath/logo-vertical-$_themeSuffix.svg';
static String get horizontalLogoWithText => static String get horizontalLogoWithText =>
_baseLogosPath + '/logo-horizontal-$_themeSuffix.svg'; '$_baseLogosPath/logo-horizontal-$_themeSuffix.svg';
static String get studioLogo => _baseLogosPath + '/studio-$_themeSuffix.svg'; static String get studioLogo => '$_baseLogosPath/studio-$_themeSuffix.svg';
static String get logoLoadingAnimation => static String get logoLoadingAnimation =>
_baseAnimationsPath + '/indicator-$_themeSuffix.riv'; '$_baseAnimationsPath/indicator-$_themeSuffix.riv';
static String get businessCategoryIcon => static String get businessCategoryIcon =>
_baseCategoriesPath + '/business-$_themeSuffix.svg'; '$_baseCategoriesPath/business-$_themeSuffix.svg';
static String get economicCategoryIcon => static String get economicCategoryIcon =>
_baseCategoriesPath + '/economic-$_themeSuffix.svg'; '$_baseCategoriesPath/economic-$_themeSuffix.svg';
static String get enviromentalCategoryIcon => static String get enviromentalCategoryIcon =>
_baseCategoriesPath + '/enviromental-$_themeSuffix.svg'; '$_baseCategoriesPath/enviromental-$_themeSuffix.svg';
static String get politicalCategoryIcon => static String get politicalCategoryIcon =>
_baseCategoriesPath + '/political-$_themeSuffix.svg'; '$_baseCategoriesPath/political-$_themeSuffix.svg';
static String get socialCategoryIcon => static String get socialCategoryIcon =>
_baseCategoriesPath + '/social-$_themeSuffix.svg'; '$_baseCategoriesPath/social-$_themeSuffix.svg';
static String get techCategoryIcon => static String get techCategoryIcon =>
_baseCategoriesPath + '/tech-$_themeSuffix.svg'; '$_baseCategoriesPath/tech-$_themeSuffix.svg';
static String get steelCategoryIcon => static String get steelCategoryIcon =>
_baseCategoriesPath + '/steel-$_themeSuffix.svg'; '$_baseCategoriesPath/steel-$_themeSuffix.svg';
static String get stockCategoryIcon => static String get stockCategoryIcon =>
_baseCategoriesPath + '/stock-$_themeSuffix.svg'; '$_baseCategoriesPath/stock-$_themeSuffix.svg';
static String get globCategoryIcon => static String get globCategoryIcon =>
_baseCategoriesPath + '/glob-$_themeSuffix.svg'; '$_baseCategoriesPath/glob-$_themeSuffix.svg';
static String get emptyBookmark => static String get emptyBookmark =>
_baseEmptyStatesPath + '/bookmark-$_themeSuffix.svg'; '$_baseEmptyStatesPath/bookmark-$_themeSuffix.svg';
static String get emptyChart => static String get emptyChart =>
_baseEmptyStatesPath + '/chart-$_themeSuffix.svg'; '$_baseEmptyStatesPath/chart-$_themeSuffix.svg';
static String get emptyChat => static String get emptyChat => '$_baseEmptyStatesPath/chat-$_themeSuffix.svg';
_baseEmptyStatesPath + '/chat-$_themeSuffix.svg';
static String get emptyConnection => static String get emptyConnection =>
_baseEmptyStatesPath + '/connection-$_themeSuffix.svg'; '$_baseEmptyStatesPath/connection-$_themeSuffix.svg';
static String get emptyResult => static String get emptyResult =>
_baseEmptyStatesPath + '/result-$_themeSuffix.svg'; '$_baseEmptyStatesPath/result-$_themeSuffix.svg';
static const String lightTheme = _baseThemesPath + '/theme-light.svg'; static const String lightTheme = '$_baseThemesPath/theme-light.svg';
static const String darkTheme = _baseThemesPath + '/theme-dark.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 => static String get _themeSuffix =>
DesignConfig.brightness == Brightness.dark ? 'dark' : 'light'; DesignConfig.brightness == Brightness.dark ? 'dark' : 'light';

View File

@ -14,6 +14,7 @@ class NewsDetailsData {
final List<Tag> tags; final List<Tag> tags;
final List<Content> contents; final List<Content> contents;
final List<OverviewData> relatedContents = []; final List<OverviewData> relatedContents = [];
bool relatedContentsIsEmpty;
NewsDetailsData({ NewsDetailsData({
required this.id, required this.id,
@ -26,6 +27,7 @@ class NewsDetailsData {
required this.tags, required this.tags,
required this.contents, required this.contents,
required this.order, required this.order,
this.relatedContentsIsEmpty = false,
}); });
factory NewsDetailsData.fromJson(Map<String, dynamic> json) { factory NewsDetailsData.fromJson(Map<String, dynamic> json) {

View File

@ -11,6 +11,7 @@ class RadarDetailsData {
final int timeToRead; final int timeToRead;
final String createdAt; final String createdAt;
final String? podcast; final String? podcast;
final int? duration;
final bool forManagers; final bool forManagers;
final bool marked; final bool marked;
int comments; int comments;
@ -19,6 +20,7 @@ class RadarDetailsData {
final List<CategoryData> categories; final List<CategoryData> categories;
final int order; final int order;
final List<OverviewData> relatedContents = []; final List<OverviewData> relatedContents = [];
bool relatedContentsIsEmpty;
RadarDetailsData({ RadarDetailsData({
required this.id, required this.id,
@ -34,6 +36,8 @@ class RadarDetailsData {
required this.contents, required this.contents,
required this.categories, required this.categories,
required this.order, required this.order,
required this.duration,
this.relatedContentsIsEmpty = false,
}); });
factory RadarDetailsData.fromJson(Map<String, dynamic> json) { factory RadarDetailsData.fromJson(Map<String, dynamic> json) {
@ -59,6 +63,7 @@ class RadarDetailsData {
(cat) => CategoryData.fromJson(cat), (cat) => CategoryData.fromJson(cat),
), ),
), ),
duration: json['duration'],
); );
} }

View File

@ -11,6 +11,7 @@ class StudioDetailsData {
final String? iframe; final String? iframe;
final String createdAt; final String createdAt;
final int order; final int order;
bool relatedContentsIsEmpty;
bool marked; bool marked;
int comments; int comments;
final List<Tag> tags; final List<Tag> tags;
@ -29,6 +30,7 @@ class StudioDetailsData {
required this.marked, required this.marked,
required this.comments, required this.comments,
required this.tags, required this.tags,
this.relatedContentsIsEmpty = false,
}); });
factory StudioDetailsData.fromJson(Map<String, dynamic> json) { factory StudioDetailsData.fromJson(Map<String, dynamic> json) {

View File

@ -25,9 +25,10 @@ class MediaService {
void Function(bool isNext)? onTrackChanged, void Function(bool isNext)? onTrackChanged,
}) async { }) async {
String tag; String tag;
tag = '${isVoiceMessage ? 'message' : 'podcast'}-$id'; tag =
'${currentPodcast?.description == 'radar' ? 'radar' : isVoiceMessage ? 'message' : 'podcast'}-$id';
if (!isVoiceMessage && MediaProvider.downloadedItemIds.contains(id)) { if (!isVoiceMessage && MediaProvider.downloadedItemIds.contains(id)) {
audioSource = StorageService.appDocsDir + '/podcasts/podcast-$id.mp3'; audioSource = '${StorageService.appDocsDir}/podcasts/podcast-$id.mp3';
isNetworkAudio = false; isNetworkAudio = false;
} }
if (audioPlayerTag == tag) { if (audioPlayerTag == tag) {
@ -52,7 +53,7 @@ class MediaService {
? null ? null
: Metas( : Metas(
artist: 'استودیو دیدوان', artist: 'استودیو دیدوان',
title: currentPodcast!.title, title: currentPodcast?.title ?? '',
), ),
); );
} else { } else {
@ -62,7 +63,7 @@ class MediaService {
? null ? null
: Metas( : Metas(
artist: 'استودیو دیدوان', artist: 'استودیو دیدوان',
title: currentPodcast!.title, title: currentPodcast?.title ?? '',
), ),
); );
} }

View File

@ -4,44 +4,41 @@ import 'package:didvan/models/requests/studio.dart';
class RequestHelper { class RequestHelper {
static const String baseUrl = 'https://api.didvan.app'; static const String baseUrl = 'https://api.didvan.app';
static const String _baseUserUrl = baseUrl + '/user'; static const String _baseUserUrl = '$baseUrl/user';
static const String _baseRadarUrl = baseUrl + '/radar'; static const String _baseRadarUrl = '$baseUrl/radar';
static const String _baseNewsUrl = baseUrl + '/news'; static const String _baseNewsUrl = '$baseUrl/news';
static const String _baseStudioUrl = baseUrl + '/studio'; static const String _baseStudioUrl = '$baseUrl/studio';
static const String _baseStatisticUrl = baseUrl + '/statistic'; static const String _baseStatisticUrl = '$baseUrl/statistic';
static const String _baseDirectUrl = _baseUserUrl + '/direct'; static const String _baseDirectUrl = '$_baseUserUrl/direct';
static const String confirmUsername = _baseUserUrl + '/confirmUsername'; static const String confirmUsername = '$_baseUserUrl/confirmUsername';
static const String changePassword = _baseUserUrl + '/changePassword'; static const String changePassword = '$_baseUserUrl/changePassword';
static const String login = _baseUserUrl + '/login'; static const String login = '$_baseUserUrl/login';
static const String directs = _baseUserUrl + '/direct'; static const String directs = '$_baseUserUrl/direct';
static const String userInfo = _baseUserUrl + '/info'; static const String userInfo = '$_baseUserUrl/info';
static const String firebaseToken = _baseUserUrl + '/firebaseToken'; static const String firebaseToken = '$_baseUserUrl/firebaseToken';
static const String silenceInterval = _baseUserUrl + '/silenceInterval'; static const String silenceInterval = '$_baseUserUrl/silenceInterval';
static const String updateProfilePhoto = _baseUserUrl + '/profile/photo'; static const String updateProfilePhoto = '$_baseUserUrl/profile/photo';
static const String checkUsername = _baseUserUrl + '/CheckUsername'; static const String checkUsername = '$_baseUserUrl/CheckUsername';
static const String updateProfile = _baseUserUrl + '/profile/edit'; static const String updateProfile = '$_baseUserUrl/profile/edit';
static const String otp = _baseUserUrl + '/otp'; static const String otp = '$_baseUserUrl/otp';
static String bookmarks({ static String bookmarks({
required int page, required int page,
String? search, String? search,
String? type, String? type,
String? studioType, String? studioType,
}) => }) =>
_baseUserUrl + '$_baseUserUrl/marked/${type ?? ''}${_urlConcatGenerator([
'/marked/${type ?? ''}' + MapEntry('page', page),
_urlConcatGenerator([ MapEntry('type', studioType),
MapEntry('page', page), MapEntry('search', search),
MapEntry('type', studioType), ])}';
MapEntry('search', search),
]);
static const String directTypes = baseUrl + '/direct/types'; static const String directTypes = '$baseUrl/direct/types';
static String direct(int id) => _baseDirectUrl + '/$id'; static String direct(int id) => '$_baseDirectUrl/$id';
static String sendDirectMessage(int id) => static String sendDirectMessage(int id) => '$_baseDirectUrl/$id/sendMessage';
_baseDirectUrl + '/$id/sendMessage';
static String deleteDirect(int id, int messageId) => static String deleteDirect(int id, int messageId) =>
_baseDirectUrl + '/$id/message/$messageId'; '$_baseDirectUrl/$id/message/$messageId';
static String tag({ static String tag({
required List<int> ids, required List<int> ids,
String? type, String? type,
@ -49,26 +46,22 @@ class RequestHelper {
int? page, int? page,
int? limit, int? limit,
}) => }) =>
baseUrl + '$baseUrl/tag${_urlConcatGenerator([
'/tag' + MapEntry('page', page),
_urlConcatGenerator([ MapEntry('limit', limit ?? '3'),
MapEntry('page', page), MapEntry('type', type),
MapEntry('limit', limit ?? '3'), MapEntry('id', itemId ?? '1'),
MapEntry('type', type), MapEntry('tags', _urlListConcatGenerator(ids)),
MapEntry('id', itemId ?? '1'), ])}';
MapEntry('tags', _urlListConcatGenerator(ids)),
]);
static String radarDetails(int id, RadarRequestArgs args) => static String radarDetails(int id, RadarRequestArgs args) =>
_baseRadarUrl + '$_baseRadarUrl/$id${_urlConcatGenerator([
'/$id' + MapEntry('page', args.page),
_urlConcatGenerator([ MapEntry('start', args.startDate),
MapEntry('page', args.page), MapEntry('end', args.endDate),
MapEntry('start', args.startDate), MapEntry('search', args.search),
MapEntry('end', args.endDate), MapEntry('categories', _urlListConcatGenerator(args.categories)),
MapEntry('search', args.search), ])}';
MapEntry('categories', _urlListConcatGenerator(args.categories)),
]);
static String radarOverviews({required RadarRequestArgs args}) => static String radarOverviews({required RadarRequestArgs args}) =>
_baseRadarUrl + _baseRadarUrl +
_urlConcatGenerator([ _urlConcatGenerator([
@ -80,14 +73,12 @@ class RequestHelper {
]); ]);
static String newsDetails(int id, NewsRequestArgs args) => static String newsDetails(int id, NewsRequestArgs args) =>
_baseNewsUrl + '$_baseNewsUrl/$id${_urlConcatGenerator([
'/$id' + MapEntry('page', args.page),
_urlConcatGenerator([ MapEntry('start', args.startDate),
MapEntry('page', args.page), MapEntry('end', args.endDate),
MapEntry('start', args.startDate), MapEntry('search', args.search),
MapEntry('end', args.endDate), ])}';
MapEntry('search', args.search),
]);
static String newsOverviews({required NewsRequestArgs args}) => static String newsOverviews({required NewsRequestArgs args}) =>
_baseNewsUrl + _baseNewsUrl +
_urlConcatGenerator([ _urlConcatGenerator([
@ -98,19 +89,15 @@ class RequestHelper {
]); ]);
static String studioSlider(String type) => static String studioSlider(String type) =>
_baseStudioUrl + '$_baseStudioUrl/slider${_urlConcatGenerator([MapEntry('type', type)])}';
'/slider' +
_urlConcatGenerator([MapEntry('type', type)]);
static String studioDetails(int id, StudioRequestArgs args) => static String studioDetails(int id, StudioRequestArgs args) =>
_baseStudioUrl + '$_baseStudioUrl/$id${_urlConcatGenerator([
'/$id' + MapEntry('page', args.page),
_urlConcatGenerator([ MapEntry('type', args.type),
MapEntry('page', args.page), MapEntry('order', args.order),
MapEntry('type', args.type), MapEntry('search', args.search),
MapEntry('order', args.order), MapEntry('asc', args.asc),
MapEntry('search', args.search), ])}';
MapEntry('asc', args.asc),
]);
static String studioOverviews({required StudioRequestArgs args}) => static String studioOverviews({required StudioRequestArgs args}) =>
_baseStudioUrl + _baseStudioUrl +
_urlConcatGenerator([ _urlConcatGenerator([
@ -130,23 +117,19 @@ class RequestHelper {
String label, String label,
String period, String period,
) => ) =>
_baseStatisticUrl + '$_baseStatisticUrl/$label${_urlConcatGenerator([
'/$label' + MapEntry('period', period),
_urlConcatGenerator([ ])}';
MapEntry('period', period),
]);
static String mark(int id, String type) => baseUrl + '/$type/$id/mark'; static String mark(int id, String type) => '$baseUrl/$type/$id/mark';
static String tracking(int id, String type) => static String tracking(int id, String type) => '$baseUrl/$type/$id/tracking';
baseUrl + '/$type/$id/tracking'; static String comments(int id, String type) => '$baseUrl/$type/$id/comments';
static String comments(int id, String type) =>
baseUrl + '/$type/$id/comments';
static String feedback(int id, int commentId, String type) => 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) => static String addComment(int id, String type) =>
baseUrl + '/$type/$id/comments/add'; '$baseUrl/$type/$id/comments/add';
static String deleteComment(int id) => baseUrl + '/comment/$id'; static String deleteComment(int id) => '$baseUrl/comment/$id';
static String reportComment(int id) => baseUrl + '/comment/$id/report'; static String reportComment(int id) => '$baseUrl/comment/$id/report';
static String _urlConcatGenerator(List<MapEntry<String, dynamic>> additions) { static String _urlConcatGenerator(List<MapEntry<String, dynamic>> additions) {
String result = ''; String result = '';
@ -156,7 +139,7 @@ class RequestHelper {
if (additions.isNotEmpty) { if (additions.isNotEmpty) {
result += '?'; result += '?';
for (var i = 0; i < additions.length; i++) { 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) { if (i != additions.length - 1) {
result += '&'; result += '&';
} }

View File

@ -1,7 +1,9 @@
import 'dart:io'; import 'dart:io';
import 'package:assets_audio_player/assets_audio_player.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/studio_details_data.dart';
import 'package:didvan/services/media/media.dart'; import 'package:didvan/services/media/media.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/widgets/didvan/icon_button.dart'; import 'package:didvan/views/widgets/didvan/icon_button.dart';
@ -11,11 +13,13 @@ class AudioWidget extends StatelessWidget {
final String? audioUrl; final String? audioUrl;
final File? audioFile; final File? audioFile;
final int id; final int id;
final StudioDetailsData? audioMetaData;
const AudioWidget({ const AudioWidget({
Key? key, Key? key,
this.audioUrl, this.audioUrl,
this.audioFile, this.audioFile,
required this.id, required this.id,
this.audioMetaData,
}) : super(key: key); }) : super(key: key);
@override @override
@ -24,16 +28,20 @@ class AudioWidget extends StatelessWidget {
stream: MediaService.audioPlayer.isPlaying, stream: MediaService.audioPlayer.isPlaying,
builder: (context, snapshot) { builder: (context, snapshot) {
return Row( return Row(
crossAxisAlignment: CrossAxisAlignment.start,
children: [ children: [
Expanded( Expanded(
child: AudioSlider( child: AudioSlider(
tag: 'message-$id', tag: audioMetaData != null ? 'radar-$id' : 'message-$id',
duration: audioMetaData?.duration,
showTimer: true,
), ),
), ),
_AudioControllerButton( _AudioControllerButton(
audioFile: audioFile, audioFile: audioFile,
audioUrl: audioUrl, audioUrl: audioUrl,
id: id, id: id,
audioMetaData: audioMetaData,
), ),
], ],
); );
@ -46,28 +54,46 @@ class _AudioControllerButton extends StatelessWidget {
final String? audioUrl; final String? audioUrl;
final File? audioFile; final File? audioFile;
final int id; final int id;
final StudioDetailsData? audioMetaData;
const _AudioControllerButton( const _AudioControllerButton({
{Key? key, this.audioUrl, this.audioFile, required this.id}) Key? key,
: super(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 @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
return DidvanIconButton( return StreamBuilder<PlayingAudio?>(
icon: MediaService.audioPlayer.isPlaying.value && _nowPlaying stream: MediaService.audioPlayer.onReadyToPlay,
? DidvanIcons.pause_circle_solid builder: (context, snapshot) {
: DidvanIcons.play_circle_solid, return DidvanIconButton(
color: Theme.of(context).colorScheme.focusedBorder, icon: MediaService.audioPlayer.isPlaying.value && _nowPlaying
onPressed: () { ? DidvanIcons.pause_circle_solid
MediaService.handleAudioPlayback( : DidvanIcons.play_circle_solid,
audioSource: audioFile?.path ?? audioUrl, gestureSize: 36,
id: id, color: Theme.of(context).colorScheme.focusedBorder,
isNetworkAudio: audioFile == null, onPressed: () async {
isVoiceMessage: true, 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,
);
},
);
});
} }
} }

View File

@ -72,6 +72,9 @@ class NewsDetailsState extends CoreProvier {
_currentIndex--; _currentIndex--;
} }
isFetchingNewItem = false; isFetchingNewItem = false;
if (currentNews.contents.length == 1) {
getRelatedContents();
}
appState = AppState.idle; appState = AppState.idle;
return; return;
} }
@ -108,7 +111,10 @@ class NewsDetailsState extends CoreProvier {
} }
Future<void> getRelatedContents() async { Future<void> getRelatedContents() async {
if (currentNews.relatedContents.isNotEmpty) return; if (currentNews.relatedContents.isNotEmpty &&
currentNews.relatedContentsIsEmpty) {
return;
}
relatedQueue.add(currentNews.id); relatedQueue.add(currentNews.id);
final service = RequestService(RequestHelper.tag( final service = RequestService(RequestHelper.tag(
ids: currentNews.tags.map((tag) => tag.id).toList(), ids: currentNews.tags.map((tag) => tag.id).toList(),
@ -125,8 +131,19 @@ class NewsDetailsState extends CoreProvier {
.relatedContents .relatedContents
.add(OverviewData.fromJson(relateds[i])); .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 @override

View File

@ -1,3 +1,4 @@
import 'package:didvan/models/enums.dart';
import 'package:didvan/models/requests/radar.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/radar/radar_details/radar_details_state.dart';
import 'package:didvan/views/home/widgets/floating_navigation_bar.dart'; import 'package:didvan/views/home/widgets/floating_navigation_bar.dart';

View File

@ -81,6 +81,9 @@ class RadarDetailsState extends CoreProvier {
_currentIndex--; _currentIndex--;
} }
isFetchingNewItem = false; isFetchingNewItem = false;
if (currentRadar.contents.length == 1) {
getRelatedContents();
}
appState = AppState.idle; appState = AppState.idle;
return; return;
} }
@ -91,7 +94,10 @@ class RadarDetailsState extends CoreProvier {
} }
Future<void> getRelatedContents() async { Future<void> getRelatedContents() async {
if (currentRadar.relatedContents.isNotEmpty) return; if (currentRadar.relatedContents.isNotEmpty &&
currentRadar.relatedContentsIsEmpty) {
return;
}
relatedQueue.add(currentRadar.id); relatedQueue.add(currentRadar.id);
final service = RequestService(RequestHelper.tag( final service = RequestService(RequestHelper.tag(
ids: currentRadar.tags.map((tag) => tag.id).toList(), ids: currentRadar.tags.map((tag) => tag.id).toList(),
@ -108,8 +114,19 @@ class RadarDetailsState extends CoreProvier {
.relatedContents .relatedContents
.add(OverviewData.fromJson(relateds[i])); .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) => bool exists(RadarDetailsData? radar) =>

View File

@ -138,17 +138,19 @@ class _ProfilePhotoState extends State<ProfilePhoto> {
return; return;
} }
final pickedFile = await MediaService.pickImage(source: source); final pickedFile = await MediaService.pickImage(source: source);
File? file; dynamic file;
if (pickedFile != null && !kIsWeb) { if (pickedFile != null && !kIsWeb) {
file = await ImageCropper().cropImage( file = await ImageCropper().cropImage(
sourcePath: pickedFile.path, sourcePath: pickedFile.path,
aspectRatio: const CropAspectRatio(ratioX: 1, ratioY: 1), aspectRatio: const CropAspectRatio(ratioX: 1, ratioY: 1),
iosUiSettings: const IOSUiSettings( uiSettings: [
title: 'برش تصویر', IOSUiSettings(
doneButtonTitle: 'تایید', title: 'برش تصویر',
cancelButtonTitle: 'بازگشت', doneButtonTitle: 'تایید',
), cancelButtonTitle: 'بازگشت',
androidUiSettings: const AndroidUiSettings(toolbarTitle: 'برش تصویر'), ),
AndroidUiSettings(toolbarTitle: 'برش تصویر')
],
compressQuality: 30, compressQuality: 30,
); );
if (file == null) return; if (file == null) return;

View File

@ -126,7 +126,7 @@ class _StudioState extends State<Studio> {
emptyState: EmptyResult( emptyState: EmptyResult(
onNewSearch: () => _focusNode.requestFocus(), onNewSearch: () => _focusNode.requestFocus(),
), ),
centerEmptyState: true, centerEmptyState: false,
enableEmptyState: state.studios.isEmpty, enableEmptyState: state.studios.isEmpty,
placeholder: state.videosSelected placeholder: state.videosSelected
? VideoOverview.placeHolder ? VideoOverview.placeHolder

View File

@ -14,7 +14,7 @@ class StudioDetailsState extends CoreProvier {
StudioDetailsData? nextStudio; StudioDetailsData? nextStudio;
StudioDetailsData? prevStudio; StudioDetailsData? prevStudio;
late int initialIndex; late int initialIndex;
late StudioRequestArgs args; StudioRequestArgs? args;
StudioRequestArgs? podcastArgs; StudioRequestArgs? podcastArgs;
final List<int> relatedQueue = []; final List<int> relatedQueue = [];
bool _positionListenerActivated = false; bool _positionListenerActivated = false;
@ -45,11 +45,11 @@ class StudioDetailsState extends CoreProvier {
if (args != null) { if (args != null) {
this.args = args; this.args = args;
} }
if (this.args.type == 'podcast') { if (this.args?.type == 'podcast') {
podcastArgs = this.args; podcastArgs = this.args;
} }
if (MediaService.currentPodcast?.id == id && if (MediaService.currentPodcast?.id == id &&
this.args.type == 'podcast' && this.args?.type == 'podcast' &&
!fetchOnly) { !fetchOnly) {
return; return;
} }
@ -68,7 +68,7 @@ class StudioDetailsState extends CoreProvier {
_handlePodcastPlayback(studio); _handlePodcastPlayback(studio);
} }
if (isForward == null) { if (isForward == null) {
if (this.args.type == 'podcast') { if (this.args?.type == 'podcast') {
MediaService.audioPlayerTag = MediaService.audioPlayerTag =
'podcast-${MediaService.currentPodcast?.id ?? ''}'; 'podcast-${MediaService.currentPodcast?.id ?? ''}';
} }
@ -77,7 +77,12 @@ class StudioDetailsState extends CoreProvier {
alongSideState = AppState.busy; alongSideState = AppState.busy;
notifyListeners(); notifyListeners();
} }
final service = RequestService(RequestHelper.studioDetails(id, this.args)); final service = RequestService(
RequestHelper.studioDetails(
id,
this.args ?? const StudioRequestArgs(page: 0),
),
);
await service.httpGet(); await service.httpGet();
nextStudio = null; nextStudio = null;
prevStudio = null; prevStudio = null;
@ -91,10 +96,10 @@ class StudioDetailsState extends CoreProvier {
} }
final result = service.result; final result = service.result;
studio = StudioDetailsData.fromJson(result['studio']); 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']); 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']); prevStudio = StudioDetailsData.fromJson(result['prevStudio']);
} }
if (isForward == null && !fetchOnly) { if (isForward == null && !fetchOnly) {
@ -113,7 +118,7 @@ class StudioDetailsState extends CoreProvier {
} }
Future<void> _handlePodcastPlayback(StudioDetailsData studio) async { Future<void> _handlePodcastPlayback(StudioDetailsData studio) async {
if (args.type == 'podcast') { if (args?.type == 'podcast') {
MediaService.currentPodcast = studio; MediaService.currentPodcast = studio;
MediaService.podcastPlaylistArgs = args; MediaService.podcastPlaylistArgs = args;
await MediaService.handleAudioPlayback( await MediaService.handleAudioPlayback(
@ -156,7 +161,7 @@ class StudioDetailsState extends CoreProvier {
final service = RequestService(RequestHelper.tag( final service = RequestService(RequestHelper.tag(
ids: studio.tags.map((tag) => tag.id).toList(), ids: studio.tags.map((tag) => tag.id).toList(),
itemId: studio.id, itemId: studio.id,
type: args.type, type: args?.type,
)); ));
await service.httpGet(); await service.httpGet();
if (service.isSuccess) { if (service.isSuccess) {
@ -164,8 +169,13 @@ class StudioDetailsState extends CoreProvier {
for (var i = 0; i < relateds.length; i++) { for (var i = 0; i < relateds.length; i++) {
studio.relatedContents.add(OverviewData.fromJson(relateds[i])); studio.relatedContents.add(OverviewData.fromJson(relateds[i]));
} }
notifyListeners(); if (relateds.isEmpty) {
studio.relatedContentsIsEmpty = true;
}
} else {
studio.relatedContentsIsEmpty = true;
} }
notifyListeners();
} }
void onCommentsChanged(int count) { void onCommentsChanged(int count) {

View File

@ -71,7 +71,7 @@ class StudioDetailsWidget extends StatelessWidget {
direction: TextDirection.rtl, direction: TextDirection.rtl,
textAlign: TextAlign.right, textAlign: TextAlign.right,
lineHeight: LineHeight.percent(135), lineHeight: LineHeight.percent(135),
margin: EdgeInsets.zero, margin: const Margins(),
padding: EdgeInsets.zero, padding: EdgeInsets.zero,
), ),
}, },
@ -144,7 +144,8 @@ class StudioDetailsWidget extends StatelessWidget {
} }
return Column( return Column(
children: [ children: [
if (state.studio.relatedContents.isEmpty) if (state.studio.relatedContents.isEmpty &&
!state.studio.relatedContentsIsEmpty)
for (var i = 0; i < 3; i++) for (var i = 0; i < 3; i++)
Padding( Padding(
padding: const EdgeInsets.only( padding: const EdgeInsets.only(

View File

@ -112,7 +112,8 @@ class _PlayerNavBar extends StatelessWidget {
return StreamBuilder<bool>( return StreamBuilder<bool>(
stream: MediaService.audioPlayer.isPlaying, stream: MediaService.audioPlayer.isPlaying,
builder: (context, snapshot) => GestureDetector( builder: (context, snapshot) => GestureDetector(
onTap: () => MediaService.currentPodcast == null onTap: () => MediaService.currentPodcast == null ||
MediaService.currentPodcast?.description == 'radar'
? null ? null
: _showPlayerBottomSheet(context), : _showPlayerBottomSheet(context),
child: Consumer<StudioDetailsState>( child: Consumer<StudioDetailsState>(
@ -203,7 +204,9 @@ class _PlayerNavBar extends StatelessWidget {
stream: MediaService.audioPlayer.onReadyToPlay, stream: MediaService.audioPlayer.onReadyToPlay,
builder: (context, snapshot) { builder: (context, snapshot) {
if (snapshot.data == null || if (snapshot.data == null ||
state.appState == AppState.busy) { state.appState == AppState.busy &&
MediaService.currentPodcast?.description !=
'radar') {
return Padding( return Padding(
padding: const EdgeInsets.only( padding: const EdgeInsets.only(
top: 4, top: 4,
@ -226,7 +229,8 @@ class _PlayerNavBar extends StatelessWidget {
}, },
), ),
if (state.appState != AppState.busy && if (state.appState != AppState.busy &&
snapshot.data != null) snapshot.data != null ||
MediaService.currentPodcast?.description == 'radar')
Padding( Padding(
padding: const EdgeInsets.only( padding: const EdgeInsets.only(
left: 12, left: 12,
@ -241,7 +245,7 @@ class _PlayerNavBar extends StatelessWidget {
? DidvanIcons.pause_solid ? DidvanIcons.pause_solid
: DidvanIcons.play_solid, : DidvanIcons.play_solid,
onPressed: () { onPressed: () {
if (state.args.type == 'video') { if (state.args?.type == 'video') {
state.getStudioDetails( state.getStudioDetails(
MediaService.currentPodcast!.id, MediaService.currentPodcast!.id,
args: state.podcastArgs, args: state.podcastArgs,
@ -270,7 +274,7 @@ class _PlayerNavBar extends StatelessWidget {
final sheetKey = GlobalKey<ExpandableBottomSheetState>(); final sheetKey = GlobalKey<ExpandableBottomSheetState>();
bool isExpanded = false; bool isExpanded = false;
final detailsState = context.read<StudioDetailsState>(); final detailsState = context.read<StudioDetailsState>();
if (detailsState.args.type == 'video') { if (detailsState.args?.type == 'video') {
detailsState.getStudioDetails( detailsState.getStudioDetails(
MediaService.currentPodcast!.id, MediaService.currentPodcast!.id,
args: detailsState.podcastArgs, args: detailsState.podcastArgs,

View File

@ -4,9 +4,12 @@ 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/requests/news.dart'; import 'package:didvan/models/requests/news.dart';
import 'package:didvan/models/requests/radar.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/routes/routes.dart';
import 'package:didvan/utils/action_sheet.dart'; import 'package:didvan/utils/action_sheet.dart';
import 'package:didvan/utils/date_time.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/overview/multitype.dart';
import 'package:didvan/views/home/widgets/tag_item.dart'; import 'package:didvan/views/home/widgets/tag_item.dart';
import 'package:didvan/views/widgets/animated_visibility.dart'; import 'package:didvan/views/widgets/animated_visibility.dart';
@ -108,6 +111,44 @@ class _DidvanPageViewState extends State<DidvanPageView> {
const EdgeInsets.symmetric(horizontal: 16), const EdgeInsets.symmetric(horizontal: 16),
child: _subtitle(item), 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++) for (var i = 0; i < item.contents.length; i++)
Padding( Padding(
padding: const EdgeInsets.symmetric( padding: const EdgeInsets.symmetric(
@ -146,7 +187,8 @@ class _DidvanPageViewState extends State<DidvanPageView> {
padding: EdgeInsets.symmetric(horizontal: 16.0), padding: EdgeInsets.symmetric(horizontal: 16.0),
child: ItemTitle(title: 'مطالب مشابه'), child: ItemTitle(title: 'مطالب مشابه'),
), ),
if (item.relatedContents.isEmpty) if (item.relatedContents.isEmpty &&
!item.relatedContentsIsEmpty)
for (var i = 0; i < 3; i++) for (var i = 0; i < 3; i++)
Padding( Padding(
padding: const EdgeInsets.only( padding: const EdgeInsets.only(
@ -178,9 +220,9 @@ class _DidvanPageViewState extends State<DidvanPageView> {
), ),
), ),
Positioned( Positioned(
child: _BackButton(scrollController: widget.scrollController),
right: 24, right: 24,
top: 24 + deviceTopPadding, top: 24 + deviceTopPadding,
child: _BackButton(scrollController: widget.scrollController),
), ),
], ],
); );
@ -272,7 +314,7 @@ class _DidvanPageViewState extends State<DidvanPageView> {
direction: TextDirection.rtl, direction: TextDirection.rtl,
textAlign: TextAlign.right, textAlign: TextAlign.right,
lineHeight: LineHeight.percent(135), lineHeight: LineHeight.percent(135),
margin: EdgeInsets.zero, margin: const Margins(),
padding: EdgeInsets.zero, padding: EdgeInsets.zero,
), ),
'a': Style( 'a': Style(

View File

@ -16,7 +16,7 @@ class DidvanSwitch extends StatefulWidget {
}) : super(key: key); }) : super(key: key);
@override @override
_DidvanSwitchState createState() => _DidvanSwitchState(); State<DidvanSwitch> createState() => _DidvanSwitchState();
} }
class _DidvanSwitchState extends State<DidvanSwitch> { class _DidvanSwitchState extends State<DidvanSwitch> {

View File

@ -1,34 +1,41 @@
# Generated by pub # Generated by pub
# See https://dart.dev/tools/pub/glossary#lockfile # See https://dart.dev/tools/pub/glossary#lockfile
packages: packages:
_flutterfire_internals:
dependency: transitive
description:
name: _flutterfire_internals
url: "https://pub.dartlang.org"
source: hosted
version: "1.0.9"
assets_audio_player: assets_audio_player:
dependency: "direct main" dependency: "direct main"
description: description:
name: assets_audio_player name: assets_audio_player
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "3.0.5" version: "3.0.6"
assets_audio_player_web: assets_audio_player_web:
dependency: transitive dependency: transitive
description: description:
name: assets_audio_player_web name: assets_audio_player_web
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "3.0.5" version: "3.0.6"
async: async:
dependency: transitive dependency: transitive
description: description:
name: async name: async
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "2.8.2" version: "2.9.0"
audio_video_progress_bar: audio_video_progress_bar:
dependency: "direct main" dependency: "direct main"
description: description:
name: audio_video_progress_bar name: audio_video_progress_bar
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "0.10.0" version: "0.11.0"
better_player: better_player:
dependency: "direct main" dependency: "direct main"
description: description:
@ -56,21 +63,21 @@ packages:
name: cached_network_image name: cached_network_image
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "3.2.1" version: "3.2.3"
cached_network_image_platform_interface: cached_network_image_platform_interface:
dependency: transitive dependency: transitive
description: description:
name: cached_network_image_platform_interface name: cached_network_image_platform_interface
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "1.0.0" version: "2.0.0"
cached_network_image_web: cached_network_image_web:
dependency: transitive dependency: transitive
description: description:
name: cached_network_image_web name: cached_network_image_web
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "1.0.1" version: "1.0.2"
carousel_slider: carousel_slider:
dependency: "direct main" dependency: "direct main"
description: description:
@ -84,7 +91,7 @@ packages:
name: characters name: characters
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "1.2.0" version: "1.2.1"
charcode: charcode:
dependency: transitive dependency: transitive
description: description:
@ -98,7 +105,21 @@ packages:
name: clock name: clock
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted 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: collection:
dependency: transitive dependency: transitive
description: description:
@ -112,7 +133,7 @@ packages:
name: cross_file name: cross_file
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "0.3.3+1" version: "0.3.3+2"
crypto: crypto:
dependency: transitive dependency: transitive
description: description:
@ -140,14 +161,14 @@ packages:
name: day_night_time_picker name: day_night_time_picker
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "1.1.2" version: "1.1.3"
equatable: equatable:
dependency: transitive dependency: transitive
description: description:
name: equatable name: equatable
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "2.0.3" version: "2.0.5"
expandable_bottom_sheet: expandable_bottom_sheet:
dependency: "direct main" dependency: "direct main"
description: description:
@ -161,7 +182,7 @@ packages:
name: fake_async name: fake_async
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "1.3.0" version: "1.3.1"
ffi: ffi:
dependency: transitive dependency: transitive
description: description:
@ -175,56 +196,56 @@ packages:
name: file name: file
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "6.1.2" version: "6.1.4"
firebase_core: firebase_core:
dependency: "direct main" dependency: "direct main"
description: description:
name: firebase_core name: firebase_core
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "1.19.2" version: "2.3.0"
firebase_core_platform_interface: firebase_core_platform_interface:
dependency: transitive dependency: transitive
description: description:
name: firebase_core_platform_interface name: firebase_core_platform_interface
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "4.4.3" version: "4.5.2"
firebase_core_web: firebase_core_web:
dependency: transitive dependency: transitive
description: description:
name: firebase_core_web name: firebase_core_web
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "1.7.0" version: "2.0.1"
firebase_messaging: firebase_messaging:
dependency: "direct main" dependency: "direct main"
description: description:
name: firebase_messaging name: firebase_messaging
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "11.4.4" version: "14.1.3"
firebase_messaging_platform_interface: firebase_messaging_platform_interface:
dependency: transitive dependency: transitive
description: description:
name: firebase_messaging_platform_interface name: firebase_messaging_platform_interface
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "3.5.4" version: "4.2.7"
firebase_messaging_web: firebase_messaging_web:
dependency: transitive dependency: transitive
description: description:
name: firebase_messaging_web name: firebase_messaging_web
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "2.4.4" version: "3.2.8"
fl_chart: fl_chart:
dependency: "direct main" dependency: "direct main"
description: description:
name: fl_chart name: fl_chart
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "0.50.6" version: "0.55.2"
flutter: flutter:
dependency: "direct main" dependency: "direct main"
description: flutter description: flutter
@ -250,14 +271,14 @@ packages:
name: flutter_html name: flutter_html
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "3.0.0-alpha.5" version: "3.0.0-alpha.6"
flutter_lints: flutter_lints:
dependency: "direct dev" dependency: "direct dev"
description: description:
name: flutter_lints name: flutter_lints
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "1.0.4" version: "2.0.1"
flutter_localizations: flutter_localizations:
dependency: "direct main" dependency: "direct main"
description: flutter description: flutter
@ -276,42 +297,42 @@ packages:
name: flutter_secure_storage name: flutter_secure_storage
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "5.0.2" version: "6.1.0"
flutter_secure_storage_linux: flutter_secure_storage_linux:
dependency: transitive dependency: transitive
description: description:
name: flutter_secure_storage_linux name: flutter_secure_storage_linux
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "1.1.0" version: "1.1.2"
flutter_secure_storage_macos: flutter_secure_storage_macos:
dependency: transitive dependency: transitive
description: description:
name: flutter_secure_storage_macos name: flutter_secure_storage_macos
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "1.1.0" version: "1.1.2"
flutter_secure_storage_platform_interface: flutter_secure_storage_platform_interface:
dependency: transitive dependency: transitive
description: description:
name: flutter_secure_storage_platform_interface name: flutter_secure_storage_platform_interface
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "1.0.0" version: "1.0.1"
flutter_secure_storage_web: flutter_secure_storage_web:
dependency: transitive dependency: transitive
description: description:
name: flutter_secure_storage_web name: flutter_secure_storage_web
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "1.0.2" version: "1.1.1"
flutter_secure_storage_windows: flutter_secure_storage_windows:
dependency: transitive dependency: transitive
description: description:
name: flutter_secure_storage_windows name: flutter_secure_storage_windows
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "1.1.2" version: "1.1.3"
flutter_spinkit: flutter_spinkit:
dependency: "direct main" dependency: "direct main"
description: description:
@ -325,7 +346,7 @@ packages:
name: flutter_svg name: flutter_svg
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "1.1.1+1" version: "1.1.6"
flutter_test: flutter_test:
dependency: "direct dev" dependency: "direct dev"
description: flutter description: flutter
@ -356,77 +377,91 @@ packages:
name: fwfh_text_style name: fwfh_text_style
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "2.7.3+2" version: "2.22.08+1"
graphs: graphs:
dependency: transitive dependency: transitive
description: description:
name: graphs name: graphs
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "2.1.0" version: "2.2.0"
html: html:
dependency: transitive dependency: transitive
description: description:
name: html name: html
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "0.15.0" version: "0.15.1"
http: http:
dependency: transitive dependency: transitive
description: description:
name: http name: http
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "0.13.4" version: "0.13.5"
http_parser: http_parser:
dependency: transitive dependency: transitive
description: description:
name: http_parser name: http_parser
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "4.0.1" version: "4.0.2"
image_cropper: image_cropper:
dependency: "direct main" dependency: "direct main"
description: description:
name: image_cropper name: image_cropper
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted 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: image_picker:
dependency: "direct main" dependency: "direct main"
description: description:
name: image_picker name: image_picker
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "0.8.5+3" version: "0.8.6"
image_picker_android: image_picker_android:
dependency: transitive dependency: transitive
description: description:
name: image_picker_android name: image_picker_android
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "0.8.5+1" version: "0.8.5+3"
image_picker_for_web: image_picker_for_web:
dependency: transitive dependency: transitive
description: description:
name: image_picker_for_web name: image_picker_for_web
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "2.1.8" version: "2.1.10"
image_picker_ios: image_picker_ios:
dependency: transitive dependency: transitive
description: description:
name: image_picker_ios name: image_picker_ios
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "0.8.5+6" version: "0.8.6+1"
image_picker_platform_interface: image_picker_platform_interface:
dependency: transitive dependency: transitive
description: description:
name: image_picker_platform_interface name: image_picker_platform_interface
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "2.5.0" version: "2.6.2"
intl: intl:
dependency: transitive dependency: transitive
description: description:
@ -447,28 +482,28 @@ packages:
name: lints name: lints
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "1.0.1" version: "2.0.1"
matcher: matcher:
dependency: transitive dependency: transitive
description: description:
name: matcher name: matcher
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "0.12.11" version: "0.12.12"
material_color_utilities: material_color_utilities:
dependency: transitive dependency: transitive
description: description:
name: material_color_utilities name: material_color_utilities
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "0.1.4" version: "0.1.5"
meta: meta:
dependency: transitive dependency: transitive
description: description:
name: meta name: meta
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "1.7.0" version: "1.8.0"
nested: nested:
dependency: transitive dependency: transitive
description: description:
@ -482,7 +517,7 @@ packages:
name: numerus name: numerus
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "1.1.1" version: "2.0.0"
octo_image: octo_image:
dependency: transitive dependency: transitive
description: description:
@ -496,21 +531,21 @@ packages:
name: path name: path
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "1.8.1" version: "1.8.2"
path_drawing: path_drawing:
dependency: transitive dependency: transitive
description: description:
name: path_drawing name: path_drawing
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "1.0.0" version: "1.0.1"
path_parsing: path_parsing:
dependency: transitive dependency: transitive
description: description:
name: path_parsing name: path_parsing
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "1.0.0" version: "1.0.1"
path_provider: path_provider:
dependency: "direct main" dependency: "direct main"
description: description:
@ -524,14 +559,14 @@ packages:
name: path_provider_android name: path_provider_android
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "2.0.16" version: "2.0.22"
path_provider_ios: path_provider_ios:
dependency: transitive dependency: transitive
description: description:
name: path_provider_ios name: path_provider_ios
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "2.0.10" version: "2.0.11"
path_provider_linux: path_provider_linux:
dependency: transitive dependency: transitive
description: description:
@ -552,14 +587,14 @@ packages:
name: path_provider_platform_interface name: path_provider_platform_interface
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "2.0.4" version: "2.0.5"
path_provider_windows: path_provider_windows:
dependency: transitive dependency: transitive
description: description:
name: path_provider_windows name: path_provider_windows
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "2.1.0" version: "2.1.3"
pedantic: pedantic:
dependency: transitive dependency: transitive
description: description:
@ -573,35 +608,35 @@ packages:
name: permission_handler name: permission_handler
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "9.2.0" version: "10.2.0"
permission_handler_android: permission_handler_android:
dependency: transitive dependency: transitive
description: description:
name: permission_handler_android name: permission_handler_android
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "9.0.2+1" version: "10.2.0"
permission_handler_apple: permission_handler_apple:
dependency: transitive dependency: transitive
description: description:
name: permission_handler_apple name: permission_handler_apple
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "9.0.4" version: "9.0.7"
permission_handler_platform_interface: permission_handler_platform_interface:
dependency: transitive dependency: transitive
description: description:
name: permission_handler_platform_interface name: permission_handler_platform_interface
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "3.7.0" version: "3.9.0"
permission_handler_windows: permission_handler_windows:
dependency: transitive dependency: transitive
description: description:
name: permission_handler_windows name: permission_handler_windows
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "0.1.0" version: "0.1.2"
persian_datetime_picker: persian_datetime_picker:
dependency: "direct main" dependency: "direct main"
description: description:
@ -622,7 +657,7 @@ packages:
name: petitparser name: petitparser
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "5.0.0" version: "5.1.0"
pin_code_fields: pin_code_fields:
dependency: "direct main" dependency: "direct main"
description: description:
@ -643,7 +678,7 @@ packages:
name: plugin_platform_interface name: plugin_platform_interface
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "2.1.2" version: "2.1.3"
process: process:
dependency: transitive dependency: transitive
description: description:
@ -657,42 +692,63 @@ packages:
name: provider name: provider
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "6.0.3" version: "6.0.4"
record: record:
dependency: "direct main" dependency: "direct main"
description: description:
name: record name: record
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted 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: record_platform_interface:
dependency: transitive dependency: transitive
description: description:
name: record_platform_interface name: record_platform_interface
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "0.2.0" version: "0.5.0"
record_web: record_web:
dependency: "direct main" dependency: "direct main"
description: description:
name: record_web name: record_web
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted 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: rive:
dependency: "direct main" dependency: "direct main"
description: description:
name: rive name: rive
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "0.7.33" version: "0.9.1"
rxdart: rxdart:
dependency: transitive dependency: transitive
description: description:
name: rxdart name: rxdart
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "0.27.5" version: "0.27.7"
skeleton_text: skeleton_text:
dependency: "direct main" dependency: "direct main"
description: description:
@ -711,21 +767,21 @@ packages:
name: source_span name: source_span
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "1.8.2" version: "1.9.0"
sqflite: sqflite:
dependency: transitive dependency: transitive
description: description:
name: sqflite name: sqflite
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "2.0.3" version: "2.2.1"
sqflite_common: sqflite_common:
dependency: transitive dependency: transitive
description: description:
name: sqflite_common name: sqflite_common
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "2.2.1+1" version: "2.4.0+2"
stack_trace: stack_trace:
dependency: transitive dependency: transitive
description: description:
@ -746,28 +802,28 @@ packages:
name: string_scanner name: string_scanner
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "1.1.0" version: "1.1.1"
synchronized: synchronized:
dependency: transitive dependency: transitive
description: description:
name: synchronized name: synchronized
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "3.0.0+2" version: "3.0.0+3"
term_glyph: term_glyph:
dependency: transitive dependency: transitive
description: description:
name: term_glyph name: term_glyph
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "1.2.0" version: "1.2.1"
test_api: test_api:
dependency: transitive dependency: transitive
description: description:
name: test_api name: test_api
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "0.4.9" version: "0.4.12"
typed_data: typed_data:
dependency: transitive dependency: transitive
description: description:
@ -795,14 +851,14 @@ packages:
name: url_launcher name: url_launcher
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "6.1.5" version: "6.1.7"
url_launcher_android: url_launcher_android:
dependency: transitive dependency: transitive
description: description:
name: url_launcher_android name: url_launcher_android
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "6.0.17" version: "6.0.22"
url_launcher_ios: url_launcher_ios:
dependency: transitive dependency: transitive
description: description:
@ -830,14 +886,14 @@ packages:
name: url_launcher_platform_interface name: url_launcher_platform_interface
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "2.1.0" version: "2.1.1"
url_launcher_web: url_launcher_web:
dependency: transitive dependency: transitive
description: description:
name: url_launcher_web name: url_launcher_web
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "2.0.12" version: "2.0.13"
url_launcher_windows: url_launcher_windows:
dependency: transitive dependency: transitive
description: description:
@ -851,7 +907,7 @@ packages:
name: uuid name: uuid
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "3.0.6" version: "3.0.7"
vector_math: vector_math:
dependency: transitive dependency: transitive
description: description:
@ -900,7 +956,7 @@ packages:
name: wakelock_windows name: wakelock_windows
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "0.2.0" version: "0.2.1"
webview_flutter: webview_flutter:
dependency: "direct main" dependency: "direct main"
description: description:
@ -914,35 +970,35 @@ packages:
name: webview_flutter_android name: webview_flutter_android
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "2.8.14" version: "2.10.4"
webview_flutter_platform_interface: webview_flutter_platform_interface:
dependency: transitive dependency: transitive
description: description:
name: webview_flutter_platform_interface name: webview_flutter_platform_interface
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "1.9.1" version: "1.9.5"
webview_flutter_wkwebview: webview_flutter_wkwebview:
dependency: transitive dependency: transitive
description: description:
name: webview_flutter_wkwebview name: webview_flutter_wkwebview
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "2.9.1" version: "2.9.5"
win32: win32:
dependency: transitive dependency: transitive
description: description:
name: win32 name: win32
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "2.7.0" version: "3.1.2"
xdg_directories: xdg_directories:
dependency: transitive dependency: transitive
description: description:
name: xdg_directories name: xdg_directories
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "0.2.0+1" version: "0.2.0+2"
xml: xml:
dependency: transitive dependency: transitive
description: description:
@ -951,5 +1007,5 @@ packages:
source: hosted source: hosted
version: "6.1.0" version: "6.1.0"
sdks: sdks:
dart: ">=2.17.0 <3.0.0" dart: ">=2.18.0 <3.0.0"
flutter: ">=3.0.0" flutter: ">=3.3.0"

View File

@ -37,7 +37,7 @@ dependencies:
cupertino_icons: ^1.0.2 cupertino_icons: ^1.0.2
provider: ^6.0.1 provider: ^6.0.1
pin_code_fields: ^7.3.0 pin_code_fields: ^7.3.0
rive: ^0.7.33 rive: ^0.9.1
image_picker: ^0.8.4+4 image_picker: ^0.8.4+4
day_night_time_picker: ^1.0.5 day_night_time_picker: ^1.0.5
path_provider: ^2.0.8 path_provider: ^2.0.8
@ -48,24 +48,24 @@ dependencies:
carousel_slider: ^4.0.0 carousel_slider: ^4.0.0
flutter_vibrate: ^1.3.0 flutter_vibrate: ^1.3.0
universal_html: ^2.0.8 universal_html: ^2.0.8
record: ^3.0.2 record: ^4.4.3
record_web: ^0.2.1 record_web: ^0.5.0
persian_datetime_picker: ^2.4.0 persian_datetime_picker: ^2.4.0
persian_number_utility: ^1.1.1 persian_number_utility: ^1.1.1
bot_toast: ^4.0.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 flutter_html: ^3.0.0-alpha.2
url_launcher: ^6.0.18 url_launcher: ^6.0.18
audio_video_progress_bar: ^0.10.0 audio_video_progress_bar: ^0.11.0
image_cropper: ^1.5.0 image_cropper: ^3.0.1
firebase_messaging: ^11.2.8 firebase_messaging: ^14.1.3
firebase_core: ^1.13.1 firebase_core: ^2.3.0
webview_flutter: ^3.0.1 webview_flutter: ^3.0.1
expandable_bottom_sheet: ^1.1.1+1 expandable_bottom_sheet: ^1.1.1+1
permission_handler: ^9.2.0 permission_handler: ^10.2.0
better_player: ^0.0.81 better_player: ^0.0.81
assets_audio_player: ^3.0.4+1 assets_audio_player: ^3.0.4+1
fl_chart: ^0.50.1 fl_chart: ^0.55.2
dev_dependencies: dev_dependencies:
flutter_test: flutter_test:
@ -76,7 +76,7 @@ dev_dependencies:
# activated in the `analysis_options.yaml` file located at the root of your # activated in the `analysis_options.yaml` file located at the root of your
# package. See that file for information about deactivating specific lint # package. See that file for information about deactivating specific lint
# rules and activating additional ones. # 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 # For information on the generic Dart part of this file, see the
# following page: https://dart.dev/tools/pub/pubspec # following page: https://dart.dev/tools/pub/pubspec