|
|
@@ -19,31 +19,46 @@ class _SettingsPageState extends ConsumerState<SettingsPage> {
|
|
|
bool _isConnecting = false;
|
|
|
bool _webdavConfigured = false;
|
|
|
bool _showWebdavForm = false;
|
|
|
+ bool _backingUp = false;
|
|
|
String? _error;
|
|
|
|
|
|
@override
|
|
|
void initState() {
|
|
|
super.initState();
|
|
|
- final conn = ref.read(connectionProvider);
|
|
|
- if (conn.serverUrl != null) {
|
|
|
- _urlCtrl.text = conn.serverUrl!;
|
|
|
- _loadWebDAVConfig();
|
|
|
- }
|
|
|
+ // Delay to ensure connection is fully initialized, then load
|
|
|
+ Future.delayed(const Duration(milliseconds: 500), () {
|
|
|
+ if (mounted) _loadWebDAVConfig();
|
|
|
+ });
|
|
|
}
|
|
|
|
|
|
Future<void> _loadWebDAVConfig() async {
|
|
|
final api = ref.read(apiServiceProvider);
|
|
|
try {
|
|
|
final data = await api.getWebDAVConfig();
|
|
|
+ final configured = data['configured'] == true;
|
|
|
+ ref.read(webdavConfiguredProvider.notifier).state = configured;
|
|
|
+ ref.read(webdavUrlProvider.notifier).state = data['url'] ?? '';
|
|
|
+ ref.read(webdavUserProvider.notifier).state = data['username'] ?? '';
|
|
|
setState(() {
|
|
|
- _webdavConfigured = data['configured'] == true;
|
|
|
- _showWebdavForm = !_webdavConfigured;
|
|
|
- if (_webdavConfigured) {
|
|
|
+ _webdavConfigured = configured;
|
|
|
+ _showWebdavForm = !configured;
|
|
|
+ if (configured) {
|
|
|
_webdavUrlCtrl.text = data['url'] ?? '';
|
|
|
_webdavUserCtrl.text = data['username'] ?? '';
|
|
|
}
|
|
|
});
|
|
|
- } catch (_) {}
|
|
|
+ } catch (_) {
|
|
|
+ // Retry once
|
|
|
+ try {
|
|
|
+ final data = await api.getWebDAVConfig();
|
|
|
+ final configured = data['configured'] == true;
|
|
|
+ ref.read(webdavConfiguredProvider.notifier).state = configured;
|
|
|
+ setState(() {
|
|
|
+ _webdavConfigured = configured;
|
|
|
+ _showWebdavForm = !configured;
|
|
|
+ });
|
|
|
+ } catch (_) {}
|
|
|
+ }
|
|
|
}
|
|
|
|
|
|
@override
|
|
|
@@ -69,12 +84,13 @@ class _SettingsPageState extends ConsumerState<SettingsPage> {
|
|
|
}
|
|
|
|
|
|
Future<void> _triggerFullBackup() async {
|
|
|
+ setState(() => _backingUp = true);
|
|
|
final api = ref.read(apiServiceProvider);
|
|
|
try {
|
|
|
await api.triggerFullBackup();
|
|
|
if (mounted) {
|
|
|
ScaffoldMessenger.of(context).showSnackBar(
|
|
|
- const SnackBar(content: Text('全量备份已触发')),
|
|
|
+ const SnackBar(content: Text('全量备份完成'), duration: Duration(seconds: 2)),
|
|
|
);
|
|
|
}
|
|
|
} catch (e) {
|
|
|
@@ -84,6 +100,7 @@ class _SettingsPageState extends ConsumerState<SettingsPage> {
|
|
|
);
|
|
|
}
|
|
|
}
|
|
|
+ if (mounted) setState(() => _backingUp = false);
|
|
|
}
|
|
|
|
|
|
Future<void> _saveWebDAV() async {
|
|
|
@@ -116,6 +133,7 @@ class _SettingsPageState extends ConsumerState<SettingsPage> {
|
|
|
Widget build(BuildContext context) {
|
|
|
final connState = ref.watch(connectionProvider);
|
|
|
final isConfigured = connState.status == ConnectionStatus.configured;
|
|
|
+ final webdavConfigured = ref.watch(webdavConfiguredProvider);
|
|
|
|
|
|
return Scaffold(
|
|
|
appBar: AppBar(title: const Text('设置')),
|
|
|
@@ -188,7 +206,7 @@ class _SettingsPageState extends ConsumerState<SettingsPage> {
|
|
|
// WebDAV 配置
|
|
|
if (isConfigured) ...[
|
|
|
Card(
|
|
|
- child: _webdavConfigured && !_showWebdavForm
|
|
|
+ child: webdavConfigured && !_showWebdavForm
|
|
|
? ListTile(
|
|
|
leading: const Icon(Icons.cloud_done, color: Colors.green),
|
|
|
title: const Text('WebDAV 已配置'),
|
|
|
@@ -274,9 +292,11 @@ class _SettingsPageState extends ConsumerState<SettingsPage> {
|
|
|
SizedBox(
|
|
|
width: double.infinity,
|
|
|
child: OutlinedButton.icon(
|
|
|
- onPressed: _triggerFullBackup,
|
|
|
- icon: const Icon(Icons.backup),
|
|
|
- label: const Text('全量备份'),
|
|
|
+ onPressed: _backingUp ? null : _triggerFullBackup,
|
|
|
+ icon: _backingUp
|
|
|
+ ? const SizedBox(width: 18, height: 18, child: CircularProgressIndicator(strokeWidth: 2))
|
|
|
+ : const Icon(Icons.backup),
|
|
|
+ label: Text(_backingUp ? '备份中...' : '全量备份'),
|
|
|
),
|
|
|
),
|
|
|
],
|