feat: add settings page for URL configuration

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
Misaka
2026-05-07 19:57:28 +08:00
parent d6bb5afb3c
commit c3b8ce02a2

View File

@@ -0,0 +1,104 @@
import 'package:flutter/material.dart';
import 'package:shared_preferences/shared_preferences.dart';
import 'package:pad_scanner/services/api_service.dart';
class SettingsPage extends StatefulWidget {
const SettingsPage({super.key});
@override
State<SettingsPage> createState() => _SettingsPageState();
}
class _SettingsPageState extends State<SettingsPage> {
final _controller = TextEditingController();
final _apiService = ApiService();
bool _saving = false;
@override
void initState() {
super.initState();
_loadUrl();
}
Future<void> _loadUrl() async {
final prefs = await SharedPreferences.getInstance();
_controller.text = prefs.getString('api_url') ?? '';
}
Future<void> _saveUrl() async {
setState(() => _saving = true);
final prefs = await SharedPreferences.getInstance();
await prefs.setString('api_url', _controller.text.trim());
setState(() => _saving = false);
if (mounted) {
ScaffoldMessenger.of(context).showSnackBar(
const SnackBar(content: Text('URL saved')),
);
}
}
Future<void> _testConnection() async {
final url = _controller.text.trim();
if (url.isEmpty) {
ScaffoldMessenger.of(context).showSnackBar(
const SnackBar(content: Text('Please enter a URL first')),
);
return;
}
final ok = await _apiService.sendScanData(
url,
barcode: 'TEST_BARCODE',
codeType: 'TEST',
);
if (mounted) {
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(content: Text(ok ? 'Connection OK' : 'Connection failed')),
);
}
}
@override
void dispose() {
_controller.dispose();
super.dispose();
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: const Text('Settings')),
body: Padding(
padding: const EdgeInsets.all(16),
child: Column(
crossAxisAlignment: CrossAxisAlignment.stretch,
children: [
TextField(
controller: _controller,
decoration: const InputDecoration(
labelText: 'API URL',
hintText: 'http://192.168.1.100:8000/scan',
border: OutlineInputBorder(),
),
keyboardType: TextInputType.url,
),
const SizedBox(height: 16),
ElevatedButton(
onPressed: _saving ? null : _saveUrl,
child: _saving
? const SizedBox(
width: 20,
height: 20,
child: CircularProgressIndicator(strokeWidth: 2))
: const Text('Save'),
),
const SizedBox(height: 8),
OutlinedButton(
onPressed: _testConnection,
child: const Text('Test Connection'),
),
],
),
),
);
}
}