Fladder/lib/models/items/images_models.dart
PartyDonut c299492d6d
feat: Android TV support (#503)
Co-authored-by: PartyDonut <PartyDonut@users.noreply.github.com>
2025-09-28 21:07:49 +02:00

290 lines
8.9 KiB
Dart

import 'dart:convert';
import 'dart:io';
import 'package:flutter/material.dart';
import 'package:flutter/widgets.dart';
import 'package:cached_network_image/cached_network_image.dart';
import 'package:collection/collection.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:fladder/jellyfin/jellyfin_open_api.enums.swagger.dart' as enums;
import 'package:fladder/jellyfin/jellyfin_open_api.swagger.dart' as dto;
import 'package:fladder/providers/image_provider.dart';
import 'package:fladder/util/custom_cache_manager.dart';
class ImagesData {
final ImageData? primary;
final List<ImageData>? backDrop;
final ImageData? logo;
ImagesData({
this.primary,
this.backDrop,
this.logo,
});
bool get isEmpty {
if (primary == null && backDrop == null) return true;
return false;
}
ImageData? get firstOrNull {
return primary ?? backDrop?[0];
}
ImageData? get randomBackDrop => (backDrop?..shuffle())?.firstOrNull ?? primary;
static ImagesData? fromBaseItem(
dto.BaseItemDto item,
Ref ref, {
Size backDrop = const Size(2000, 2000),
Size logo = const Size(500, 500),
Size primary = const Size(600, 600),
bool getOriginalSize = false,
}) {
final itemid = item.id;
if (itemid == null) return null;
final imageProvider = ref.read(imageUtilityProvider);
final newImgesData = ImagesData(
primary: item.imageTags?['Primary'] != null
? ImageData(
path: getOriginalSize
? imageProvider.getItemsOrigImageUrl(
itemid,
type: enums.ImageType.primary,
)
: imageProvider.getItemsImageUrl(
itemid,
type: enums.ImageType.primary,
maxHeight: primary.height.toInt(),
maxWidth: primary.width.toInt(),
),
key: "${itemid}_primary_${item.imageTags?['Primary']}",
hash: item.imageBlurHashes?.primary?[item.imageTags?['Primary']] ?? "",
)
: null,
logo: item.imageTags?['Logo'] != null
? ImageData(
path: getOriginalSize
? imageProvider.getItemsOrigImageUrl(
itemid,
type: enums.ImageType.logo,
)
: imageProvider.getItemsImageUrl(
itemid,
type: enums.ImageType.logo,
maxHeight: logo.height.toInt(),
maxWidth: logo.width.toInt(),
),
key: "${itemid}_logo_${item.imageTags?['Logo']}",
hash: item.imageBlurHashes?.logo?[item.imageTags?['Logo']] ?? "")
: null,
backDrop: (item.backdropImageTags ?? [])
.mapIndexed(
(index, backdrop) {
final image = ImageData(
path: getOriginalSize
? imageProvider.getBackdropOrigImage(
itemid,
index,
backdrop,
)
: imageProvider.getBackdropImage(
itemid,
index,
backdrop,
maxHeight: backDrop.height.toInt(),
maxWidth: backDrop.width.toInt(),
),
key: "${itemid}_backdrop_${index}_$backdrop",
hash: item.imageBlurHashes?.backdrop?[backdrop] ?? "",
);
return image;
},
)
.nonNulls
.toList(),
);
return newImgesData;
}
static ImagesData? fromBaseItemParent(
dto.BaseItemDto item,
Ref ref, {
Size backDrop = const Size(2000, 2000),
Size logo = const Size(500, 500),
Size primary = const Size(600, 600),
}) {
if (item.seriesId == null && item.parentId == null) return null;
final imageProvider = ref.read(imageUtilityProvider);
final newImgesData = ImagesData(
primary: (item.seriesPrimaryImageTag != null)
? ImageData(
path: imageProvider.getItemsImageUrl(
item.seriesId,
type: enums.ImageType.primary,
maxHeight: primary.height.toInt(),
maxWidth: primary.width.toInt(),
),
key: "${item.seriesId}_primary_${item.seriesPrimaryImageTag ?? ""}",
hash: item.imageBlurHashes?.primary?[item.seriesPrimaryImageTag] ?? "")
: null,
logo: (item.parentLogoImageTag != null)
? ImageData(
path: imageProvider.getItemsImageUrl(
item.seriesId,
type: enums.ImageType.logo,
maxHeight: logo.height.toInt(),
maxWidth: logo.width.toInt(),
),
key: "${item.seriesId}_logo_${item.parentLogoImageTag ?? ""}",
hash: item.imageBlurHashes?.logo?[item.parentLogoImageTag] ?? "")
: null,
backDrop: (item.backdropImageTags ?? [])
.mapIndexed(
(index, backdrop) {
final itemId = item.seriesId ?? item.parentId;
if (itemId == null) return null;
final image = ImageData(
path: imageProvider.getBackdropImage(
itemId,
index,
backdrop,
maxHeight: backDrop.height.toInt(),
maxWidth: backDrop.width.toInt(),
),
key: "${itemId}_backdrop_${index}_$backdrop",
hash: item.imageBlurHashes?.backdrop?[backdrop] ?? "",
);
return image;
},
)
.nonNulls
.toList(),
);
return newImgesData;
}
static ImagesData? fromPersonDto(
dto.BaseItemPerson item,
Ref ref, {
Size backDrop = const Size(2000, 2000),
Size logo = const Size(1000, 1000),
Size primary = const Size(500, 500),
}) {
return ImagesData(
primary: (item.primaryImageTag != null && item.imageBlurHashes != null)
? ImageData(
path: ref.read(imageUtilityProvider).getItemsImageUrl(
item.id ?? "",
type: enums.ImageType.primary,
maxHeight: primary.height.toInt(),
maxWidth: primary.width.toInt(),
),
key: "${item.id ?? ""}_primary_${item.primaryImageTag ?? ''}",
hash: item.imageBlurHashes?.primary?[item.primaryImageTag] ?? '')
: null,
logo: null,
backDrop: null,
);
}
@override
String toString() => 'ImagesData(primary: $primary, backDrop: $backDrop, logo: $logo)';
ImagesData copyWith({
ValueGetter<ImageData?>? primary,
ValueGetter<List<ImageData>?>? backDrop,
ValueGetter<ImageData?>? logo,
}) {
return ImagesData(
primary: primary != null ? primary() : this.primary,
backDrop: backDrop != null ? backDrop() : this.backDrop,
logo: logo != null ? logo() : this.logo,
);
}
Map<String, dynamic> toMap() {
return {
'primary': primary?.toMap(),
'backDrop': backDrop?.map((x) => x.toMap()).toList(),
'logo': logo?.toMap(),
};
}
factory ImagesData.fromMap(Map<String, dynamic> map) {
return ImagesData(
primary: map['primary'] != null ? ImageData.fromMap(map['primary']) : null,
backDrop:
map['backDrop'] != null ? List<ImageData>.from(map['backDrop']?.map((x) => ImageData.fromMap(x))) : null,
logo: map['logo'] != null ? ImageData.fromMap(map['logo']) : null,
);
}
String toJson() => json.encode(toMap());
factory ImagesData.fromJson(String source) => ImagesData.fromMap(json.decode(source));
}
class ImageData {
final String path;
final String hash;
final String key;
ImageData({
this.path = '',
this.hash = '',
this.key = '',
});
ImageProvider get imageProvider {
if (path.startsWith("http")) {
return CachedNetworkImageProvider(
cacheKey: key,
cacheManager: CustomCacheManager.instance,
path,
);
} else {
return Image.file(
key: Key(key),
File(path),
).image;
}
}
@override
String toString() => 'ImageData(path: $path, hash: $hash, key: $key)';
ImageData copyWith({
String? path,
String? hash,
String? key,
}) {
return ImageData(
path: path ?? this.path,
hash: hash ?? this.hash,
key: key ?? this.key,
);
}
Map<String, dynamic> toMap() {
return {
'path': path,
'hash': hash,
'key': key,
};
}
factory ImageData.fromMap(Map<String, dynamic> map) {
return ImageData(
path: map['path'] ?? '',
hash: map['hash'] ?? '',
key: map['key'] ?? '',
);
}
String toJson() => json.encode(toMap());
factory ImageData.fromJson(String source) => ImageData.fromMap(json.decode(source));
}