Create management portal in Flutter #39
This commit is contained in:
parent
847bf68f85
commit
0318489b6c
@ -1 +1,8 @@
|
||||
const String addMountTitle = 'New Mount Settings';
|
||||
const String appTitle = 'Repertory Management Portal';
|
||||
const databaseTypeList = ['rocksdb', 'sqlite'];
|
||||
const downloadTypeList = ['default', 'direct', 'ring_buffer'];
|
||||
const eventLevelList = ['critical', 'error', 'warn', 'info', 'debug', 'trace'];
|
||||
const protocolTypeList = ['http', 'https'];
|
||||
const providerTypeList = ['Encrypt', 'Remote', 'S3', 'Sia'];
|
||||
const ringBufferSizeList = ['128', '256', '512', '1024', '2048'];
|
||||
|
@ -4,9 +4,9 @@ import 'package:repertory/constants.dart' as constants;
|
||||
import 'package:repertory/helpers.dart';
|
||||
import 'package:repertory/models/mount.dart';
|
||||
import 'package:repertory/models/mount_list.dart';
|
||||
import 'package:repertory/widgets/add_mount_widget.dart';
|
||||
import 'package:repertory/widgets/mount_list_widget.dart';
|
||||
import 'package:repertory/widgets/mount_settings.dart';
|
||||
import 'package:repertory/screens/add_mount_screen.dart';
|
||||
import 'package:repertory/screens/edit_mount_screen.dart';
|
||||
import 'package:repertory/screens/home_screen.dart';
|
||||
|
||||
void main() {
|
||||
runApp(
|
||||
@ -14,9 +14,14 @@ void main() {
|
||||
);
|
||||
}
|
||||
|
||||
class MyApp extends StatelessWidget {
|
||||
class MyApp extends StatefulWidget {
|
||||
const MyApp({super.key});
|
||||
|
||||
@override
|
||||
State<MyApp> createState() => _MyAppState();
|
||||
}
|
||||
|
||||
class _MyAppState extends State<MyApp> {
|
||||
@override
|
||||
Widget build(context) {
|
||||
return MaterialApp(
|
||||
@ -41,7 +46,11 @@ class MyApp extends StatelessWidget {
|
||||
),
|
||||
),
|
||||
initialRoute: '/',
|
||||
routes: {'/': (context) => const MyHomePage(title: constants.appTitle)},
|
||||
routes: {
|
||||
'/': (context) => const HomeScreen(title: constants.appTitle),
|
||||
'/add':
|
||||
(context) => const AddMountScreen(title: constants.addMountTitle),
|
||||
},
|
||||
onGenerateRoute: (settings) {
|
||||
if (settings.name != '/settings') {
|
||||
return null;
|
||||
@ -50,14 +59,10 @@ class MyApp extends StatelessWidget {
|
||||
final mount = settings.arguments as Mount;
|
||||
return MaterialPageRoute(
|
||||
builder: (context) {
|
||||
return Scaffold(
|
||||
appBar: AppBar(
|
||||
backgroundColor: Theme.of(context).colorScheme.inversePrimary,
|
||||
title: Text(
|
||||
return EditMountScreen(
|
||||
mount: mount,
|
||||
title:
|
||||
'${initialCaps(mount.type)} [${formatMountName(mount.type, mount.name)}] Settings',
|
||||
),
|
||||
),
|
||||
body: MountSettingsWidget(mount: mount),
|
||||
);
|
||||
},
|
||||
);
|
||||
@ -65,152 +70,3 @@ class MyApp extends StatelessWidget {
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
class MyHomePage extends StatefulWidget {
|
||||
final String title;
|
||||
const MyHomePage({super.key, required this.title});
|
||||
|
||||
@override
|
||||
State<MyHomePage> createState() => _MyHomePageState();
|
||||
}
|
||||
|
||||
class _MyHomePageState extends State<MyHomePage> {
|
||||
bool _allowAdd = true;
|
||||
String? _apiPassword;
|
||||
String? _apiPort;
|
||||
String? _bucket;
|
||||
String? _encryptionToken;
|
||||
String? _hostNameOrIp;
|
||||
String _mountType = 'Encrypt';
|
||||
String _mountName = "";
|
||||
String? _path;
|
||||
|
||||
void _resetData() {
|
||||
_apiPassword = null;
|
||||
_apiPort = null;
|
||||
_bucket = null;
|
||||
_encryptionToken = null;
|
||||
_hostNameOrIp = null;
|
||||
_mountName = "";
|
||||
_mountType = 'Encrypt';
|
||||
_path = null;
|
||||
}
|
||||
|
||||
void _updateData(String name, String? value) {
|
||||
switch (name) {
|
||||
case 'ApiPassword':
|
||||
_apiPassword = value ?? '';
|
||||
return;
|
||||
|
||||
case 'ApiPort':
|
||||
_apiPort = value ?? '';
|
||||
return;
|
||||
|
||||
case 'Bucket':
|
||||
_bucket = value ?? '';
|
||||
return;
|
||||
|
||||
case 'EncryptionToken':
|
||||
_encryptionToken = value ?? '';
|
||||
return;
|
||||
|
||||
case 'HostNameOrIp':
|
||||
_hostNameOrIp = value ?? '';
|
||||
return;
|
||||
|
||||
case 'Name':
|
||||
_mountName = value ?? '';
|
||||
return;
|
||||
|
||||
case 'Provider':
|
||||
_mountType = value ?? 'Encrypt';
|
||||
return;
|
||||
|
||||
case 'Path':
|
||||
_path = value ?? '';
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(context) {
|
||||
return Scaffold(
|
||||
appBar: AppBar(
|
||||
backgroundColor: Theme.of(context).colorScheme.inversePrimary,
|
||||
leading: const Icon(Icons.storage),
|
||||
title: Text(widget.title),
|
||||
),
|
||||
body: MountListWidget(),
|
||||
floatingActionButton: FloatingActionButton(
|
||||
onPressed:
|
||||
_allowAdd
|
||||
? () async => showDialog(
|
||||
context: context,
|
||||
builder: (context) {
|
||||
return AlertDialog(
|
||||
title: const Text('Add Mount'),
|
||||
content: Consumer<MountList>(
|
||||
builder: (_, MountList mountList, __) {
|
||||
return AddMountWidget(
|
||||
mountType: _mountType,
|
||||
onDataChanged: _updateData,
|
||||
);
|
||||
},
|
||||
),
|
||||
actions: [
|
||||
TextButton(
|
||||
child: const Text('Cancel'),
|
||||
onPressed: () {
|
||||
_resetData();
|
||||
Navigator.of(context).pop();
|
||||
},
|
||||
),
|
||||
TextButton(
|
||||
child: const Text('OK'),
|
||||
onPressed: () {
|
||||
setState(() => _allowAdd = false);
|
||||
|
||||
Provider.of<MountList>(context, listen: false)
|
||||
.add(
|
||||
_mountType,
|
||||
_mountName,
|
||||
apiPassword: _apiPassword,
|
||||
apiPort: _apiPort,
|
||||
bucket: _bucket,
|
||||
encryptionToken: _encryptionToken,
|
||||
hostNameOrIp: _hostNameOrIp,
|
||||
path: _path,
|
||||
)
|
||||
.then((_) {
|
||||
_resetData();
|
||||
setState(() {
|
||||
_allowAdd = true;
|
||||
});
|
||||
})
|
||||
.catchError((_) {
|
||||
setState(() => _allowAdd = true);
|
||||
});
|
||||
|
||||
Navigator.of(context).pop();
|
||||
},
|
||||
),
|
||||
],
|
||||
);
|
||||
},
|
||||
)
|
||||
: null,
|
||||
tooltip: 'Add Mount',
|
||||
child: const Icon(Icons.add),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
@override
|
||||
void setState(VoidCallback fn) {
|
||||
if (!mounted) {
|
||||
return;
|
||||
}
|
||||
|
||||
super.setState(fn);
|
||||
}
|
||||
}
|
||||
|
78
web/repertory/lib/screens/add_mount_screen.dart
Normal file
78
web/repertory/lib/screens/add_mount_screen.dart
Normal file
@ -0,0 +1,78 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:repertory/constants.dart';
|
||||
import 'package:repertory/models/mount.dart';
|
||||
import 'package:repertory/widgets/mount_settings.dart';
|
||||
|
||||
class AddMountScreen extends StatefulWidget {
|
||||
final String title;
|
||||
const AddMountScreen({super.key, required this.title});
|
||||
|
||||
@override
|
||||
State<AddMountScreen> createState() => _AddMountScreenState();
|
||||
}
|
||||
|
||||
class _AddMountScreenState extends State<AddMountScreen> {
|
||||
Mount? _mount;
|
||||
String _mountType = "";
|
||||
bool _showAdvanced = false;
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Scaffold(
|
||||
appBar: AppBar(
|
||||
backgroundColor: Theme.of(context).colorScheme.inversePrimary,
|
||||
title: Text(widget.title),
|
||||
actions: [
|
||||
Row(
|
||||
children: [
|
||||
const Text("Advanced"),
|
||||
IconButton(
|
||||
icon: Icon(_showAdvanced ? Icons.toggle_on : Icons.toggle_off),
|
||||
onPressed: () => setState(() => _showAdvanced = !_showAdvanced),
|
||||
),
|
||||
],
|
||||
),
|
||||
],
|
||||
),
|
||||
body: Column(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: [
|
||||
Row(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: [
|
||||
const Text('Provider Type'),
|
||||
const SizedBox(width: 15.0),
|
||||
DropdownButton<String>(
|
||||
value: _mountType,
|
||||
onChanged: (newValue) {
|
||||
setState(() {
|
||||
_mountType = newValue ?? "";
|
||||
if (_mountType.isNotEmpty) {}
|
||||
});
|
||||
},
|
||||
items:
|
||||
providerTypeList.map<DropdownMenuItem<String>>((item) {
|
||||
return DropdownMenuItem<String>(
|
||||
value: item,
|
||||
child: Text(item),
|
||||
);
|
||||
}).toList(),
|
||||
),
|
||||
],
|
||||
),
|
||||
if (_mount != null)
|
||||
MountSettingsWidget(mount: _mount!, showAdvanced: _showAdvanced),
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
@override
|
||||
void setState(VoidCallback fn) {
|
||||
if (!mounted) {
|
||||
return;
|
||||
}
|
||||
|
||||
super.setState(fn);
|
||||
}
|
||||
}
|
50
web/repertory/lib/screens/edit_mount_screen.dart
Normal file
50
web/repertory/lib/screens/edit_mount_screen.dart
Normal file
@ -0,0 +1,50 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:repertory/models/mount.dart';
|
||||
import 'package:repertory/widgets/mount_settings.dart';
|
||||
|
||||
class EditMountScreen extends StatefulWidget {
|
||||
final Mount mount;
|
||||
final String title;
|
||||
const EditMountScreen({super.key, required this.mount, required this.title});
|
||||
|
||||
@override
|
||||
State<EditMountScreen> createState() => _EditMountScreenState();
|
||||
}
|
||||
|
||||
class _EditMountScreenState extends State<EditMountScreen> {
|
||||
bool _showAdvanced = false;
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Scaffold(
|
||||
appBar: AppBar(
|
||||
backgroundColor: Theme.of(context).colorScheme.inversePrimary,
|
||||
title: Text(widget.title),
|
||||
actions: [
|
||||
Row(
|
||||
children: [
|
||||
const Text("Advanced"),
|
||||
IconButton(
|
||||
icon: Icon(_showAdvanced ? Icons.toggle_on : Icons.toggle_off),
|
||||
onPressed: () => setState(() => _showAdvanced = !_showAdvanced),
|
||||
),
|
||||
],
|
||||
),
|
||||
],
|
||||
),
|
||||
body: MountSettingsWidget(
|
||||
mount: widget.mount,
|
||||
showAdvanced: _showAdvanced,
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
@override
|
||||
void setState(VoidCallback fn) {
|
||||
if (!mounted) {
|
||||
return;
|
||||
}
|
||||
|
||||
super.setState(fn);
|
||||
}
|
||||
}
|
38
web/repertory/lib/screens/home_screen.dart
Normal file
38
web/repertory/lib/screens/home_screen.dart
Normal file
@ -0,0 +1,38 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:repertory/widgets/mount_list_widget.dart';
|
||||
|
||||
class HomeScreen extends StatefulWidget {
|
||||
final String title;
|
||||
const HomeScreen({super.key, required this.title});
|
||||
|
||||
@override
|
||||
State<HomeScreen> createState() => _HomeScreeState();
|
||||
}
|
||||
|
||||
class _HomeScreeState extends State<HomeScreen> {
|
||||
@override
|
||||
Widget build(context) {
|
||||
return Scaffold(
|
||||
appBar: AppBar(
|
||||
backgroundColor: Theme.of(context).colorScheme.inversePrimary,
|
||||
leading: const Icon(Icons.storage),
|
||||
title: Text(widget.title),
|
||||
),
|
||||
body: MountListWidget(),
|
||||
floatingActionButton: FloatingActionButton(
|
||||
onPressed: () => Navigator.pushNamed(context, '/add'),
|
||||
tooltip: 'Add Mount',
|
||||
child: const Icon(Icons.add),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
@override
|
||||
void setState(VoidCallback fn) {
|
||||
if (!mounted) {
|
||||
return;
|
||||
}
|
||||
|
||||
super.setState(fn);
|
||||
}
|
||||
}
|
@ -1,125 +0,0 @@
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
class AddMountWidget extends StatefulWidget {
|
||||
final String mountType;
|
||||
final void Function(String name, String? value) onDataChanged;
|
||||
|
||||
const AddMountWidget({
|
||||
super.key,
|
||||
required this.mountType,
|
||||
required this.onDataChanged,
|
||||
});
|
||||
|
||||
@override
|
||||
State<AddMountWidget> createState() => _AddMountWidgetState();
|
||||
}
|
||||
|
||||
class _AddMountWidgetState extends State<AddMountWidget> {
|
||||
static const _items = <String>['Encrypt', 'Remote', 'S3', 'Sia'];
|
||||
static const _padding = 15.0;
|
||||
|
||||
late String _mountType;
|
||||
|
||||
List<Widget> _createTextField(
|
||||
String title,
|
||||
String dataName, {
|
||||
String? value,
|
||||
}) {
|
||||
if (value != null) {
|
||||
widget.onDataChanged(dataName, value);
|
||||
}
|
||||
|
||||
return [
|
||||
const SizedBox(height: _padding),
|
||||
Text(
|
||||
title,
|
||||
textAlign: TextAlign.left,
|
||||
style: TextStyle(
|
||||
color: Theme.of(context).colorScheme.onSurface,
|
||||
fontWeight: FontWeight.bold,
|
||||
),
|
||||
),
|
||||
TextField(
|
||||
autofocus: dataName == 'Name',
|
||||
decoration: InputDecoration(),
|
||||
onChanged: (value) => widget.onDataChanged(dataName, value),
|
||||
controller: TextEditingController(text: value),
|
||||
),
|
||||
];
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final mountTypeLower = _mountType.toLowerCase();
|
||||
|
||||
return Column(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
mainAxisAlignment: MainAxisAlignment.start,
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Column(
|
||||
mainAxisAlignment: MainAxisAlignment.start,
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Text(
|
||||
'Provider Type',
|
||||
textAlign: TextAlign.left,
|
||||
style: TextStyle(
|
||||
color: Theme.of(context).colorScheme.onSurface,
|
||||
fontWeight: FontWeight.bold,
|
||||
),
|
||||
),
|
||||
const SizedBox(width: _padding),
|
||||
DropdownButton<String>(
|
||||
value: _mountType,
|
||||
onChanged: (value) {
|
||||
widget.onDataChanged('Provider', value);
|
||||
setState(() {
|
||||
_mountType = value ?? "";
|
||||
});
|
||||
},
|
||||
items:
|
||||
_items.map<DropdownMenuItem<String>>((item) {
|
||||
return DropdownMenuItem<String>(
|
||||
value: item,
|
||||
child: Text(item),
|
||||
);
|
||||
}).toList(),
|
||||
),
|
||||
],
|
||||
),
|
||||
if (mountTypeLower != 'remote')
|
||||
..._createTextField('Configuration Name', 'Name'),
|
||||
if (mountTypeLower == 'encrypt') ..._createTextField('Path', 'Path'),
|
||||
if (mountTypeLower == 'sia')
|
||||
..._createTextField('ApiPassword', 'ApiPassword'),
|
||||
if (mountTypeLower == 's3' || mountTypeLower == 'sia')
|
||||
..._createTextField(
|
||||
'Bucket',
|
||||
'Bucket',
|
||||
value: mountTypeLower == 'sia' ? 'default' : null,
|
||||
),
|
||||
if (mountTypeLower == 'remote' || mountTypeLower == 'sia')
|
||||
..._createTextField(
|
||||
'HostNameOrIp',
|
||||
'HostNameOrIp',
|
||||
value: 'localhost',
|
||||
),
|
||||
if (mountTypeLower == 'remote' || mountTypeLower == 'sia')
|
||||
..._createTextField(
|
||||
'ApiPort',
|
||||
'ApiPort',
|
||||
value: mountTypeLower == 'sia' ? '9980' : null,
|
||||
),
|
||||
if (mountTypeLower == 'encrypt' || mountTypeLower == 'remote')
|
||||
..._createTextField('EncryptionToken', 'EncryptionToken'),
|
||||
],
|
||||
);
|
||||
}
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
_mountType = widget.mountType;
|
||||
super.initState();
|
||||
}
|
||||
}
|
@ -3,12 +3,18 @@ import 'dart:convert';
|
||||
import 'package:collection/collection.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter/services.dart';
|
||||
import 'package:repertory/constants.dart';
|
||||
import 'package:repertory/models/mount.dart';
|
||||
import 'package:settings_ui/settings_ui.dart';
|
||||
|
||||
class MountSettingsWidget extends StatefulWidget {
|
||||
final bool showAdvanced;
|
||||
final Mount mount;
|
||||
const MountSettingsWidget({super.key, required this.mount});
|
||||
const MountSettingsWidget({
|
||||
super.key,
|
||||
required this.mount,
|
||||
required this.showAdvanced,
|
||||
});
|
||||
|
||||
@override
|
||||
State<MountSettingsWidget> createState() => _MountSettingsWidgetState();
|
||||
@ -17,71 +23,75 @@ class MountSettingsWidget extends StatefulWidget {
|
||||
class _MountSettingsWidgetState extends State<MountSettingsWidget> {
|
||||
Map<String, dynamic> _settings = {};
|
||||
|
||||
void _addBooleanSetting(list, root, key, value) {
|
||||
list.add(
|
||||
SettingsTile.switchTile(
|
||||
leading: Icon(Icons.quiz),
|
||||
title: Text(key),
|
||||
initialValue: (value as bool),
|
||||
onPressed: (_) {
|
||||
setState(() {
|
||||
root[key] = !value;
|
||||
});
|
||||
},
|
||||
onToggle: (bool nextValue) {
|
||||
setState(() {
|
||||
root[key] = nextValue;
|
||||
});
|
||||
},
|
||||
),
|
||||
);
|
||||
void _addBooleanSetting(list, root, key, value, isAdvanced) {
|
||||
if (!isAdvanced || widget.showAdvanced) {
|
||||
list.add(
|
||||
SettingsTile.switchTile(
|
||||
leading: Icon(Icons.quiz),
|
||||
title: Text(key),
|
||||
initialValue: (value as bool),
|
||||
onPressed: (_) {
|
||||
setState(() {
|
||||
root[key] = !value;
|
||||
});
|
||||
},
|
||||
onToggle: (bool nextValue) {
|
||||
setState(() {
|
||||
root[key] = nextValue;
|
||||
});
|
||||
},
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
void _addIntSetting(list, root, key, value) {
|
||||
list.add(
|
||||
SettingsTile.navigation(
|
||||
leading: Icon(Icons.onetwothree),
|
||||
title: Text(key),
|
||||
value: Text(value.toString()),
|
||||
onPressed: (_) {
|
||||
String updatedValue = value.toString();
|
||||
showDialog(
|
||||
context: context,
|
||||
builder: (context) {
|
||||
return AlertDialog(
|
||||
actions: [
|
||||
TextButton(
|
||||
child: Text('Cancel'),
|
||||
onPressed: () {
|
||||
Navigator.of(context).pop();
|
||||
void _addIntSetting(list, root, key, value, isAdvanced) {
|
||||
if (!isAdvanced || widget.showAdvanced) {
|
||||
list.add(
|
||||
SettingsTile.navigation(
|
||||
leading: Icon(Icons.onetwothree),
|
||||
title: Text(key),
|
||||
value: Text(value.toString()),
|
||||
onPressed: (_) {
|
||||
String updatedValue = value.toString();
|
||||
showDialog(
|
||||
context: context,
|
||||
builder: (context) {
|
||||
return AlertDialog(
|
||||
actions: [
|
||||
TextButton(
|
||||
child: Text('Cancel'),
|
||||
onPressed: () {
|
||||
Navigator.of(context).pop();
|
||||
},
|
||||
),
|
||||
TextButton(
|
||||
child: Text('OK'),
|
||||
onPressed: () {
|
||||
setState(() {
|
||||
root[key] = int.parse(updatedValue);
|
||||
});
|
||||
Navigator.of(context).pop();
|
||||
},
|
||||
),
|
||||
],
|
||||
content: TextField(
|
||||
autofocus: true,
|
||||
controller: TextEditingController(text: updatedValue),
|
||||
inputFormatters: [FilteringTextInputFormatter.digitsOnly],
|
||||
keyboardType: TextInputType.number,
|
||||
onChanged: (nextValue) {
|
||||
updatedValue = nextValue;
|
||||
},
|
||||
),
|
||||
TextButton(
|
||||
child: Text('OK'),
|
||||
onPressed: () {
|
||||
setState(() {
|
||||
root[key] = int.parse(updatedValue);
|
||||
});
|
||||
Navigator.of(context).pop();
|
||||
},
|
||||
),
|
||||
],
|
||||
content: TextField(
|
||||
autofocus: true,
|
||||
controller: TextEditingController(text: updatedValue),
|
||||
inputFormatters: [FilteringTextInputFormatter.digitsOnly],
|
||||
keyboardType: TextInputType.number,
|
||||
onChanged: (nextValue) {
|
||||
updatedValue = nextValue;
|
||||
},
|
||||
),
|
||||
title: Text(key),
|
||||
);
|
||||
},
|
||||
);
|
||||
},
|
||||
),
|
||||
);
|
||||
title: Text(key),
|
||||
);
|
||||
},
|
||||
);
|
||||
},
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
void _addIntListSetting(
|
||||
@ -92,101 +102,124 @@ class _MountSettingsWidgetState extends State<MountSettingsWidget> {
|
||||
List<String> valueList,
|
||||
defaultValue,
|
||||
icon,
|
||||
isAdvanced,
|
||||
) {
|
||||
list.add(
|
||||
SettingsTile.navigation(
|
||||
title: Text(key),
|
||||
leading: Icon(icon),
|
||||
value: DropdownButton<String>(
|
||||
value: value.toString(),
|
||||
onChanged: (newValue) {
|
||||
setState(() {
|
||||
root[key] = int.parse(newValue ?? defaultValue.toString());
|
||||
});
|
||||
},
|
||||
items:
|
||||
valueList.map<DropdownMenuItem<String>>((item) {
|
||||
return DropdownMenuItem<String>(value: item, child: Text(item));
|
||||
}).toList(),
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
void _addListSetting(list, root, key, value, List<String> valueList, icon) {
|
||||
list.add(
|
||||
SettingsTile.navigation(
|
||||
title: Text(key),
|
||||
leading: Icon(icon),
|
||||
value: DropdownButton<String>(
|
||||
value: value,
|
||||
onChanged: (newValue) {
|
||||
setState(() {
|
||||
root[key] = newValue;
|
||||
});
|
||||
},
|
||||
items:
|
||||
valueList.map<DropdownMenuItem<String>>((item) {
|
||||
return DropdownMenuItem<String>(value: item, child: Text(item));
|
||||
}).toList(),
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
void _addPasswordSetting(list, root, key, value) {
|
||||
list.add(
|
||||
SettingsTile.navigation(
|
||||
leading: Icon(Icons.password),
|
||||
title: Text(key),
|
||||
value: Text('*' * (value as String).length),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
void _addStringSetting(list, root, key, value, icon) {
|
||||
list.add(
|
||||
SettingsTile.navigation(
|
||||
leading: Icon(icon),
|
||||
title: Text(key),
|
||||
value: Text(value),
|
||||
onPressed: (_) {
|
||||
String updatedValue = value;
|
||||
showDialog(
|
||||
context: context,
|
||||
builder: (context) {
|
||||
return AlertDialog(
|
||||
actions: [
|
||||
TextButton(
|
||||
child: Text('Cancel'),
|
||||
onPressed: () {
|
||||
Navigator.of(context).pop();
|
||||
},
|
||||
),
|
||||
TextButton(
|
||||
child: Text('OK'),
|
||||
onPressed: () {
|
||||
setState(() {
|
||||
root[key] = updatedValue;
|
||||
});
|
||||
Navigator.of(context).pop();
|
||||
},
|
||||
),
|
||||
],
|
||||
content: TextField(
|
||||
autofocus: true,
|
||||
controller: TextEditingController(text: updatedValue),
|
||||
onChanged: (value) {
|
||||
updatedValue = value;
|
||||
},
|
||||
),
|
||||
title: Text(key),
|
||||
);
|
||||
if (!isAdvanced || widget.showAdvanced) {
|
||||
list.add(
|
||||
SettingsTile.navigation(
|
||||
title: Text(key),
|
||||
leading: Icon(icon),
|
||||
value: DropdownButton<String>(
|
||||
value: value.toString(),
|
||||
onChanged: (newValue) {
|
||||
setState(() {
|
||||
root[key] = int.parse(newValue ?? defaultValue.toString());
|
||||
});
|
||||
},
|
||||
);
|
||||
},
|
||||
),
|
||||
);
|
||||
items:
|
||||
valueList.map<DropdownMenuItem<String>>((item) {
|
||||
return DropdownMenuItem<String>(
|
||||
value: item,
|
||||
child: Text(item),
|
||||
);
|
||||
}).toList(),
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
void _addListSetting(
|
||||
list,
|
||||
root,
|
||||
key,
|
||||
value,
|
||||
List<String> valueList,
|
||||
icon,
|
||||
isAdvanced,
|
||||
) {
|
||||
if (!isAdvanced || widget.showAdvanced) {
|
||||
list.add(
|
||||
SettingsTile.navigation(
|
||||
title: Text(key),
|
||||
leading: Icon(icon),
|
||||
value: DropdownButton<String>(
|
||||
value: value,
|
||||
onChanged: (newValue) {
|
||||
setState(() {
|
||||
root[key] = newValue;
|
||||
});
|
||||
},
|
||||
items:
|
||||
valueList.map<DropdownMenuItem<String>>((item) {
|
||||
return DropdownMenuItem<String>(
|
||||
value: item,
|
||||
child: Text(item),
|
||||
);
|
||||
}).toList(),
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
void _addPasswordSetting(list, root, key, value, isAdvanced) {
|
||||
if (!isAdvanced || widget.showAdvanced) {
|
||||
list.add(
|
||||
SettingsTile.navigation(
|
||||
leading: Icon(Icons.password),
|
||||
title: Text(key),
|
||||
value: Text('*' * (value as String).length),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
void _addStringSetting(list, root, key, value, icon, isAdvanced) {
|
||||
if (!isAdvanced || widget.showAdvanced) {
|
||||
list.add(
|
||||
SettingsTile.navigation(
|
||||
leading: Icon(icon),
|
||||
title: Text(key),
|
||||
value: Text(value),
|
||||
onPressed: (_) {
|
||||
String updatedValue = value;
|
||||
showDialog(
|
||||
context: context,
|
||||
builder: (context) {
|
||||
return AlertDialog(
|
||||
actions: [
|
||||
TextButton(
|
||||
child: Text('Cancel'),
|
||||
onPressed: () {
|
||||
Navigator.of(context).pop();
|
||||
},
|
||||
),
|
||||
TextButton(
|
||||
child: Text('OK'),
|
||||
onPressed: () {
|
||||
setState(() {
|
||||
root[key] = updatedValue;
|
||||
});
|
||||
Navigator.of(context).pop();
|
||||
},
|
||||
),
|
||||
],
|
||||
content: TextField(
|
||||
autofocus: true,
|
||||
controller: TextEditingController(text: updatedValue),
|
||||
onChanged: (value) {
|
||||
updatedValue = value;
|
||||
},
|
||||
),
|
||||
title: Text(key),
|
||||
);
|
||||
},
|
||||
);
|
||||
},
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@override
|
||||
@ -201,58 +234,76 @@ class _MountSettingsWidgetState extends State<MountSettingsWidget> {
|
||||
|
||||
_settings.forEach((key, value) {
|
||||
if (key == 'ApiAuth') {
|
||||
_addPasswordSetting(commonSettings, _settings, key, value);
|
||||
_addPasswordSetting(commonSettings, _settings, key, value, true);
|
||||
} else if (key == 'ApiPort') {
|
||||
_addIntSetting(commonSettings, _settings, key, value);
|
||||
_addIntSetting(commonSettings, _settings, key, value, true);
|
||||
} else if (key == 'ApiUser') {
|
||||
_addStringSetting(commonSettings, _settings, key, value, Icons.person);
|
||||
_addStringSetting(
|
||||
commonSettings,
|
||||
_settings,
|
||||
key,
|
||||
value,
|
||||
Icons.person,
|
||||
true,
|
||||
);
|
||||
} else if (key == 'DatabaseType') {
|
||||
_addListSetting(commonSettings, _settings, key, value, [
|
||||
'rocksdb',
|
||||
'sqlite',
|
||||
], Icons.dataset);
|
||||
_addListSetting(
|
||||
commonSettings,
|
||||
_settings,
|
||||
key,
|
||||
value,
|
||||
databaseTypeList,
|
||||
Icons.dataset,
|
||||
true,
|
||||
);
|
||||
} else if (key == 'DownloadTimeoutSeconds') {
|
||||
_addIntSetting(commonSettings, _settings, key, value);
|
||||
_addIntSetting(commonSettings, _settings, key, value, true);
|
||||
} else if (key == 'EnableDownloadTimeout') {
|
||||
_addBooleanSetting(commonSettings, _settings, key, value);
|
||||
_addBooleanSetting(commonSettings, _settings, key, value, true);
|
||||
} else if (key == 'EnableDriveEvents') {
|
||||
_addBooleanSetting(commonSettings, _settings, key, value);
|
||||
_addBooleanSetting(commonSettings, _settings, key, value, true);
|
||||
} else if (key == 'EventLevel') {
|
||||
_addListSetting(commonSettings, _settings, key, value, [
|
||||
'critical',
|
||||
'error',
|
||||
'warn',
|
||||
'info',
|
||||
'debug',
|
||||
'trace',
|
||||
], Icons.event);
|
||||
_addListSetting(
|
||||
commonSettings,
|
||||
_settings,
|
||||
key,
|
||||
value,
|
||||
eventLevelList,
|
||||
Icons.event,
|
||||
false,
|
||||
);
|
||||
} else if (key == 'EvictionDelayMinutes') {
|
||||
_addIntSetting(commonSettings, _settings, key, value);
|
||||
_addIntSetting(commonSettings, _settings, key, value, true);
|
||||
} else if (key == 'EvictionUseAccessedTime') {
|
||||
_addBooleanSetting(commonSettings, _settings, key, value);
|
||||
_addBooleanSetting(commonSettings, _settings, key, value, true);
|
||||
} else if (key == 'MaxCacheSizeBytes') {
|
||||
_addIntSetting(commonSettings, _settings, key, value);
|
||||
_addIntSetting(commonSettings, _settings, key, value, false);
|
||||
} else if (key == 'MaxUploadCount') {
|
||||
_addIntSetting(commonSettings, _settings, key, value);
|
||||
_addIntSetting(commonSettings, _settings, key, value, true);
|
||||
} else if (key == 'OnlineCheckRetrySeconds') {
|
||||
_addIntSetting(commonSettings, _settings, key, value);
|
||||
_addIntSetting(commonSettings, _settings, key, value, true);
|
||||
} else if (key == 'PreferredDownloadType') {
|
||||
_addListSetting(commonSettings, _settings, key, value, [
|
||||
'default',
|
||||
'direct',
|
||||
'ring_buffer',
|
||||
], Icons.download);
|
||||
_addListSetting(
|
||||
commonSettings,
|
||||
_settings,
|
||||
key,
|
||||
value,
|
||||
downloadTypeList,
|
||||
Icons.download,
|
||||
false,
|
||||
);
|
||||
} else if (key == 'RetryReadCount') {
|
||||
_addIntSetting(commonSettings, _settings, key, value);
|
||||
_addIntSetting(commonSettings, _settings, key, value, true);
|
||||
} else if (key == 'RingBufferFileSize') {
|
||||
_addIntListSetting(
|
||||
commonSettings,
|
||||
_settings,
|
||||
key,
|
||||
value,
|
||||
['128', '256', '512', '1024', '2048'],
|
||||
ringBufferSizeList,
|
||||
512,
|
||||
Icons.animation,
|
||||
false,
|
||||
);
|
||||
} else if (key == 'EncryptConfig') {
|
||||
value.forEach((subKey, subValue) {
|
||||
@ -262,6 +313,7 @@ class _MountSettingsWidgetState extends State<MountSettingsWidget> {
|
||||
_settings[key],
|
||||
subKey,
|
||||
subValue,
|
||||
false,
|
||||
);
|
||||
} else if (subKey == 'Path') {
|
||||
_addStringSetting(
|
||||
@ -270,6 +322,7 @@ class _MountSettingsWidgetState extends State<MountSettingsWidget> {
|
||||
subKey,
|
||||
subValue,
|
||||
Icons.folder,
|
||||
false,
|
||||
);
|
||||
}
|
||||
});
|
||||
@ -282,6 +335,7 @@ class _MountSettingsWidgetState extends State<MountSettingsWidget> {
|
||||
subKey,
|
||||
subValue,
|
||||
Icons.support_agent,
|
||||
true,
|
||||
);
|
||||
} else if (subKey == 'ApiPassword') {
|
||||
_addPasswordSetting(
|
||||
@ -289,6 +343,7 @@ class _MountSettingsWidgetState extends State<MountSettingsWidget> {
|
||||
_settings[key],
|
||||
subKey,
|
||||
subValue,
|
||||
false,
|
||||
);
|
||||
} else if (subKey == 'ApiPort') {
|
||||
_addIntSetting(
|
||||
@ -296,6 +351,7 @@ class _MountSettingsWidgetState extends State<MountSettingsWidget> {
|
||||
_settings[key],
|
||||
subKey,
|
||||
subValue,
|
||||
false,
|
||||
);
|
||||
} else if (subKey == 'ApiUser') {
|
||||
_addStringSetting(
|
||||
@ -304,6 +360,7 @@ class _MountSettingsWidgetState extends State<MountSettingsWidget> {
|
||||
subKey,
|
||||
subValue,
|
||||
Icons.person,
|
||||
true,
|
||||
);
|
||||
} else if (subKey == 'HostNameOrIp') {
|
||||
_addStringSetting(
|
||||
@ -312,6 +369,7 @@ class _MountSettingsWidgetState extends State<MountSettingsWidget> {
|
||||
subKey,
|
||||
subValue,
|
||||
Icons.computer,
|
||||
false,
|
||||
);
|
||||
} else if (subKey == 'Path') {
|
||||
_addStringSetting(
|
||||
@ -320,6 +378,7 @@ class _MountSettingsWidgetState extends State<MountSettingsWidget> {
|
||||
subKey,
|
||||
subValue,
|
||||
Icons.route,
|
||||
true,
|
||||
);
|
||||
} else if (subKey == 'Protocol') {
|
||||
_addListSetting(
|
||||
@ -327,8 +386,9 @@ class _MountSettingsWidgetState extends State<MountSettingsWidget> {
|
||||
_settings[key],
|
||||
subKey,
|
||||
subValue,
|
||||
['http', 'https'],
|
||||
protocolTypeList,
|
||||
Icons.http,
|
||||
true,
|
||||
);
|
||||
} else if (subKey == 'TimeoutMs') {
|
||||
_addIntSetting(
|
||||
@ -336,6 +396,7 @@ class _MountSettingsWidgetState extends State<MountSettingsWidget> {
|
||||
_settings[key],
|
||||
subKey,
|
||||
subValue,
|
||||
true,
|
||||
);
|
||||
}
|
||||
});
|
||||
@ -347,6 +408,7 @@ class _MountSettingsWidgetState extends State<MountSettingsWidget> {
|
||||
_settings[key],
|
||||
subKey,
|
||||
subValue,
|
||||
false,
|
||||
);
|
||||
} else if (subKey == 'EncryptionToken') {
|
||||
_addPasswordSetting(
|
||||
@ -354,6 +416,7 @@ class _MountSettingsWidgetState extends State<MountSettingsWidget> {
|
||||
_settings[key],
|
||||
subKey,
|
||||
subValue,
|
||||
false,
|
||||
);
|
||||
} else if (subKey == 'HostNameOrIp') {
|
||||
_addStringSetting(
|
||||
@ -362,6 +425,7 @@ class _MountSettingsWidgetState extends State<MountSettingsWidget> {
|
||||
subKey,
|
||||
subValue,
|
||||
Icons.computer,
|
||||
false,
|
||||
);
|
||||
} else if (subKey == 'MaxConnections') {
|
||||
_addIntSetting(
|
||||
@ -369,6 +433,7 @@ class _MountSettingsWidgetState extends State<MountSettingsWidget> {
|
||||
_settings[key],
|
||||
subKey,
|
||||
subValue,
|
||||
true,
|
||||
);
|
||||
} else if (subKey == 'ReceiveTimeoutMs') {
|
||||
_addIntSetting(
|
||||
@ -376,6 +441,7 @@ class _MountSettingsWidgetState extends State<MountSettingsWidget> {
|
||||
_settings[key],
|
||||
subKey,
|
||||
subValue,
|
||||
true,
|
||||
);
|
||||
} else if (subKey == 'SendTimeoutMs') {
|
||||
_addIntSetting(
|
||||
@ -383,6 +449,7 @@ class _MountSettingsWidgetState extends State<MountSettingsWidget> {
|
||||
_settings[key],
|
||||
subKey,
|
||||
subValue,
|
||||
true,
|
||||
);
|
||||
}
|
||||
});
|
||||
@ -390,7 +457,13 @@ class _MountSettingsWidgetState extends State<MountSettingsWidget> {
|
||||
value.forEach((subKey, subValue) {
|
||||
if (subKey == 'Enable') {
|
||||
List<SettingsTile> tempSettings = [];
|
||||
_addBooleanSetting(tempSettings, _settings[key], subKey, subValue);
|
||||
_addBooleanSetting(
|
||||
tempSettings,
|
||||
_settings[key],
|
||||
subKey,
|
||||
subValue,
|
||||
false,
|
||||
);
|
||||
remoteMountSettings.insertAll(0, tempSettings);
|
||||
} else if (subKey == 'ApiPort') {
|
||||
_addIntSetting(
|
||||
@ -398,6 +471,7 @@ class _MountSettingsWidgetState extends State<MountSettingsWidget> {
|
||||
_settings[key],
|
||||
subKey,
|
||||
subValue,
|
||||
false,
|
||||
);
|
||||
} else if (subKey == 'ClientPoolSize') {
|
||||
_addIntSetting(
|
||||
@ -405,6 +479,7 @@ class _MountSettingsWidgetState extends State<MountSettingsWidget> {
|
||||
_settings[key],
|
||||
subKey,
|
||||
subValue,
|
||||
true,
|
||||
);
|
||||
} else if (subKey == 'EncryptionToken') {
|
||||
_addPasswordSetting(
|
||||
@ -412,6 +487,7 @@ class _MountSettingsWidgetState extends State<MountSettingsWidget> {
|
||||
_settings[key],
|
||||
subKey,
|
||||
subValue,
|
||||
false,
|
||||
);
|
||||
}
|
||||
});
|
||||
@ -423,6 +499,7 @@ class _MountSettingsWidgetState extends State<MountSettingsWidget> {
|
||||
_settings[key],
|
||||
subKey,
|
||||
subValue,
|
||||
false,
|
||||
);
|
||||
} else if (subKey == 'Bucket') {
|
||||
_addStringSetting(
|
||||
@ -431,6 +508,7 @@ class _MountSettingsWidgetState extends State<MountSettingsWidget> {
|
||||
subKey,
|
||||
subValue,
|
||||
Icons.folder,
|
||||
false,
|
||||
);
|
||||
} else if (subKey == 'EncryptionToken') {
|
||||
_addPasswordSetting(
|
||||
@ -438,6 +516,7 @@ class _MountSettingsWidgetState extends State<MountSettingsWidget> {
|
||||
_settings[key],
|
||||
subKey,
|
||||
subValue,
|
||||
false,
|
||||
);
|
||||
} else if (subKey == 'Region') {
|
||||
_addStringSetting(
|
||||
@ -446,6 +525,7 @@ class _MountSettingsWidgetState extends State<MountSettingsWidget> {
|
||||
subKey,
|
||||
subValue,
|
||||
Icons.map,
|
||||
false,
|
||||
);
|
||||
} else if (subKey == 'SecretKey') {
|
||||
_addPasswordSetting(
|
||||
@ -453,9 +533,16 @@ class _MountSettingsWidgetState extends State<MountSettingsWidget> {
|
||||
_settings[key],
|
||||
subKey,
|
||||
subValue,
|
||||
false,
|
||||
);
|
||||
} else if (subKey == 'TimeoutMs') {
|
||||
_addIntSetting(s3ConfigSettings, _settings[key], subKey, subValue);
|
||||
_addIntSetting(
|
||||
s3ConfigSettings,
|
||||
_settings[key],
|
||||
subKey,
|
||||
subValue,
|
||||
true,
|
||||
);
|
||||
} else if (subKey == 'URL') {
|
||||
_addStringSetting(
|
||||
s3ConfigSettings,
|
||||
@ -463,6 +550,7 @@ class _MountSettingsWidgetState extends State<MountSettingsWidget> {
|
||||
subKey,
|
||||
subValue,
|
||||
Icons.http,
|
||||
false,
|
||||
);
|
||||
} else if (subKey == 'UsePathStyle') {
|
||||
_addBooleanSetting(
|
||||
@ -470,6 +558,7 @@ class _MountSettingsWidgetState extends State<MountSettingsWidget> {
|
||||
_settings[key],
|
||||
subKey,
|
||||
subValue,
|
||||
false,
|
||||
);
|
||||
} else if (subKey == 'UseRegionInURL') {
|
||||
_addBooleanSetting(
|
||||
@ -477,6 +566,7 @@ class _MountSettingsWidgetState extends State<MountSettingsWidget> {
|
||||
_settings[key],
|
||||
subKey,
|
||||
subValue,
|
||||
false,
|
||||
);
|
||||
}
|
||||
});
|
||||
@ -489,6 +579,7 @@ class _MountSettingsWidgetState extends State<MountSettingsWidget> {
|
||||
subKey,
|
||||
subValue,
|
||||
Icons.folder,
|
||||
false,
|
||||
);
|
||||
}
|
||||
});
|
||||
|
Loading…
x
Reference in New Issue
Block a user