mirror of
https://github.com/gabehf/Fladder.git
synced 2026-03-07 21:48:14 -08:00
feature: Add guest actors to episode view (#299)
Co-authored-by: PartyDonut <PartyDonut@users.noreply.github.com>
This commit is contained in:
parent
71eab225f9
commit
7a50e0cb0f
7 changed files with 55 additions and 7 deletions
|
|
@ -1184,5 +1184,16 @@
|
||||||
"segmentActionNone": "None",
|
"segmentActionNone": "None",
|
||||||
"segmentActionAskToSkip": "Ask to skip",
|
"segmentActionAskToSkip": "Ask to skip",
|
||||||
"segmentActionSkip": "Skip",
|
"segmentActionSkip": "Skip",
|
||||||
"loading": "Loading"
|
"loading": "Loading",
|
||||||
|
"castAndCrew": "Cast & Crew",
|
||||||
|
"guestActor": "{count, plural, other{Guest Actors} one{Guest Actor}}",
|
||||||
|
"@guestActor": {
|
||||||
|
"description": "Guest actors",
|
||||||
|
"placeholders": {
|
||||||
|
"count": {
|
||||||
|
"type": "int",
|
||||||
|
"example": "1"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -4,6 +4,7 @@ import 'package:flutter_riverpod/flutter_riverpod.dart';
|
||||||
|
|
||||||
import 'package:fladder/models/item_base_model.dart';
|
import 'package:fladder/models/item_base_model.dart';
|
||||||
import 'package:fladder/models/items/episode_model.dart';
|
import 'package:fladder/models/items/episode_model.dart';
|
||||||
|
import 'package:fladder/models/items/item_shared_models.dart';
|
||||||
import 'package:fladder/models/items/series_model.dart';
|
import 'package:fladder/models/items/series_model.dart';
|
||||||
import 'package:fladder/providers/api_provider.dart';
|
import 'package:fladder/providers/api_provider.dart';
|
||||||
import 'package:fladder/providers/service_provider.dart';
|
import 'package:fladder/providers/service_provider.dart';
|
||||||
|
|
@ -13,21 +14,25 @@ class EpisodeDetailModel {
|
||||||
final SeriesModel? series;
|
final SeriesModel? series;
|
||||||
final List<EpisodeModel> episodes;
|
final List<EpisodeModel> episodes;
|
||||||
final EpisodeModel? episode;
|
final EpisodeModel? episode;
|
||||||
|
final List<Person> guestActors;
|
||||||
EpisodeDetailModel({
|
EpisodeDetailModel({
|
||||||
this.series,
|
this.series,
|
||||||
this.episodes = const [],
|
this.episodes = const [],
|
||||||
this.episode,
|
this.episode,
|
||||||
|
this.guestActors = const [],
|
||||||
});
|
});
|
||||||
|
|
||||||
EpisodeDetailModel copyWith({
|
EpisodeDetailModel copyWith({
|
||||||
SeriesModel? series,
|
SeriesModel? series,
|
||||||
List<EpisodeModel>? episodes,
|
List<EpisodeModel>? episodes,
|
||||||
EpisodeModel? episode,
|
EpisodeModel? episode,
|
||||||
|
List<Person>? guestActors,
|
||||||
}) {
|
}) {
|
||||||
return EpisodeDetailModel(
|
return EpisodeDetailModel(
|
||||||
series: series ?? this.series,
|
series: series ?? this.series,
|
||||||
episodes: episodes ?? this.episodes,
|
episodes: episodes ?? this.episodes,
|
||||||
episode: episode ?? this.episode,
|
episode: episode ?? this.episode,
|
||||||
|
guestActors: guestActors ?? this.guestActors,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -17,11 +17,13 @@ import 'package:fladder/screens/shared/media/components/media_play_button.dart';
|
||||||
import 'package:fladder/screens/shared/media/episode_posters.dart';
|
import 'package:fladder/screens/shared/media/episode_posters.dart';
|
||||||
import 'package:fladder/screens/shared/media/expanding_overview.dart';
|
import 'package:fladder/screens/shared/media/expanding_overview.dart';
|
||||||
import 'package:fladder/screens/shared/media/external_urls.dart';
|
import 'package:fladder/screens/shared/media/external_urls.dart';
|
||||||
|
import 'package:fladder/screens/shared/media/people_row.dart';
|
||||||
import 'package:fladder/util/adaptive_layout.dart';
|
import 'package:fladder/util/adaptive_layout.dart';
|
||||||
import 'package:fladder/util/item_base_model/item_base_model_extensions.dart';
|
import 'package:fladder/util/item_base_model/item_base_model_extensions.dart';
|
||||||
import 'package:fladder/util/item_base_model/play_item_helpers.dart';
|
import 'package:fladder/util/item_base_model/play_item_helpers.dart';
|
||||||
import 'package:fladder/util/list_padding.dart';
|
import 'package:fladder/util/list_padding.dart';
|
||||||
import 'package:fladder/util/localization_helper.dart';
|
import 'package:fladder/util/localization_helper.dart';
|
||||||
|
import 'package:fladder/util/people_extension.dart';
|
||||||
import 'package:fladder/util/router_extension.dart';
|
import 'package:fladder/util/router_extension.dart';
|
||||||
import 'package:fladder/util/widget_extensions.dart';
|
import 'package:fladder/util/widget_extensions.dart';
|
||||||
import 'package:fladder/widgets/shared/selectable_icon_button.dart';
|
import 'package:fladder/widgets/shared/selectable_icon_button.dart';
|
||||||
|
|
@ -46,6 +48,8 @@ class _ItemDetailScreenState extends ConsumerState<EpisodeDetailScreen> {
|
||||||
final wrapAlignment =
|
final wrapAlignment =
|
||||||
AdaptiveLayout.viewSizeOf(context) != ViewSize.phone ? WrapAlignment.start : WrapAlignment.center;
|
AdaptiveLayout.viewSizeOf(context) != ViewSize.phone ? WrapAlignment.start : WrapAlignment.center;
|
||||||
|
|
||||||
|
final actors = details.episode?.overview.people ?? [];
|
||||||
|
|
||||||
return DetailScaffold(
|
return DetailScaffold(
|
||||||
label: widget.item.name,
|
label: widget.item.name,
|
||||||
item: details.episode,
|
item: details.episode,
|
||||||
|
|
@ -155,6 +159,16 @@ class _ItemDetailScreenState extends ConsumerState<EpisodeDetailScreen> {
|
||||||
ref.read(providerInstance.notifier).fetchDetails(widget.item);
|
ref.read(providerInstance.notifier).fetchDetails(widget.item);
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
|
if (actors.mainCast.isNotEmpty == true)
|
||||||
|
PeopleRow(
|
||||||
|
people: actors.mainCast,
|
||||||
|
contentPadding: padding,
|
||||||
|
),
|
||||||
|
if (actors.guestActors.isNotEmpty == true)
|
||||||
|
PeopleRow(
|
||||||
|
people: actors.guestActors,
|
||||||
|
contentPadding: padding,
|
||||||
|
),
|
||||||
if (details.episodes.length > 1)
|
if (details.episodes.length > 1)
|
||||||
EpisodePosters(
|
EpisodePosters(
|
||||||
contentPadding: padding,
|
contentPadding: padding,
|
||||||
|
|
|
||||||
|
|
@ -17,6 +17,7 @@ import 'package:fladder/screens/shared/media/person_list_.dart';
|
||||||
import 'package:fladder/util/item_base_model/item_base_model_extensions.dart';
|
import 'package:fladder/util/item_base_model/item_base_model_extensions.dart';
|
||||||
import 'package:fladder/util/list_padding.dart';
|
import 'package:fladder/util/list_padding.dart';
|
||||||
import 'package:fladder/util/localization_helper.dart';
|
import 'package:fladder/util/localization_helper.dart';
|
||||||
|
import 'package:fladder/util/people_extension.dart';
|
||||||
import 'package:fladder/util/string_extensions.dart';
|
import 'package:fladder/util/string_extensions.dart';
|
||||||
import 'package:fladder/util/theme_extensions.dart';
|
import 'package:fladder/util/theme_extensions.dart';
|
||||||
import 'package:fladder/util/widget_extensions.dart';
|
import 'package:fladder/util/widget_extensions.dart';
|
||||||
|
|
@ -154,9 +155,14 @@ class _SeasonDetailScreenState extends ConsumerState<SeasonDetailScreen> {
|
||||||
episodes: details.episodes,
|
episodes: details.episodes,
|
||||||
padding: padding,
|
padding: padding,
|
||||||
),
|
),
|
||||||
if (details.overview.people.isNotEmpty)
|
if (details.overview.people.mainCast.isNotEmpty)
|
||||||
PeopleRow(
|
PeopleRow(
|
||||||
people: details.overview.people,
|
people: details.overview.people.mainCast,
|
||||||
|
contentPadding: padding,
|
||||||
|
),
|
||||||
|
if (details.overview.people.guestActors.isNotEmpty)
|
||||||
|
PeopleRow(
|
||||||
|
people: details.overview.people.guestActors,
|
||||||
contentPadding: padding,
|
contentPadding: padding,
|
||||||
),
|
),
|
||||||
if (details.overview.externalUrls?.isNotEmpty == true)
|
if (details.overview.externalUrls?.isNotEmpty == true)
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,3 @@
|
||||||
import 'package:fladder/models/settings/home_settings_model.dart';
|
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
|
|
||||||
import 'package:auto_route/auto_route.dart';
|
import 'package:auto_route/auto_route.dart';
|
||||||
|
|
@ -7,6 +6,7 @@ import 'package:flutter_riverpod/flutter_riverpod.dart';
|
||||||
|
|
||||||
import 'package:fladder/models/item_base_model.dart';
|
import 'package:fladder/models/item_base_model.dart';
|
||||||
import 'package:fladder/models/items/series_model.dart';
|
import 'package:fladder/models/items/series_model.dart';
|
||||||
|
import 'package:fladder/models/settings/home_settings_model.dart';
|
||||||
import 'package:fladder/providers/items/series_details_provider.dart';
|
import 'package:fladder/providers/items/series_details_provider.dart';
|
||||||
import 'package:fladder/providers/user_provider.dart';
|
import 'package:fladder/providers/user_provider.dart';
|
||||||
import 'package:fladder/screens/details_screens/components/overview_header.dart';
|
import 'package:fladder/screens/details_screens/components/overview_header.dart';
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,9 @@
|
||||||
|
import 'package:flutter/material.dart';
|
||||||
|
|
||||||
import 'package:animations/animations.dart';
|
import 'package:animations/animations.dart';
|
||||||
|
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
||||||
|
|
||||||
|
import 'package:fladder/jellyfin/jellyfin_open_api.enums.swagger.dart';
|
||||||
import 'package:fladder/models/items/item_shared_models.dart';
|
import 'package:fladder/models/items/item_shared_models.dart';
|
||||||
import 'package:fladder/screens/details_screens/person_detail_screen.dart';
|
import 'package:fladder/screens/details_screens/person_detail_screen.dart';
|
||||||
import 'package:fladder/screens/shared/flat_button.dart';
|
import 'package:fladder/screens/shared/flat_button.dart';
|
||||||
|
|
@ -8,8 +13,6 @@ import 'package:fladder/util/localization_helper.dart';
|
||||||
import 'package:fladder/util/string_extensions.dart';
|
import 'package:fladder/util/string_extensions.dart';
|
||||||
import 'package:fladder/widgets/shared/clickable_text.dart';
|
import 'package:fladder/widgets/shared/clickable_text.dart';
|
||||||
import 'package:fladder/widgets/shared/horizontal_list.dart';
|
import 'package:fladder/widgets/shared/horizontal_list.dart';
|
||||||
import 'package:flutter/material.dart';
|
|
||||||
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
|
||||||
|
|
||||||
class PeopleRow extends ConsumerWidget {
|
class PeopleRow extends ConsumerWidget {
|
||||||
final List<Person> people;
|
final List<Person> people;
|
||||||
|
|
@ -36,7 +39,9 @@ class PeopleRow extends ConsumerWidget {
|
||||||
}
|
}
|
||||||
|
|
||||||
return HorizontalList(
|
return HorizontalList(
|
||||||
label: context.localized.actor(people.length),
|
label: people.any((e) => e.type != PersonKind.gueststar)
|
||||||
|
? context.localized.castAndCrew
|
||||||
|
: context.localized.guestActor(people.length),
|
||||||
height: AdaptiveLayout.poster(context).size * 0.9,
|
height: AdaptiveLayout.poster(context).size * 0.9,
|
||||||
contentPadding: contentPadding,
|
contentPadding: contentPadding,
|
||||||
items: people,
|
items: people,
|
||||||
|
|
|
||||||
7
lib/util/people_extension.dart
Normal file
7
lib/util/people_extension.dart
Normal file
|
|
@ -0,0 +1,7 @@
|
||||||
|
import 'package:fladder/jellyfin/jellyfin_open_api.enums.swagger.dart';
|
||||||
|
import 'package:fladder/models/items/item_shared_models.dart';
|
||||||
|
|
||||||
|
extension PeopleExtension on List<Person> {
|
||||||
|
List<Person> get guestActors => where((person) => person.type == PersonKind.gueststar).toList();
|
||||||
|
List<Person> get mainCast => where((person) => person.type != PersonKind.gueststar).toList();
|
||||||
|
}
|
||||||
Loading…
Add table
Add a link
Reference in a new issue