From c800baeb25c62183a9c6b773597615e0ca58305e Mon Sep 17 00:00:00 2001 From: Bryce Kehoe Date: Thu, 30 Apr 2026 22:09:54 +0100 Subject: [PATCH 1/2] fix(media): format UHD version labels Normalize Plex 4k/8k resolution values for display so version pickers show 4K/8K instead of appending a p suffix. --- lib/models/plex_media_version.dart | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/lib/models/plex_media_version.dart b/lib/models/plex_media_version.dart index 2d9925d0..6a6804fb 100644 --- a/lib/models/plex_media_version.dart +++ b/lib/models/plex_media_version.dart @@ -27,6 +27,16 @@ bool? _flexibleBoolNullable(Object? v) => switch (v) { _ => null, }; +final _videoResolution = RegExp(r'^(\d+)(k?)$', caseSensitive: false); + +/// Plex uses numeric heights for SD/HD and values like `4k`/`8k` for UHD+. +String _videoResolutionDisplayLabel(String resolution) { + final value = resolution.trim(); + final match = _videoResolution.firstMatch(value); + if (match == null) return value; + return match.group(2)!.isEmpty ? '${match.group(1)}p' : '${match.group(1)}K'; +} + @JsonSerializable(createToJson: false) class PlexMediaVersion { @JsonKey(fromJson: _flexibleIntOrZero) @@ -77,7 +87,7 @@ class PlexMediaVersion { // Add resolution if (videoResolution != null && videoResolution!.isNotEmpty) { - parts.add('${videoResolution}p'); + parts.add(_videoResolutionDisplayLabel(videoResolution!)); } else if (height != null) { parts.add('${height}p'); } From e733a0abc70b291d6a07c9d0d6caba55396cb43e Mon Sep 17 00:00:00 2001 From: Bryce Kehoe Date: Thu, 30 Apr 2026 22:09:54 +0100 Subject: [PATCH 2/2] test(media): cover UHD version labels Add display label coverage for numeric resolutions and UHD values returned by Plex. --- test/models/plex_media_version_test.dart | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/test/models/plex_media_version_test.dart b/test/models/plex_media_version_test.dart index b15e9cfe..a6fb5b21 100644 --- a/test/models/plex_media_version_test.dart +++ b/test/models/plex_media_version_test.dart @@ -100,4 +100,17 @@ void main() { expect(v.isPlayable, isTrue); }); }); + + group('PlexMediaVersion displayLabel', () { + test('formats Plex videoResolution for display', () { + expect(PlexMediaVersion(id: 1, partKey: '/k', videoResolution: '1080').displayLabel, startsWith('1080p ')); + for (final resolution in ['4k', '4K']) { + expect(PlexMediaVersion(id: 1, partKey: '/k', videoResolution: resolution).displayLabel, startsWith('4K ')); + } + for (final resolution in ['8k', '8K']) { + expect(PlexMediaVersion(id: 1, partKey: '/k', videoResolution: resolution).displayLabel, startsWith('8K ')); + } + expect(PlexMediaVersion(id: 1, partKey: '/k', videoResolution: 'sd').displayLabel, startsWith('sd ')); + }); + }); }