fix: properly clear connections on switch
This commit is contained in:
+58
-48
@@ -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<String, dynamic>)
|
||||
.copyWith(serverId: serverId, serverName: serverName))
|
||||
.map(
|
||||
(json) => PlexLibrary.fromJson(
|
||||
json as Map<String, dynamic>,
|
||||
).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<String, dynamic>)
|
||||
.copyWith(serverId: serverId, serverName: serverName))
|
||||
.map(
|
||||
(json) => PlexPlaylist.fromJson(
|
||||
json as Map<String, dynamic>,
|
||||
).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 {
|
||||
|
||||
@@ -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<DiscoverScreen>
|
||||
listen: false,
|
||||
);
|
||||
final plexClientProvider = context.plexClient;
|
||||
final multiServerProvider = context.read<MultiServerProvider>();
|
||||
final serverStateProvider = context.read<ServerStateProvider>();
|
||||
final hiddenLibrariesProvider = context.read<HiddenLibrariesProvider>();
|
||||
final playbackStateProvider = context.read<PlaybackStateProvider>();
|
||||
|
||||
// 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(
|
||||
|
||||
@@ -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<MainScreen> 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<MultiServerProvider>();
|
||||
final serverStateProvider = context.read<ServerStateProvider>();
|
||||
final hiddenLibrariesProvider = context.read<HiddenLibrariesProvider>();
|
||||
final playbackStateProvider = context.read<PlaybackStateProvider>();
|
||||
|
||||
// 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) {
|
||||
|
||||
@@ -79,7 +79,10 @@ Future<void> playCollectionOrPlaylist({
|
||||
if (!context.mounted) return;
|
||||
|
||||
// Navigate to first item
|
||||
await navigateToVideoPlayer(context, metadata: fetchedQueue.items!.first);
|
||||
await navigateToVideoPlayer(
|
||||
context,
|
||||
metadata: fetchedQueue.items!.first,
|
||||
);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user