|
|
@@ -17,6 +17,8 @@ class _SettingsPageState extends ConsumerState<SettingsPage> {
|
|
|
final _webdavUserCtrl = TextEditingController();
|
|
|
final _webdavPassCtrl = TextEditingController();
|
|
|
bool _isConnecting = false;
|
|
|
+ bool _webdavConfigured = false;
|
|
|
+ bool _showWebdavForm = false;
|
|
|
String? _error;
|
|
|
|
|
|
@override
|
|
|
@@ -33,10 +35,14 @@ class _SettingsPageState extends ConsumerState<SettingsPage> {
|
|
|
final api = ref.read(apiServiceProvider);
|
|
|
try {
|
|
|
final data = await api.getWebDAVConfig();
|
|
|
- if (data['configured'] == true) {
|
|
|
- _webdavUrlCtrl.text = data['url'] ?? '';
|
|
|
- _webdavUserCtrl.text = data['username'] ?? '';
|
|
|
- }
|
|
|
+ setState(() {
|
|
|
+ _webdavConfigured = data['configured'] == true;
|
|
|
+ _showWebdavForm = !_webdavConfigured;
|
|
|
+ if (_webdavConfigured) {
|
|
|
+ _webdavUrlCtrl.text = data['url'] ?? '';
|
|
|
+ _webdavUserCtrl.text = data['username'] ?? '';
|
|
|
+ }
|
|
|
+ });
|
|
|
} catch (_) {}
|
|
|
}
|
|
|
|
|
|
@@ -53,12 +59,13 @@ class _SettingsPageState extends ConsumerState<SettingsPage> {
|
|
|
setState(() { _isConnecting = true; _error = null; });
|
|
|
final ok = await ref.read(connectionProvider.notifier).connect(url, token);
|
|
|
if (!mounted) return;
|
|
|
- setState(() { _isConnecting = false; if (!ok) _error = '连接失败'; });
|
|
|
+ setState(() { _isConnecting = false; if (!ok) _error = '连接失败'; else _loadWebDAVConfig(); });
|
|
|
}
|
|
|
|
|
|
Future<void> _disconnect() async {
|
|
|
await ref.read(connectionProvider.notifier).disconnect();
|
|
|
_urlCtrl.clear(); _tokenCtrl.clear();
|
|
|
+ _webdavConfigured = false; _showWebdavForm = false;
|
|
|
}
|
|
|
|
|
|
Future<void> _saveWebDAV() async {
|
|
|
@@ -69,6 +76,10 @@ class _SettingsPageState extends ConsumerState<SettingsPage> {
|
|
|
_webdavUserCtrl.text.trim(),
|
|
|
_webdavPassCtrl.text.trim(),
|
|
|
);
|
|
|
+ setState(() {
|
|
|
+ _webdavConfigured = true;
|
|
|
+ _showWebdavForm = false;
|
|
|
+ });
|
|
|
if (mounted) {
|
|
|
ScaffoldMessenger.of(context).showSnackBar(
|
|
|
const SnackBar(content: Text('WebDAV 配置已保存')),
|
|
|
@@ -159,41 +170,72 @@ class _SettingsPageState extends ConsumerState<SettingsPage> {
|
|
|
// WebDAV 配置
|
|
|
if (isConfigured) ...[
|
|
|
Card(
|
|
|
- child: Padding(
|
|
|
- padding: const EdgeInsets.all(16),
|
|
|
- child: Column(
|
|
|
- crossAxisAlignment: CrossAxisAlignment.start,
|
|
|
- children: [
|
|
|
- Text('WebDAV 远程备份', style: Theme.of(context).textTheme.titleMedium),
|
|
|
- const SizedBox(height: 12),
|
|
|
- TextField(
|
|
|
- controller: _webdavUrlCtrl,
|
|
|
- decoration: const InputDecoration(
|
|
|
- labelText: 'WebDAV 地址', hintText: 'https://nas.example.com/remote.php/dav/files/user/',
|
|
|
- border: OutlineInputBorder(), isDense: true,
|
|
|
+ child: _webdavConfigured && !_showWebdavForm
|
|
|
+ ? ListTile(
|
|
|
+ leading: const Icon(Icons.cloud_done, color: Colors.green),
|
|
|
+ title: const Text('WebDAV 已配置'),
|
|
|
+ subtitle: Text(_webdavUrlCtrl.text),
|
|
|
+ trailing: TextButton(
|
|
|
+ onPressed: () => setState(() => _showWebdavForm = true),
|
|
|
+ child: const Text('修改'),
|
|
|
),
|
|
|
- ),
|
|
|
- const SizedBox(height: 8),
|
|
|
- TextField(
|
|
|
- controller: _webdavUserCtrl,
|
|
|
- decoration: const InputDecoration(
|
|
|
- labelText: '用户名', border: OutlineInputBorder(), isDense: true,
|
|
|
+ )
|
|
|
+ : Padding(
|
|
|
+ padding: const EdgeInsets.all(16),
|
|
|
+ child: Column(
|
|
|
+ crossAxisAlignment: CrossAxisAlignment.start,
|
|
|
+ children: [
|
|
|
+ Text('WebDAV 远程备份', style: Theme.of(context).textTheme.titleMedium),
|
|
|
+ const SizedBox(height: 8),
|
|
|
+ Text('备份 bank.db 到坚果云等 WebDAV 服务器',
|
|
|
+ style: Theme.of(context).textTheme.bodySmall),
|
|
|
+ const SizedBox(height: 12),
|
|
|
+ TextField(
|
|
|
+ controller: _webdavUrlCtrl,
|
|
|
+ decoration: const InputDecoration(
|
|
|
+ labelText: 'WebDAV 地址',
|
|
|
+ hintText: 'https://dav.jianguoyun.com/dav/',
|
|
|
+ border: OutlineInputBorder(), isDense: true,
|
|
|
+ ),
|
|
|
+ ),
|
|
|
+ const SizedBox(height: 8),
|
|
|
+ TextField(
|
|
|
+ controller: _webdavUserCtrl,
|
|
|
+ decoration: const InputDecoration(
|
|
|
+ labelText: '用户名', border: OutlineInputBorder(), isDense: true,
|
|
|
+ ),
|
|
|
+ ),
|
|
|
+ const SizedBox(height: 8),
|
|
|
+ TextField(
|
|
|
+ controller: _webdavPassCtrl,
|
|
|
+ decoration: const InputDecoration(
|
|
|
+ labelText: '密码', border: OutlineInputBorder(), isDense: true,
|
|
|
+ ),
|
|
|
+ obscureText: true,
|
|
|
+ ),
|
|
|
+ const SizedBox(height: 12),
|
|
|
+ Row(
|
|
|
+ children: [
|
|
|
+ Expanded(
|
|
|
+ child: FilledButton.tonal(
|
|
|
+ onPressed: _saveWebDAV,
|
|
|
+ child: const Text('保存'),
|
|
|
+ ),
|
|
|
+ ),
|
|
|
+ if (_webdavConfigured) ...[
|
|
|
+ const SizedBox(width: 8),
|
|
|
+ Expanded(
|
|
|
+ child: OutlinedButton(
|
|
|
+ onPressed: () => setState(() => _showWebdavForm = false),
|
|
|
+ child: const Text('取消'),
|
|
|
+ ),
|
|
|
+ ),
|
|
|
+ ],
|
|
|
+ ],
|
|
|
+ ),
|
|
|
+ ],
|
|
|
),
|
|
|
),
|
|
|
- const SizedBox(height: 8),
|
|
|
- TextField(
|
|
|
- controller: _webdavPassCtrl,
|
|
|
- decoration: const InputDecoration(
|
|
|
- labelText: '密码', border: OutlineInputBorder(), isDense: true,
|
|
|
- ),
|
|
|
- obscureText: true,
|
|
|
- ),
|
|
|
- const SizedBox(height: 12),
|
|
|
- SizedBox(width: double.infinity,
|
|
|
- child: FilledButton.tonal(onPressed: _saveWebDAV, child: const Text('保存 WebDAV 配置'))),
|
|
|
- ],
|
|
|
- ),
|
|
|
- ),
|
|
|
),
|
|
|
],
|
|
|
|