Add episode release date to episode listing within season

This commit is contained in:
Micah Morrison
2026-01-23 20:21:08 -05:00
parent e77585ca6f
commit ffbd504042
5 changed files with 43 additions and 0 deletions
+4
View File
@@ -39,6 +39,7 @@ import 'utils/orientation_helper.dart';
import 'utils/language_codes.dart';
import 'i18n/strings.g.dart';
import 'focus/input_mode_tracker.dart';
import 'package:intl/date_symbol_data_local.dart';
// Workaround for Flutter bug #177992: iPadOS 26.1+ misinterprets fake touch events
// at (0,0) as barrier taps, causing modals to dismiss immediately.
@@ -68,6 +69,9 @@ void main() async {
// Initialize localization with saved locale
LocaleSettings.setLocale(savedLocale);
// Needed for formatting dates in different locales
await initializeDateFormatting(savedLocale.languageCode, null);
// Configure image cache for large libraries
PaintingBinding.instance.imageCache.maximumSizeBytes = 200 << 20; // 200MB
+4
View File
@@ -47,6 +47,7 @@ class PlexMetadata with MultiServerFields {
final double? rating;
final double? audienceRating;
final int? year;
final String? originallyAvailableAt; // Full release date (YYYY-MM-DD)
final String? thumb;
final String? art;
final int? duration;
@@ -120,6 +121,7 @@ class PlexMetadata with MultiServerFields {
this.rating,
this.audienceRating,
this.year,
this.originallyAvailableAt,
this.thumb,
this.art,
this.duration,
@@ -165,6 +167,7 @@ class PlexMetadata with MultiServerFields {
double? rating,
double? audienceRating,
int? year,
String? originallyAvailableAt,
String? thumb,
String? art,
int? duration,
@@ -208,6 +211,7 @@ class PlexMetadata with MultiServerFields {
rating: rating ?? this.rating,
audienceRating: audienceRating ?? this.audienceRating,
year: year ?? this.year,
originallyAvailableAt: originallyAvailableAt ?? this.originallyAvailableAt,
thumb: thumb ?? this.thumb,
art: art ?? this.art,
duration: duration ?? this.duration,
+2
View File
@@ -18,6 +18,7 @@ PlexMetadata _$PlexMetadataFromJson(Map<String, dynamic> json) => PlexMetadata(
rating: (json['rating'] as num?)?.toDouble(),
audienceRating: (json['audienceRating'] as num?)?.toDouble(),
year: (json['year'] as num?)?.toInt(),
originallyAvailableAt: json['originallyAvailableAt'] as String?,
thumb: json['thumb'] as String?,
art: json['art'] as String?,
duration: (json['duration'] as num?)?.toInt(),
@@ -60,6 +61,7 @@ Map<String, dynamic> _$PlexMetadataToJson(PlexMetadata instance) => <String, dyn
'rating': instance.rating,
'audienceRating': instance.audienceRating,
'year': instance.year,
'originallyAvailableAt': instance.originallyAvailableAt,
'thumb': instance.thumb,
'art': instance.art,
'duration': instance.duration,
+16
View File
@@ -1,6 +1,7 @@
import 'dart:io';
import 'package:flutter/material.dart';
import 'package:plezy/utils/platform_detector.dart';
import 'package:plezy/widgets/app_icon.dart';
import 'package:material_symbols_icons/symbols.dart';
import 'package:provider/provider.dart';
@@ -224,6 +225,8 @@ class _EpisodeCard extends StatelessWidget {
});
Widget _buildEpisodeMetaRow(BuildContext context) {
final isMobile = PlatformDetector.isMobile(context);
return Row(
children: [
if (episode.duration != null)
@@ -231,6 +234,19 @@ class _EpisodeCard extends StatelessWidget {
formatDurationTimestamp(Duration(milliseconds: episode.duration!)),
style: Theme.of(context).textTheme.bodySmall?.copyWith(color: tokens(context).textMuted, fontSize: 12),
),
if (!isMobile && episode.originallyAvailableAt != null) ...[
Padding(
padding: const EdgeInsets.symmetric(horizontal: 6),
child: Text(
'',
style: Theme.of(context).textTheme.bodySmall?.copyWith(color: tokens(context).textMuted, fontSize: 12),
),
),
Text(
formatFullDate(episode.originallyAvailableAt!),
style: Theme.of(context).textTheme.bodySmall?.copyWith(color: tokens(context).textMuted, fontSize: 12),
),
],
// Hide watch status when offline (not tracked)
if (!isOffline && episode.duration != null && episode.isWatched) ...[
Padding(
+17
View File
@@ -1,5 +1,6 @@
import 'package:duration/duration.dart';
import 'package:duration/locale.dart';
import 'package:intl/intl.dart';
import '../i18n/strings.g.dart';
/// Formats a number with a minimum number of digits using leading zeros.
@@ -183,3 +184,19 @@ DurationLocale _getDurationLocale() {
String toBulletedString(List<String> parts) {
return parts.join(' · ');
}
/// Takes a date string in the format "YYYY-MM-DD" and returns a localized full date string
/// If there is any error, `dateString` is returned as is
String formatFullDate(String dateString) {
try {
// Parse the date
final date = DateTime.parse(dateString);
// Create a DateFormat with the full date pattern for the current locale
final formatter = DateFormat.yMMMMd(LocaleSettings.currentLocale.languageCode);
return formatter.format(date);
} catch (e) {
return dateString;
}
}