diff --git a/lib/client/plex_client.dart b/lib/client/plex_client.dart index ccf78ff1..b0185997 100644 --- a/lib/client/plex_client.dart +++ b/lib/client/plex_client.dart @@ -228,10 +228,11 @@ class PlexClient { final container = _getMediaContainer(response); if (container != null && container['Metadata'] != null) { return (container['Metadata'] as List) - .map((json) => PlexMetadata.fromJson(json).copyWith( - serverId: serverId, - serverName: serverName, - )) + .map( + (json) => PlexMetadata.fromJson( + json, + ).copyWith(serverId: serverId, serverName: serverName), + ) .toList(); } return []; @@ -253,10 +254,9 @@ class PlexClient { PlexMetadata? _extractSingleMetadata(Response response) { final metadataJson = _getFirstMetadataJson(response); return metadataJson != null - ? PlexMetadata.fromJson(metadataJson).copyWith( - serverId: serverId, - serverName: serverName, - ) + ? PlexMetadata.fromJson( + metadataJson, + ).copyWith(serverId: serverId, serverName: serverName) : null; } @@ -279,8 +279,11 @@ class PlexClient { final container = _getMediaContainer(response); if (container != null && container['Directory'] != null) { return (container['Directory'] as List) - .map((json) => PlexLibrary.fromJson(json as Map) - .copyWith(serverId: serverId, serverName: serverName)) + .map( + (json) => PlexLibrary.fromJson( + json as Map, + ).copyWith(serverId: serverId, serverName: serverName), + ) .toList(); } return []; @@ -291,8 +294,11 @@ class PlexClient { final container = _getMediaContainer(response); if (container != null && container['Metadata'] != null) { return (container['Metadata'] as List) - .map((json) => PlexPlaylist.fromJson(json as Map) - .copyWith(serverId: serverId, serverName: serverName)) + .map( + (json) => PlexPlaylist.fromJson( + json as Map, + ).copyWith(serverId: serverId, serverName: serverName), + ) .toList(); } return []; @@ -387,10 +393,9 @@ class PlexClient { // Log the parsed metadata JSON if (metadataJson != null) { - metadata = PlexMetadata.fromJsonWithImages(metadataJson).copyWith( - serverId: serverId, - serverName: serverName, - ); + metadata = PlexMetadata.fromJsonWithImages( + metadataJson, + ).copyWith(serverId: serverId, serverName: serverName); // Check if OnDeck is nested inside Metadata if (metadataJson.containsKey('OnDeck') && @@ -401,10 +406,9 @@ class PlexClient { if (onDeckData is Map && onDeckData.containsKey('Metadata')) { final onDeckMetadata = onDeckData['Metadata']; if (onDeckMetadata != null) { - onDeckEpisode = PlexMetadata.fromJson(onDeckMetadata).copyWith( - serverId: serverId, - serverName: serverName, - ); + onDeckEpisode = PlexMetadata.fromJson( + onDeckMetadata, + ).copyWith(serverId: serverId, serverName: serverName); } } } @@ -418,10 +422,9 @@ class PlexClient { final response = await _dio.get('/library/metadata/$ratingKey'); final metadataJson = _getFirstMetadataJson(response); return metadataJson != null - ? PlexMetadata.fromJsonWithImages(metadataJson).copyWith( - serverId: serverId, - serverName: serverName, - ) + ? PlexMetadata.fromJsonWithImages( + metadataJson, + ).copyWith(serverId: serverId, serverName: serverName) : null; } @@ -489,10 +492,11 @@ class PlexClient { if (hub['Metadata'] != null) { for (final json in hub['Metadata'] as List) { try { - results.add(PlexMetadata.fromJson(json).copyWith( - serverId: serverId, - serverName: serverName, - )); + results.add( + PlexMetadata.fromJson( + json, + ).copyWith(serverId: serverId, serverName: serverName), + ); } catch (e) { // Skip items that fail to parse appLogger.w('Failed to parse search result', error: e); @@ -503,10 +507,11 @@ class PlexClient { if (hub['Directory'] != null) { for (final json in hub['Directory'] as List) { try { - results.add(PlexMetadata.fromJson(json).copyWith( - serverId: serverId, - serverName: serverName, - )); + results.add( + PlexMetadata.fromJson( + json, + ).copyWith(serverId: serverId, serverName: serverName), + ); } catch (e) { // Skip items that fail to parse appLogger.w('Failed to parse search result', error: e); @@ -542,10 +547,11 @@ class PlexClient { final container = _getMediaContainer(response); if (container != null && container['Metadata'] != null) { final allItems = (container['Metadata'] as List) - .map((json) => PlexMetadata.fromJsonWithImages(json).copyWith( - serverId: serverId, - serverName: serverName, - )) + .map( + (json) => PlexMetadata.fromJsonWithImages( + json, + ).copyWith(serverId: serverId, serverName: serverName), + ) .toList(); // Filter out music content (artists, albums, tracks) @@ -1189,10 +1195,12 @@ class PlexClient { final type = item.type.toLowerCase(); return type == 'movie' || type == 'show'; }) - .map((item) => item.copyWith( - serverId: serverId, - serverName: serverName, - )) + .map( + (item) => item.copyWith( + serverId: serverId, + serverName: serverName, + ), + ) .toList(); if (videoItems.isNotEmpty) { @@ -1770,10 +1778,11 @@ class PlexClient { for (final json in container['Metadata'] as List) { try { // Try to parse with full PlexMetadata.fromJson first - items.add(PlexMetadata.fromJson(json).copyWith( - serverId: serverId, - serverName: serverName, - )); + items.add( + PlexMetadata.fromJson( + json, + ).copyWith(serverId: serverId, serverName: serverName), + ); } catch (e) { // If full parsing fails, use minimal safe parsing appLogger.d('Using minimal parsing for metadata item: $e'); @@ -1803,10 +1812,11 @@ class PlexClient { for (final json in container['Directory'] as List) { try { // Try to parse as PlexMetadata first - items.add(PlexMetadata.fromJson(json).copyWith( - serverId: serverId, - serverName: serverName, - )); + items.add( + PlexMetadata.fromJson( + json, + ).copyWith(serverId: serverId, serverName: serverName), + ); } catch (e) { // If that fails, use minimal folder representation try { diff --git a/lib/screens/discover_screen.dart b/lib/screens/discover_screen.dart index de09c315..990505b1 100644 --- a/lib/screens/discover_screen.dart +++ b/lib/screens/discover_screen.dart @@ -6,6 +6,9 @@ import '../client/plex_client.dart'; import '../models/plex_metadata.dart'; import '../models/plex_hub.dart'; import '../providers/multi_server_provider.dart'; +import '../providers/server_state_provider.dart'; +import '../providers/hidden_libraries_provider.dart'; +import '../providers/playback_state_provider.dart'; import '../widgets/media_card.dart'; import '../widgets/desktop_app_bar.dart'; import '../widgets/user_avatar_widget.dart'; @@ -449,10 +452,18 @@ class _DiscoverScreenState extends State listen: false, ); final plexClientProvider = context.plexClient; + final multiServerProvider = context.read(); + final serverStateProvider = context.read(); + final hiddenLibrariesProvider = context.read(); + final playbackStateProvider = context.read(); // Clear all user data and provider states await userProfileProvider.logout(); plexClientProvider.clearClient(); + multiServerProvider.clearAllConnections(); + serverStateProvider.reset(); + await hiddenLibrariesProvider.refresh(); + playbackStateProvider.clearShuffle(); if (mounted) { Navigator.of(context).pushAndRemoveUntil( diff --git a/lib/screens/main_screen.dart b/lib/screens/main_screen.dart index 79918672..1e06635c 100644 --- a/lib/screens/main_screen.dart +++ b/lib/screens/main_screen.dart @@ -1,10 +1,15 @@ import 'package:flutter/material.dart'; +import 'package:provider/provider.dart'; import '../client/plex_client.dart'; import '../i18n/strings.g.dart'; import '../utils/app_logger.dart'; import '../utils/provider_extensions.dart'; import '../main.dart'; import '../mixins/refreshable.dart'; +import '../providers/multi_server_provider.dart'; +import '../providers/server_state_provider.dart'; +import '../providers/hidden_libraries_provider.dart'; +import '../providers/playback_state_provider.dart'; import 'discover_screen.dart'; import 'libraries_screen.dart'; import 'search_screen.dart'; @@ -94,6 +99,20 @@ class _MainScreenState extends State with RouteAware { void _invalidateAllScreens() { appLogger.d('Invalidating all screen data due to profile switch'); + // Clear all provider states first (servers, playback, UI state) + final multiServerProvider = context.read(); + final serverStateProvider = context.read(); + final hiddenLibrariesProvider = context.read(); + final playbackStateProvider = context.read(); + + // Clear all server connections (new profile may have different servers) + multiServerProvider.clearAllConnections(); + serverStateProvider.reset(); + hiddenLibrariesProvider.refresh(); + playbackStateProvider.clearShuffle(); + + appLogger.d('Cleared all provider states for profile switch'); + // Full refresh discover screen (reload all content for new profile) final discoverState = _discoverKey.currentState; if (discoverState != null) { diff --git a/lib/utils/collection_playlist_play_helper.dart b/lib/utils/collection_playlist_play_helper.dart index 3f293fc0..d2e2e46d 100644 --- a/lib/utils/collection_playlist_play_helper.dart +++ b/lib/utils/collection_playlist_play_helper.dart @@ -79,7 +79,10 @@ Future playCollectionOrPlaylist({ if (!context.mounted) return; // Navigate to first item - await navigateToVideoPlayer(context, metadata: fetchedQueue.items!.first); + await navigateToVideoPlayer( + context, + metadata: fetchedQueue.items!.first, + ); return; } }