Files
ReelShort/lib/pages/home/widgets/home_drama_classification.dart

50 lines
1.7 KiB
Dart

// Author: fruit.com.cn
import '../../../core/data/models/drama.dart';
const int homeNewReleaseDays = 7;
const int homeHotViewThreshold = 100000;
const int _snowflakeEpochMillis = 1288834974657;
const int _snowflakeTimestampShift = 22;
const Map<String, List<String>> _tagAliases = {
'uplifting': ['爽剧', '逆袭', '复仇', 'revenge', 'balas'],
'sweet': ['甜宠', '甜', 'sweet', 'romantis'],
'faceSlap': ['打脸', '虐渣', 'comeuppance', 'comeback'],
'angst': ['虐恋', '虐心', 'angst', 'heartbreak'],
};
DateTime? publishedAtForDrama(Drama drama) {
if (drama.createdAt != null) return drama.createdAt;
final snowflake = BigInt.tryParse(drama.id);
if (snowflake == null) return null;
final timestamp =
(snowflake >> _snowflakeTimestampShift).toInt() + _snowflakeEpochMillis;
final publishedAt = DateTime.fromMillisecondsSinceEpoch(timestamp);
return publishedAt.year >= 2015 ? publishedAt : null;
}
bool isNewDrama(Drama drama, {DateTime? now}) {
final publishedAt = publishedAtForDrama(drama);
if (publishedAt == null) return false;
final age = (now ?? DateTime.now()).difference(publishedAt);
return !age.isNegative && age <= const Duration(days: homeNewReleaseDays);
}
bool isHotDrama(Drama drama) {
return drama.isHot || drama.viewCount >= homeHotViewThreshold;
}
bool matchesHomeTag(Drama drama, String tagId) {
if (tagId == 'hot') return isHotDrama(drama);
return tagMatchesText(tagId, drama.genre) ||
tagMatchesText(tagId, drama.category);
}
bool tagMatchesText(String tagId, String text) {
if (tagId == 'hot') return false;
final normalized = text.toLowerCase();
final aliases = _tagAliases[tagId] ?? const [];
return aliases.any(normalized.contains);
}