feat(overseerr): serialized movie & tv objects

This commit is contained in:
Jagandeep Brar
2022-02-08 10:14:22 -05:00
parent 3f603d442a
commit 2b778dc437
33 changed files with 1223 additions and 48 deletions

View File

@@ -204,7 +204,7 @@
"settings.SystemStatus": "System Status",
"settings.SystemStatusDescription": "Status Page for Hosted Services",
"settings.TestBuilds": "Test Builds",
"settings.TestBuildsDescription": "Install Pre-Release Builds of LunaSea",
"settings.TestBuildsDescription": "Install Prerelease Builds of LunaSea",
"settings.TestConnection": "Test Connection",
"settings.TLSCertificateValidation": "TLS Certificate Validation",
"settings.TLSCertificateValidationDescription": "Validate Certificates in TLS Connections",

View File

@@ -30,6 +30,7 @@ export 'core/models.dart';
export 'core/modules.dart';
export 'core/pages.dart';
export 'core/router.dart';
export 'core/services.dart';
export 'core/state.dart';
export 'core/system.dart';
export 'core/ui.dart';

1
lib/core/services.dart Normal file
View File

@@ -0,0 +1 @@
export 'services/the_movie_db.dart';

View File

@@ -0,0 +1 @@
export 'the_movie_db/api.dart';

View File

@@ -0,0 +1,9 @@
class TheMovieDB {
static const String _IMAGE_ENDPOINT_URL = 'https://image.tmdb.org/t/p/';
static const String _IMAGE_POSTER_SIZE = 'w154';
static String? getImageURL(String? id) {
if (id != null) return '$_IMAGE_ENDPOINT_URL$_IMAGE_POSTER_SIZE$id';
return null;
}
}

View File

@@ -94,6 +94,10 @@ class LunaBlock extends StatelessWidget {
@override
Widget build(BuildContext context) {
return _buildBlock(context);
}
Widget _buildBlock(BuildContext context) {
double _height = _calculateHeight();
return LunaCard(
context: context,

View File

@@ -1,3 +1,21 @@
export 'models/content/collection.dart';
export 'models/content/content_ratings.dart';
export 'models/content/created_by.dart';
export 'models/content/credits.dart';
export 'models/content/episode.dart';
export 'models/content/external_ids.dart';
export 'models/content/genre.dart';
export 'models/content/keyword.dart';
export 'models/content/movie.dart';
export 'models/content/movie_releases.dart';
export 'models/content/network.dart';
export 'models/content/production_company.dart';
export 'models/content/production_country.dart';
export 'models/content/related_video.dart';
export 'models/content/season.dart';
export 'models/content/series.dart';
export 'models/content/spoken_language.dart';
export 'models/content/watch_provider.dart';
export 'models/media/media.dart';
export 'models/media/season.dart';
export 'models/requests/request_count.dart';

View File

@@ -0,0 +1,33 @@
import 'package:lunasea/core.dart';
part 'collection.g.dart';
@JsonSerializable(explicitToJson: true, includeIfNull: false)
class OverseerrCollection {
@JsonKey()
int? id;
@JsonKey()
String? name;
@JsonKey()
String? posterPath;
@JsonKey()
String? backdropPath;
OverseerrCollection({
this.id,
this.name,
this.posterPath,
this.backdropPath,
});
@override
String toString() => json.encode(this.toJson());
factory OverseerrCollection.fromJson(Map<String, dynamic> json) =>
_$OverseerrCollectionFromJson(json);
Map<String, dynamic> toJson() => _$OverseerrCollectionToJson(this);
}

View File

@@ -0,0 +1,43 @@
import 'package:lunasea/core.dart';
part 'content_ratings.g.dart';
@JsonSerializable(explicitToJson: true, includeIfNull: false)
class OverseerrContentRatings {
@JsonKey()
List<OverseerrContentRating>? results;
OverseerrContentRatings({
this.results,
});
@override
String toString() => json.encode(this.toJson());
factory OverseerrContentRatings.fromJson(Map<String, dynamic> json) =>
_$OverseerrContentRatingsFromJson(json);
Map<String, dynamic> toJson() => _$OverseerrContentRatingsToJson(this);
}
@JsonSerializable(explicitToJson: true, includeIfNull: false)
class OverseerrContentRating {
@JsonKey(name: 'iso_3166_1')
String? iso31661;
@JsonKey()
String? rating;
OverseerrContentRating({
this.iso31661,
this.rating,
});
@override
String toString() => json.encode(this.toJson());
factory OverseerrContentRating.fromJson(Map<String, dynamic> json) =>
_$OverseerrContentRatingFromJson(json);
Map<String, dynamic> toJson() => _$OverseerrContentRatingToJson(this);
}

View File

@@ -0,0 +1,37 @@
import 'package:lunasea/core.dart';
part 'created_by.g.dart';
@JsonSerializable(explicitToJson: true, includeIfNull: false)
class OverseerrCreatedBy {
@JsonKey()
int? id;
@JsonKey(name: 'credit_id')
String? creditId;
@JsonKey()
String? name;
@JsonKey()
int? gender;
@JsonKey(name: 'profile_path')
String? profilePath;
OverseerrCreatedBy({
this.id,
this.creditId,
this.name,
this.gender,
this.profilePath,
});
@override
String toString() => json.encode(this.toJson());
factory OverseerrCreatedBy.fromJson(Map<String, dynamic> json) =>
_$OverseerrCreatedByFromJson(json);
Map<String, dynamic> toJson() => _$OverseerrCreatedByToJson(this);
}

View File

@@ -0,0 +1,113 @@
import 'package:lunasea/core.dart';
part 'credits.g.dart';
@JsonSerializable(explicitToJson: true, includeIfNull: false)
class OverseerrCredits {
@JsonKey()
List<OverseerrCast>? cast;
@JsonKey()
List<OverseerrCrew>? crew;
OverseerrCredits({
this.cast,
this.crew,
});
@override
String toString() => json.encode(this.toJson());
factory OverseerrCredits.fromJson(Map<String, dynamic> json) =>
_$OverseerrCreditsFromJson(json);
Map<String, dynamic> toJson() => _$OverseerrCreditsToJson(this);
}
@JsonSerializable(explicitToJson: true, includeIfNull: false)
class OverseerrCast {
@JsonKey()
int? id;
@JsonKey()
int? castId;
@JsonKey()
String? character;
@JsonKey()
String? creditId;
@JsonKey()
int? gender;
@JsonKey()
String? name;
@JsonKey()
int? order;
@JsonKey()
String? profilePath;
OverseerrCast({
this.id,
this.castId,
this.character,
this.creditId,
this.gender,
this.name,
this.order,
this.profilePath,
});
@override
String toString() => json.encode(this.toJson());
factory OverseerrCast.fromJson(Map<String, dynamic> json) =>
_$OverseerrCastFromJson(json);
Map<String, dynamic> toJson() => _$OverseerrCastToJson(this);
}
@JsonSerializable(explicitToJson: true, includeIfNull: false)
class OverseerrCrew {
@JsonKey()
int? id;
@JsonKey()
String? creditId;
@JsonKey()
String? department;
@JsonKey()
int? gender;
@JsonKey()
String? job;
@JsonKey()
String? name;
@JsonKey()
String? profilePath;
OverseerrCrew({
this.id,
this.creditId,
this.department,
this.gender,
this.job,
this.name,
this.profilePath,
});
@override
String toString() => json.encode(this.toJson());
factory OverseerrCrew.fromJson(Map<String, dynamic> json) =>
_$OverseerrCrewFromJson(json);
Map<String, dynamic> toJson() => _$OverseerrCrewToJson(this);
}

View File

@@ -0,0 +1,53 @@
import 'package:lunasea/core.dart';
part 'episode.g.dart';
@JsonSerializable(explicitToJson: true, includeIfNull: false)
class OverseerrEpisode {
@JsonKey()
int? id;
@JsonKey()
String? airDate;
@JsonKey()
int? episodeNumber;
@JsonKey()
String? name;
@JsonKey()
String? overview;
@JsonKey()
String? productionCode;
@JsonKey()
int? seasonNumber;
@JsonKey()
double? voteAverage;
@JsonKey()
String? stillPath;
OverseerrEpisode({
this.id,
this.airDate,
this.episodeNumber,
this.name,
this.overview,
this.productionCode,
this.seasonNumber,
this.voteAverage,
this.stillPath,
});
@override
String toString() => json.encode(this.toJson());
factory OverseerrEpisode.fromJson(Map<String, dynamic> json) =>
_$OverseerrEpisodeFromJson(json);
Map<String, dynamic> toJson() => _$OverseerrEpisodeToJson(this);
}

View File

@@ -0,0 +1,49 @@
import 'package:lunasea/core.dart';
part 'external_ids.g.dart';
@JsonSerializable(explicitToJson: true, includeIfNull: false)
class OverseerrExternalIds {
@JsonKey()
String? imdbId;
@JsonKey()
String? freebaseMid;
@JsonKey()
String? freebaseId;
@JsonKey()
int? tvdbId;
@JsonKey()
int? tvrageId;
@JsonKey()
String? facebookId;
@JsonKey()
String? instagramId;
@JsonKey()
String? twitterId;
OverseerrExternalIds({
this.imdbId,
this.freebaseMid,
this.freebaseId,
this.tvdbId,
this.tvrageId,
this.facebookId,
this.instagramId,
this.twitterId,
});
@override
String toString() => json.encode(this.toJson());
factory OverseerrExternalIds.fromJson(Map<String, dynamic> json) =>
_$OverseerrExternalIdsFromJson(json);
Map<String, dynamic> toJson() => _$OverseerrExternalIdsToJson(this);
}

View File

@@ -0,0 +1,25 @@
import 'package:lunasea/core.dart';
part 'genre.g.dart';
@JsonSerializable(explicitToJson: true, includeIfNull: false)
class OverseerrGenre {
@JsonKey()
int? id;
@JsonKey()
String? name;
OverseerrGenre({
this.id,
this.name,
});
@override
String toString() => json.encode(this.toJson());
factory OverseerrGenre.fromJson(Map<String, dynamic> json) =>
_$OverseerrGenreFromJson(json);
Map<String, dynamic> toJson() => _$OverseerrGenreToJson(this);
}

View File

@@ -0,0 +1,25 @@
import 'package:lunasea/core.dart';
part 'keyword.g.dart';
@JsonSerializable(explicitToJson: true, includeIfNull: false)
class OverseerrKeyword {
@JsonKey()
int? id;
@JsonKey()
String? name;
OverseerrKeyword({
this.id,
this.name,
});
@override
String toString() => json.encode(this.toJson());
factory OverseerrKeyword.fromJson(Map<String, dynamic> json) =>
_$OverseerrKeywordFromJson(json);
Map<String, dynamic> toJson() => _$OverseerrKeywordToJson(this);
}

View File

@@ -0,0 +1,145 @@
import 'package:lunasea/core.dart';
import 'package:lunasea/modules/overseerr.dart';
part 'movie.g.dart';
@JsonSerializable(explicitToJson: true, includeIfNull: false)
class OverseerrMovie {
@JsonKey()
int? id;
@JsonKey()
String? imdbId;
@JsonKey()
bool? adult;
@JsonKey()
String? backdropPath;
@JsonKey()
int? budget;
@JsonKey()
List<OverseerrGenre>? genres;
@JsonKey()
String? homepage;
@JsonKey()
String? originalLanguage;
@JsonKey()
String? originalTitle;
@JsonKey()
String? overview;
@JsonKey()
double? popularity;
@JsonKey()
List<OverseerrRelatedVideo>? relatedVideos;
@JsonKey()
String? posterPath;
@JsonKey()
List<OverseerrProductionCompany>? productionCompanies;
@JsonKey()
List<OverseerrProductionCountry>? productionCountries;
@JsonKey()
String? releaseDate;
@JsonKey()
int? revenue;
@JsonKey()
int? runtime;
@JsonKey()
String? status;
@JsonKey()
String? tagline;
@JsonKey()
String? title;
@JsonKey()
bool? video;
@JsonKey()
double? voteAverage;
@JsonKey()
int? voteCount;
@JsonKey()
String? plexUrl;
@JsonKey()
OverseerrCollection? collection;
@JsonKey()
OverseerrExternalIds? externalIds;
@JsonKey()
OverseerrMedia? mediaInfo;
@JsonKey()
List<OverseerrWatchProvider>? watchProviders;
@JsonKey()
OverseerrCredits? credits;
@JsonKey()
List<OverseerrSpokenLanguage>? spokenLanguages;
@JsonKey()
OverseerrMovieReleases? releases;
OverseerrMovie({
this.id,
this.imdbId,
this.adult,
this.backdropPath,
this.budget,
this.genres,
this.homepage,
this.originalLanguage,
this.originalTitle,
this.overview,
this.popularity,
this.relatedVideos,
this.posterPath,
this.productionCompanies,
this.productionCountries,
this.releaseDate,
this.revenue,
this.runtime,
this.status,
this.tagline,
this.title,
this.video,
this.voteAverage,
this.voteCount,
this.plexUrl,
this.collection,
this.externalIds,
this.mediaInfo,
this.watchProviders,
this.credits,
this.spokenLanguages,
});
@override
String toString() => json.encode(this.toJson());
factory OverseerrMovie.fromJson(Map<String, dynamic> json) =>
_$OverseerrMovieFromJson(json);
Map<String, dynamic> toJson() => _$OverseerrMovieToJson(this);
}

View File

@@ -0,0 +1,78 @@
import 'package:lunasea/core.dart';
part 'movie_releases.g.dart';
@JsonSerializable(explicitToJson: true, includeIfNull: false)
class OverseerrMovieReleases {
@JsonKey()
List<OverseerrMovieReleaseResult>? results;
OverseerrMovieReleases({
this.results,
});
@override
String toString() => json.encode(this.toJson());
factory OverseerrMovieReleases.fromJson(Map<String, dynamic> json) =>
_$OverseerrMovieReleasesFromJson(json);
Map<String, dynamic> toJson() => _$OverseerrMovieReleasesToJson(this);
}
@JsonSerializable(explicitToJson: true, includeIfNull: false)
class OverseerrMovieReleaseResult {
@JsonKey(name: 'iso_3166_1')
String? iso31661;
@JsonKey(name: 'release_dates')
List<OverseerrMovieReleaseResultDate>? releaseDates;
OverseerrMovieReleaseResult({
this.iso31661,
this.releaseDates,
});
@override
String toString() => json.encode(this.toJson());
factory OverseerrMovieReleaseResult.fromJson(Map<String, dynamic> json) =>
_$OverseerrMovieReleaseResultFromJson(json);
Map<String, dynamic> toJson() => _$OverseerrMovieReleaseResultToJson(this);
}
@JsonSerializable(explicitToJson: true, includeIfNull: false)
class OverseerrMovieReleaseResultDate {
@JsonKey()
String? certification;
@JsonKey(name: 'iso_639_1')
String? iso6391;
@JsonKey()
String? note;
@JsonKey(name: 'release_date')
String? releaseDate;
@JsonKey()
int? type;
OverseerrMovieReleaseResultDate({
this.certification,
this.iso6391,
this.note,
this.releaseDate,
this.type,
});
@override
String toString() => json.encode(this.toJson());
factory OverseerrMovieReleaseResultDate.fromJson(Map<String, dynamic> json) =>
_$OverseerrMovieReleaseResultDateFromJson(json);
Map<String, dynamic> toJson() =>
_$OverseerrMovieReleaseResultDateToJson(this);
}

View File

@@ -0,0 +1,33 @@
import 'package:lunasea/core.dart';
part 'network.g.dart';
@JsonSerializable(explicitToJson: true, includeIfNull: false)
class OverseerrNetwork {
@JsonKey()
int? id;
@JsonKey()
String? name;
@JsonKey()
String? originCountry;
@JsonKey()
String? logoPath;
OverseerrNetwork({
this.id,
this.name,
this.originCountry,
this.logoPath,
});
@override
String toString() => json.encode(this.toJson());
factory OverseerrNetwork.fromJson(Map<String, dynamic> json) =>
_$OverseerrNetworkFromJson(json);
Map<String, dynamic> toJson() => _$OverseerrNetworkToJson(this);
}

View File

@@ -0,0 +1,45 @@
import 'package:lunasea/core.dart';
part 'production_company.g.dart';
@JsonSerializable(explicitToJson: true, includeIfNull: false)
class OverseerrProductionCompany {
@JsonKey()
int? id;
@JsonKey()
String? logoPath;
@JsonKey()
String? originCountry;
@JsonKey()
String? name;
@JsonKey()
String? description;
@JsonKey()
String? headquarters;
@JsonKey()
String? homepage;
OverseerrProductionCompany({
this.id,
this.logoPath,
this.originCountry,
this.name,
this.description,
this.headquarters,
this.homepage,
});
@override
String toString() => json.encode(this.toJson());
factory OverseerrProductionCompany.fromJson(Map<String, dynamic> json) =>
_$OverseerrProductionCompanyFromJson(json);
Map<String, dynamic> toJson() => _$OverseerrProductionCompanyToJson(this);
}

View File

@@ -0,0 +1,25 @@
import 'package:lunasea/core.dart';
part 'production_country.g.dart';
@JsonSerializable(explicitToJson: true, includeIfNull: false)
class OverseerrProductionCountry {
@JsonKey(name: 'iso_3166_1')
String? iso31661;
@JsonKey()
String? name;
OverseerrProductionCountry({
this.iso31661,
this.name,
});
@override
String toString() => json.encode(this.toJson());
factory OverseerrProductionCountry.fromJson(Map<String, dynamic> json) =>
_$OverseerrProductionCountryFromJson(json);
Map<String, dynamic> toJson() => _$OverseerrProductionCountryToJson(this);
}

View File

@@ -0,0 +1,41 @@
import 'package:lunasea/core.dart';
part 'related_video.g.dart';
@JsonSerializable(explicitToJson: true, includeIfNull: false)
class OverseerrRelatedVideo {
@JsonKey()
String? site;
@JsonKey()
String? key;
@JsonKey()
String? name;
@JsonKey()
int? size;
@JsonKey()
String? type;
@JsonKey()
String? url;
OverseerrRelatedVideo({
this.site,
this.key,
this.name,
this.size,
this.type,
this.url,
});
@override
String toString() => json.encode(this.toJson());
factory OverseerrRelatedVideo.fromJson(Map<String, dynamic> json) =>
_$OverseerrRelatedVideoFromJson(json);
Map<String, dynamic> toJson() => _$OverseerrRelatedVideoToJson(this);
}

View File

@@ -0,0 +1,45 @@
import 'package:lunasea/core.dart';
part 'season.g.dart';
@JsonSerializable(explicitToJson: true, includeIfNull: false)
class OverseerrSeason {
@JsonKey()
int? id;
@JsonKey()
String? airDate;
@JsonKey()
int? episodeCount;
@JsonKey()
String? name;
@JsonKey()
String? overview;
@JsonKey()
int? seasonNumber;
@JsonKey()
String? posterPath;
OverseerrSeason({
this.id,
this.airDate,
this.episodeCount,
this.name,
this.overview,
this.seasonNumber,
this.posterPath,
});
@override
String toString() => json.encode(this.toJson());
factory OverseerrSeason.fromJson(Map<String, dynamic> json) =>
_$OverseerrSeasonFromJson(json);
Map<String, dynamic> toJson() => _$OverseerrSeasonToJson(this);
}

View File

@@ -0,0 +1,167 @@
import 'package:lunasea/core.dart';
import 'package:lunasea/modules/overseerr.dart';
part 'series.g.dart';
@JsonSerializable(explicitToJson: true, includeIfNull: false)
class OverseerrSeries {
@JsonKey()
int? id;
@JsonKey()
List<OverseerrCreatedBy>? createdBy;
@JsonKey()
String? homepage;
@JsonKey()
String? name;
@JsonKey()
List<int>? episodeRunTime;
@JsonKey()
String? firstAirDate;
@JsonKey()
String? lastAirDate;
@JsonKey()
List<OverseerrGenre>? genres;
@JsonKey()
String? backdropPath;
@JsonKey()
String? posterPath;
@JsonKey()
bool? inProduction;
@JsonKey()
List<String>? languages;
@JsonKey()
int? numberOfEpisodes;
@JsonKey()
int? numberOfSeasons;
@JsonKey()
List<String>? originCountry;
@JsonKey()
String? originalLanguage;
@JsonKey()
String? originalName;
@JsonKey()
String? overview;
@JsonKey()
double? popularity;
@JsonKey()
List<OverseerrProductionCompany>? productionCompanies;
@JsonKey()
List<OverseerrProductionCountry>? productionCountries;
@JsonKey()
List<OverseerrSpokenLanguage>? spokenLanguages;
@JsonKey()
List<OverseerrRelatedVideo>? relatedVideos;
@JsonKey()
List<OverseerrNetwork>? networks;
@JsonKey()
String? status;
@JsonKey()
String? type;
@JsonKey()
double? voteAverage;
@JsonKey()
int? voteCount;
@JsonKey()
String? tagline;
@JsonKey()
OverseerrCredits? credits;
@JsonKey()
List<OverseerrWatchProvider>? watchProviders;
@JsonKey()
List<OverseerrKeyword>? keywords;
@JsonKey()
OverseerrExternalIds? externalIds;
@JsonKey()
OverseerrContentRatings? contentRatings;
@JsonKey()
List<OverseerrMediaSeason>? seasons;
@JsonKey()
OverseerrMedia? mediaInfo;
@JsonKey()
OverseerrEpisode? lastEpisodeToAir;
@JsonKey()
OverseerrEpisode? nextEpisodeToAir;
OverseerrSeries({
this.id,
this.createdBy,
this.homepage,
this.name,
this.episodeRunTime,
this.firstAirDate,
this.lastAirDate,
this.genres,
this.backdropPath,
this.posterPath,
this.inProduction,
this.languages,
this.numberOfEpisodes,
this.numberOfSeasons,
this.originCountry,
this.originalLanguage,
this.originalName,
this.overview,
this.popularity,
this.productionCompanies,
this.productionCountries,
this.relatedVideos,
this.spokenLanguages,
this.networks,
this.status,
this.type,
this.voteAverage,
this.voteCount,
this.tagline,
this.credits,
this.watchProviders,
this.keywords,
this.externalIds,
this.seasons,
this.mediaInfo,
});
@override
String toString() => json.encode(this.toJson());
factory OverseerrSeries.fromJson(Map<String, dynamic> json) =>
_$OverseerrSeriesFromJson(json);
Map<String, dynamic> toJson() => _$OverseerrSeriesToJson(this);
}

View File

@@ -0,0 +1,33 @@
import 'package:lunasea/core.dart';
part 'spoken_language.g.dart';
@JsonSerializable(explicitToJson: true, includeIfNull: false)
class OverseerrSpokenLanguage {
@JsonKey()
String? englishName;
@JsonKey(name: 'english_name')
String? englishNameSecondary;
@JsonKey(name: 'iso_639_1')
String? iso6391;
@JsonKey()
String? name;
OverseerrSpokenLanguage({
this.englishName,
this.englishNameSecondary,
this.iso6391,
this.name,
});
@override
String toString() => json.encode(this.toJson());
factory OverseerrSpokenLanguage.fromJson(Map<String, dynamic> json) =>
_$OverseerrSpokenLanguageFromJson(json);
Map<String, dynamic> toJson() => _$OverseerrSpokenLanguageToJson(this);
}

View File

@@ -0,0 +1,63 @@
import 'package:lunasea/core.dart';
part 'watch_provider.g.dart';
@JsonSerializable(explicitToJson: true, includeIfNull: false)
class OverseerrWatchProvider {
@JsonKey(name: 'iso_3166_1')
String? iso31661;
@JsonKey()
String? link;
@JsonKey()
List<OverseerrWatchProviderDetails>? buy;
@JsonKey()
List<OverseerrWatchProviderDetails>? flatrate;
OverseerrWatchProvider({
this.iso31661,
this.link,
this.buy,
this.flatrate,
});
@override
String toString() => json.encode(this.toJson());
factory OverseerrWatchProvider.fromJson(Map<String, dynamic> json) =>
_$OverseerrWatchProviderFromJson(json);
Map<String, dynamic> toJson() => _$OverseerrWatchProviderToJson(this);
}
@JsonSerializable(explicitToJson: true, includeIfNull: false)
class OverseerrWatchProviderDetails {
@JsonKey()
int? id;
@JsonKey()
String? name;
@JsonKey()
int? displayPriority;
@JsonKey()
String? logoPath;
OverseerrWatchProviderDetails({
this.id,
this.name,
this.displayPriority,
this.logoPath,
});
@override
String toString() => json.encode(this.toJson());
factory OverseerrWatchProviderDetails.fromJson(Map<String, dynamic> json) =>
_$OverseerrWatchProviderDetailsFromJson(json);
Map<String, dynamic> toJson() => _$OverseerrWatchProviderDetailsToJson(this);
}

View File

@@ -5,95 +5,91 @@ part 'media.g.dart';
@JsonSerializable(explicitToJson: true, includeIfNull: false)
class OverseerrMedia {
@JsonKey(name: 'id')
@JsonKey()
int? id;
@JsonKey(
name: 'mediaType',
fromJson: OverseerrUtilities.mediaTypeFromJson,
toJson: OverseerrUtilities.mediaTypeToJson,
)
OverseerrMediaType? mediaType;
@JsonKey(name: 'tmdbId')
@JsonKey()
int? tmdbId;
@JsonKey(name: 'tvdbId')
@JsonKey()
int? tvdbId;
@JsonKey(name: 'imdbId')
@JsonKey()
String? imdbId;
@JsonKey(
name: 'status',
fromJson: OverseerrUtilities.requestStatusFromJson,
toJson: OverseerrUtilities.requestStatusToJson,
fromJson: OverseerrUtilities.mediaStatusFromJson,
toJson: OverseerrUtilities.mediaStatusToJson,
)
OverseerrRequestStatus? status;
OverseerrMediaStatus? status;
@JsonKey(
name: 'status4k',
fromJson: OverseerrUtilities.requestStatusFromJson,
toJson: OverseerrUtilities.requestStatusToJson,
fromJson: OverseerrUtilities.mediaStatusFromJson,
toJson: OverseerrUtilities.mediaStatusToJson,
)
OverseerrRequestStatus? status4k;
OverseerrMediaStatus? status4k;
@JsonKey(
name: 'createdAt',
fromJson: OverseerrUtilities.dateTimeFromJson,
toJson: OverseerrUtilities.dateTimeToJson,
)
DateTime? createdAt;
@JsonKey(
name: 'updatedAt',
fromJson: OverseerrUtilities.dateTimeFromJson,
toJson: OverseerrUtilities.dateTimeToJson,
)
DateTime? updatedAt;
@JsonKey(
name: 'lastSeasonChange',
fromJson: OverseerrUtilities.dateTimeFromJson,
toJson: OverseerrUtilities.dateTimeToJson,
)
DateTime? lastSeasonChange;
@JsonKey(
name: 'mediaAddedAt',
fromJson: OverseerrUtilities.dateTimeFromJson,
toJson: OverseerrUtilities.dateTimeToJson,
)
DateTime? mediaAddedAt;
@JsonKey(name: 'serviceId')
@JsonKey()
int? serviceId;
@JsonKey(name: 'serviceId4k')
@JsonKey()
int? serviceId4k;
@JsonKey(name: 'externalServiceId')
@JsonKey()
int? externalServiceId;
@JsonKey(name: 'externalServiceId4k')
@JsonKey()
int? externalServiceId4k;
@JsonKey(name: 'externalServiceSlug')
@JsonKey()
String? externalServiceSlug;
@JsonKey(name: 'externalServiceSlug4k')
@JsonKey()
String? externalServiceSlug4k;
@JsonKey(name: 'ratingKey')
@JsonKey()
String? ratingKey;
@JsonKey(name: 'ratingKey4k')
@JsonKey()
String? ratingKey4k;
@JsonKey(name: 'plexUrl')
@JsonKey()
List<OverseerrSeason>? seasons;
@JsonKey()
String? plexUrl;
@JsonKey(name: 'serviceUrl')
@JsonKey()
String? serviceUrl;
OverseerrMedia({
@@ -116,6 +112,7 @@ class OverseerrMedia {
this.externalServiceSlug4k,
this.ratingKey,
this.ratingKey4k,
this.seasons,
this.plexUrl,
this.serviceUrl,
});

View File

@@ -4,7 +4,7 @@ import 'package:lunasea/modules/overseerr.dart';
part 'season.g.dart';
@JsonSerializable(explicitToJson: true, includeIfNull: false)
class OverseerrSeason {
class OverseerrMediaSeason {
@JsonKey(name: 'id')
int? id;
@@ -18,6 +18,13 @@ class OverseerrSeason {
)
OverseerrRequestStatus? status;
@JsonKey(
name: 'status4k',
fromJson: OverseerrUtilities.requestStatusFromJson,
toJson: OverseerrUtilities.requestStatusToJson,
)
OverseerrRequestStatus? status4k;
@JsonKey(
name: 'createdAt',
fromJson: OverseerrUtilities.dateTimeFromJson,
@@ -32,10 +39,11 @@ class OverseerrSeason {
)
DateTime? updatedAt;
OverseerrSeason({
OverseerrMediaSeason({
this.id,
this.seasonNumber,
this.status,
this.status4k,
this.createdAt,
this.updatedAt,
});
@@ -44,10 +52,10 @@ class OverseerrSeason {
@override
String toString() => json.encode(this.toJson());
/// Deserialize a JSON map to a [OverseerrSeason] object.
factory OverseerrSeason.fromJson(Map<String, dynamic> json) =>
_$OverseerrSeasonFromJson(json);
/// Deserialize a JSON map to a [OverseerrMediaSeason] object.
factory OverseerrMediaSeason.fromJson(Map<String, dynamic> json) =>
_$OverseerrMediaSeasonFromJson(json);
/// Serialize a [OverseerrSeason] object to a JSON map.
Map<String, dynamic> toJson() => _$OverseerrSeasonToJson(this);
/// Serialize a [OverseerrMediaSeason] object to a JSON map.
Map<String, dynamic> toJson() => _$OverseerrMediaSeasonToJson(this);
}

View File

@@ -63,6 +63,9 @@ class OverseerrRequest {
@JsonKey(name: 'modifiedBy')
OverseerrUser? modifiedBy;
@JsonKey(name: 'seasons')
List<OverseerrSeason>? seasons;
@JsonKey(name: 'seasonCount')
int? seasonCount;
@@ -81,6 +84,7 @@ class OverseerrRequest {
this.media,
this.requestedBy,
this.modifiedBy,
this.seasons,
this.seasonCount,
});

View File

@@ -14,6 +14,9 @@ class OverseerrUser {
@JsonKey(name: 'email')
String? email;
@JsonKey(name: 'plexId')
int? plexId;
@JsonKey(name: 'plexUsername')
String? plexUsername;
@@ -65,6 +68,7 @@ class OverseerrUser {
this.permissions,
this.id,
this.email,
this.plexId,
this.plexUsername,
this.username,
this.recoveryLinkExpirationDate,

View File

@@ -25,6 +25,12 @@ abstract class Overseerr {
return _Overseerr(_dio, baseUrl: _baseUrl);
}
@GET('movie/{id}')
Future<OverseerrMovie> getMovie({
@Path('id') required int id,
@Query('language') String? language,
});
@GET('request')
Future<OverseerrRequestPage> getRequests({
@Query('take') int? take,
@@ -48,6 +54,12 @@ abstract class Overseerr {
@GET('status/appdata')
Future<OverseerrStatusAppData> getStatusAppData();
@GET('tv/{id}')
Future<OverseerrSeries> getSeries({
@Path('id') required int id,
@Query('language') String? language,
});
@GET('user')
Future<OverseerrUserPage> getUsers({
@Query('take') int? take,

View File

@@ -2,7 +2,7 @@ import 'package:flutter/material.dart';
import 'package:lunasea/core.dart';
import 'package:lunasea/modules/overseerr.dart';
class OverseerrRequestTile extends StatelessWidget {
class OverseerrRequestTile extends StatefulWidget {
final OverseerrRequest request;
const OverseerrRequestTile({
@@ -10,18 +10,81 @@ class OverseerrRequestTile extends StatelessWidget {
required this.request,
}) : super(key: key);
@override
State<StatefulWidget> createState() => _State();
}
class _State extends State<OverseerrRequestTile> with LunaLoadCallbackMixin {
OverseerrMovie? _movie;
OverseerrSeries? _series;
@override
Future<void> loadCallback() async {
// Temporary, for testing purposes
if (widget.request.type == OverseerrMediaType.MOVIE) {
OverseerrMovie movie = await context
.read<OverseerrState>()
.api!
.getMovie(id: widget.request.media!.tmdbId!);
if (mounted) setState(() => _movie = movie);
}
if (widget.request.type == OverseerrMediaType.TV) {
OverseerrSeries series = await context
.read<OverseerrState>()
.api!
.getSeries(id: widget.request.media!.tmdbId!);
if (mounted) setState(() => _series = series);
}
}
@override
Widget build(BuildContext context) {
return LunaBlock(
title: request.requestedBy!.displayName ?? 'overseerr.UnknownUser'.tr(),
body: const [
TextSpan(text: 'Placeholder 1'),
TextSpan(text: 'Placeholder 2'),
],
posterPlaceholderIcon: LunaIcons.USER,
posterHeaders: context.read<OverseerrState>().headers,
posterUrl: request.requestedBy!.avatar,
posterIsSquare: true,
);
// Temporary, for testing purposes
if (_movie != null) {
return LunaBlock(
title: _movie!.title ?? 'lunasea.Unknown'.tr(),
body: [
const TextSpan(text: 'Placeholder 1'),
TextSpan(
text: 'Requested by ${widget.request.requestedBy?.displayName}',
style: const TextStyle(
fontWeight: LunaUI.FONT_WEIGHT_BOLD,
color: LunaColours.accent,
)),
],
posterHeaders: context.read<OverseerrState>().headers,
posterUrl: TheMovieDB.getImageURL(_movie!.posterPath),
posterPlaceholderIcon: LunaIcons.VIDEO_CAM,
);
} else if (_series != null) {
return LunaBlock(
title: _series!.name ?? 'lunasea.Unknown'.tr(),
body: [
const TextSpan(text: 'Placeholder 1'),
TextSpan(
text: 'Requested by ${widget.request.requestedBy?.displayName}',
style: const TextStyle(
fontWeight: LunaUI.FONT_WEIGHT_BOLD,
color: LunaColours.accent,
)),
],
posterHeaders: context.read<OverseerrState>().headers,
posterUrl: TheMovieDB.getImageURL(_series!.posterPath),
posterPlaceholderIcon: LunaIcons.VIDEO_CAM,
);
} else {
return LunaBlock(
title: widget.request.requestedBy!.displayName ??
'overseerr.UnknownUser'.tr(),
body: const [
TextSpan(text: 'Placeholder 1'),
TextSpan(text: 'Placeholder 2'),
],
posterPlaceholderIcon: LunaIcons.USER,
posterHeaders: context.read<OverseerrState>().headers,
posterUrl: widget.request.requestedBy!.avatar,
);
}
}
}

View File

@@ -204,7 +204,7 @@
"settings.SystemStatus": "System Status",
"settings.SystemStatusDescription": "Status Page for Hosted Services",
"settings.TestBuilds": "Test Builds",
"settings.TestBuildsDescription": "Install Pre-Release Builds of LunaSea",
"settings.TestBuildsDescription": "Install Prerelease Builds of LunaSea",
"settings.TestConnection": "Test Connection",
"settings.TLSCertificateValidation": "TLS Certificate Validation",
"settings.TLSCertificateValidationDescription": "Validate Certificates in TLS Connections",