fix: standardize bool parsing with flexibleBool helper

close #844
This commit is contained in:
edde746
2026-04-11 21:22:15 +02:00
parent b92842f9ac
commit 1b2ecd9de4
10 changed files with 192 additions and 53 deletions
+36 -10
View File
@@ -1,5 +1,6 @@
import 'dart:async';
import '../utils/isolate_helper.dart';
import '../utils/json_utils.dart';
import 'dart:math';
import 'package:flutter/foundation.dart';
@@ -44,22 +45,28 @@ class LibraryContentResult {
/// Process hub response in an isolate.
/// Top-level function so it can be passed to [Isolate.run].
List<PlexHub> _processHubResponse(Map<String, dynamic> decoded, String serverId, String? serverName) {
List<PlexHub> _processHubResponse(
Map<String, dynamic> decoded,
String serverId,
String? serverName, {
bool Function(PlexMetadata)? filter,
}) {
final container = decoded['MediaContainer'] as Map<String, dynamic>?;
if (container == null || container['Hub'] == null) return [];
final itemFilter = filter ?? (PlexMetadata item) => item.isVideoContent;
final hubs = <PlexHub>[];
for (final hubJson in container['Hub'] as List) {
try {
final hub = PlexHub.fromJson(hubJson as Map<String, dynamic>);
if (hub.items.isEmpty) continue;
final videoItems = hub.items
.where((item) => item.isVideoContent)
final filteredItems = hub.items
.where(itemFilter)
.map((item) => item.copyWith(serverId: serverId, serverName: serverName))
.toList();
if (videoItems.isNotEmpty) {
if (filteredItems.isNotEmpty) {
hubs.add(
PlexHub(
hubKey: hub.hubKey,
@@ -68,7 +75,7 @@ List<PlexHub> _processHubResponse(Map<String, dynamic> decoded, String serverId,
hubIdentifier: hub.hubIdentifier,
size: hub.size,
more: hub.more,
items: videoItems,
items: filteredItems,
serverId: serverId,
serverName: serverName,
),
@@ -839,7 +846,7 @@ class PlexClient {
title: stream['title'] as String?,
displayTitle: stream['displayTitle'] as String?,
channels: stream['channels'] as int?,
selected: stream['selected'] == 1 || stream['selected'] == true,
selected: flexibleBool(stream['selected']),
),
);
} else if (streamType == PlexStreamType.subtitle) {
@@ -852,8 +859,8 @@ class PlexClient {
languageCode: stream['languageCode'] as String?,
title: stream['title'] as String?,
displayTitle: stream['displayTitle'] as String?,
selected: stream['selected'] == 1 || stream['selected'] == true,
forced: stream['forced'] == 1,
selected: flexibleBool(stream['selected']),
forced: flexibleBool(stream['forced']),
key: stream['key'] as String?,
),
);
@@ -1297,8 +1304,8 @@ class PlexClient {
audioCodec: media['audioCodec'] as String?,
audioProfile: media['audioProfile'] as String?,
audioChannels: media['audioChannels'] as int?,
optimizedForStreaming: media['optimizedForStreaming'] as bool?,
has64bitOffsets: media['has64bitOffsets'] as bool?,
optimizedForStreaming: flexibleBool(media['optimizedForStreaming']),
has64bitOffsets: flexibleBool(media['has64bitOffsets']),
// Part level properties (file)
filePath: part?['file'] as String?,
fileSize: part?['size'] as int?,
@@ -1594,6 +1601,25 @@ class PlexClient {
return [];
}
/// Get related hubs for a specific metadata item (collections, similar, "more from" director/actor)
Future<List<PlexHub>> getRelatedHubs(String ratingKey, {int count = 10}) async {
try {
final response = await _getWithFailover(
'/hubs/metadata/$ratingKey/related',
queryParameters: {'count': count},
);
final sid = serverId;
final sname = serverName;
return await tryIsolateRun(() => _processHubResponse(
response.data as Map<String, dynamic>, sid, sname,
filter: (item) => item.isVideoContent || item.isCollection,
));
} catch (e) {
appLogger.e('Failed to get related hubs: $e');
}
return [];
}
/// Get full content from a hub using its hub key
/// Returns the complete list of metadata items in the hub
Future<List<PlexMetadata>> getHubContent(String hubKey) async {