Browse Source

lazy load media card images

pull/2750/head
Jason Dove 7 months ago
parent
commit
ad023bd470
No known key found for this signature in database
  1. 3
      CHANGELOG.md
  2. 33
      ErsatzTV/Shared/MediaCard.razor

3
CHANGELOG.md

@ -72,7 +72,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).
- Sequential schedules: fix `count` instruction validation to accept integer (constant) or string (expression) - Sequential schedules: fix `count` instruction validation to accept integer (constant) or string (expression)
- Fix multi-part episode grouping logic so that it does NOT require release date metadata for episodes within a single show - Fix multi-part episode grouping logic so that it does NOT require release date metadata for episodes within a single show
- When **Treat Collections As Shows** is enabled (i.e. for crossover episodes) release date metadata is required for proper grouping - When **Treat Collections As Shows** is enabled (i.e. for crossover episodes) release date metadata is required for proper grouping
- Fix *many* cases of duplicate names; enforce case-insensitive unique names at the schema level - Fix *many* cases of duplicate names; enforce case-insensitive unique names at the db schema level
### Changed ### Changed
- No longer round framerate to nearest integer when normalizing framerate - No longer round framerate to nearest integer when normalizing framerate
@ -85,6 +85,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).
- Optimize Jellyfin database fields and indexes - Optimize Jellyfin database fields and indexes
- Optimize Jellyfin show library scans by only requesting `People` (actors, directors, writers) when etags don't match - Optimize Jellyfin show library scans by only requesting `People` (actors, directors, writers) when etags don't match
- This should significantly speed up periodic library scans, particularly against Jellyfin 10.11.x - This should significantly speed up periodic library scans, particularly against Jellyfin 10.11.x
- Lazy load media item images in UI
## [25.9.0] - 2025-11-29 ## [25.9.0] - 2025-11-29
### Added ### Added

33
ErsatzTV/Shared/MediaCard.razor

@ -10,7 +10,7 @@
{ {
<div class="@(IsSelected ? DeleteClicked.HasDelegate ? "media-card-selected-delete" : "media-card-selected" : "")" <div class="@(IsSelected ? DeleteClicked.HasDelegate ? "media-card-selected-delete" : "media-card-selected" : "")"
style="border-radius: 4px; position: relative;"> style="border-radius: 4px; position: relative;">
<MudPaper Class="@($"media-card {CardClass}")" Style="@ArtworkForItem()"> <MudPaper Class="@($"media-card {CardClass}")" Style="position: relative; overflow: hidden;">
@if (string.IsNullOrWhiteSpace(Data.Poster)) @if (string.IsNullOrWhiteSpace(Data.Poster))
{ {
string placeholder = GetPlaceholder(Data.SortTitle); string placeholder = GetPlaceholder(Data.SortTitle);
@ -24,6 +24,13 @@
@placeholder @placeholder
</MudText> </MudText>
} }
else
{
<img src="@GetPosterUrl()"
loading="lazy"
style="position: absolute; top: 0; left: 0; width: 100%; height: 100%; object-fit: cover; object-position: center;"
alt="@Data.SortTitle"/>
}
</MudPaper> </MudPaper>
@if (IsSelected) @if (IsSelected)
{ {
@ -100,7 +107,7 @@
} }
else else
{ {
<MudPaper Class="@($"media-card {CardClass}")" Style="@ArtworkForItem()"> <MudPaper Class="@($"media-card {CardClass}")" Style="position: relative; overflow: hidden;">
@if (string.IsNullOrWhiteSpace(Data.Poster)) @if (string.IsNullOrWhiteSpace(Data.Poster))
{ {
string placeholder = GetPlaceholder(Data.SortTitle); string placeholder = GetPlaceholder(Data.SortTitle);
@ -114,6 +121,13 @@
@placeholder @placeholder
</MudText> </MudText>
} }
else
{
<img src="@GetPosterUrl()"
loading="lazy"
style="position: absolute; top: 0; left: 0; width: 100%; height: 100%; object-fit: cover; object-position: center;"
alt="@Data.SortTitle"/>
}
</MudPaper> </MudPaper>
} }
<MudText Align="Align.Center" Class="media-card-title" UserAttributes="@(new Dictionary<string, object> { { "title", Data.Title } })"> <MudText Align="Align.Center" Class="media-card-title" UserAttributes="@(new Dictionary<string, object> { { "title", Data.Title } })">
@ -190,16 +204,19 @@
return char.IsDigit(first) || !char.IsLetter(first) ? "#" : first.ToString(); return char.IsDigit(first) || !char.IsLetter(first) ? "#" : first.ToString();
} }
private string ArtworkForItem() private string GetPosterUrl()
{ {
if (IsRemoteArtwork || Data.Poster?.StartsWith("http://") == true || Data.Poster?.StartsWith("https://") == true) if (string.IsNullOrWhiteSpace(Data.Poster))
{
return null;
}
if (IsRemoteArtwork || Data.Poster.StartsWith("http://") || Data.Poster.StartsWith("https://"))
{ {
return $"position: relative; background-image: url({Data.Poster}); background-size: cover; background-position: center"; return Data.Poster;
} }
return string.IsNullOrWhiteSpace(Data.Poster) return $"artwork/{PathForArtwork()}/{Data.Poster}";
? "position: relative"
: $"position: relative; background-image: url(artwork/{PathForArtwork()}/{Data.Poster}); background-size: cover; background-position: center";
} }
private string PathForArtwork() => ArtworkKind switch private string PathForArtwork() => ArtworkKind switch

Loading…
Cancel
Save