162 lines
4.9 KiB
Dart
162 lines
4.9 KiB
Dart
import 'dart:async';
|
|
import 'dart:math';
|
|
|
|
import 'package:didvan/models/enums.dart';
|
|
import 'package:didvan/models/news_details_data.dart';
|
|
import 'package:didvan/models/overview_data.dart';
|
|
import 'package:didvan/models/requests/news.dart';
|
|
import 'package:didvan/providers/core.dart';
|
|
import 'package:didvan/services/network/request.dart';
|
|
import 'package:didvan/services/network/request_helper.dart';
|
|
|
|
class NewsDetailsState extends CoreProvier {
|
|
final List<NewsDetailsData?> news = [];
|
|
late final int initialIndex;
|
|
late final NewsRequestArgs args;
|
|
late Timer _trackingTimer;
|
|
int _trackingTimerCounter = 0;
|
|
bool isFetchingNewItem = false;
|
|
final List<int> relatedQueue = [];
|
|
|
|
int _currentIndex = 0;
|
|
int get currentIndex => _currentIndex;
|
|
bool openComments = false;
|
|
|
|
NewsDetailsData get currentNews => news[_currentIndex]!;
|
|
|
|
Future<void> getNewsDetails(int id, {bool? isForward}) async {
|
|
|
|
print("isForward: $isForward");
|
|
// if (isForward == null) {
|
|
// appState = AppState.busy;
|
|
// } else {
|
|
isFetchingNewItem = true;
|
|
notifyListeners();
|
|
// }
|
|
final service = RequestService(RequestHelper.newsDetails(id, args));
|
|
await service.httpGet();
|
|
print("making request to news endpoint $id");
|
|
_handleTracking(sendRequest: isForward != null);
|
|
if (service.isSuccess) {
|
|
print("success in receiving news detail for id $id");
|
|
final result = service.result;
|
|
final newsItem = NewsDetailsData.fromJson(result['news']);
|
|
if (args.page == 0) {
|
|
news.add(newsItem);
|
|
initialIndex = 0;
|
|
appState = AppState.idle;
|
|
return;
|
|
}
|
|
NewsDetailsData? prevNews;
|
|
if (result['prevNews'].isNotEmpty) {
|
|
prevNews = NewsDetailsData.fromJson(result['prevNews']);
|
|
}
|
|
NewsDetailsData? nextNews;
|
|
if (result['nextNews'].isNotEmpty) {
|
|
nextNews = NewsDetailsData.fromJson(result['nextNews']);
|
|
}
|
|
if (isForward == null) {
|
|
news.addAll(List.generate(max(newsItem.order - 2, 0), (index) => null));
|
|
if (prevNews != null) {
|
|
news.add(prevNews);
|
|
}
|
|
news.add(newsItem);
|
|
if (nextNews != null) {
|
|
news.add(nextNews);
|
|
}
|
|
_currentIndex = initialIndex = newsItem.order - 1;
|
|
} else if (isForward) {
|
|
if (!exists(nextNews) && nextNews != null) {
|
|
news.add(nextNews);
|
|
}
|
|
_currentIndex++;
|
|
} else if (!isForward) {
|
|
if (!exists(prevNews) && prevNews != null) {
|
|
news[_currentIndex - 2] = prevNews;
|
|
}
|
|
_currentIndex--;
|
|
}
|
|
isFetchingNewItem = false;
|
|
if (currentNews.contents.length == 1) {
|
|
getRelatedContents();
|
|
}
|
|
appState = AppState.idle;
|
|
return;
|
|
}
|
|
print("failed to receive news detail for id $id");
|
|
// if (isForward == null) {
|
|
// appState = AppState.failed;
|
|
// }
|
|
}
|
|
|
|
bool exists(NewsDetailsData? newsItem) =>
|
|
news.any((n) => newsItem != null && n != null && n.id == newsItem.id);
|
|
|
|
void onCommentsChanged(int count) {
|
|
news.firstWhere((item) => item?.id == currentNews.id)!.comments = count;
|
|
notifyListeners();
|
|
}
|
|
|
|
Future<void> _handleTracking({bool sendRequest = true}) async {
|
|
if (!sendRequest) {
|
|
_trackingTimerCounter = 0;
|
|
_trackingTimer = Timer.periodic(const Duration(seconds: 1), (timer) {
|
|
_trackingTimerCounter++;
|
|
});
|
|
return;
|
|
}
|
|
final service = RequestService(
|
|
RequestHelper.tracking(currentNews.id, 'news'),
|
|
body: {
|
|
'sec': _trackingTimerCounter,
|
|
},
|
|
);
|
|
service.put();
|
|
_trackingTimerCounter = 0;
|
|
_trackingTimer.cancel();
|
|
}
|
|
|
|
Future<void> getRelatedContents() async {
|
|
if (currentNews.relatedContents.isNotEmpty &&
|
|
currentNews.relatedContentsIsEmpty) {
|
|
return;
|
|
}
|
|
relatedQueue.add(currentNews.id);
|
|
final service = RequestService(RequestHelper.tag(
|
|
ids: currentNews.tags.map((tag) => tag.id).toList(),
|
|
itemId: currentNews.id,
|
|
type: 'news',
|
|
));
|
|
await service.httpGet();
|
|
if (service.isSuccess) {
|
|
final relateds = service.result['contents'];
|
|
for (var i = 0; i < relateds.length; i++) {
|
|
news
|
|
.where((element) => element != null)
|
|
.firstWhere((element) => element!.id == currentNews.id)!
|
|
.relatedContents
|
|
.add(OverviewData.fromJson(relateds[i]));
|
|
}
|
|
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
|
|
void dispose() {
|
|
_handleTracking(sendRequest: true);
|
|
_trackingTimer.cancel();
|
|
super.dispose();
|
|
}
|
|
}
|