import 'package:flutter/material.dart'; import 'package:flutter_riverpod/flutter_riverpod.dart'; import '../../core/contracts/server.dart'; import '../../providers/di_providers.dart'; import '../../providers/server_provider.dart'; import '../../providers/session_provider.dart'; import 'adaptive_modal.dart'; import 'connection_form.dart'; class EditingServer { final String id; final String baseUrl; final String? userName; final String? password; final String? displayName; final String iconUrl; const EditingServer({ required this.id, required this.baseUrl, this.userName, this.password, this.displayName, this.iconUrl = '', }); factory EditingServer.fromServer(EmbyServer s) => EditingServer( id: s.id, baseUrl: s.baseUrl, displayName: s.name, iconUrl: s.iconUrl, ); } class _AddServerDialogContent extends ConsumerStatefulWidget { final EditingServer? editingServer; const _AddServerDialogContent({this.editingServer}); @override ConsumerState<_AddServerDialogContent> createState() => _AddServerDialogContentState(); } class _AddServerDialogContentState extends ConsumerState<_AddServerDialogContent> { bool _loading = false; String? _error; bool get _isEdit => widget.editingServer != null; Future _handleConnect( String url, String username, String password, String? displayName, String iconUrl, ) async { setState(() { _loading = true; _error = null; }); try { final probeUc = await ref.read(probeServerUseCaseProvider.future); final probeResult = await probeUc.execute( EmbyServerProbeReq(baseUrl: url), ); final gw = await ref.read(embyGatewayProvider.future); await gw.authenticateByName( baseUrl: url, username: username, password: password, ); final name = (displayName != null && displayName.isNotEmpty) ? displayName : probeResult.serverName; final server = await ref .read(serverListProvider.notifier) .save( EmbyServerSaveReq( id: widget.editingServer?.id, name: name, baseUrl: url, iconUrl: iconUrl, ), ); if (_isEdit) { await ref.read(sessionProvider.notifier).logout(serverId: server.id); } await ref .read(sessionProvider.notifier) .login(serverId: server.id, username: username, password: password); if (!mounted) return; Navigator.of(context).pop(server); } catch (e) { if (mounted) setState(() => _error = e.toString()); } finally { if (mounted) setState(() => _loading = false); } } void _handleClose() { if (_loading) return; Navigator.of(context).pop(); } @override Widget build(BuildContext context) { final editing = widget.editingServer; return PopScope( canPop: !_loading, child: SingleChildScrollView( padding: const EdgeInsets.fromLTRB(24, 20, 24, 24), child: ConnectionForm( mode: _isEdit ? 'edit' : 'add', initialUrl: editing?.baseUrl, initialUsername: editing?.userName, initialPassword: editing?.password, initialDisplayName: editing?.displayName, initialIconUrl: editing?.iconUrl ?? '', onConnect: _handleConnect, onCancel: _handleClose, loading: _loading, error: _error, ), ), ); } } Future showAddServerModal( BuildContext context, { EmbyServer? initial, EditingServer? editingServer, }) async { final target = editingServer ?? (initial != null ? EditingServer.fromServer(initial) : null); return showAdaptiveModal( context: context, maxWidth: 520, compactMaxHeightFactor: 0.92, builder: (_) => _AddServerDialogContent(editingServer: target), ); }