149 lines
4.4 KiB
Dart
149 lines
4.4 KiB
Dart
import 'dart:convert';
|
||
|
||
import 'package:flutter/foundation.dart';
|
||
import 'package:yumi/shared/business_logic/models/res/sc_top_four_with_reward_res.dart';
|
||
import 'package:yumi/shared/data_sources/sources/local/data_persistence.dart';
|
||
import 'package:yumi/shared/data_sources/sources/repositories/sc_config_repository_imp.dart';
|
||
|
||
class WeeklyStarSplashEntry {
|
||
const WeeklyStarSplashEntry({
|
||
required this.rank,
|
||
required this.avatarUrl,
|
||
required this.nickname,
|
||
});
|
||
|
||
final int rank;
|
||
final String avatarUrl;
|
||
final String nickname;
|
||
|
||
factory WeeklyStarSplashEntry.fromJson(Map<String, dynamic> json) {
|
||
return WeeklyStarSplashEntry(
|
||
rank: (json['rank'] as num?)?.toInt() ?? 0,
|
||
avatarUrl: (json['avatarUrl'] as String?) ?? '',
|
||
nickname: (json['nickname'] as String?) ?? '',
|
||
);
|
||
}
|
||
|
||
Map<String, dynamic> toJson() {
|
||
return {'rank': rank, 'avatarUrl': avatarUrl, 'nickname': nickname};
|
||
}
|
||
}
|
||
|
||
class WeeklyStarSplashCache {
|
||
static const String _cacheKey = 'weekly_star_splash_cache_v1';
|
||
|
||
/// 搜索 `api-ready-launch-splash` 可以快速找到后续要恢复接入的位置。
|
||
///
|
||
/// 当前周榜接口链路还未 ready,因此先关闭这套自定义启动页。
|
||
/// 正式恢复时保持“本地有缓存才展示、无缓存不展示”的逻辑,不要再回退到预览数据。
|
||
static const bool _allowCacheDrivenSplash = false;
|
||
|
||
static bool get shouldShow {
|
||
if (!_allowCacheDrivenSplash) {
|
||
return false;
|
||
}
|
||
return loadCachedEntries().isNotEmpty;
|
||
}
|
||
|
||
static List<WeeklyStarSplashEntry> loadDisplayEntries() {
|
||
if (!_allowCacheDrivenSplash) {
|
||
return const [];
|
||
}
|
||
return loadCachedEntries();
|
||
}
|
||
|
||
static List<WeeklyStarSplashEntry> loadCachedEntries() {
|
||
final raw = DataPersistence.getString(_cacheKey);
|
||
if (raw.isEmpty) {
|
||
return const [];
|
||
}
|
||
|
||
try {
|
||
final decoded = jsonDecode(raw);
|
||
if (decoded is! List) {
|
||
return const [];
|
||
}
|
||
return decoded
|
||
.whereType<Map>()
|
||
.map(
|
||
(item) =>
|
||
WeeklyStarSplashEntry.fromJson(Map<String, dynamic>.from(item)),
|
||
)
|
||
.toList()
|
||
..sort((a, b) => a.rank.compareTo(b.rank));
|
||
} catch (error, stackTrace) {
|
||
debugPrint('WeeklyStarSplashCache parse failed: $error\n$stackTrace');
|
||
return const [];
|
||
}
|
||
}
|
||
|
||
static Future<void> refreshCacheInBackground() async {
|
||
// TODO(api-ready-launch-splash): 周榜接口 ready 后,把 `_allowCacheDrivenSplash`
|
||
// 改为 true,并继续只在这里写入真实接口结果到 `_cacheKey`。
|
||
// 这样就能保持“有缓存才展示、无缓存不展示”的正式逻辑。
|
||
if (!_allowCacheDrivenSplash) {
|
||
return;
|
||
}
|
||
|
||
try {
|
||
final result = await SCConfigRepositoryImp().topFourWithReward();
|
||
final entries = _mapTopThree(result);
|
||
if (entries.isEmpty) {
|
||
return;
|
||
}
|
||
await DataPersistence.setString(
|
||
_cacheKey,
|
||
jsonEncode(entries.map((entry) => entry.toJson()).toList()),
|
||
);
|
||
} catch (error, stackTrace) {
|
||
debugPrint('WeeklyStarSplashCache refresh failed: $error\n$stackTrace');
|
||
}
|
||
}
|
||
|
||
static List<WeeklyStarSplashEntry> _mapTopThree(
|
||
List<SCTopFourWithRewardRes> result,
|
||
) {
|
||
final topThree =
|
||
result
|
||
.where(
|
||
(item) =>
|
||
(item.avatar ?? '').trim().isNotEmpty ||
|
||
(item.nickname ?? '').trim().isNotEmpty,
|
||
)
|
||
.map(
|
||
(item) => WeeklyStarSplashEntry(
|
||
rank: (item.rank ?? 0).toInt(),
|
||
avatarUrl: (item.avatar ?? '').trim(),
|
||
nickname: (item.nickname ?? '').trim(),
|
||
),
|
||
)
|
||
.toList()
|
||
..sort((a, b) => a.rank.compareTo(b.rank));
|
||
|
||
return _ensureThreeEntries(topThree.take(3).toList());
|
||
}
|
||
|
||
static List<WeeklyStarSplashEntry> _ensureThreeEntries(
|
||
List<WeeklyStarSplashEntry> entries,
|
||
) {
|
||
final normalized = List<WeeklyStarSplashEntry>.from(entries)
|
||
..sort((a, b) => a.rank.compareTo(b.rank));
|
||
|
||
for (var rank = 1; rank <= 3; rank++) {
|
||
final hasRank = normalized.any((entry) => entry.rank == rank);
|
||
if (!hasRank) {
|
||
normalized.add(
|
||
WeeklyStarSplashEntry(
|
||
rank: rank,
|
||
avatarUrl: '',
|
||
nickname: 'Namename',
|
||
),
|
||
);
|
||
}
|
||
}
|
||
|
||
normalized.sort((a, b) => a.rank.compareTo(b.rank));
|
||
return normalized.take(3).toList();
|
||
}
|
||
}
|