Flutter Android login vault: local DB (id+base64 content), email/Google auth, dashboard search/edit/swipe-delete, dark/system theme, minSdk 29
This commit is contained in:
111
lib/settings_screen.dart
Normal file
111
lib/settings_screen.dart
Normal file
@@ -0,0 +1,111 @@
|
||||
import 'dart:io';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter/services.dart';
|
||||
import 'package:login_vault_app/auth_service.dart';
|
||||
import 'package:login_vault_app/theme_provider.dart';
|
||||
|
||||
/// Settings: change app password, switch theme (dark/system), and Exit.
|
||||
class SettingsScreen extends StatefulWidget {
|
||||
final AuthService auth;
|
||||
final ThemeProvider theme;
|
||||
const SettingsScreen({super.key, required this.auth, required this.theme});
|
||||
|
||||
@override
|
||||
State<SettingsScreen> createState() => _SettingsScreenState();
|
||||
}
|
||||
|
||||
class _SettingsScreenState extends State<SettingsScreen> {
|
||||
final _oldCtrl = TextEditingController();
|
||||
final _newCtrl = TextEditingController();
|
||||
String? _msg;
|
||||
|
||||
Future<void> _changePassword() async {
|
||||
final oldP = _oldCtrl.text;
|
||||
final newP = _newCtrl.text;
|
||||
if (newP.isEmpty) {
|
||||
setState(() => _msg = 'Password baru wajib diisi');
|
||||
return;
|
||||
}
|
||||
final stored = await widget.auth.getAppPassword();
|
||||
if (stored != null && stored != '__google__' && stored != oldP) {
|
||||
setState(() => _msg = 'Password lama salah');
|
||||
return;
|
||||
}
|
||||
await widget.auth.changePassword(newP);
|
||||
setState(() => _msg = 'Password aplikasi berhasil diubah');
|
||||
_oldCtrl.clear();
|
||||
_newCtrl.clear();
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Scaffold(
|
||||
appBar: AppBar(title: const Text('Pengaturan')),
|
||||
body: ListView(
|
||||
padding: const EdgeInsets.all(16),
|
||||
children: [
|
||||
const Text('Tema',
|
||||
style: TextStyle(fontWeight: FontWeight.bold)),
|
||||
ListTile(
|
||||
title: const Text('Gelap (Dark)'),
|
||||
leading: const Icon(Icons.dark_mode),
|
||||
trailing: Radio<ThemeMode>(
|
||||
value: ThemeMode.dark,
|
||||
groupValue: widget.theme.mode,
|
||||
onChanged: (m) => widget.theme.setMode(m!),
|
||||
),
|
||||
onTap: () => widget.theme.setMode(ThemeMode.dark),
|
||||
),
|
||||
ListTile(
|
||||
title: const Text('Sistem (System)'),
|
||||
leading: const Icon(Icons.brightness_auto),
|
||||
trailing: Radio<ThemeMode>(
|
||||
value: ThemeMode.system,
|
||||
groupValue: widget.theme.mode,
|
||||
onChanged: (m) => widget.theme.setMode(m!),
|
||||
),
|
||||
onTap: () => widget.theme.setMode(ThemeMode.system),
|
||||
),
|
||||
const Divider(),
|
||||
const Text('Ubah Password Aplikasi',
|
||||
style: TextStyle(fontWeight: FontWeight.bold)),
|
||||
TextField(
|
||||
controller: _oldCtrl,
|
||||
obscureText: true,
|
||||
decoration: const InputDecoration(labelText: 'Password lama'),
|
||||
),
|
||||
TextField(
|
||||
controller: _newCtrl,
|
||||
obscureText: true,
|
||||
decoration: const InputDecoration(labelText: 'Password baru'),
|
||||
),
|
||||
const SizedBox(height: 8),
|
||||
ElevatedButton(
|
||||
onPressed: _changePassword,
|
||||
child: const Text('Simpan Password'),
|
||||
),
|
||||
if (_msg != null)
|
||||
Padding(
|
||||
padding: const EdgeInsets.only(top: 8),
|
||||
child: Text(_msg!,
|
||||
style: const TextStyle(color: Colors.green)),
|
||||
),
|
||||
const Divider(),
|
||||
ListTile(
|
||||
leading: const Icon(Icons.exit_to_app),
|
||||
title: const Text('Keluar (Exit)'),
|
||||
onTap: () {
|
||||
// On Android, pop the whole stack then ask the system to close.
|
||||
Navigator.of(context).popUntil((r) => r.isFirst);
|
||||
if (Platform.isAndroid) {
|
||||
SystemNavigator.pop();
|
||||
} else {
|
||||
exit(0);
|
||||
}
|
||||
},
|
||||
),
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user