240 lines
6.5 KiB
Dart
240 lines
6.5 KiB
Dart
import 'dart:async';
|
|
|
|
import 'package:didvan/config/auth_config.dart';
|
|
import 'package:didvan/models/enums.dart';
|
|
import 'package:didvan/models/overview_data.dart';
|
|
import 'package:didvan/models/requests/studio.dart';
|
|
import 'package:didvan/models/slider_data.dart';
|
|
import 'package:didvan/providers/core.dart';
|
|
import 'package:didvan/services/app_initalizer.dart';
|
|
import 'package:didvan/services/content/content_service.dart';
|
|
import 'package:didvan/services/network/request.dart';
|
|
import 'package:didvan/services/network/request_helper.dart';
|
|
import 'package:collection/collection.dart';
|
|
|
|
class PodcastsState extends CoreProvier {
|
|
final List<OverviewData> studios = [];
|
|
final List<SliderData> sliders = [];
|
|
|
|
String? startDate;
|
|
String? endDate;
|
|
|
|
String search = '';
|
|
String lastSearch = '';
|
|
int page = 1;
|
|
int lastPage = 1;
|
|
|
|
int selectedSortTypeIndex = 0;
|
|
|
|
bool _videosSelected = true;
|
|
|
|
bool get videosSelected => _videosSelected;
|
|
|
|
bool get searching => search.isNotEmpty;
|
|
|
|
void resetFilters(bool isInit) {
|
|
startDate = null;
|
|
endDate = null;
|
|
search = '';
|
|
lastSearch = '';
|
|
if (!isInit) {
|
|
getStudios(page: 1);
|
|
}
|
|
}
|
|
|
|
set videosSelected(bool value) {
|
|
if (_videosSelected == value || appState == AppState.busy) return;
|
|
_videosSelected = value;
|
|
selectedSortTypeIndex = 0;
|
|
_getSliders();
|
|
getStudios(page: page);
|
|
}
|
|
|
|
String get order {
|
|
if (selectedSortTypeIndex == 0 || selectedSortTypeIndex == 1) return 'date';
|
|
if (selectedSortTypeIndex == 2) return 'view';
|
|
return 'comment';
|
|
}
|
|
|
|
String get orderString {
|
|
if (selectedSortTypeIndex == 0) return 'جدیدترینها';
|
|
if (selectedSortTypeIndex == 1) return 'قدیمیترینها';
|
|
if (selectedSortTypeIndex == 2) return 'پربازدیدترینها';
|
|
return 'پربحثترینها';
|
|
}
|
|
|
|
String get type {
|
|
if (videosSelected) return 'video';
|
|
return 'podcast';
|
|
}
|
|
|
|
void init(bool? viewPodcasts) {
|
|
search = '';
|
|
lastSearch = '';
|
|
_videosSelected =
|
|
!(AppInitializer.clickAction?.contains('podcast') == true) &&
|
|
viewPodcasts != true;
|
|
selectedSortTypeIndex = 0;
|
|
Future.delayed(Duration.zero, () {
|
|
_getSliders();
|
|
getStudios(page: 1);
|
|
});
|
|
}
|
|
|
|
Future<void> _getSliders() async {
|
|
if (!AuthConfig.useLegacyApi) {
|
|
sliders.clear();
|
|
notifyListeners();
|
|
return;
|
|
}
|
|
final service = RequestService(
|
|
RequestHelper.studioSlider(type),
|
|
);
|
|
await service.httpGet();
|
|
if (service.isSuccess) {
|
|
sliders.clear();
|
|
final sliderItems = service.result['studios'];
|
|
for (var i = 0; i < sliderItems.length; i++) {
|
|
sliders.add(SliderData.fromJson(sliderItems[i]));
|
|
}
|
|
}
|
|
notifyListeners();
|
|
}
|
|
|
|
static const String _podcastCategoryId =
|
|
'7cbe250a-d0c4-44c2-970b-c4abbdf0d6c2';
|
|
|
|
static const String _videocastCategoryId =
|
|
'321a1cc9-b1e0-4787-a8db-6faa9a3477c4';
|
|
|
|
static const String _visibleStatusFilter = '\$in:accepted,published';
|
|
|
|
Future<void> getStudios({required int page}) async {
|
|
this.page = page;
|
|
lastSearch = search;
|
|
if (page == 1) {
|
|
appState = AppState.busy;
|
|
}
|
|
|
|
if (type == 'podcast') {
|
|
await _getMediaFromContentService(page, _podcastCategoryId,
|
|
isVideo: false);
|
|
return;
|
|
}
|
|
if (type == 'video') {
|
|
await _getMediaFromContentService(page, _videocastCategoryId,
|
|
isVideo: true);
|
|
return;
|
|
}
|
|
|
|
final service = RequestService(
|
|
RequestHelper.studioOverviews(
|
|
args: StudioRequestArgs(
|
|
page: page,
|
|
type: type,
|
|
search: search,
|
|
order: order,
|
|
asc: selectedSortTypeIndex == 1,
|
|
endDate: endDate?.split(' ').first,
|
|
startDate: startDate?.split(' ').first,
|
|
),
|
|
),
|
|
);
|
|
await service.httpGet();
|
|
if (service.isSuccess) {
|
|
if (page == 1) {
|
|
studios.clear();
|
|
}
|
|
lastPage = service.result['lastPage'];
|
|
final studioItems = service.result['studios'];
|
|
for (var i = 0; i < studioItems.length; i++) {
|
|
studios.add(OverviewData.fromJson(studioItems[i]));
|
|
}
|
|
appState = AppState.idle;
|
|
return;
|
|
}
|
|
appState = AppState.failed;
|
|
}
|
|
|
|
Future<void> _getMediaFromContentService(
|
|
int page,
|
|
String categoryId, {
|
|
required bool isVideo,
|
|
}) async {
|
|
final res = await ContentService.instance.getContents(
|
|
page: page,
|
|
limit: 100,
|
|
search: search.isEmpty ? null : search,
|
|
filterStatus: _visibleStatusFilter,
|
|
categoryId: categoryId,
|
|
sortBy: [_mediaSort()],
|
|
);
|
|
|
|
if (!res.isSuccess || res.data == null) {
|
|
appState = AppState.failed;
|
|
return;
|
|
}
|
|
|
|
final data = res.data!;
|
|
if (page == 1) {
|
|
studios.clear();
|
|
}
|
|
final initial = data.data
|
|
.map((c) => isVideo
|
|
? OverviewData.fromVideocastContent(c)
|
|
: OverviewData.fromPodcastContent(c))
|
|
.toList();
|
|
studios.addAll(initial);
|
|
lastPage = data.totalPages;
|
|
|
|
final fetches = <Future<void>>[];
|
|
for (var i = 0; i < studios.length; i++) {
|
|
final ov = studios[i];
|
|
if (ov.keycloakId == null) continue;
|
|
if ((ov.duration != null && ov.duration! > 0) &&
|
|
(ov.link != null && ov.link!.isNotEmpty)) {
|
|
continue;
|
|
}
|
|
fetches
|
|
.add(ContentService.instance.getContent(ov.keycloakId!).then((res) {
|
|
if (!res.isSuccess || res.data == null) return;
|
|
final item = res.data!;
|
|
final newOv = isVideo
|
|
? OverviewData.fromVideocastContent(item)
|
|
: OverviewData.fromPodcastContent(item);
|
|
final idx = studios.indexWhere((e) => e.keycloakId == ov.keycloakId);
|
|
if (idx >= 0) studios[idx] = newOv;
|
|
}).catchError((_) {}));
|
|
}
|
|
await Future.wait(fetches);
|
|
|
|
appState = AppState.idle;
|
|
notifyListeners();
|
|
}
|
|
|
|
MapEntry<String, String> _mediaSort() {
|
|
switch (selectedSortTypeIndex) {
|
|
case 1:
|
|
return const MapEntry('createdAt', 'ASC');
|
|
case 2:
|
|
return const MapEntry('readCount', 'DESC');
|
|
case 3:
|
|
return const MapEntry('likeCount', 'DESC');
|
|
default:
|
|
return const MapEntry('createdAt', 'DESC');
|
|
}
|
|
}
|
|
|
|
Future<void> changeMark(int id, bool value, bool shouldUpdate) async {
|
|
studios.firstWhereOrNull((element) => element.id == id)?.marked = value;
|
|
if (shouldUpdate) {
|
|
notifyListeners();
|
|
}
|
|
}
|
|
|
|
void onCommentsChanged(int id, int count) {
|
|
studios.firstWhere((radar) => radar.id == id).comments = count;
|
|
notifyListeners();
|
|
}
|
|
}
|