feat: persist server settings
This commit is contained in:
@@ -1,10 +1,14 @@
|
|||||||
import 'package:flutter_secure_storage/flutter_secure_storage.dart';
|
import 'package:flutter_secure_storage/flutter_secure_storage.dart';
|
||||||
|
|
||||||
|
import '../../../domain/models/server_config.dart';
|
||||||
|
|
||||||
typedef Credentials = ({String username, String password});
|
typedef Credentials = ({String username, String password});
|
||||||
|
|
||||||
class CredentialStore {
|
class CredentialStore {
|
||||||
static const _usernameKey = 'localiserd_username';
|
static const _usernameKey = 'localiserd_username';
|
||||||
static const _passwordKey = 'localiserd_password';
|
static const _passwordKey = 'localiserd_password';
|
||||||
|
static const _hostKey = 'localiserd_host';
|
||||||
|
static const _portKey = 'localiserd_port';
|
||||||
|
|
||||||
final _storage = const FlutterSecureStorage();
|
final _storage = const FlutterSecureStorage();
|
||||||
|
|
||||||
@@ -24,8 +28,28 @@ class CredentialStore {
|
|||||||
return (username: username, password: password);
|
return (username: username, password: password);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Future<void> saveServer(ServerConfig config) => Future.wait([
|
||||||
|
_storage.write(key: _hostKey, value: config.host),
|
||||||
|
_storage.write(key: _portKey, value: config.port.toString()),
|
||||||
|
]).then((_) {});
|
||||||
|
|
||||||
|
Future<ServerConfig?> loadServer() async {
|
||||||
|
final results = await Future.wait([
|
||||||
|
_storage.read(key: _hostKey),
|
||||||
|
_storage.read(key: _portKey),
|
||||||
|
]);
|
||||||
|
final host = results[0];
|
||||||
|
final portStr = results[1];
|
||||||
|
if (host == null || portStr == null) return null;
|
||||||
|
final port = int.tryParse(portStr);
|
||||||
|
if (port == null) return null;
|
||||||
|
return ServerConfig(host: host, port: port);
|
||||||
|
}
|
||||||
|
|
||||||
Future<void> clear() => Future.wait([
|
Future<void> clear() => Future.wait([
|
||||||
_storage.delete(key: _usernameKey),
|
_storage.delete(key: _usernameKey),
|
||||||
_storage.delete(key: _passwordKey),
|
_storage.delete(key: _passwordKey),
|
||||||
|
_storage.delete(key: _hostKey),
|
||||||
|
_storage.delete(key: _portKey),
|
||||||
]).then((_) {});
|
]).then((_) {});
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -18,12 +18,6 @@ class _LoginScreenState extends ConsumerState<LoginScreen> {
|
|||||||
bool _loading = false;
|
bool _loading = false;
|
||||||
String? _error;
|
String? _error;
|
||||||
|
|
||||||
@override
|
|
||||||
void initState() {
|
|
||||||
super.initState();
|
|
||||||
_tryAutoLogin();
|
|
||||||
}
|
|
||||||
|
|
||||||
@override
|
@override
|
||||||
void dispose() {
|
void dispose() {
|
||||||
_usernameController.dispose();
|
_usernameController.dispose();
|
||||||
@@ -31,18 +25,7 @@ class _LoginScreenState extends ConsumerState<LoginScreen> {
|
|||||||
super.dispose();
|
super.dispose();
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<void> _tryAutoLogin() async {
|
Future<void> _login(String username, String password) async {
|
||||||
final store = ref.read(credentialStoreProvider);
|
|
||||||
final saved = await store.load();
|
|
||||||
if (saved == null || !mounted) return;
|
|
||||||
|
|
||||||
_usernameController.text = saved.username;
|
|
||||||
_passwordController.text = saved.password;
|
|
||||||
await _login(saved.username, saved.password, saveCredentials: false);
|
|
||||||
}
|
|
||||||
|
|
||||||
Future<void> _login(String username, String password,
|
|
||||||
{bool saveCredentials = true}) async {
|
|
||||||
setState(() {
|
setState(() {
|
||||||
_loading = true;
|
_loading = true;
|
||||||
_error = null;
|
_error = null;
|
||||||
@@ -59,11 +42,9 @@ class _LoginScreenState extends ConsumerState<LoginScreen> {
|
|||||||
await realtime.connect();
|
await realtime.connect();
|
||||||
ref.read(realtimeDataClientProvider.notifier).state = realtime;
|
ref.read(realtimeDataClientProvider.notifier).state = realtime;
|
||||||
|
|
||||||
if (saveCredentials) {
|
await ref
|
||||||
await ref
|
.read(credentialStoreProvider)
|
||||||
.read(credentialStoreProvider)
|
.save((username: username, password: password));
|
||||||
.save((username: username, password: password));
|
|
||||||
}
|
|
||||||
|
|
||||||
if (mounted) context.go('/floorplan');
|
if (mounted) context.go('/floorplan');
|
||||||
} on Exception catch (e) {
|
} on Exception catch (e) {
|
||||||
|
|||||||
@@ -59,12 +59,13 @@ class _ServerDiscoveryScreenState extends ConsumerState<ServerDiscoveryScreen> {
|
|||||||
await OnboardingClient(config: config).getChecklist();
|
await OnboardingClient(config: config).getChecklist();
|
||||||
|
|
||||||
ref.read(serverConfigProvider.notifier).state = config;
|
ref.read(serverConfigProvider.notifier).state = config;
|
||||||
|
await ref.read(credentialStoreProvider).saveServer(config);
|
||||||
|
|
||||||
if (!mounted) return;
|
if (!mounted) return;
|
||||||
if (!checklist.hasAdmin) {
|
if (!checklist.hasAdmin) {
|
||||||
context.go('/onboarding');
|
context.push('/onboarding');
|
||||||
} else {
|
} else {
|
||||||
context.go('/login');
|
context.push('/login');
|
||||||
}
|
}
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
setState(() => _error = e.toString());
|
setState(() => _error = e.toString());
|
||||||
|
|||||||
Reference in New Issue
Block a user