fix: profile switcher
This commit is contained in:
@@ -3,6 +3,7 @@ import 'package:flutter/foundation.dart';
|
||||
import '../client/plex_client.dart';
|
||||
import '../services/data_aggregation_service.dart';
|
||||
import '../services/multi_server_manager.dart';
|
||||
import '../services/plex_auth_service.dart';
|
||||
import '../utils/app_logger.dart';
|
||||
|
||||
/// Provider for multi-server Plex connections
|
||||
@@ -70,6 +71,31 @@ class MultiServerProvider extends ChangeNotifier {
|
||||
notifyListeners();
|
||||
}
|
||||
|
||||
/// Reconnect all servers after a profile switch
|
||||
/// Clears existing connections and connects to all provided servers
|
||||
Future<int> reconnectWithServers(
|
||||
List<PlexServer> servers, {
|
||||
String? clientIdentifier,
|
||||
}) async {
|
||||
// Clear existing connections first
|
||||
_serverManager.disconnectAll();
|
||||
appLogger.d(
|
||||
'MultiServerProvider: Cleared connections, reconnecting to ${servers.length} servers',
|
||||
);
|
||||
|
||||
// Connect with new server tokens
|
||||
final connectedCount = await _serverManager.connectToAllServers(
|
||||
servers,
|
||||
clientIdentifier: clientIdentifier,
|
||||
);
|
||||
|
||||
appLogger.i(
|
||||
'MultiServerProvider: Reconnected to $connectedCount/${servers.length} servers after profile switch',
|
||||
);
|
||||
notifyListeners();
|
||||
return connectedCount;
|
||||
}
|
||||
|
||||
/// Check server health for all connected servers
|
||||
Future<void> checkServerHealth() async {
|
||||
await _serverManager.checkServerHealth();
|
||||
|
||||
@@ -34,18 +34,24 @@ class UserProfileProvider extends ChangeNotifier {
|
||||
StorageService? _storageService;
|
||||
|
||||
// Callback for data invalidation when switching profiles
|
||||
VoidCallback? _onDataInvalidationRequested;
|
||||
// Receives the list of servers with new profile tokens for reconnection
|
||||
Future<void> Function(List<PlexServer>)? _onDataInvalidationRequested;
|
||||
|
||||
/// Set a callback to be called when profile switching requires data invalidation
|
||||
void setDataInvalidationCallback(VoidCallback? callback) {
|
||||
/// The callback receives the list of servers with the new profile's access tokens
|
||||
void setDataInvalidationCallback(
|
||||
Future<void> Function(List<PlexServer>)? callback,
|
||||
) {
|
||||
_onDataInvalidationRequested = callback;
|
||||
}
|
||||
|
||||
/// Trigger data invalidation for all screens
|
||||
void _invalidateAllData() {
|
||||
/// Trigger data invalidation for all screens with the new profile's servers
|
||||
Future<void> _invalidateAllData(List<PlexServer> servers) async {
|
||||
if (_onDataInvalidationRequested != null) {
|
||||
_onDataInvalidationRequested!();
|
||||
appLogger.d('Data invalidation triggered for profile switch');
|
||||
await _onDataInvalidationRequested!(servers);
|
||||
appLogger.d(
|
||||
'Data invalidation triggered for profile switch with ${servers.length} servers',
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -294,7 +300,7 @@ class UserProfileProvider extends ChangeNotifier {
|
||||
);
|
||||
|
||||
// switchResponse.authToken is the new user's Plex.tv token
|
||||
// We need to fetch servers with this token to get the proper server access token
|
||||
// Fetch servers with this token to get the proper server access tokens
|
||||
appLogger.d('Got new user Plex.tv token, fetching servers...');
|
||||
|
||||
final servers = await _authService!.fetchServers(
|
||||
@@ -304,38 +310,14 @@ class UserProfileProvider extends ChangeNotifier {
|
||||
throw Exception('No servers available for this user');
|
||||
}
|
||||
|
||||
// Find the current server from storage
|
||||
final currentServerData = _storageService!.getServerData();
|
||||
if (currentServerData == null) {
|
||||
throw Exception('No current server data found');
|
||||
}
|
||||
appLogger.d('Fetched ${servers.length} servers for new profile');
|
||||
|
||||
// Find matching server by name or client identifier
|
||||
final currentServerName = currentServerData['name'] as String?;
|
||||
final currentServerClientId =
|
||||
currentServerData['clientIdentifier'] as String?;
|
||||
|
||||
final matchingServer = servers.firstWhere(
|
||||
(server) =>
|
||||
server.name == currentServerName ||
|
||||
server.clientIdentifier == currentServerClientId,
|
||||
orElse: () => servers.first, // Fallback to first server
|
||||
);
|
||||
|
||||
appLogger.d(
|
||||
'Found matching server: ${matchingServer.name}, getting access token',
|
||||
);
|
||||
|
||||
// Update storage with new tokens
|
||||
await _storageService!.updateCurrentUser(
|
||||
user.uuid,
|
||||
matchingServer
|
||||
.accessToken, // Use server access token, not Plex.tv token
|
||||
);
|
||||
|
||||
// Also save the new Plex.tv token for future profile operations
|
||||
// Save the new Plex.tv token for future profile operations
|
||||
await _storageService!.savePlexToken(switchResponse.authToken);
|
||||
|
||||
// Update current user UUID in storage
|
||||
await _storageService!.saveCurrentUserUUID(user.uuid);
|
||||
|
||||
// Update current user
|
||||
_currentUser = user;
|
||||
|
||||
@@ -351,26 +333,14 @@ class UserProfileProvider extends ChangeNotifier {
|
||||
},
|
||||
);
|
||||
|
||||
// Update PlexClient with proper server access token
|
||||
if (clientProvider != null) {
|
||||
try {
|
||||
clientProvider.updateToken(matchingServer.accessToken);
|
||||
appLogger.d(
|
||||
'Updated PlexClient with server access token for user: ${user.displayName}',
|
||||
);
|
||||
} catch (e) {
|
||||
appLogger.w('Failed to update PlexClient token', error: e);
|
||||
}
|
||||
}
|
||||
|
||||
notifyListeners();
|
||||
|
||||
// Invalidate all cached data for the new profile
|
||||
// This will cause screens to refresh and rebuild widgets with the new token
|
||||
_invalidateAllData();
|
||||
// Invalidate all cached data and reconnect to all servers with new tokens
|
||||
// The callback will handle server reconnection using the servers list
|
||||
await _invalidateAllData(servers);
|
||||
|
||||
appLogger.d(
|
||||
'Profile switch complete, all data and images should refresh with new token',
|
||||
'Profile switch complete, all servers reconnected with new tokens',
|
||||
);
|
||||
|
||||
appLogger.i('Successfully switched to user: ${user.displayName}');
|
||||
|
||||
@@ -10,6 +10,8 @@ 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 '../services/plex_auth_service.dart';
|
||||
import '../services/storage_service.dart';
|
||||
import 'discover_screen.dart';
|
||||
import 'libraries_screen.dart';
|
||||
import 'search_screen.dart';
|
||||
@@ -96,17 +98,33 @@ class _MainScreenState extends State<MainScreen> with RouteAware {
|
||||
}
|
||||
|
||||
/// Invalidate all cached data across all screens when profile is switched
|
||||
void _invalidateAllScreens() {
|
||||
appLogger.d('Invalidating all screen data due to profile switch');
|
||||
/// Receives the list of servers with new profile tokens for reconnection
|
||||
Future<void> _invalidateAllScreens(List<PlexServer> servers) async {
|
||||
appLogger.d(
|
||||
'Invalidating all screen data due to profile switch with ${servers.length} servers',
|
||||
);
|
||||
|
||||
// Clear all provider states first (servers, playback, UI state)
|
||||
// Get all providers
|
||||
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();
|
||||
// Reconnect to all servers with new profile tokens
|
||||
if (servers.isNotEmpty) {
|
||||
final storage = await StorageService.getInstance();
|
||||
final clientId = storage.getClientIdentifier();
|
||||
|
||||
final connectedCount = await multiServerProvider.reconnectWithServers(
|
||||
servers,
|
||||
clientIdentifier: clientId,
|
||||
);
|
||||
appLogger.d(
|
||||
'Reconnected to $connectedCount/${servers.length} servers after profile switch',
|
||||
);
|
||||
}
|
||||
|
||||
// Reset other provider states
|
||||
serverStateProvider.reset();
|
||||
hiddenLibrariesProvider.refresh();
|
||||
playbackStateProvider.clearShuffle();
|
||||
|
||||
Reference in New Issue
Block a user