158 lines
3.9 KiB
Dart
158 lines
3.9 KiB
Dart
|
|
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<void> _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<EmbyServer?> showAddServerModal(
|
||
|
|
BuildContext context, {
|
||
|
|
EmbyServer? initial,
|
||
|
|
EditingServer? editingServer,
|
||
|
|
}) async {
|
||
|
|
final target =
|
||
|
|
editingServer ??
|
||
|
|
(initial != null ? EditingServer.fromServer(initial) : null);
|
||
|
|
return showAdaptiveModal<EmbyServer>(
|
||
|
|
context: context,
|
||
|
|
maxWidth: 520,
|
||
|
|
compactMaxHeightFactor: 0.92,
|
||
|
|
builder: (_) => _AddServerDialogContent(editingServer: target),
|
||
|
|
);
|
||
|
|
}
|