250 lines
8.2 KiB
Dart
250 lines
8.2 KiB
Dart
import 'package:flutter/material.dart';
|
|
import '../services/webdav_service.dart';
|
|
|
|
class WebDAVSetupPage extends StatefulWidget {
|
|
const WebDAVSetupPage({super.key});
|
|
|
|
@override
|
|
State<WebDAVSetupPage> createState() => _WebDAVSetupPageState();
|
|
}
|
|
|
|
class _WebDAVSetupPageState extends State<WebDAVSetupPage> {
|
|
final _formKey = GlobalKey<FormState>();
|
|
final _baseUrlController = TextEditingController();
|
|
final _usernameController = TextEditingController();
|
|
final _passwordController = TextEditingController();
|
|
bool _isLoading = false;
|
|
bool _isConnected = false;
|
|
String _statusText = '未连接';
|
|
|
|
@override
|
|
void initState() {
|
|
super.initState();
|
|
_loadSavedCredentials();
|
|
}
|
|
|
|
@override
|
|
void dispose() {
|
|
_baseUrlController.dispose();
|
|
_usernameController.dispose();
|
|
_passwordController.dispose();
|
|
super.dispose();
|
|
}
|
|
|
|
Future<void> _loadSavedCredentials() async {
|
|
final hasCred = await WebDAVService.instance.loadCredentials();
|
|
setState(() {
|
|
_isConnected = hasCred;
|
|
_statusText = hasCred ? '已连接' : '未连接';
|
|
if (hasCred) {
|
|
_baseUrlController.text = WebDAVService.instance._baseUrl ?? '';
|
|
// 用户名不显示,保持隐私
|
|
}
|
|
});
|
|
}
|
|
|
|
Future<void> _connect() async {
|
|
if (!_formKey.currentState!.validate()) return;
|
|
|
|
setState(() => _isLoading = true);
|
|
|
|
try {
|
|
await WebDAVService.instance.saveCredentials(
|
|
_baseUrlController.text.trim(),
|
|
_usernameController.text.trim(),
|
|
_passwordController.text.trim(),
|
|
);
|
|
|
|
// 尝试列出文件以验证连接
|
|
await WebDAVService.instance.getMusicFiles();
|
|
|
|
setState(() {
|
|
_isConnected = true;
|
|
_statusText = '已连接';
|
|
_isLoading = false;
|
|
});
|
|
|
|
if (mounted) {
|
|
ScaffoldMessenger.of(context).showSnackBar(
|
|
const SnackBar(
|
|
content: Text('✅ WebDAV 连接成功'),
|
|
backgroundColor: Color(0xFF4CAF50),
|
|
),
|
|
);
|
|
Navigator.pop(context, true);
|
|
}
|
|
} catch (e) {
|
|
setState(() {
|
|
_isConnected = false;
|
|
_statusText = '连接失败';
|
|
_isLoading = false;
|
|
});
|
|
if (mounted) {
|
|
ScaffoldMessenger.of(context).showSnackBar(
|
|
SnackBar(
|
|
content: Text('❌ 连接失败: $e'),
|
|
backgroundColor: Colors.red,
|
|
),
|
|
);
|
|
}
|
|
}
|
|
}
|
|
|
|
Future<void> _disconnect() async {
|
|
await WebDAVService.instance.clearCredentials();
|
|
setState(() {
|
|
_isConnected = false;
|
|
_statusText = '未连接';
|
|
});
|
|
if (mounted) {
|
|
ScaffoldMessenger.of(context).showSnackBar(
|
|
const SnackBar(
|
|
content: Text('已断开连接'),
|
|
backgroundColor: Colors.grey,
|
|
),
|
|
);
|
|
}
|
|
}
|
|
|
|
@override
|
|
Widget build(BuildContext context) {
|
|
return Scaffold(
|
|
backgroundColor: const Color(0xFF0E1211),
|
|
appBar: AppBar(
|
|
title: const Text('WebDAV 设置'),
|
|
backgroundColor: Colors.transparent,
|
|
elevation: 0,
|
|
foregroundColor: Colors.white,
|
|
),
|
|
body: Padding(
|
|
padding: const EdgeInsets.all(24),
|
|
child: Form(
|
|
key: _formKey,
|
|
child: Column(
|
|
crossAxisAlignment: CrossAxisAlignment.start,
|
|
children: [
|
|
// 状态显示
|
|
Container(
|
|
padding: const EdgeInsets.all(16),
|
|
decoration: BoxDecoration(
|
|
color: const Color(0xFF1A2A2A),
|
|
borderRadius: BorderRadius.circular(8),
|
|
),
|
|
child: Row(
|
|
children: [
|
|
Icon(
|
|
_isConnected ? Icons.cloud_done : Icons.cloud_off,
|
|
color:
|
|
_isConnected ? const Color(0xFF4CAF50) : Colors.grey,
|
|
),
|
|
const SizedBox(width: 12),
|
|
Text(
|
|
'状态: $_statusText',
|
|
style: TextStyle(
|
|
color: _isConnected
|
|
? const Color(0xFF4CAF50)
|
|
: Colors.grey[400],
|
|
),
|
|
),
|
|
const Spacer(),
|
|
if (_isConnected)
|
|
TextButton(
|
|
onPressed: _disconnect,
|
|
style:
|
|
TextButton.styleFrom(foregroundColor: Colors.red),
|
|
child: const Text('断开'),
|
|
),
|
|
],
|
|
),
|
|
),
|
|
const SizedBox(height: 24),
|
|
|
|
// 表单
|
|
TextFormField(
|
|
controller: _baseUrlController,
|
|
enabled: !_isConnected,
|
|
style: const TextStyle(color: Colors.white),
|
|
decoration: const InputDecoration(
|
|
labelText: 'WebDAV 地址',
|
|
labelStyle: TextStyle(color: Colors.grey),
|
|
hintText: 'https://nas.local/dav/',
|
|
hintStyle: TextStyle(color: Colors.grey),
|
|
enabledBorder: UnderlineInputBorder(
|
|
borderSide: BorderSide(color: Colors.grey),
|
|
),
|
|
focusedBorder: UnderlineInputBorder(
|
|
borderSide: BorderSide(color: Color(0xFFB8D4D0)),
|
|
),
|
|
),
|
|
validator: (v) =>
|
|
v == null || v.isEmpty ? '请输入 WebDAV 地址' : null,
|
|
),
|
|
const SizedBox(height: 16),
|
|
TextFormField(
|
|
controller: _usernameController,
|
|
enabled: !_isConnected,
|
|
style: const TextStyle(color: Colors.white),
|
|
decoration: const InputDecoration(
|
|
labelText: '用户名',
|
|
labelStyle: TextStyle(color: Colors.grey),
|
|
enabledBorder: UnderlineInputBorder(
|
|
borderSide: BorderSide(color: Colors.grey),
|
|
),
|
|
focusedBorder: UnderlineInputBorder(
|
|
borderSide: BorderSide(color: Color(0xFFB8D4D0)),
|
|
),
|
|
),
|
|
validator: (v) => v == null || v.isEmpty ? '请输入用户名' : null,
|
|
),
|
|
const SizedBox(height: 16),
|
|
TextFormField(
|
|
controller: _passwordController,
|
|
enabled: !_isConnected,
|
|
obscureText: true,
|
|
style: const TextStyle(color: Colors.white),
|
|
decoration: const InputDecoration(
|
|
labelText: '密码',
|
|
labelStyle: TextStyle(color: Colors.grey),
|
|
enabledBorder: UnderlineInputBorder(
|
|
borderSide: BorderSide(color: Colors.grey),
|
|
),
|
|
focusedBorder: UnderlineInputBorder(
|
|
borderSide: BorderSide(color: Color(0xFFB8D4D0)),
|
|
),
|
|
),
|
|
validator: (v) => v == null || v.isEmpty ? '请输入密码' : null,
|
|
),
|
|
const SizedBox(height: 32),
|
|
SizedBox(
|
|
width: double.infinity,
|
|
child: ElevatedButton(
|
|
onPressed:
|
|
_isConnected ? null : (_isLoading ? null : _connect),
|
|
style: ElevatedButton.styleFrom(
|
|
backgroundColor: const Color(0xFFB8D4D0),
|
|
foregroundColor: Colors.black87,
|
|
padding: const EdgeInsets.symmetric(vertical: 16),
|
|
shape: RoundedRectangleBorder(
|
|
borderRadius: BorderRadius.circular(8),
|
|
),
|
|
),
|
|
child: _isLoading
|
|
? const SizedBox(
|
|
height: 20,
|
|
width: 20,
|
|
child: CircularProgressIndicator(
|
|
strokeWidth: 2,
|
|
color: Colors.black87,
|
|
),
|
|
)
|
|
: Text(_isConnected ? '已连接' : '连接'),
|
|
),
|
|
),
|
|
],
|
|
),
|
|
),
|
|
),
|
|
);
|
|
}
|
|
}
|