Create management portal in Flutter #39

This commit is contained in:
Scott E. Graves 2025-03-06 12:50:31 -06:00
parent d2065af398
commit 8da6008e29
3 changed files with 65 additions and 77 deletions

View File

@ -110,7 +110,7 @@ class _AddMountScreenState extends State<AddMountScreen> {
child: MountSettingsWidget( child: MountSettingsWidget(
isAdd: true, isAdd: true,
mount: _mount!, mount: _mount!,
onChanged: (settings) => _settings[_mountType] = settings, settings: _settings[_mountType]!,
showAdvanced: _showAdvanced, showAdvanced: _showAdvanced,
), ),
), ),

View File

@ -1,3 +1,5 @@
import 'dart:convert';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:repertory/models/mount.dart'; import 'package:repertory/models/mount.dart';
import 'package:repertory/widgets/mount_settings.dart'; import 'package:repertory/widgets/mount_settings.dart';
@ -34,6 +36,7 @@ class _EditMountScreenState extends State<EditMountScreen> {
), ),
body: MountSettingsWidget( body: MountSettingsWidget(
mount: widget.mount, mount: widget.mount,
settings: jsonDecode(jsonEncode(widget.mount.mountConfig.settings)),
showAdvanced: _showAdvanced, showAdvanced: _showAdvanced,
), ),
); );

View File

@ -1,5 +1,3 @@
import 'dart:convert';
import 'package:collection/collection.dart'; import 'package:collection/collection.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter/services.dart'; import 'package:flutter/services.dart';
@ -12,11 +10,13 @@ class MountSettingsWidget extends StatefulWidget {
final bool showAdvanced; final bool showAdvanced;
final Mount mount; final Mount mount;
final Function? onChanged; final Function? onChanged;
final Map<String, dynamic> settings;
const MountSettingsWidget({ const MountSettingsWidget({
super.key, super.key,
this.isAdd = false, this.isAdd = false,
required this.mount, required this.mount,
this.onChanged, this.onChanged,
required this.settings,
required this.showAdvanced, required this.showAdvanced,
}); });
@ -25,8 +25,6 @@ class MountSettingsWidget extends StatefulWidget {
} }
class _MountSettingsWidgetState extends State<MountSettingsWidget> { class _MountSettingsWidgetState extends State<MountSettingsWidget> {
Map<String, dynamic> _settings = {};
void _addBooleanSetting(list, root, key, value, isAdvanced) { void _addBooleanSetting(list, root, key, value, isAdvanced) {
if (!isAdvanced || widget.showAdvanced) { if (!isAdvanced || widget.showAdvanced) {
list.add( list.add(
@ -37,13 +35,13 @@ class _MountSettingsWidgetState extends State<MountSettingsWidget> {
onPressed: (_) { onPressed: (_) {
setState(() { setState(() {
root[key] = !value; root[key] = !value;
widget.onChanged?.call(_settings); widget.onChanged?.call(widget.settings);
}); });
}, },
onToggle: (bool nextValue) { onToggle: (bool nextValue) {
setState(() { setState(() {
root[key] = nextValue; root[key] = nextValue;
widget.onChanged?.call(_settings); widget.onChanged?.call(widget.settings);
}); });
}, },
), ),
@ -76,7 +74,7 @@ class _MountSettingsWidgetState extends State<MountSettingsWidget> {
onPressed: () { onPressed: () {
setState(() { setState(() {
root[key] = int.parse(updatedValue); root[key] = int.parse(updatedValue);
widget.onChanged?.call(_settings); widget.onChanged?.call(widget.settings);
}); });
Navigator.of(context).pop(); Navigator.of(context).pop();
}, },
@ -121,7 +119,7 @@ class _MountSettingsWidgetState extends State<MountSettingsWidget> {
onChanged: (newValue) { onChanged: (newValue) {
setState(() { setState(() {
root[key] = int.parse(newValue ?? defaultValue.toString()); root[key] = int.parse(newValue ?? defaultValue.toString());
widget.onChanged?.call(_settings); widget.onChanged?.call(widget.settings);
}); });
}, },
items: items:
@ -156,7 +154,7 @@ class _MountSettingsWidgetState extends State<MountSettingsWidget> {
onChanged: (newValue) { onChanged: (newValue) {
setState(() { setState(() {
root[key] = newValue; root[key] = newValue;
widget.onChanged?.call(_settings); widget.onChanged?.call(widget.settings);
}); });
}, },
items: items:
@ -209,7 +207,7 @@ class _MountSettingsWidgetState extends State<MountSettingsWidget> {
onPressed: () { onPressed: () {
setState(() { setState(() {
root[key] = updatedValue; root[key] = updatedValue;
widget.onChanged?.call(_settings); widget.onChanged?.call(widget.settings);
}); });
Navigator.of(context).pop(); Navigator.of(context).pop();
}, },
@ -242,15 +240,15 @@ class _MountSettingsWidgetState extends State<MountSettingsWidget> {
List<SettingsTile> s3ConfigSettings = []; List<SettingsTile> s3ConfigSettings = [];
List<SettingsTile> siaConfigSettings = []; List<SettingsTile> siaConfigSettings = [];
_settings.forEach((key, value) { widget.settings.forEach((key, value) {
if (key == 'ApiAuth') { if (key == 'ApiAuth') {
_addPasswordSetting(commonSettings, _settings, key, value, true); _addPasswordSetting(commonSettings, widget.settings, key, value, true);
} else if (key == 'ApiPort') { } else if (key == 'ApiPort') {
_addIntSetting(commonSettings, _settings, key, value, true); _addIntSetting(commonSettings, widget.settings, key, value, true);
} else if (key == 'ApiUser') { } else if (key == 'ApiUser') {
_addStringSetting( _addStringSetting(
commonSettings, commonSettings,
_settings, widget.settings,
key, key,
value, value,
Icons.person, Icons.person,
@ -259,7 +257,7 @@ class _MountSettingsWidgetState extends State<MountSettingsWidget> {
} else if (key == 'DatabaseType') { } else if (key == 'DatabaseType') {
_addListSetting( _addListSetting(
commonSettings, commonSettings,
_settings, widget.settings,
key, key,
value, value,
databaseTypeList, databaseTypeList,
@ -267,15 +265,15 @@ class _MountSettingsWidgetState extends State<MountSettingsWidget> {
true, true,
); );
} else if (key == 'DownloadTimeoutSeconds') { } else if (key == 'DownloadTimeoutSeconds') {
_addIntSetting(commonSettings, _settings, key, value, true); _addIntSetting(commonSettings, widget.settings, key, value, true);
} else if (key == 'EnableDownloadTimeout') { } else if (key == 'EnableDownloadTimeout') {
_addBooleanSetting(commonSettings, _settings, key, value, true); _addBooleanSetting(commonSettings, widget.settings, key, value, true);
} else if (key == 'EnableDriveEvents') { } else if (key == 'EnableDriveEvents') {
_addBooleanSetting(commonSettings, _settings, key, value, true); _addBooleanSetting(commonSettings, widget.settings, key, value, true);
} else if (key == 'EventLevel') { } else if (key == 'EventLevel') {
_addListSetting( _addListSetting(
commonSettings, commonSettings,
_settings, widget.settings,
key, key,
value, value,
eventLevelList, eventLevelList,
@ -283,19 +281,19 @@ class _MountSettingsWidgetState extends State<MountSettingsWidget> {
false, false,
); );
} else if (key == 'EvictionDelayMinutes') { } else if (key == 'EvictionDelayMinutes') {
_addIntSetting(commonSettings, _settings, key, value, true); _addIntSetting(commonSettings, widget.settings, key, value, true);
} else if (key == 'EvictionUseAccessedTime') { } else if (key == 'EvictionUseAccessedTime') {
_addBooleanSetting(commonSettings, _settings, key, value, true); _addBooleanSetting(commonSettings, widget.settings, key, value, true);
} else if (key == 'MaxCacheSizeBytes') { } else if (key == 'MaxCacheSizeBytes') {
_addIntSetting(commonSettings, _settings, key, value, false); _addIntSetting(commonSettings, widget.settings, key, value, false);
} else if (key == 'MaxUploadCount') { } else if (key == 'MaxUploadCount') {
_addIntSetting(commonSettings, _settings, key, value, true); _addIntSetting(commonSettings, widget.settings, key, value, true);
} else if (key == 'OnlineCheckRetrySeconds') { } else if (key == 'OnlineCheckRetrySeconds') {
_addIntSetting(commonSettings, _settings, key, value, true); _addIntSetting(commonSettings, widget.settings, key, value, true);
} else if (key == 'PreferredDownloadType') { } else if (key == 'PreferredDownloadType') {
_addListSetting( _addListSetting(
commonSettings, commonSettings,
_settings, widget.settings,
key, key,
value, value,
downloadTypeList, downloadTypeList,
@ -303,11 +301,11 @@ class _MountSettingsWidgetState extends State<MountSettingsWidget> {
false, false,
); );
} else if (key == 'RetryReadCount') { } else if (key == 'RetryReadCount') {
_addIntSetting(commonSettings, _settings, key, value, true); _addIntSetting(commonSettings, widget.settings, key, value, true);
} else if (key == 'RingBufferFileSize') { } else if (key == 'RingBufferFileSize') {
_addIntListSetting( _addIntListSetting(
commonSettings, commonSettings,
_settings, widget.settings,
key, key,
value, value,
ringBufferSizeList, ringBufferSizeList,
@ -320,7 +318,7 @@ class _MountSettingsWidgetState extends State<MountSettingsWidget> {
if (subKey == 'EncryptionToken') { if (subKey == 'EncryptionToken') {
_addPasswordSetting( _addPasswordSetting(
encryptConfigSettings, encryptConfigSettings,
_settings[key], widget.settings[key],
subKey, subKey,
subValue, subValue,
false, false,
@ -328,7 +326,7 @@ class _MountSettingsWidgetState extends State<MountSettingsWidget> {
} else if (subKey == 'Path') { } else if (subKey == 'Path') {
_addStringSetting( _addStringSetting(
encryptConfigSettings, encryptConfigSettings,
_settings[key], widget.settings[key],
subKey, subKey,
subValue, subValue,
Icons.folder, Icons.folder,
@ -341,7 +339,7 @@ class _MountSettingsWidgetState extends State<MountSettingsWidget> {
if (subKey == 'AgentString') { if (subKey == 'AgentString') {
_addStringSetting( _addStringSetting(
hostConfigSettings, hostConfigSettings,
_settings[key], widget.settings[key],
subKey, subKey,
subValue, subValue,
Icons.support_agent, Icons.support_agent,
@ -350,7 +348,7 @@ class _MountSettingsWidgetState extends State<MountSettingsWidget> {
} else if (subKey == 'ApiPassword') { } else if (subKey == 'ApiPassword') {
_addPasswordSetting( _addPasswordSetting(
hostConfigSettings, hostConfigSettings,
_settings[key], widget.settings[key],
subKey, subKey,
subValue, subValue,
false, false,
@ -358,7 +356,7 @@ class _MountSettingsWidgetState extends State<MountSettingsWidget> {
} else if (subKey == 'ApiPort') { } else if (subKey == 'ApiPort') {
_addIntSetting( _addIntSetting(
hostConfigSettings, hostConfigSettings,
_settings[key], widget.settings[key],
subKey, subKey,
subValue, subValue,
false, false,
@ -366,7 +364,7 @@ class _MountSettingsWidgetState extends State<MountSettingsWidget> {
} else if (subKey == 'ApiUser') { } else if (subKey == 'ApiUser') {
_addStringSetting( _addStringSetting(
hostConfigSettings, hostConfigSettings,
_settings[key], widget.settings[key],
subKey, subKey,
subValue, subValue,
Icons.person, Icons.person,
@ -375,7 +373,7 @@ class _MountSettingsWidgetState extends State<MountSettingsWidget> {
} else if (subKey == 'HostNameOrIp') { } else if (subKey == 'HostNameOrIp') {
_addStringSetting( _addStringSetting(
hostConfigSettings, hostConfigSettings,
_settings[key], widget.settings[key],
subKey, subKey,
subValue, subValue,
Icons.computer, Icons.computer,
@ -384,7 +382,7 @@ class _MountSettingsWidgetState extends State<MountSettingsWidget> {
} else if (subKey == 'Path') { } else if (subKey == 'Path') {
_addStringSetting( _addStringSetting(
hostConfigSettings, hostConfigSettings,
_settings[key], widget.settings[key],
subKey, subKey,
subValue, subValue,
Icons.route, Icons.route,
@ -393,7 +391,7 @@ class _MountSettingsWidgetState extends State<MountSettingsWidget> {
} else if (subKey == 'Protocol') { } else if (subKey == 'Protocol') {
_addListSetting( _addListSetting(
hostConfigSettings, hostConfigSettings,
_settings[key], widget.settings[key],
subKey, subKey,
subValue, subValue,
protocolTypeList, protocolTypeList,
@ -403,7 +401,7 @@ class _MountSettingsWidgetState extends State<MountSettingsWidget> {
} else if (subKey == 'TimeoutMs') { } else if (subKey == 'TimeoutMs') {
_addIntSetting( _addIntSetting(
hostConfigSettings, hostConfigSettings,
_settings[key], widget.settings[key],
subKey, subKey,
subValue, subValue,
true, true,
@ -415,7 +413,7 @@ class _MountSettingsWidgetState extends State<MountSettingsWidget> {
if (subKey == 'ApiPort') { if (subKey == 'ApiPort') {
_addIntSetting( _addIntSetting(
remoteConfigSettings, remoteConfigSettings,
_settings[key], widget.settings[key],
subKey, subKey,
subValue, subValue,
false, false,
@ -423,7 +421,7 @@ class _MountSettingsWidgetState extends State<MountSettingsWidget> {
} else if (subKey == 'EncryptionToken') { } else if (subKey == 'EncryptionToken') {
_addPasswordSetting( _addPasswordSetting(
remoteConfigSettings, remoteConfigSettings,
_settings[key], widget.settings[key],
subKey, subKey,
subValue, subValue,
false, false,
@ -431,7 +429,7 @@ class _MountSettingsWidgetState extends State<MountSettingsWidget> {
} else if (subKey == 'HostNameOrIp') { } else if (subKey == 'HostNameOrIp') {
_addStringSetting( _addStringSetting(
remoteConfigSettings, remoteConfigSettings,
_settings[key], widget.settings[key],
subKey, subKey,
subValue, subValue,
Icons.computer, Icons.computer,
@ -440,7 +438,7 @@ class _MountSettingsWidgetState extends State<MountSettingsWidget> {
} else if (subKey == 'MaxConnections') { } else if (subKey == 'MaxConnections') {
_addIntSetting( _addIntSetting(
remoteConfigSettings, remoteConfigSettings,
_settings[key], widget.settings[key],
subKey, subKey,
subValue, subValue,
true, true,
@ -448,7 +446,7 @@ class _MountSettingsWidgetState extends State<MountSettingsWidget> {
} else if (subKey == 'ReceiveTimeoutMs') { } else if (subKey == 'ReceiveTimeoutMs') {
_addIntSetting( _addIntSetting(
remoteConfigSettings, remoteConfigSettings,
_settings[key], widget.settings[key],
subKey, subKey,
subValue, subValue,
true, true,
@ -456,7 +454,7 @@ class _MountSettingsWidgetState extends State<MountSettingsWidget> {
} else if (subKey == 'SendTimeoutMs') { } else if (subKey == 'SendTimeoutMs') {
_addIntSetting( _addIntSetting(
remoteConfigSettings, remoteConfigSettings,
_settings[key], widget.settings[key],
subKey, subKey,
subValue, subValue,
true, true,
@ -469,7 +467,7 @@ class _MountSettingsWidgetState extends State<MountSettingsWidget> {
List<SettingsTile> tempSettings = []; List<SettingsTile> tempSettings = [];
_addBooleanSetting( _addBooleanSetting(
tempSettings, tempSettings,
_settings[key], widget.settings[key],
subKey, subKey,
subValue, subValue,
false, false,
@ -478,7 +476,7 @@ class _MountSettingsWidgetState extends State<MountSettingsWidget> {
} else if (subKey == 'ApiPort') { } else if (subKey == 'ApiPort') {
_addIntSetting( _addIntSetting(
remoteMountSettings, remoteMountSettings,
_settings[key], widget.settings[key],
subKey, subKey,
subValue, subValue,
false, false,
@ -486,7 +484,7 @@ class _MountSettingsWidgetState extends State<MountSettingsWidget> {
} else if (subKey == 'ClientPoolSize') { } else if (subKey == 'ClientPoolSize') {
_addIntSetting( _addIntSetting(
remoteMountSettings, remoteMountSettings,
_settings[key], widget.settings[key],
subKey, subKey,
subValue, subValue,
true, true,
@ -494,7 +492,7 @@ class _MountSettingsWidgetState extends State<MountSettingsWidget> {
} else if (subKey == 'EncryptionToken') { } else if (subKey == 'EncryptionToken') {
_addPasswordSetting( _addPasswordSetting(
remoteMountSettings, remoteMountSettings,
_settings[key], widget.settings[key],
subKey, subKey,
subValue, subValue,
false, false,
@ -506,7 +504,7 @@ class _MountSettingsWidgetState extends State<MountSettingsWidget> {
if (subKey == 'AccessKey') { if (subKey == 'AccessKey') {
_addPasswordSetting( _addPasswordSetting(
s3ConfigSettings, s3ConfigSettings,
_settings[key], widget.settings[key],
subKey, subKey,
subValue, subValue,
false, false,
@ -514,7 +512,7 @@ class _MountSettingsWidgetState extends State<MountSettingsWidget> {
} else if (subKey == 'Bucket') { } else if (subKey == 'Bucket') {
_addStringSetting( _addStringSetting(
s3ConfigSettings, s3ConfigSettings,
_settings[key], widget.settings[key],
subKey, subKey,
subValue, subValue,
Icons.folder, Icons.folder,
@ -523,7 +521,7 @@ class _MountSettingsWidgetState extends State<MountSettingsWidget> {
} else if (subKey == 'EncryptionToken') { } else if (subKey == 'EncryptionToken') {
_addPasswordSetting( _addPasswordSetting(
s3ConfigSettings, s3ConfigSettings,
_settings[key], widget.settings[key],
subKey, subKey,
subValue, subValue,
false, false,
@ -531,7 +529,7 @@ class _MountSettingsWidgetState extends State<MountSettingsWidget> {
} else if (subKey == 'Region') { } else if (subKey == 'Region') {
_addStringSetting( _addStringSetting(
s3ConfigSettings, s3ConfigSettings,
_settings[key], widget.settings[key],
subKey, subKey,
subValue, subValue,
Icons.map, Icons.map,
@ -540,7 +538,7 @@ class _MountSettingsWidgetState extends State<MountSettingsWidget> {
} else if (subKey == 'SecretKey') { } else if (subKey == 'SecretKey') {
_addPasswordSetting( _addPasswordSetting(
s3ConfigSettings, s3ConfigSettings,
_settings[key], widget.settings[key],
subKey, subKey,
subValue, subValue,
false, false,
@ -548,7 +546,7 @@ class _MountSettingsWidgetState extends State<MountSettingsWidget> {
} else if (subKey == 'TimeoutMs') { } else if (subKey == 'TimeoutMs') {
_addIntSetting( _addIntSetting(
s3ConfigSettings, s3ConfigSettings,
_settings[key], widget.settings[key],
subKey, subKey,
subValue, subValue,
true, true,
@ -556,7 +554,7 @@ class _MountSettingsWidgetState extends State<MountSettingsWidget> {
} else if (subKey == 'URL') { } else if (subKey == 'URL') {
_addStringSetting( _addStringSetting(
s3ConfigSettings, s3ConfigSettings,
_settings[key], widget.settings[key],
subKey, subKey,
subValue, subValue,
Icons.http, Icons.http,
@ -565,7 +563,7 @@ class _MountSettingsWidgetState extends State<MountSettingsWidget> {
} else if (subKey == 'UsePathStyle') { } else if (subKey == 'UsePathStyle') {
_addBooleanSetting( _addBooleanSetting(
s3ConfigSettings, s3ConfigSettings,
_settings[key], widget.settings[key],
subKey, subKey,
subValue, subValue,
false, false,
@ -573,7 +571,7 @@ class _MountSettingsWidgetState extends State<MountSettingsWidget> {
} else if (subKey == 'UseRegionInURL') { } else if (subKey == 'UseRegionInURL') {
_addBooleanSetting( _addBooleanSetting(
s3ConfigSettings, s3ConfigSettings,
_settings[key], widget.settings[key],
subKey, subKey,
subValue, subValue,
false, false,
@ -585,7 +583,7 @@ class _MountSettingsWidgetState extends State<MountSettingsWidget> {
if (subKey == 'Bucket') { if (subKey == 'Bucket') {
_addStringSetting( _addStringSetting(
siaConfigSettings, siaConfigSettings,
_settings[key], widget.settings[key],
subKey, subKey,
subValue, subValue,
Icons.folder, Icons.folder,
@ -628,11 +626,12 @@ class _MountSettingsWidgetState extends State<MountSettingsWidget> {
SettingsSection( SettingsSection(
title: const Text('Remote Mount'), title: const Text('Remote Mount'),
tiles: tiles:
_settings['RemoteMount']['Enable'] as bool widget.settings['RemoteMount']['Enable'] as bool
? remoteMountSettings ? remoteMountSettings
: [remoteMountSettings[0]], : [remoteMountSettings[0]],
), ),
SettingsSection(title: const Text('Settings'), tiles: commonSettings), if (commonSettings.isNotEmpty)
SettingsSection(title: const Text('Settings'), tiles: commonSettings),
], ],
); );
} }
@ -641,8 +640,8 @@ class _MountSettingsWidgetState extends State<MountSettingsWidget> {
void dispose() { void dispose() {
if (!widget.isAdd) { if (!widget.isAdd) {
var settings = widget.mount.mountConfig.settings; var settings = widget.mount.mountConfig.settings;
if (!DeepCollectionEquality().equals(_settings, settings)) { if (!DeepCollectionEquality().equals(widget.settings, settings)) {
_settings.forEach((key, value) { widget.settings.forEach((key, value) {
if (!DeepCollectionEquality().equals(settings[key], value)) { if (!DeepCollectionEquality().equals(settings[key], value)) {
if (value is Map<String, dynamic>) { if (value is Map<String, dynamic>) {
value.forEach((subKey, subValue) { value.forEach((subKey, subValue) {
@ -660,21 +659,7 @@ class _MountSettingsWidgetState extends State<MountSettingsWidget> {
}); });
} }
} }
super.dispose(); super.dispose();
} }
@override
void initState() {
_settings = jsonDecode(jsonEncode(widget.mount.mountConfig.settings));
super.initState();
}
@override
void setState(VoidCallback fn) {
if (!mounted) {
return;
}
super.setState(fn);
}
} }