Initial commit
This commit is contained in:
@@ -0,0 +1,324 @@
|
||||
import 'package:freezed_annotation/freezed_annotation.dart';
|
||||
|
||||
part 'tmdb.freezed.dart';
|
||||
part 'tmdb.g.dart';
|
||||
|
||||
@freezed
|
||||
abstract class TmdbCastMember with _$TmdbCastMember {
|
||||
const factory TmdbCastMember({
|
||||
@JsonKey(fromJson: _intRequired) required int id,
|
||||
@JsonKey(fromJson: _strOrEmpty) @Default('') String name,
|
||||
String? character,
|
||||
@JsonKey(name: 'profile_path') String? profilePath,
|
||||
@JsonKey(fromJson: _intOrZero) @Default(0) int order,
|
||||
}) = _TmdbCastMember;
|
||||
|
||||
factory TmdbCastMember.fromJson(Map<String, dynamic> json) =>
|
||||
_$TmdbCastMemberFromJson(json);
|
||||
}
|
||||
|
||||
@freezed
|
||||
abstract class TmdbCrewMember with _$TmdbCrewMember {
|
||||
const factory TmdbCrewMember({
|
||||
@JsonKey(fromJson: _intRequired) required int id,
|
||||
@JsonKey(fromJson: _strOrEmpty) @Default('') String name,
|
||||
String? job,
|
||||
String? department,
|
||||
@JsonKey(name: 'profile_path') String? profilePath,
|
||||
}) = _TmdbCrewMember;
|
||||
|
||||
factory TmdbCrewMember.fromJson(Map<String, dynamic> json) =>
|
||||
_$TmdbCrewMemberFromJson(json);
|
||||
}
|
||||
|
||||
@freezed
|
||||
abstract class TmdbCreditsRes with _$TmdbCreditsRes {
|
||||
const factory TmdbCreditsRes({
|
||||
@Default(<TmdbCastMember>[]) List<TmdbCastMember> cast,
|
||||
@Default(<TmdbCrewMember>[]) List<TmdbCrewMember> crew,
|
||||
}) = _TmdbCreditsRes;
|
||||
|
||||
factory TmdbCreditsRes.fromJson(Map<String, dynamic> json) =>
|
||||
_$TmdbCreditsResFromJson(json);
|
||||
}
|
||||
|
||||
@freezed
|
||||
abstract class TmdbRecommendation with _$TmdbRecommendation {
|
||||
const factory TmdbRecommendation({
|
||||
@JsonKey(fromJson: _intRequired) required int id,
|
||||
required String title,
|
||||
@JsonKey(name: 'poster_path') String? posterPath,
|
||||
@JsonKey(name: 'backdrop_path') String? backdropPath,
|
||||
String? overview,
|
||||
@JsonKey(name: 'vote_average', fromJson: _doubleOrNull) double? voteAverage,
|
||||
@JsonKey(name: 'media_type') String? mediaType,
|
||||
}) = _TmdbRecommendation;
|
||||
|
||||
factory TmdbRecommendation.fromJson(Map<String, dynamic> json) =>
|
||||
_$TmdbRecommendationFromJson({
|
||||
...json,
|
||||
'title': json['title'] ?? json['name'] ?? '',
|
||||
});
|
||||
}
|
||||
|
||||
@freezed
|
||||
abstract class TmdbRecommendationsRes with _$TmdbRecommendationsRes {
|
||||
const factory TmdbRecommendationsRes({
|
||||
@Default(<TmdbRecommendation>[]) List<TmdbRecommendation> results,
|
||||
@JsonKey(name: 'total_results', fromJson: _intOrZero)
|
||||
@Default(0)
|
||||
int totalResults,
|
||||
}) = _TmdbRecommendationsRes;
|
||||
|
||||
factory TmdbRecommendationsRes.fromJson(Map<String, dynamic> json) =>
|
||||
_$TmdbRecommendationsResFromJson(json);
|
||||
}
|
||||
|
||||
@freezed
|
||||
abstract class TmdbEpisode with _$TmdbEpisode {
|
||||
const factory TmdbEpisode({
|
||||
@JsonKey(name: 'episode_number', fromJson: _intRequired)
|
||||
required int episodeNumber,
|
||||
@JsonKey(fromJson: _strOrEmpty) @Default('') String name,
|
||||
String? overview,
|
||||
@JsonKey(name: 'still_path') String? stillPath,
|
||||
@JsonKey(name: 'air_date') String? airDate,
|
||||
@JsonKey(name: 'vote_average', fromJson: _doubleOrNull) double? voteAverage,
|
||||
@JsonKey(fromJson: _intOrNull) int? runtime,
|
||||
}) = _TmdbEpisode;
|
||||
|
||||
factory TmdbEpisode.fromJson(Map<String, dynamic> json) =>
|
||||
_$TmdbEpisodeFromJson(json);
|
||||
}
|
||||
|
||||
@freezed
|
||||
abstract class TmdbSeasonDetail with _$TmdbSeasonDetail {
|
||||
const factory TmdbSeasonDetail({
|
||||
@JsonKey(name: 'season_number', fromJson: _intRequired)
|
||||
required int seasonNumber,
|
||||
@JsonKey(fromJson: _strOrEmpty) @Default('') String name,
|
||||
String? overview,
|
||||
@JsonKey(name: 'poster_path') String? posterPath,
|
||||
@Default(<TmdbEpisode>[]) List<TmdbEpisode> episodes,
|
||||
}) = _TmdbSeasonDetail;
|
||||
|
||||
factory TmdbSeasonDetail.fromJson(Map<String, dynamic> json) =>
|
||||
_$TmdbSeasonDetailFromJson(json);
|
||||
}
|
||||
|
||||
@freezed
|
||||
abstract class TmdbVideo with _$TmdbVideo {
|
||||
const TmdbVideo._();
|
||||
|
||||
const factory TmdbVideo({
|
||||
@JsonKey(fromJson: _strOrEmpty) @Default('') String id,
|
||||
@JsonKey(fromJson: _strOrEmpty) @Default('') String key,
|
||||
@JsonKey(fromJson: _strOrEmpty) @Default('') String name,
|
||||
@JsonKey(fromJson: _strOrEmpty) @Default('') String site,
|
||||
@JsonKey(fromJson: _strOrEmpty) @Default('') String type,
|
||||
@JsonKey(fromJson: _intOrZero) @Default(0) int size,
|
||||
@JsonKey(fromJson: _boolOrFalse) @Default(false) bool official,
|
||||
}) = _TmdbVideo;
|
||||
|
||||
factory TmdbVideo.fromJson(Map<String, dynamic> json) =>
|
||||
_$TmdbVideoFromJson(json);
|
||||
|
||||
String? get youtubeUrl => site == 'YouTube' && key.isNotEmpty
|
||||
? 'https://www.youtube.com/watch?v=$key'
|
||||
: null;
|
||||
|
||||
String? get youtubeThumbnailUrl => site == 'YouTube' && key.isNotEmpty
|
||||
? 'https://img.youtube.com/vi/$key/mqdefault.jpg'
|
||||
: null;
|
||||
}
|
||||
|
||||
@freezed
|
||||
abstract class TmdbVideosRes with _$TmdbVideosRes {
|
||||
const factory TmdbVideosRes({
|
||||
@Default(<TmdbVideo>[]) List<TmdbVideo> results,
|
||||
}) = _TmdbVideosRes;
|
||||
|
||||
factory TmdbVideosRes.fromJson(Map<String, dynamic> json) =>
|
||||
_$TmdbVideosResFromJson(json);
|
||||
}
|
||||
|
||||
@freezed
|
||||
abstract class TmdbPersonDetail with _$TmdbPersonDetail {
|
||||
const factory TmdbPersonDetail({
|
||||
@JsonKey(fromJson: _intRequired) required int id,
|
||||
@JsonKey(fromJson: _strOrEmpty) @Default('') String name,
|
||||
String? biography,
|
||||
String? birthday,
|
||||
String? deathday,
|
||||
@JsonKey(name: 'place_of_birth') String? placeOfBirth,
|
||||
@JsonKey(name: 'profile_path') String? profilePath,
|
||||
@JsonKey(name: 'known_for_department') String? knownForDepartment,
|
||||
@JsonKey(fromJson: _doubleOrNull) double? popularity,
|
||||
}) = _TmdbPersonDetail;
|
||||
|
||||
factory TmdbPersonDetail.fromJson(Map<String, dynamic> json) =>
|
||||
_$TmdbPersonDetailFromJson(json);
|
||||
}
|
||||
|
||||
@freezed
|
||||
abstract class TmdbPersonCredit with _$TmdbPersonCredit {
|
||||
const factory TmdbPersonCredit({
|
||||
@JsonKey(fromJson: _intRequired) required int id,
|
||||
required String title,
|
||||
String? character,
|
||||
@JsonKey(name: 'poster_path') String? posterPath,
|
||||
@JsonKey(name: 'release_date') String? releaseDate,
|
||||
@JsonKey(name: 'vote_average', fromJson: _doubleOrNull) double? voteAverage,
|
||||
@JsonKey(name: 'media_type') String? mediaType,
|
||||
}) = _TmdbPersonCredit;
|
||||
|
||||
factory TmdbPersonCredit.fromJson(Map<String, dynamic> json) =>
|
||||
_$TmdbPersonCreditFromJson({
|
||||
...json,
|
||||
'title': json['title'] ?? json['name'] ?? '',
|
||||
'release_date': json['release_date'] ?? json['first_air_date'],
|
||||
});
|
||||
}
|
||||
|
||||
@freezed
|
||||
abstract class TmdbPersonCreditsRes with _$TmdbPersonCreditsRes {
|
||||
const factory TmdbPersonCreditsRes({
|
||||
@Default(<TmdbPersonCredit>[]) List<TmdbPersonCredit> cast,
|
||||
}) = _TmdbPersonCreditsRes;
|
||||
|
||||
factory TmdbPersonCreditsRes.fromJson(Map<String, dynamic> json) =>
|
||||
_$TmdbPersonCreditsResFromJson(json);
|
||||
}
|
||||
|
||||
@freezed
|
||||
abstract class TmdbGenre with _$TmdbGenre {
|
||||
const factory TmdbGenre({
|
||||
@JsonKey(fromJson: _intRequired) required int id,
|
||||
@JsonKey(fromJson: _strOrEmpty) @Default('') String name,
|
||||
}) = _TmdbGenre;
|
||||
|
||||
factory TmdbGenre.fromJson(Map<String, dynamic> json) =>
|
||||
_$TmdbGenreFromJson(json);
|
||||
}
|
||||
|
||||
@freezed
|
||||
abstract class TmdbMediaDetail with _$TmdbMediaDetail {
|
||||
const factory TmdbMediaDetail({
|
||||
@JsonKey(fromJson: _intRequired) required int id,
|
||||
@JsonKey(fromJson: _strOrEmpty) @Default('') String title,
|
||||
@JsonKey(name: 'poster_path') String? posterPath,
|
||||
@JsonKey(name: 'backdrop_path') String? backdropPath,
|
||||
@JsonKey(name: 'release_date') String? releaseDate,
|
||||
@Default(<TmdbGenre>[]) List<TmdbGenre> genres,
|
||||
@JsonKey(fromJson: _intOrNull) int? runtime,
|
||||
String? tagline,
|
||||
String? overview,
|
||||
String? status,
|
||||
String? homepage,
|
||||
@JsonKey(name: 'vote_average', fromJson: _doubleOrNull) double? voteAverage,
|
||||
@JsonKey(name: 'vote_count', fromJson: _intOrNull) int? voteCount,
|
||||
@JsonKey(fromJson: _intOrNull) int? revenue,
|
||||
@JsonKey(fromJson: _intOrNull) int? budget,
|
||||
}) = _TmdbMediaDetail;
|
||||
|
||||
|
||||
factory TmdbMediaDetail.fromJson(Map<String, dynamic> json) =>
|
||||
_$TmdbMediaDetailFromJson({
|
||||
...json,
|
||||
'title': json['title'] ?? json['name'] ?? '',
|
||||
'release_date': json['release_date'] ?? json['first_air_date'],
|
||||
'runtime':
|
||||
json['runtime'] ??
|
||||
(json['episode_run_time'] is List &&
|
||||
(json['episode_run_time'] as List).isNotEmpty
|
||||
? (json['episode_run_time'] as List).first
|
||||
: null),
|
||||
});
|
||||
}
|
||||
|
||||
@freezed
|
||||
abstract class TmdbImage with _$TmdbImage {
|
||||
const TmdbImage._();
|
||||
|
||||
const factory TmdbImage({
|
||||
@JsonKey(name: 'file_path', fromJson: _strOrEmpty)
|
||||
@Default('')
|
||||
String filePath,
|
||||
@JsonKey(fromJson: _intOrZero) @Default(0) int width,
|
||||
@JsonKey(fromJson: _intOrZero) @Default(0) int height,
|
||||
@JsonKey(name: 'vote_average', fromJson: _doubleOrNull) double? voteAverage,
|
||||
@JsonKey(name: 'iso_639_1') String? iso639,
|
||||
}) = _TmdbImage;
|
||||
|
||||
factory TmdbImage.fromJson(Map<String, dynamic> json) =>
|
||||
_$TmdbImageFromJson(json);
|
||||
|
||||
bool get isLanguageNeutral => iso639 == null;
|
||||
}
|
||||
|
||||
@freezed
|
||||
abstract class TmdbImageSet with _$TmdbImageSet {
|
||||
const factory TmdbImageSet({
|
||||
@Default(<TmdbImage>[]) List<TmdbImage> backdrops,
|
||||
@Default(<TmdbImage>[]) List<TmdbImage> posters,
|
||||
@Default(<TmdbImage>[]) List<TmdbImage> logos,
|
||||
}) = _TmdbImageSet;
|
||||
|
||||
factory TmdbImageSet.fromJson(Map<String, dynamic> json) =>
|
||||
_$TmdbImageSetFromJson(json);
|
||||
}
|
||||
|
||||
@freezed
|
||||
abstract class TmdbNetwork with _$TmdbNetwork {
|
||||
const factory TmdbNetwork({
|
||||
@JsonKey(fromJson: _intRequired) required int id,
|
||||
@JsonKey(fromJson: _strOrEmpty) @Default('') String name,
|
||||
@JsonKey(name: 'logo_path') String? logoPath,
|
||||
@JsonKey(name: 'origin_country') String? originCountry,
|
||||
}) = _TmdbNetwork;
|
||||
|
||||
factory TmdbNetwork.fromJson(Map<String, dynamic> json) =>
|
||||
_$TmdbNetworkFromJson(json);
|
||||
}
|
||||
|
||||
@freezed
|
||||
abstract class TmdbEnrichedDetail with _$TmdbEnrichedDetail {
|
||||
const factory TmdbEnrichedDetail({
|
||||
required TmdbMediaDetail detail,
|
||||
TmdbVideosRes? videos,
|
||||
TmdbCreditsRes? credits,
|
||||
TmdbRecommendationsRes? recommendations,
|
||||
TmdbImageSet? images,
|
||||
|
||||
|
||||
String? imdbId,
|
||||
@Default(<TmdbNetwork>[]) List<TmdbNetwork> networks,
|
||||
}) = _TmdbEnrichedDetail;
|
||||
|
||||
factory TmdbEnrichedDetail.fromJson(Map<String, dynamic> json) =>
|
||||
_$TmdbEnrichedDetailFromJson({
|
||||
'detail': json,
|
||||
'videos': json['videos'],
|
||||
'credits': json['credits'],
|
||||
'recommendations': json['recommendations'],
|
||||
'images': json['images'],
|
||||
'imdbId': _imdbIdOf(json['external_ids']),
|
||||
'networks': json['networks'],
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
String? _imdbIdOf(Object? externalIds) {
|
||||
if (externalIds is! Map) return null;
|
||||
final v = externalIds['imdb_id'];
|
||||
if (v is! String) return null;
|
||||
final trimmed = v.trim();
|
||||
return trimmed.isEmpty ? null : trimmed;
|
||||
}
|
||||
|
||||
int _intRequired(Object? v) => (v as num).toInt();
|
||||
int _intOrZero(Object? v) => (v as num?)?.toInt() ?? 0;
|
||||
int? _intOrNull(Object? v) => (v as num?)?.toInt();
|
||||
double? _doubleOrNull(Object? v) => (v as num?)?.toDouble();
|
||||
bool _boolOrFalse(Object? v) => (v as bool?) ?? false;
|
||||
String _strOrEmpty(Object? v) => v?.toString() ?? '';
|
||||
Reference in New Issue
Block a user