import 'dart:async'; import 'dart:math' as math; import 'package:flutter/material.dart'; import 'package:yumi/shared/data_sources/sources/repositories/sc_config_repository_imp.dart'; import 'package:yumi/shared/data_sources/sources/repositories/sc_room_repository_imp.dart'; import 'package:yumi/shared/tools/sc_gift_vap_svga_manager.dart'; import 'package:yumi/shared/tools/sc_network_image_utils.dart'; import 'package:yumi/shared/data_sources/models/country_mode.dart'; import 'package:yumi/shared/business_logic/models/res/sc_banner_leaderboard_res.dart'; import 'package:yumi/shared/business_logic/models/res/country_res.dart'; import 'package:yumi/shared/business_logic/models/res/gift_res.dart'; import 'package:yumi/shared/business_logic/models/res/sc_index_banner_res.dart'; import 'package:yumi/shared/business_logic/models/res/sc_room_emoji_res.dart'; import '../../shared/data_sources/models/enum/sc_banner_type.dart'; import '../../shared/data_sources/models/enum/sc_gift_type.dart'; class SCAppGeneralManager extends ChangeNotifier { List countryModeList = []; final Map> _countryMap = {}; final Map _countryByNameMap = {}; bool _isFetchingCountryList = false; ///礼物 List giftResList = []; final Map _giftByIdMap = {}; final Set _warmedGiftCoverUrls = {}; final Set _warmingGiftCoverUrls = {}; bool _isFetchingGiftList = false; bool _hasGiftListLoaded = false; Map> giftByTab = {}; Map> activityGiftByTab = {}; ///选中的国家 Country? selectCountryInfo; List activityList = []; SCAppGeneralManager() { fetchCountryList(); giftList(); // 使用默认参数 giftActivityList(); // giftBackpack(); // configLevel(); } bool get isGiftListLoading => _isFetchingGiftList && !_hasGiftListLoaded; ///加载国家列表 Future fetchCountryList() async { if (_isFetchingCountryList) { return; } if (countryModeList.isNotEmpty) { clearCountrySelection(); notifyListeners(); return; } _isFetchingCountryList = true; try { await Future.delayed(Duration(milliseconds: 550)); final result = await SCConfigRepositoryImp().loadCountry(); _countryMap.clear(); _countryByNameMap.clear(); countryModeList.clear(); for (final c in result.openCountry ?? const []) { final prefix = c.aliasName?.substring(0, 1) ?? ""; if (prefix.isNotEmpty) { final countryList = _countryMap[prefix] ?? []; countryList.add(c.copyWith()); _countryMap[prefix] = countryList; } if ((c.countryName ?? "").isNotEmpty) { _countryByNameMap[c.countryName!] = c; } } _countryMap.forEach((k, v) { countryModeList.add(CountryMode(k, v)); }); ///排序 countryModeList.sort((a, b) => a.prefix.compareTo(b.prefix)); notifyListeners(); } catch (_) { notifyListeners(); } finally { _isFetchingCountryList = false; } } ///国家国家名称获取国家 Country? findCountryByName(String countryName) { return _countryByNameMap[countryName]; } ///选择国家 Country? chooseCountry(int subIndex, int cIndex) { var selectCm = countryModeList[subIndex].prefixCountrys[cIndex]; if (selectCountryInfo != null) { selectCountryInfo = null; } else { selectCountryInfo = selectCm; } return selectCountryInfo; } void updateCurrentCountry(Country? countryInfo) { selectCountryInfo = countryInfo; notifyListeners(); } void clearCountrySelection() { selectCountryInfo = null; } void openDrawer(BuildContext context) { Scaffold.of(context).openDrawer(); } void closeDrawer(BuildContext context) { Scaffold.of(context).closeDrawer(); } Future giftList({ bool includeCustomized = true, bool forceRefresh = false, }) async { if (_isFetchingGiftList) { return; } if (_hasGiftListLoaded && giftResList.isNotEmpty && !forceRefresh) { _rebuildGiftTabs(includeCustomized: includeCustomized); notifyListeners(); unawaited( warmGiftPageCovers("ALL", pageIndex: 0, pageCount: 2, pageSize: 8), ); return; } _isFetchingGiftList = true; if (!_hasGiftListLoaded) { notifyListeners(); } try { giftResList = await SCChatRoomRepository().giftList(); _hasGiftListLoaded = true; _rebuildGiftTabs(includeCustomized: includeCustomized); notifyListeners(); ///先去预下载 downLoad(giftResList); unawaited( warmGiftPageCovers("ALL", pageIndex: 0, pageCount: 2, pageSize: 8), ); } catch (_) { return; } finally { _isFetchingGiftList = false; notifyListeners(); } } void _rebuildGiftTabs({required bool includeCustomized}) { giftByTab.clear(); _giftByIdMap.clear(); for (var gift in giftResList) { giftByTab[gift.giftTab]; var gmap = giftByTab[gift.giftTab]; gmap ??= []; gmap.add(gift); giftByTab[gift.giftTab!] = gmap; var gAllMap = giftByTab["ALL"]; gAllMap ??= []; if (gift.giftTab != "NSCIONAL_FLAG" && gift.giftTab != "ACTIVITY" && gift.giftTab != "LUCKY_GIFT" && gift.giftTab != "CP" && gift.giftTab != "CUSTOMIZED" && gift.giftTab != "MAGIC") { gAllMap.add(gift); } giftByTab["ALL"] = gAllMap; _giftByIdMap[gift.id!] = gift; } if (includeCustomized) { giftByTab["CUSTOMIZED"] ??= []; ///定制礼物需要一个占位符,显示规则的 giftByTab["CUSTOMIZED"]?.insert(0, SocialChatGiftRes(id: "-1000")); } else { giftByTab.remove("CUSTOMIZED"); } } Future warmGiftPageCovers( String type, { required int pageIndex, int pageCount = 1, int pageSize = 8, }) async { final gifts = giftByTab[type] ?? []; if (gifts.isEmpty) { return; } final start = pageIndex * pageSize; if (start >= gifts.length) { return; } final end = math.min(gifts.length, start + (pageSize * pageCount)); await warmGiftCoverImages(gifts.sublist(start, end)); } Future warmGiftCoverImages( Iterable gifts, { int maxConcurrency = 4, }) async { final pending = >[]; for (final gift in gifts) { final coverUrl = gift.giftPhoto ?? ""; if (coverUrl.isEmpty || _warmedGiftCoverUrls.contains(coverUrl) || !_warmingGiftCoverUrls.add(coverUrl)) { continue; } pending.add(() async { final warmed = await warmNetworkImage(coverUrl); _warmingGiftCoverUrls.remove(coverUrl); if (warmed) { _warmedGiftCoverUrls.add(coverUrl); } }()); if (pending.length >= maxConcurrency) { await Future.wait(pending); pending.clear(); } } if (pending.isNotEmpty) { await Future.wait(pending); } } void giftActivityList() async { try { activityList.clear(); activityList = await SCChatRoomRepository().giftActivityList(); activityGiftByTab.clear(); for (var gift in activityList) { var gmap = activityGiftByTab["${gift.activityId}"]; gmap ??= []; gmap.add(gift); activityGiftByTab["${gift.activityId}"] = gmap; } notifyListeners(); } catch (_) { return; } } ///礼物背包 void giftBackpack() async { try { await SCChatRoomRepository().giftBackpack(); } catch (_) { return; } } ///礼物id获取礼物 SocialChatGiftRes? getGiftById(String id) { return _giftByIdMap[id]; } void downLoad(List giftResList) { for (var gift in giftResList) { final giftSourceUrl = gift.giftSourceUrl ?? ""; if (giftSourceUrl.isEmpty) { continue; } if (!scGiftHasFullScreenEffect(gift.special)) { continue; } SCGiftVapSvgaManager().preload(giftSourceUrl); } } List homeBanners = []; List exploreBanners = []; List roomBanners = []; List gameBanners = []; ///首页banner Future loadMainBanner() async { try { var banners = await SCConfigRepositoryImp().getBanner(); homeBanners.clear(); roomBanners.clear(); gameBanners.clear(); exploreBanners.clear(); for (var v in banners) { if ((v.displayPosition ?? "").contains( SCBannerType.EXPLORE_PAGE.name, )) { exploreBanners.add(v); } if ((v.displayPosition ?? "").contains(SCBannerType.ROOM.name)) { roomBanners.add(v); } if ((v.displayPosition ?? "").contains(SCBannerType.HOME_ALERT.name)) { homeBanners.add(v); } if ((v.displayPosition ?? "").contains(SCBannerType.GAME.name)) { gameBanners.add(v); } } notifyListeners(); } catch (_) { return; } } Map> emojiByTab = {}; ///emoji表情 void emojiAll() async { var roomEmojis = await SCChatRoomRepository().emojiAll(); for (var value in roomEmojis) { emojiByTab[value.groupName!] = value.emojis ?? []; } notifyListeners(); } ///加载等级资源 void configLevel() { SCConfigRepositoryImp().configLevel(); } SCBannerLeaderboardRes? appLeaderResult; ///查询榜单前三名 Future appLeaderboard() async { try { appLeaderResult = await SCChatRoomRepository().appLeaderboard(); notifyListeners(); } catch (_) { return; } } }