mirror of
https://github.com/jellyfin/jellyfin.git
synced 2026-07-19 20:54:20 +01:00
Merge pull request #17280 from Shadowghost/remove-image-override-hack
Remove episode image override hack
This commit is contained in:
@@ -1385,38 +1385,22 @@ namespace Emby.Server.Implementations.Dto
|
||||
}
|
||||
}
|
||||
|
||||
if (options.PreferEpisodeParentPoster)
|
||||
if (options.GetImageLimit(ImageType.Primary) > 0)
|
||||
{
|
||||
var episodeSeason = episode.Season;
|
||||
var seasonPrimaryTag = episodeSeason is not null
|
||||
? GetTagAndFillBlurhash(dto, episodeSeason, ImageType.Primary)
|
||||
: null;
|
||||
|
||||
BaseItem? posterParent = null;
|
||||
if (seasonPrimaryTag is not null)
|
||||
{
|
||||
dto.ParentPrimaryImageItemId = episodeSeason!.Id;
|
||||
dto.ParentPrimaryImageTag = seasonPrimaryTag;
|
||||
posterParent = episodeSeason;
|
||||
}
|
||||
else if (episodeSeries is not null && dto.SeriesPrimaryImageTag is not null)
|
||||
{
|
||||
dto.ParentPrimaryImageItemId = episodeSeries.Id;
|
||||
dto.ParentPrimaryImageTag = dto.SeriesPrimaryImageTag;
|
||||
posterParent = episodeSeries;
|
||||
}
|
||||
|
||||
if (posterParent is not null)
|
||||
{
|
||||
if (dto.ImageTags is not null && dto.ImageTags.Remove(ImageType.Primary, out var ownPrimaryTag))
|
||||
{
|
||||
// Only drop the episode's own primary blurhash; keep the poster parent's.
|
||||
dto.ImageBlurHashes?.GetValueOrDefault(ImageType.Primary)?.Remove(ownPrimaryTag);
|
||||
}
|
||||
|
||||
dto.SeriesPrimaryImageTag = null;
|
||||
dto.PrimaryImageAspectRatio = null;
|
||||
AttachPrimaryImageAspectRatio(dto, posterParent);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -551,8 +551,6 @@ public class UserLibraryController : BaseJellyfinApiController
|
||||
var dtoOptions = new DtoOptions { Fields = fields }
|
||||
.AddAdditionalDtoOptions(enableImages, enableUserData, imageTypeLimit, enableImageTypes);
|
||||
|
||||
dtoOptions.PreferEpisodeParentPoster = true;
|
||||
|
||||
var list = _userViewManager.GetLatestItems(
|
||||
new LatestItemsQuery
|
||||
{
|
||||
|
||||
@@ -81,13 +81,6 @@ namespace MediaBrowser.Controller.Dto
|
||||
/// </summary>
|
||||
public bool AddCurrentProgram { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets a value indicating whether an episode's portrait poster (its season's primary
|
||||
/// image, falling back to the series') should replace the episode's own (16:9) primary image.
|
||||
/// Used by views that render episodes as poster cards, e.g. "Latest".
|
||||
/// </summary>
|
||||
public bool PreferEpisodeParentPoster { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets a value indicating whether the specified field is populated.
|
||||
/// </summary>
|
||||
|
||||
@@ -11,6 +11,7 @@ using MediaBrowser.Controller.LiveTv;
|
||||
using MediaBrowser.Controller.Providers;
|
||||
using MediaBrowser.Controller.Trickplay;
|
||||
using MediaBrowser.Model.Entities;
|
||||
using MediaBrowser.Model.Querying;
|
||||
using Microsoft.Extensions.Logging.Abstractions;
|
||||
using Moq;
|
||||
using Xunit;
|
||||
@@ -56,57 +57,63 @@ public class DtoServiceTests
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void GetBaseItemDto_PreferEpisodeParentPoster_PrefersSeasonPosterOverEpisodeAndSeries()
|
||||
public void GetBaseItemDto_Episode_AttachesSeasonPosterAsParentPrimaryImage()
|
||||
{
|
||||
var (episode, season, series) = BuildEpisode(seasonHasPoster: true);
|
||||
var options = new DtoOptions(false) { PreferEpisodeParentPoster = true };
|
||||
var (episode, season, _) = BuildEpisode(seasonHasPoster: true);
|
||||
var options = new DtoOptions(false) { Fields = [ItemFields.PrimaryImageAspectRatio] };
|
||||
|
||||
var dto = _dtoService.GetBaseItemDto(episode, options);
|
||||
|
||||
// The episode's own 16:9 primary is dropped in favor of the season's portrait poster.
|
||||
Assert.False(dto.ImageTags is not null && dto.ImageTags.ContainsKey(ImageType.Primary));
|
||||
Assert.Null(dto.SeriesPrimaryImageTag);
|
||||
// The season poster is attached additively; the episode keeps its own primary and 16:9 ratio,
|
||||
// and clients decide per view whether to prefer the parent/series poster over the episode still.
|
||||
Assert.NotNull(dto.ImageTags);
|
||||
Assert.True(dto.ImageTags.ContainsKey(ImageType.Primary));
|
||||
Assert.NotNull(dto.SeriesPrimaryImageTag);
|
||||
Assert.Equal(season.Id, dto.ParentPrimaryImageItemId);
|
||||
Assert.Equal("tag:" + season.GetImageInfo(ImageType.Primary, 0)!.Path, dto.ParentPrimaryImageTag);
|
||||
// Aspect ratio follows the (portrait) poster, not the episode's 16:9 image.
|
||||
Assert.Equal(season.GetDefaultPrimaryImageAspectRatio(), dto.PrimaryImageAspectRatio);
|
||||
// Aspect ratio stays the episode's own image, not the poster's.
|
||||
Assert.Equal(episode.GetDefaultPrimaryImageAspectRatio(), dto.PrimaryImageAspectRatio);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void GetBaseItemDto_PreferEpisodeParentPoster_FallsBackToSeriesWhenSeasonHasNoPoster()
|
||||
public void GetBaseItemDto_Episode_ParentPrimaryImageFallsBackToSeriesWhenSeasonHasNoPoster()
|
||||
{
|
||||
var (episode, _, series) = BuildEpisode(seasonHasPoster: false);
|
||||
var options = new DtoOptions(false) { PreferEpisodeParentPoster = true };
|
||||
var options = new DtoOptions(false);
|
||||
|
||||
var dto = _dtoService.GetBaseItemDto(episode, options);
|
||||
|
||||
Assert.False(dto.ImageTags is not null && dto.ImageTags.ContainsKey(ImageType.Primary));
|
||||
Assert.Null(dto.SeriesPrimaryImageTag);
|
||||
// Episode image is retained; ParentPrimaryImage falls back to the series poster.
|
||||
Assert.NotNull(dto.ImageTags);
|
||||
Assert.True(dto.ImageTags.ContainsKey(ImageType.Primary));
|
||||
Assert.NotNull(dto.SeriesPrimaryImageTag);
|
||||
Assert.Equal(series.Id, dto.ParentPrimaryImageItemId);
|
||||
Assert.Equal("tag:" + series.GetImageInfo(ImageType.Primary, 0)!.Path, dto.ParentPrimaryImageTag);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void GetBaseItemDto_WithoutPreferEpisodeParentPoster_KeepsEpisodePrimary()
|
||||
public void GetBaseItemDto_Episode_WithoutParentPosters_KeepsOnlyEpisodePrimary()
|
||||
{
|
||||
var (episode, _, _) = BuildEpisode(seasonHasPoster: true);
|
||||
var (episode, _, _) = BuildEpisode(seasonHasPoster: false, seriesHasPoster: false);
|
||||
var options = new DtoOptions(false);
|
||||
|
||||
var dto = _dtoService.GetBaseItemDto(episode, options);
|
||||
|
||||
// Default behavior: the episode keeps its own primary and exposes the series poster as a tag.
|
||||
// With no season or series poster there is nothing to attach; the episode keeps its own primary.
|
||||
Assert.NotNull(dto.ImageTags);
|
||||
Assert.True(dto.ImageTags.ContainsKey(ImageType.Primary));
|
||||
Assert.NotNull(dto.SeriesPrimaryImageTag);
|
||||
Assert.Null(dto.ParentPrimaryImageItemId);
|
||||
}
|
||||
|
||||
private (Episode Episode, Season Season, Series Series) BuildEpisode(bool seasonHasPoster)
|
||||
private (Episode Episode, Season Season, Series Series) BuildEpisode(bool seasonHasPoster, bool seriesHasPoster = true)
|
||||
{
|
||||
// Non-local (http) paths keep aspect-ratio resolution off the image processor and on the
|
||||
// item's default ratio, which is portrait (2/3) for Season/Series and 16:9 for Episode.
|
||||
var series = new Series { Id = Guid.NewGuid(), Name = "Series" };
|
||||
series.SetImage(new ItemImageInfo { Type = ImageType.Primary, Path = "http://test/series.jpg" }, 0);
|
||||
if (seriesHasPoster)
|
||||
{
|
||||
series.SetImage(new ItemImageInfo { Type = ImageType.Primary, Path = "http://test/series.jpg" }, 0);
|
||||
}
|
||||
|
||||
var season = new Season { Id = Guid.NewGuid(), Name = "Season", SeriesId = series.Id };
|
||||
if (seasonHasPoster)
|
||||
|
||||
Reference in New Issue
Block a user