Initial commit

This commit is contained in:
admin1
2026-07-14 11:11:36 +08:00
commit 656499cf94
604 changed files with 119518 additions and 0 deletions
+105
View File
@@ -0,0 +1,105 @@
import '../../core/contracts/tmdb.dart';
import 'tmdb_image_url.dart';
class TmdbImageSelector {
static TmdbImage? bestImage(
List<TmdbImage> images, {
bool preferNeutral = false,
}) {
if (images.isEmpty) return null;
if (preferNeutral) {
final neutrals = images
.where((i) => i.filePath.isNotEmpty && i.isLanguageNeutral)
.toList();
if (neutrals.isNotEmpty) return _pickBest(neutrals);
}
return _pickBest(images);
}
static TmdbImage? _pickBest(List<TmdbImage> images) {
TmdbImage? best;
for (final image in images) {
if (image.filePath.isEmpty) continue;
if (best == null || _isBetter(image, best)) best = image;
}
return best;
}
static String? backdropUrl(
TmdbImageSet? imageSet,
String? imageBaseUrl, {
String size = 'original',
}) {
if (imageBaseUrl == null || imageBaseUrl.isEmpty) return null;
final image = bestImage(
imageSet?.backdrops ?? const [],
preferNeutral: true,
);
return TmdbImageUrl.backdrop(imageBaseUrl, image?.filePath, size: size);
}
static String? posterUrl(
TmdbImageSet? imageSet,
String? imageBaseUrl, {
String size = 'w500',
}) {
if (imageBaseUrl == null || imageBaseUrl.isEmpty) return null;
final image = bestImage(imageSet?.posters ?? const []);
return TmdbImageUrl.poster(imageBaseUrl, image?.filePath, size: size);
}
static String? logoUrl(
TmdbImageSet? imageSet,
String? imageBaseUrl, {
String? language,
String size = 'w500',
}) {
if (imageBaseUrl == null || imageBaseUrl.isEmpty) return null;
final logos = imageSet?.logos ?? const <TmdbImage>[];
if (logos.isEmpty) return null;
final lang = _iso639Of(language);
final image =
(lang != null ? _pickBest(_withLang(logos, lang)) : null) ??
_pickBest(_withLang(logos, 'en')) ??
_pickBest(logos.where((i) => i.isLanguageNeutral).toList()) ??
_pickBest(logos);
return TmdbImageUrl.logo(imageBaseUrl, image?.filePath, size: size);
}
static List<TmdbImage> _withLang(List<TmdbImage> images, String iso) =>
images.where((i) => i.iso639 == iso).toList();
static String? _iso639Of(String? language) {
if (language == null || language.isEmpty) return null;
final dash = language.indexOf('-');
final code = dash >= 0 ? language.substring(0, dash) : language;
return code.isEmpty ? null : code.toLowerCase();
}
static List<String> buildFallbackUrls({
required String? primaryUrl,
required Iterable<String?> candidates,
}) {
final urls = <String>[];
for (final url in candidates) {
if (url == null || url.isEmpty || url == primaryUrl) continue;
if (!urls.contains(url)) urls.add(url);
}
return urls;
}
static bool _isBetter(TmdbImage candidate, TmdbImage current) {
final voteCompare = (candidate.voteAverage ?? 0).compareTo(
current.voteAverage ?? 0,
);
if (voteCompare != 0) return voteCompare > 0;
final pixelsCompare = (candidate.width * candidate.height).compareTo(
current.width * current.height,
);
if (pixelsCompare != 0) return pixelsCompare > 0;
return candidate.filePath.compareTo(current.filePath) < 0;
}
}