more-configs
Felix 10 months ago
parent 3aa084801e
commit db22c750f8

@ -44,10 +44,27 @@ class _ProxmoxListerState extends State<ProxmoxListerView> {
Future<ProxmoxNodeMap> getVms() async {
await settings.loadSettings();
final protocol = settings.get("protocol", 'https://');
final hostname = settings.get("hostname", "");
final username = settings.get("username", "");
final password = settings.get("password", "");
var port = settings.get("port", 0);
if (hostname.isEmpty) return {};
if (port == 0) {
if (settings.get("protocol", 'https://') == 'https://') {
port = 443;
} else {
port = 80;
}
}
_service = ProxmoxWebService(
hostname: settings.hostname,
username: settings.username,
password: settings.password,
protocol: protocol,
hostname: hostname,
port: port,
username: username,
password: password,
);
final success = await _service.authenticate();
if (!success) {

@ -6,12 +6,16 @@ import 'model.dart';
class ProxmoxWebService {
ProxmoxWebService({
this.hostname = "",
this.username = "",
this.password = "",
required this.protocol,
required this.hostname,
required this.port,
required this.username,
required this.password,
});
final String protocol;
final String hostname;
final int port;
final String username;
final String password;

@ -1,5 +1,4 @@
import 'package:flutter/material.dart';
import 'package:pi_dashboard/logger.dart';
import 'settings_service.dart';
@ -9,48 +8,50 @@ import 'settings_service.dart';
/// Controllers glue Data Services to Flutter Widgets. The SettingsController
/// uses the SettingsService to store and retrieve user settings.
class SettingsController with ChangeNotifier {
SettingsController(this._settingsService);
SettingsController(
this._settingsService,
) : _stringOpts = {},
_boolOpts = {},
_intOpts = {};
final SettingsService _settingsService;
Future<void> loadSettings() async {
_themeMode = await _settingsService.themeMode();
_hostname = await _settingsService.keyStr("hostname");
_username = await _settingsService.keyStr("username");
_password = await _settingsService.keyStr("password");
_stringOpts["protocol"] = await _settingsService.get<String>("protocol");
_stringOpts["hostname"] = await _settingsService.get("hostname");
_intOpts["port"] = await _settingsService.get("port");
_stringOpts["username"] = await _settingsService.get("username");
_stringOpts["password"] = await _settingsService.get("password");
_boolOpts["lockApp"] = await _settingsService.get("lockApp");
// Important! Inform listeners a change has occurred.
notifyListeners();
}
late ThemeMode _themeMode;
ThemeMode get themeMode => _themeMode;
late String _hostname;
String get hostname => _hostname;
late String _username;
String get username => _username;
late String _password;
String get password => _password;
final Map<String, String?> _stringOpts;
final Map<String, bool?> _boolOpts;
final Map<String, int?> _intOpts;
Future<void> _setKey(String key, String value) async {
Future<void> set<T>(String key, T? value) async {
if (value == null) return;
await _settingsService.set(key, value);
notifyListeners();
await _settingsService.setKeyStr(key, value);
}
Future<void> setHostname(String newHostname) async {
_hostname = newHostname;
await _setKey("hostname", hostname);
Log().debug("Hostname update: $hostname");
}
Future<void> setUsername(String newUsername) async {
_username = newUsername;
await _setKey("username", username);
Log().debug("username update: $username");
}
Future<void> setPassword(String newPassword) async {
_password = newPassword;
await _setKey("password", password);
Log().debug("password update");
T get<T>(String key, T default_) {
if (T is String) {
return _stringOpts.containsKey(key) ? _stringOpts[key] as T : default_;
} else if (T is bool) {
return _boolOpts.containsKey(key) ? _boolOpts[key] as T : default_;
} else if (T is int) {
return _intOpts.containsKey(key) ? _intOpts[key] as T : default_;
} else {
throw Exception("this type is not implemented");
}
}
/// Update and persist the ThemeMode based on the user's selection.
Future<void> updateThemeMode(ThemeMode? newThemeMode) async {
if (newThemeMode == null) return;

@ -22,14 +22,30 @@ class SettingsService {
prefs.setInt("theme", theme.index);
}
Future<String> keyStr(String key) async {
Future<T?> get<T>(String key) async {
final SharedPreferences prefs = await SharedPreferences.getInstance();
final res = prefs.getString(key);
if (res == null) return "";
T? res;
if (T == String) {
res = prefs.getString(key) as T?;
} else if (T == bool) {
res = prefs.getBool(key) as T?;
} else if (T == int) {
res = prefs.getInt(key) as T?;
} else {
res = null as T?;
}
return res;
}
Future<void> setKeyStr(String key, String value) async {
Future<void> set<T>(String k, T v) async {
final SharedPreferences prefs = await SharedPreferences.getInstance();
await prefs.setString(key, value);
if (T is String) {
await prefs.setString(k, v as String);
} else if (T is bool) {
await prefs.setBool(k, v as bool);
} else if (T is int) {
await prefs.setInt(k, v as int);
}
}
}

@ -20,57 +20,96 @@ class SettingsView extends StatelessWidget {
title: const Text('Settings'),
),
body: Padding(
padding: const EdgeInsets.all(16),
child: Column(
padding: const EdgeInsets.all(16),
child: Column(
children: [
DropdownButton<ThemeMode>(
value: controller.themeMode,
onChanged: controller.updateThemeMode,
items: const [
DropdownMenuItem(
value: ThemeMode.system,
child: Text('System Theme'),
),
DropdownMenuItem(
value: ThemeMode.light,
child: Text('Light Theme'),
),
DropdownMenuItem(
value: ThemeMode.dark,
child: Text('Dark Theme'),
)
],
),
TextFormField(
decoration: const InputDecoration(
border: UnderlineInputBorder(),
labelText: "Hostname",
),
initialValue: controller.hostname,
onChanged: controller.setHostname,
),
TextFormField(
decoration: const InputDecoration(
border: UnderlineInputBorder(),
labelText: "Username",
),
initialValue: controller.username,
onChanged: controller.setUsername,
),
TextFormField(
decoration: const InputDecoration(
border: UnderlineInputBorder(),
labelText: "Password",
),
obscureText: true,
enableSuggestions: false,
autocorrect: false,
initialValue: controller.password,
onChanged: controller.setPassword,
),
],
themeSelector(),
...hostSelector(),
...loginForm(),
],
),
),
);
}
Widget themeSelector() {
return DropdownButton<ThemeMode>(
value: controller.themeMode,
onChanged: controller.updateThemeMode,
items: const [
DropdownMenuItem(
value: ThemeMode.system,
child: Text('System Theme'),
),
DropdownMenuItem(
value: ThemeMode.light,
child: Text('Light Theme'),
),
DropdownMenuItem(
value: ThemeMode.dark,
child: Text('Dark Theme'),
)
],
);
}
List<Widget> hostSelector() {
return [
DropdownButton<String?>(
value: controller.get('protocol', 'https://'),
onChanged: (v) => controller.set('protocol', v),
items: const [
DropdownMenuItem(
value: 'https://',
child: Text('https://'),
),
DropdownMenuItem(
value: 'http://',
child: Text('http://'),
)
],
),
TextFormField(
decoration: const InputDecoration(
border: UnderlineInputBorder(),
labelText: "Hostname",
),
initialValue: controller.get('hostname', ''),
onChanged: (v) => controller.set('hostname', v),
),
TextFormField(
decoration: const InputDecoration(
border: UnderlineInputBorder(),
labelText: "Port",
),
keyboardType: TextInputType.number,
initialValue: controller.get("port", 0).toString(),
onChanged: (v) => controller.set('port', int.parse(v)),
),
];
}
List<Widget> loginForm() {
return [
TextFormField(
decoration: const InputDecoration(
border: UnderlineInputBorder(),
labelText: "Username",
),
initialValue: controller.get('username', ''),
onChanged: (v) => controller.set('username', v),
),
TextFormField(
decoration: const InputDecoration(
border: UnderlineInputBorder(),
labelText: "Password",
),
obscureText: true,
enableSuggestions: false,
autocorrect: false,
initialValue: controller.get('password', ''),
onChanged: (v) => controller.set('password', v),
),
];
}
}

Loading…
Cancel
Save