didvan-app/lib/views/home/new_statistic/new_statistics_state.dart

137 lines
4.5 KiB
Dart

import 'package:didvan/constants/assets.dart';
import 'package:didvan/models/enums.dart';
import 'package:didvan/models/new_statistic/new_statistics_model.dart';
import 'package:didvan/providers/core.dart';
import 'package:didvan/services/content/content_service.dart';
import 'package:didvan/services/market/statista_market_service.dart';
import 'package:didvan/views/home/new_statistic/widgets/statistic_cat.dart';
import 'dart:async';
import 'package:flutter/foundation.dart';
class NewStatisticState extends CoreProvier {
final List<CategoryList> contents = [];
DateTime? generatedAt;
String? errorMessage;
/// Signed URL of the «نبض صنعت» banner, managed from the panel
/// (`/panel/market-symbols`). Null while loading or when unset.
String? bannerUrl;
/// Title of the content-category that holds the banner. Resolved by title so
/// no UUID needs to be hardcoded — the panel creates it on first upload.
static const String _bannerCategoryTitle = 'بنر نبض صنعت';
static String? _cachedBannerCategoryId;
Future<void> getBanner() async {
try {
final categoryId = await _resolveBannerCategoryId();
if (categoryId == null) return;
final res = await ContentService.instance.getContents(
page: 1,
limit: 1,
categoryId: categoryId,
sortBy: const [MapEntry('createdAt', 'DESC')],
);
if (!res.isSuccess || res.data == null || res.data!.data.isEmpty) {
bannerUrl = null;
notifyListeners();
return;
}
final first = res.data!.data.first;
var cover = first.coverImage;
if (cover == null || cover.isEmpty) {
// The list endpoint does not always sign the cover; the detail one does.
final detail = await ContentService.instance.getContent(first.id);
if (detail.isSuccess && detail.data != null) {
cover = detail.data!.coverImage;
}
}
bannerUrl = (cover != null && cover.isNotEmpty) ? cover : null;
notifyListeners();
} catch (e) {
debugPrint('industry pulse banner failed: $e');
}
}
Future<String?> _resolveBannerCategoryId() async {
if (_cachedBannerCategoryId != null) return _cachedBannerCategoryId;
final res = await ContentService.instance.getCategories(limit: 100);
if (!res.isSuccess || res.data == null) return null;
for (final c in res.data!) {
if (c.name == _bannerCategoryTitle && c.id != null) {
_cachedBannerCategoryId = c.id;
return c.id;
}
}
return null;
}
List<StatMenuItemType> statCat = [];
Future<void> getStatistic() async {
appState = AppState.busy;
errorMessage = null;
// Banner is independent of the price feed — fire and forget.
unawaited(getBanner());
final result = await StatistaMarketService.instance.getLatestPrices();
if (result.isSuccess) {
contents
..clear()
..addAll(result.categories);
generatedAt = result.generatedAt;
appState = AppState.idle;
return;
}
contents.clear();
errorMessage = result.errorMessage;
appState = AppState.idle;
}
void init() {
statCat = [
StatMenuItemType(
label: "بازار ارز و طلا", asset: Assets.currencyGoldStatCat, id: 1),
StatMenuItemType(
label: "ارزهای دیجیتال", asset: Assets.cryptoStatCat, id: 2),
StatMenuItemType(label: "فلزات پایه", asset: Assets.metalStatCat, id: 3),
StatMenuItemType(
label: "کامودیتی‌ها", asset: Assets.commodityStatCat, id: 4),
StatMenuItemType(label: "صنعت فولاد", asset: Assets.steelStatCat, id: 5),
StatMenuItemType(
label: "بازار سرمایه", asset: Assets.stockStatCat, id: 6),
];
Future.delayed(Duration.zero, () {
getStatistic();
});
}
void refresh() {
statCat = [
StatMenuItemType(
label: "بازار ارز و طلا", asset: Assets.currencyGoldStatCat, id: 1),
StatMenuItemType(
label: "ارزهای دیجیتال", asset: Assets.cryptoStatCat, id: 2),
StatMenuItemType(label: "فلزات پایه", asset: Assets.metalStatCat, id: 3),
StatMenuItemType(
label: "کامودیتی‌ها", asset: Assets.commodityStatCat, id: 4),
StatMenuItemType(label: "صنعت فولاد", asset: Assets.steelStatCat, id: 5),
StatMenuItemType(
label: "بازار سرمایه", asset: Assets.stockStatCat, id: 6),
];
update();
}
void resetState() {
contents.clear();
notifyListeners();
getStatistic();
}
}