Files
QingTing-Player/lib/pages/webdav_setup_page.dart
T

263 lines
8.7 KiB
Dart
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
import 'package:flutter/material.dart';
import '../services/webdav_service.dart';
import 'webdav_file_list_page.dart';
import '../base/base_state.dart';
class WebDAVSetupPage extends StatefulWidget {
const WebDAVSetupPage({super.key});
@override
State<WebDAVSetupPage> createState() => _WebDAVSetupPageState();
}
class _WebDAVSetupPageState extends BaseState<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();
safeSetState(() {
_isConnected = hasCred;
_statusText = hasCred ? '已连接' : '未连接';
if (hasCred) {
_baseUrlController.text = WebDAVService.instance.baseUrl ?? '';
}
});
}
Future<void> _connect() async {
if (!_formKey.currentState!.validate()) return;
safeSetState(() => _isLoading = true);
try {
await WebDAVService.instance.saveCredentials(
_baseUrlController.text.trim(),
_usernameController.text.trim(),
_passwordController.text.trim(),
);
// 验证连接
await WebDAVService.instance.getMusicFiles();
safeSetState(() {
_isConnected = true;
_statusText = '已连接';
_isLoading = false;
});
if (mounted) {
ScaffoldMessenger.of(context).showSnackBar(
const SnackBar(
content: Text('✅ WebDAV 连接成功'),
backgroundColor: Color(0xFF4CAF50),
),
);
// ⭐ 用 pushReplacement 替换当前页面(WebDAVSetupPage
// 此时栈底是 HomePage,替换后栈变为 [HomePage, WebDAVFileListPage]
Navigator.pushReplacement(
context,
MaterialPageRoute(
builder: (_) => const WebDAVFileListPage(),
),
);
}
} catch (e) {
safeSetState(() {
_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();
safeSetState(() {
_isConnected = false;
_statusText = '未连接';
});
if (mounted) {
ScaffoldMessenger.of(context).showSnackBar(
const SnackBar(
content: Text('已断开连接'),
backgroundColor: Colors.grey,
),
);
Navigator.pop(context);
}
}
@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,
leading: IconButton(
icon: const Icon(Icons.arrow_back_ios_new),
onPressed: () => Navigator.pop(context),
),
),
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 ? '已连接' : '连接'),
),
),
],
),
),
),
);
}
}