This commit is contained in:
@@ -96,7 +96,7 @@ createUriValidator<Validator>({host, port}) {
|
|||||||
Uri.tryParse('http://${host ?? value}:${port ?? value}/') != null;
|
Uri.tryParse('http://${host ?? value}:${port ?? value}/') != null;
|
||||||
}
|
}
|
||||||
|
|
||||||
createHostNameOrIpValidators() => <Validator>[
|
List<Validator> createHostNameOrIpValidators() => <Validator>[
|
||||||
trimNotEmptyValidator,
|
trimNotEmptyValidator,
|
||||||
createUriValidator(port: 9000),
|
createUriValidator(port: 9000),
|
||||||
];
|
];
|
||||||
@@ -153,7 +153,11 @@ void displayAuthError(Auth auth) {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
void displayErrorMessage(context, String text, {bool clear = false}) {
|
void displayErrorMessage(
|
||||||
|
BuildContext context,
|
||||||
|
String text, {
|
||||||
|
bool clear = false,
|
||||||
|
}) {
|
||||||
if (!context.mounted) {
|
if (!context.mounted) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -431,39 +435,166 @@ Future<String?> editMountLocation(
|
|||||||
}
|
}
|
||||||
|
|
||||||
Scaffold createCommonScaffold(
|
Scaffold createCommonScaffold(
|
||||||
|
BuildContext context,
|
||||||
|
String title,
|
||||||
List<Widget> children, {
|
List<Widget> children, {
|
||||||
|
Widget? advancedWidget,
|
||||||
Widget? floatingActionButton,
|
Widget? floatingActionButton,
|
||||||
}) => Scaffold(
|
bool showBack = false,
|
||||||
body: SafeArea(
|
}) {
|
||||||
child: Stack(
|
final scheme = Theme.of(context).colorScheme;
|
||||||
children: [
|
final textTheme = Theme.of(context).textTheme;
|
||||||
Container(
|
|
||||||
width: double.infinity,
|
return Scaffold(
|
||||||
height: double.infinity,
|
body: SafeArea(
|
||||||
decoration: const BoxDecoration(
|
child: Stack(
|
||||||
gradient: LinearGradient(
|
children: [
|
||||||
begin: Alignment.topLeft,
|
Container(
|
||||||
end: Alignment.bottomRight,
|
width: double.infinity,
|
||||||
colors: constants.gradientColors,
|
height: double.infinity,
|
||||||
|
decoration: const BoxDecoration(
|
||||||
|
gradient: LinearGradient(
|
||||||
|
begin: Alignment.topLeft,
|
||||||
|
end: Alignment.bottomRight,
|
||||||
|
colors: constants.gradientColors,
|
||||||
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
Consumer<Settings>(
|
||||||
Consumer<Settings>(
|
builder: (_, settings, _) =>
|
||||||
builder: (_, settings, _) =>
|
AuroraSweep(enabled: settings.enableAnimations),
|
||||||
AuroraSweep(enabled: settings.enableAnimations),
|
|
||||||
),
|
|
||||||
Positioned.fill(
|
|
||||||
child: BackdropFilter(
|
|
||||||
filter: ImageFilter.blur(sigmaX: 6, sigmaY: 6),
|
|
||||||
child: Container(color: Colors.black.withValues(alpha: 0.06)),
|
|
||||||
),
|
),
|
||||||
),
|
Positioned.fill(
|
||||||
...children,
|
child: BackdropFilter(
|
||||||
],
|
filter: ImageFilter.blur(sigmaX: 6, sigmaY: 6),
|
||||||
|
child: Container(color: Colors.black.withValues(alpha: 0.06)),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
Padding(
|
||||||
|
padding: const EdgeInsets.all(constants.padding),
|
||||||
|
child: Column(
|
||||||
|
crossAxisAlignment: CrossAxisAlignment.stretch,
|
||||||
|
children: [
|
||||||
|
Row(
|
||||||
|
children: [
|
||||||
|
if (!showBack) ...[
|
||||||
|
SizedBox(
|
||||||
|
width: 40,
|
||||||
|
height: 40,
|
||||||
|
child: Image.asset(
|
||||||
|
'assets/images/repertory.png',
|
||||||
|
fit: BoxFit.contain,
|
||||||
|
errorBuilder: (_, _, _) {
|
||||||
|
return Icon(
|
||||||
|
Icons.folder,
|
||||||
|
color: scheme.primary,
|
||||||
|
size: 32,
|
||||||
|
);
|
||||||
|
},
|
||||||
|
),
|
||||||
|
),
|
||||||
|
const SizedBox(width: constants.padding),
|
||||||
|
],
|
||||||
|
if (showBack) ...[
|
||||||
|
Material(
|
||||||
|
color: Colors.transparent,
|
||||||
|
child: InkWell(
|
||||||
|
borderRadius: BorderRadius.circular(
|
||||||
|
constants.borderRadius,
|
||||||
|
),
|
||||||
|
onTap: () => Navigator.of(context).pop(),
|
||||||
|
child: Ink(
|
||||||
|
width: 40,
|
||||||
|
height: 40,
|
||||||
|
decoration: BoxDecoration(
|
||||||
|
color: scheme.surface.withValues(alpha: 0.40),
|
||||||
|
borderRadius: BorderRadius.circular(
|
||||||
|
constants.borderRadius,
|
||||||
|
),
|
||||||
|
border: Border.all(
|
||||||
|
color: scheme.outlineVariant.withValues(
|
||||||
|
alpha: 0.08,
|
||||||
|
),
|
||||||
|
width: 1,
|
||||||
|
),
|
||||||
|
boxShadow: [
|
||||||
|
BoxShadow(
|
||||||
|
color: Colors.black.withValues(alpha: 0.22),
|
||||||
|
blurRadius: constants.borderRadius,
|
||||||
|
offset: Offset(0, constants.borderRadius),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
child: const Icon(Icons.arrow_back),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
const SizedBox(width: constants.padding),
|
||||||
|
],
|
||||||
|
Expanded(
|
||||||
|
child: Text(
|
||||||
|
title,
|
||||||
|
maxLines: 1,
|
||||||
|
overflow: TextOverflow.ellipsis,
|
||||||
|
style: textTheme.headlineSmall?.copyWith(
|
||||||
|
fontWeight: FontWeight.w700,
|
||||||
|
letterSpacing: 0.2,
|
||||||
|
color: scheme.onSurface.withValues(alpha: 0.96),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
const SizedBox(width: constants.padding),
|
||||||
|
if (!showBack) ...[
|
||||||
|
const Text("Auto-start"),
|
||||||
|
Consumer<Settings>(
|
||||||
|
builder: (context, settings, _) {
|
||||||
|
return IconButton(
|
||||||
|
icon: Icon(
|
||||||
|
settings.autoStart
|
||||||
|
? Icons.toggle_on
|
||||||
|
: Icons.toggle_off,
|
||||||
|
),
|
||||||
|
color: settings.autoStart
|
||||||
|
? scheme.primary
|
||||||
|
: scheme.onSurface.withValues(alpha: 0.70),
|
||||||
|
onPressed: () =>
|
||||||
|
settings.setAutoStart(!settings.autoStart),
|
||||||
|
);
|
||||||
|
},
|
||||||
|
),
|
||||||
|
IconButton(
|
||||||
|
tooltip: 'Settings',
|
||||||
|
icon: const Icon(Icons.settings),
|
||||||
|
onPressed: () {
|
||||||
|
Navigator.pushNamed(context, '/settings');
|
||||||
|
},
|
||||||
|
),
|
||||||
|
const SizedBox(width: constants.padding),
|
||||||
|
],
|
||||||
|
if (showBack && advancedWidget != null) ...[
|
||||||
|
advancedWidget,
|
||||||
|
const SizedBox(width: constants.padding),
|
||||||
|
],
|
||||||
|
Consumer<Auth>(
|
||||||
|
builder: (context, auth, _) => IconButton(
|
||||||
|
tooltip: 'Log out',
|
||||||
|
icon: const Icon(Icons.logout),
|
||||||
|
onPressed: auth.logoff,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
const SizedBox(height: constants.padding),
|
||||||
|
...children,
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
),
|
),
|
||||||
),
|
floatingActionButton: floatingActionButton,
|
||||||
floatingActionButton: floatingActionButton,
|
);
|
||||||
);
|
}
|
||||||
|
|
||||||
InputDecoration createCommonDecoration(
|
InputDecoration createCommonDecoration(
|
||||||
ColorScheme colorScheme,
|
ColorScheme colorScheme,
|
||||||
|
@@ -38,9 +38,9 @@ class MountList with ChangeNotifier {
|
|||||||
return (excludeName == null
|
return (excludeName == null
|
||||||
? list
|
? list
|
||||||
: list.whereNot(
|
: list.whereNot(
|
||||||
(item) =>
|
(item) =>
|
||||||
item.name.toLowerCase() == excludeName.toLowerCase(),
|
item.name.toLowerCase() == excludeName.toLowerCase(),
|
||||||
))
|
))
|
||||||
.firstWhereOrNull((Mount item) {
|
.firstWhereOrNull((Mount item) {
|
||||||
return item.bucket != null &&
|
return item.bucket != null &&
|
||||||
item.bucket!.toLowerCase() == bucket.toLowerCase();
|
item.bucket!.toLowerCase() == bucket.toLowerCase();
|
||||||
@@ -98,7 +98,7 @@ class MountList with ChangeNotifier {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void _sort(list) {
|
void _sort(List list) {
|
||||||
list.sort((a, b) {
|
list.sort((a, b) {
|
||||||
final res = a.type.compareTo(b.type);
|
final res = a.type.compareTo(b.type);
|
||||||
if (res != 0) {
|
if (res != 0) {
|
||||||
|
@@ -8,7 +8,7 @@ import 'package:repertory/models/auth.dart';
|
|||||||
class Settings with ChangeNotifier {
|
class Settings with ChangeNotifier {
|
||||||
final Auth _auth;
|
final Auth _auth;
|
||||||
bool _autoStart = false;
|
bool _autoStart = false;
|
||||||
bool _enableAnimations = true;
|
bool _enableAnimations = false;
|
||||||
|
|
||||||
Settings(this._auth) {
|
Settings(this._auth) {
|
||||||
_auth.addListener(() {
|
_auth.addListener(() {
|
||||||
|
@@ -1,6 +1,5 @@
|
|||||||
// add_mount_screen.dart
|
// add_mount_screen.dart
|
||||||
|
|
||||||
import 'dart:ui';
|
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:flutter/services.dart';
|
import 'package:flutter/services.dart';
|
||||||
import 'package:provider/provider.dart';
|
import 'package:provider/provider.dart';
|
||||||
@@ -45,248 +44,149 @@ class _AddMountScreenState extends State<AddMountScreen>
|
|||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
final scheme = Theme.of(context).colorScheme;
|
final scheme = Theme.of(context).colorScheme;
|
||||||
final textTheme = Theme.of(context).textTheme;
|
|
||||||
|
|
||||||
return createCommonScaffold([
|
return createCommonScaffold(context, widget.title, [
|
||||||
Padding(
|
AppDropdownFormField<String>(
|
||||||
padding: const EdgeInsets.all(constants.padding),
|
constrainToIntrinsic: true,
|
||||||
child: Column(
|
isExpanded: false,
|
||||||
crossAxisAlignment: CrossAxisAlignment.stretch,
|
labelOf: (s) => s,
|
||||||
|
labelText: 'Provider Type',
|
||||||
|
onChanged: (mountType) {
|
||||||
|
_handleChange(
|
||||||
|
Provider.of<Auth>(context, listen: false),
|
||||||
|
mountType ?? '',
|
||||||
|
);
|
||||||
|
},
|
||||||
|
prefixIcon: Icons.miscellaneous_services,
|
||||||
|
value: _mountType.isEmpty ? null : _mountType,
|
||||||
|
values: constants.providerTypeList,
|
||||||
|
widthMultiplier: 2.0,
|
||||||
|
),
|
||||||
|
if (_mountType.isNotEmpty && _mountType != 'Remote') ...[
|
||||||
|
const SizedBox(height: constants.padding),
|
||||||
|
TextField(
|
||||||
|
autofocus: true,
|
||||||
|
controller: _mountNameController,
|
||||||
|
keyboardType: TextInputType.text,
|
||||||
|
inputFormatters: [FilteringTextInputFormatter.deny(RegExp(r'\s'))],
|
||||||
|
onChanged: (_) => _handleChange(
|
||||||
|
Provider.of<Auth>(context, listen: false),
|
||||||
|
_mountType,
|
||||||
|
),
|
||||||
|
decoration: createCommonDecoration(
|
||||||
|
scheme,
|
||||||
|
'Configuration Name',
|
||||||
|
hintText: 'Enter a unique name',
|
||||||
|
icon: Icons.drive_file_rename_outline,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
if (_mount != null) ...[
|
||||||
|
const SizedBox(height: constants.padding),
|
||||||
|
Expanded(
|
||||||
|
child: Padding(
|
||||||
|
padding: const EdgeInsets.symmetric(horizontal: constants.padding),
|
||||||
|
child: ClipRRect(
|
||||||
|
borderRadius: BorderRadius.circular(constants.borderRadius),
|
||||||
|
child: MountSettingsWidget(
|
||||||
|
isAdd: true,
|
||||||
|
mount: _mount!,
|
||||||
|
settings: _settings[_mountType]!,
|
||||||
|
showAdvanced: false,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
const SizedBox(height: constants.padding),
|
||||||
|
Row(
|
||||||
children: [
|
children: [
|
||||||
Row(
|
IntrinsicWidth(
|
||||||
children: [
|
child: ElevatedButton.icon(
|
||||||
Material(
|
label: const Text('Test'),
|
||||||
color: Colors.transparent,
|
icon: const Icon(Icons.check),
|
||||||
child: InkWell(
|
style: ElevatedButton.styleFrom(
|
||||||
|
backgroundColor: scheme.primary.withValues(alpha: 0.18),
|
||||||
|
foregroundColor: scheme.primary,
|
||||||
|
elevation: 0,
|
||||||
|
shape: RoundedRectangleBorder(
|
||||||
borderRadius: BorderRadius.circular(constants.borderRadius),
|
borderRadius: BorderRadius.circular(constants.borderRadius),
|
||||||
onTap: () => Navigator.of(context).pop(),
|
side: BorderSide(
|
||||||
child: Ink(
|
color: scheme.outlineVariant.withValues(alpha: 0.15),
|
||||||
width: 40,
|
width: 1,
|
||||||
height: 40,
|
|
||||||
decoration: BoxDecoration(
|
|
||||||
color: scheme.surface.withValues(alpha: 0.40),
|
|
||||||
borderRadius: BorderRadius.circular(
|
|
||||||
constants.borderRadius,
|
|
||||||
),
|
|
||||||
border: Border.all(
|
|
||||||
color: scheme.outlineVariant.withValues(alpha: 0.08),
|
|
||||||
width: 1,
|
|
||||||
),
|
|
||||||
boxShadow: [
|
|
||||||
BoxShadow(
|
|
||||||
color: Colors.black.withValues(alpha: 0.22),
|
|
||||||
blurRadius: constants.borderRadius,
|
|
||||||
offset: Offset(0, constants.borderRadius),
|
|
||||||
),
|
|
||||||
],
|
|
||||||
),
|
|
||||||
child: const Icon(Icons.arrow_back),
|
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
const SizedBox(width: constants.padding),
|
onPressed: _handleProviderTest,
|
||||||
Expanded(
|
|
||||||
child: Text(
|
|
||||||
widget.title,
|
|
||||||
maxLines: 1,
|
|
||||||
overflow: TextOverflow.ellipsis,
|
|
||||||
style: textTheme.headlineSmall?.copyWith(
|
|
||||||
fontWeight: FontWeight.w700,
|
|
||||||
letterSpacing: 0.2,
|
|
||||||
color: scheme.onSurface.withValues(alpha: 0.96),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
const SizedBox(width: constants.padding),
|
|
||||||
ClipRRect(
|
|
||||||
borderRadius: BorderRadius.circular(constants.borderRadius),
|
|
||||||
child: BackdropFilter(
|
|
||||||
filter: ImageFilter.blur(
|
|
||||||
sigmaX: constants.borderRadius,
|
|
||||||
sigmaY: constants.borderRadius,
|
|
||||||
),
|
|
||||||
child: Container(
|
|
||||||
height: 40,
|
|
||||||
padding: const EdgeInsets.symmetric(horizontal: 6),
|
|
||||||
decoration: BoxDecoration(
|
|
||||||
color: scheme.surface.withValues(alpha: 0.40),
|
|
||||||
borderRadius: BorderRadius.circular(
|
|
||||||
constants.borderRadius,
|
|
||||||
),
|
|
||||||
border: Border.all(
|
|
||||||
color: scheme.outlineVariant.withValues(alpha: 0.08),
|
|
||||||
width: 1,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
child: Consumer<Auth>(
|
|
||||||
builder: (context, auth, _) => IconButton(
|
|
||||||
tooltip: 'Log out',
|
|
||||||
icon: const Icon(Icons.logout),
|
|
||||||
onPressed: auth.logoff,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
],
|
|
||||||
),
|
|
||||||
const SizedBox(height: constants.padding),
|
|
||||||
AppDropdownFormField<String>(
|
|
||||||
constrainToIntrinsic: true,
|
|
||||||
isExpanded: false,
|
|
||||||
labelOf: (s) => s,
|
|
||||||
labelText: 'Provider Type',
|
|
||||||
onChanged: (mountType) {
|
|
||||||
_handleChange(
|
|
||||||
Provider.of<Auth>(context, listen: false),
|
|
||||||
mountType ?? '',
|
|
||||||
);
|
|
||||||
},
|
|
||||||
prefixIcon: Icons.miscellaneous_services,
|
|
||||||
value: _mountType.isEmpty ? null : _mountType,
|
|
||||||
values: constants.providerTypeList,
|
|
||||||
widthMultiplier: 2.0,
|
|
||||||
),
|
|
||||||
if (_mountType.isNotEmpty && _mountType != 'Remote') ...[
|
|
||||||
const SizedBox(height: constants.padding),
|
|
||||||
TextField(
|
|
||||||
autofocus: true,
|
|
||||||
controller: _mountNameController,
|
|
||||||
keyboardType: TextInputType.text,
|
|
||||||
inputFormatters: [
|
|
||||||
FilteringTextInputFormatter.deny(RegExp(r'\s')),
|
|
||||||
],
|
|
||||||
onChanged: (_) => _handleChange(
|
|
||||||
Provider.of<Auth>(context, listen: false),
|
|
||||||
_mountType,
|
|
||||||
),
|
|
||||||
decoration: createCommonDecoration(
|
|
||||||
scheme,
|
|
||||||
'Configuration Name',
|
|
||||||
hintText: 'Enter a unique name',
|
|
||||||
icon: Icons.drive_file_rename_outline,
|
|
||||||
),
|
|
||||||
),
|
),
|
||||||
],
|
),
|
||||||
if (_mount != null) ...[
|
const SizedBox(width: constants.padding),
|
||||||
const SizedBox(height: constants.padding),
|
IntrinsicWidth(
|
||||||
Expanded(
|
child: ElevatedButton.icon(
|
||||||
child: Padding(
|
label: const Text('Add'),
|
||||||
padding: const EdgeInsets.symmetric(
|
icon: const Icon(Icons.add),
|
||||||
horizontal: constants.padding,
|
style: ElevatedButton.styleFrom(
|
||||||
),
|
backgroundColor: scheme.primary,
|
||||||
child: ClipRRect(
|
foregroundColor: scheme.onPrimary,
|
||||||
|
elevation: 8,
|
||||||
|
shadowColor: scheme.primary.withValues(alpha: 0.45),
|
||||||
|
shape: RoundedRectangleBorder(
|
||||||
borderRadius: BorderRadius.circular(constants.borderRadius),
|
borderRadius: BorderRadius.circular(constants.borderRadius),
|
||||||
child: MountSettingsWidget(
|
|
||||||
isAdd: true,
|
|
||||||
mount: _mount!,
|
|
||||||
settings: _settings[_mountType]!,
|
|
||||||
showAdvanced: false,
|
|
||||||
),
|
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
onPressed: () async {
|
||||||
|
final mountList = Provider.of<MountList>(
|
||||||
|
context,
|
||||||
|
listen: false,
|
||||||
|
);
|
||||||
|
|
||||||
|
List<String> failed = [];
|
||||||
|
if (!validateSettings(_settings[_mountType]!, failed)) {
|
||||||
|
for (var key in failed) {
|
||||||
|
displayErrorMessage(
|
||||||
|
context,
|
||||||
|
"Setting '$key' is not valid",
|
||||||
|
);
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (mountList.hasConfigName(_mountNameController.text)) {
|
||||||
|
return displayErrorMessage(
|
||||||
|
context,
|
||||||
|
"Configuration name '${_mountNameController.text}' already exists",
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (_mountType == "Sia" || _mountType == "S3") {
|
||||||
|
final bucket =
|
||||||
|
_settings[_mountType]!["${_mountType}Config"]["Bucket"]
|
||||||
|
as String;
|
||||||
|
if (mountList.hasBucketName(_mountType, bucket)) {
|
||||||
|
return displayErrorMessage(
|
||||||
|
context,
|
||||||
|
"Bucket '$bucket' already exists",
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
final success = await mountList.add(
|
||||||
|
_mountType,
|
||||||
|
_mountType == 'Remote'
|
||||||
|
? '${_settings[_mountType]!['RemoteConfig']['HostNameOrIp']}_${_settings[_mountType]!['RemoteConfig']['ApiPort']}'
|
||||||
|
: _mountNameController.text,
|
||||||
|
_settings[_mountType]!,
|
||||||
|
);
|
||||||
|
|
||||||
|
if (!success || !context.mounted) return;
|
||||||
|
|
||||||
|
Navigator.pop(context);
|
||||||
|
},
|
||||||
),
|
),
|
||||||
const SizedBox(height: constants.padding),
|
),
|
||||||
Row(
|
|
||||||
children: [
|
|
||||||
IntrinsicWidth(
|
|
||||||
child: ElevatedButton.icon(
|
|
||||||
label: const Text('Test'),
|
|
||||||
icon: const Icon(Icons.check),
|
|
||||||
style: ElevatedButton.styleFrom(
|
|
||||||
backgroundColor: scheme.primary.withValues(alpha: 0.18),
|
|
||||||
foregroundColor: scheme.primary,
|
|
||||||
elevation: 0,
|
|
||||||
shape: RoundedRectangleBorder(
|
|
||||||
borderRadius: BorderRadius.circular(
|
|
||||||
constants.borderRadius,
|
|
||||||
),
|
|
||||||
side: BorderSide(
|
|
||||||
color: scheme.outlineVariant.withValues(
|
|
||||||
alpha: 0.15,
|
|
||||||
),
|
|
||||||
width: 1,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
onPressed: _handleProviderTest,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
const SizedBox(width: constants.padding),
|
|
||||||
IntrinsicWidth(
|
|
||||||
child: ElevatedButton.icon(
|
|
||||||
label: const Text('Add'),
|
|
||||||
icon: const Icon(Icons.add),
|
|
||||||
style: ElevatedButton.styleFrom(
|
|
||||||
backgroundColor: scheme.primary,
|
|
||||||
foregroundColor: scheme.onPrimary,
|
|
||||||
elevation: 8,
|
|
||||||
shadowColor: scheme.primary.withValues(alpha: 0.45),
|
|
||||||
shape: RoundedRectangleBorder(
|
|
||||||
borderRadius: BorderRadius.circular(
|
|
||||||
constants.borderRadius,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
onPressed: () async {
|
|
||||||
final mountList = Provider.of<MountList>(
|
|
||||||
context,
|
|
||||||
listen: false,
|
|
||||||
);
|
|
||||||
|
|
||||||
List<String> failed = [];
|
|
||||||
if (!validateSettings(_settings[_mountType]!, failed)) {
|
|
||||||
for (var key in failed) {
|
|
||||||
displayErrorMessage(
|
|
||||||
context,
|
|
||||||
"Setting '$key' is not valid",
|
|
||||||
);
|
|
||||||
}
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (mountList.hasConfigName(
|
|
||||||
_mountNameController.text,
|
|
||||||
)) {
|
|
||||||
return displayErrorMessage(
|
|
||||||
context,
|
|
||||||
"Configuration name '${_mountNameController.text}' already exists",
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (_mountType == "Sia" || _mountType == "S3") {
|
|
||||||
final bucket =
|
|
||||||
_settings[_mountType]!["${_mountType}Config"]["Bucket"]
|
|
||||||
as String;
|
|
||||||
if (mountList.hasBucketName(_mountType, bucket)) {
|
|
||||||
return displayErrorMessage(
|
|
||||||
context,
|
|
||||||
"Bucket '$bucket' already exists",
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
final success = await mountList.add(
|
|
||||||
_mountType,
|
|
||||||
_mountType == 'Remote'
|
|
||||||
? '${_settings[_mountType]!['RemoteConfig']['HostNameOrIp']}_${_settings[_mountType]!['RemoteConfig']['ApiPort']}'
|
|
||||||
: _mountNameController.text,
|
|
||||||
_settings[_mountType]!,
|
|
||||||
);
|
|
||||||
|
|
||||||
if (!success || !context.mounted) return;
|
|
||||||
|
|
||||||
Navigator.pop(context);
|
|
||||||
},
|
|
||||||
),
|
|
||||||
),
|
|
||||||
],
|
|
||||||
),
|
|
||||||
],
|
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
),
|
],
|
||||||
]);
|
], showBack: true);
|
||||||
}
|
}
|
||||||
|
|
||||||
void _handleChange(Auth auth, String mountType) {
|
void _handleChange(Auth auth, String mountType) {
|
||||||
|
@@ -1,12 +1,9 @@
|
|||||||
// edit_mount_screen.dart
|
// edit_mount_screen.dart
|
||||||
|
|
||||||
import 'dart:convert';
|
import 'dart:convert';
|
||||||
import 'dart:ui';
|
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:provider/provider.dart';
|
|
||||||
import 'package:repertory/constants.dart' as constants;
|
import 'package:repertory/constants.dart' as constants;
|
||||||
import 'package:repertory/helpers.dart';
|
import 'package:repertory/helpers.dart';
|
||||||
import 'package:repertory/models/auth.dart';
|
|
||||||
import 'package:repertory/models/mount.dart';
|
import 'package:repertory/models/mount.dart';
|
||||||
import 'package:repertory/utils/safe_set_state_mixin.dart';
|
import 'package:repertory/utils/safe_set_state_mixin.dart';
|
||||||
import 'package:repertory/widgets/mount_settings.dart';
|
import 'package:repertory/widgets/mount_settings.dart';
|
||||||
@@ -28,164 +25,48 @@ class _EditMountScreenState extends State<EditMountScreen>
|
|||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
final scheme = Theme.of(context).colorScheme;
|
final scheme = Theme.of(context).colorScheme;
|
||||||
final textTheme = Theme.of(context).textTheme;
|
final textTheme = Theme.of(context).textTheme;
|
||||||
|
return createCommonScaffold(
|
||||||
return createCommonScaffold([
|
context,
|
||||||
Column(
|
widget.title,
|
||||||
crossAxisAlignment: CrossAxisAlignment.stretch,
|
[
|
||||||
children: [
|
Expanded(
|
||||||
const SizedBox(height: constants.padding),
|
child: Padding(
|
||||||
Padding(
|
|
||||||
padding: const EdgeInsets.symmetric(horizontal: constants.padding),
|
padding: const EdgeInsets.symmetric(horizontal: constants.padding),
|
||||||
child: Row(
|
child: ClipRRect(
|
||||||
children: [
|
borderRadius: BorderRadius.circular(constants.borderRadius),
|
||||||
Material(
|
child: MountSettingsWidget(
|
||||||
color: Colors.transparent,
|
mount: widget.mount,
|
||||||
child: InkWell(
|
settings: jsonDecode(
|
||||||
borderRadius: BorderRadius.circular(constants.borderRadius),
|
jsonEncode(widget.mount.mountConfig.settings),
|
||||||
onTap: () => Navigator.of(context).pop(),
|
|
||||||
child: Ink(
|
|
||||||
width: 40,
|
|
||||||
height: 40,
|
|
||||||
decoration: BoxDecoration(
|
|
||||||
color: scheme.surface.withValues(alpha: 0.40),
|
|
||||||
borderRadius: BorderRadius.circular(
|
|
||||||
constants.borderRadius,
|
|
||||||
),
|
|
||||||
border: Border.all(
|
|
||||||
color: scheme.outlineVariant.withValues(alpha: 0.08),
|
|
||||||
width: 1,
|
|
||||||
),
|
|
||||||
boxShadow: [
|
|
||||||
BoxShadow(
|
|
||||||
color: Colors.black.withValues(alpha: 0.22),
|
|
||||||
blurRadius: constants.borderRadius,
|
|
||||||
offset: Offset(0, constants.borderRadius),
|
|
||||||
),
|
|
||||||
],
|
|
||||||
),
|
|
||||||
child: const Icon(Icons.arrow_back),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
const SizedBox(width: constants.padding),
|
|
||||||
Expanded(
|
|
||||||
child: Text(
|
|
||||||
widget.title,
|
|
||||||
maxLines: 1,
|
|
||||||
overflow: TextOverflow.ellipsis,
|
|
||||||
style: textTheme.headlineSmall?.copyWith(
|
|
||||||
fontWeight: FontWeight.w700,
|
|
||||||
letterSpacing: 0.2,
|
|
||||||
color: scheme.onSurface.withValues(alpha: 0.96),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
const SizedBox(width: constants.padding),
|
|
||||||
ClipRRect(
|
|
||||||
borderRadius: BorderRadius.circular(constants.borderRadius),
|
|
||||||
child: BackdropFilter(
|
|
||||||
filter: ImageFilter.blur(
|
|
||||||
sigmaX: constants.borderRadius,
|
|
||||||
sigmaY: constants.borderRadius,
|
|
||||||
),
|
|
||||||
child: Container(
|
|
||||||
height: 40,
|
|
||||||
padding: const EdgeInsets.symmetric(horizontal: 10),
|
|
||||||
decoration: BoxDecoration(
|
|
||||||
color: scheme.surface.withValues(alpha: 0.40),
|
|
||||||
borderRadius: BorderRadius.circular(
|
|
||||||
constants.borderRadius,
|
|
||||||
),
|
|
||||||
border: Border.all(
|
|
||||||
color: scheme.outlineVariant.withValues(alpha: 0.08),
|
|
||||||
width: 1,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
child: Row(
|
|
||||||
mainAxisSize: MainAxisSize.min,
|
|
||||||
children: [
|
|
||||||
Text(
|
|
||||||
"Advanced",
|
|
||||||
style: textTheme.labelLarge?.copyWith(
|
|
||||||
color: scheme.onSurface.withValues(alpha: 0.90),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
const SizedBox(width: 6),
|
|
||||||
IconButton(
|
|
||||||
tooltip: _showAdvanced
|
|
||||||
? 'Hide advanced'
|
|
||||||
: 'Show advanced',
|
|
||||||
icon: Icon(
|
|
||||||
_showAdvanced
|
|
||||||
? Icons.toggle_on
|
|
||||||
: Icons.toggle_off,
|
|
||||||
),
|
|
||||||
color: _showAdvanced
|
|
||||||
? scheme.primary
|
|
||||||
: scheme.onSurface.withValues(alpha: 0.70),
|
|
||||||
onPressed: () =>
|
|
||||||
setState(() => _showAdvanced = !_showAdvanced),
|
|
||||||
),
|
|
||||||
],
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
const SizedBox(width: constants.padding),
|
|
||||||
ClipRRect(
|
|
||||||
borderRadius: BorderRadius.circular(constants.borderRadius),
|
|
||||||
child: BackdropFilter(
|
|
||||||
filter: ImageFilter.blur(
|
|
||||||
sigmaX: constants.borderRadius,
|
|
||||||
sigmaY: constants.borderRadius,
|
|
||||||
),
|
|
||||||
child: Container(
|
|
||||||
height: 40,
|
|
||||||
padding: const EdgeInsets.symmetric(horizontal: 6),
|
|
||||||
decoration: BoxDecoration(
|
|
||||||
color: scheme.surface.withValues(alpha: 0.40),
|
|
||||||
borderRadius: BorderRadius.circular(
|
|
||||||
constants.borderRadius,
|
|
||||||
),
|
|
||||||
border: Border.all(
|
|
||||||
color: scheme.outlineVariant.withValues(alpha: 0.08),
|
|
||||||
width: 1,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
child: Consumer<Auth>(
|
|
||||||
builder: (context, auth, _) => IconButton(
|
|
||||||
tooltip: 'Log out',
|
|
||||||
icon: const Icon(Icons.logout),
|
|
||||||
onPressed: auth.logoff,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
],
|
|
||||||
),
|
|
||||||
),
|
|
||||||
const SizedBox(height: constants.padding),
|
|
||||||
Expanded(
|
|
||||||
child: Padding(
|
|
||||||
padding: const EdgeInsets.symmetric(
|
|
||||||
horizontal: constants.padding,
|
|
||||||
),
|
|
||||||
child: ClipRRect(
|
|
||||||
borderRadius: BorderRadius.circular(constants.borderRadius),
|
|
||||||
child: MountSettingsWidget(
|
|
||||||
mount: widget.mount,
|
|
||||||
settings: jsonDecode(
|
|
||||||
jsonEncode(widget.mount.mountConfig.settings),
|
|
||||||
),
|
|
||||||
showAdvanced: _showAdvanced,
|
|
||||||
),
|
),
|
||||||
|
showAdvanced: _showAdvanced,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
const SizedBox(height: constants.padding),
|
),
|
||||||
|
const SizedBox(height: constants.padding),
|
||||||
|
],
|
||||||
|
showBack: true,
|
||||||
|
advancedWidget: Row(
|
||||||
|
mainAxisSize: MainAxisSize.min,
|
||||||
|
children: [
|
||||||
|
Text(
|
||||||
|
"Advanced",
|
||||||
|
style: textTheme.labelLarge?.copyWith(
|
||||||
|
color: scheme.onSurface.withValues(alpha: 0.90),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
const SizedBox(width: 6),
|
||||||
|
IconButton(
|
||||||
|
tooltip: _showAdvanced ? 'Hide advanced' : 'Show advanced',
|
||||||
|
icon: Icon(_showAdvanced ? Icons.toggle_on : Icons.toggle_off),
|
||||||
|
color: _showAdvanced
|
||||||
|
? scheme.primary
|
||||||
|
: scheme.onSurface.withValues(alpha: 0.70),
|
||||||
|
onPressed: () => setState(() => _showAdvanced = !_showAdvanced),
|
||||||
|
),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
]);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -2,7 +2,6 @@
|
|||||||
|
|
||||||
import 'dart:convert' show jsonDecode, jsonEncode;
|
import 'dart:convert' show jsonDecode, jsonEncode;
|
||||||
|
|
||||||
import 'dart:ui';
|
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:http/http.dart' as http;
|
import 'package:http/http.dart' as http;
|
||||||
import 'package:provider/provider.dart';
|
import 'package:provider/provider.dart';
|
||||||
@@ -24,132 +23,32 @@ class _EditSettingsScreenState extends State<EditSettingsScreen>
|
|||||||
with SafeSetState<EditSettingsScreen> {
|
with SafeSetState<EditSettingsScreen> {
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
final scheme = Theme.of(context).colorScheme;
|
return createCommonScaffold(context, widget.title, [
|
||||||
final textTheme = Theme.of(context).textTheme;
|
Expanded(
|
||||||
|
child: Padding(
|
||||||
|
padding: const EdgeInsets.symmetric(horizontal: constants.padding),
|
||||||
|
child: ClipRRect(
|
||||||
|
borderRadius: BorderRadius.circular(constants.borderRadius),
|
||||||
|
child: FutureBuilder<Map<String, dynamic>>(
|
||||||
|
future: _grabSettings(),
|
||||||
|
initialData: const <String, dynamic>{},
|
||||||
|
builder: (context, snapshot) {
|
||||||
|
if (!snapshot.hasData) {
|
||||||
|
return const Center(child: CircularProgressIndicator());
|
||||||
|
}
|
||||||
|
|
||||||
return createCommonScaffold([
|
return UISettingsWidget(
|
||||||
Column(
|
origSettings: jsonDecode(jsonEncode(snapshot.requireData)),
|
||||||
crossAxisAlignment: CrossAxisAlignment.stretch,
|
settings: snapshot.requireData,
|
||||||
children: [
|
showAdvanced: false,
|
||||||
const SizedBox(height: constants.padding),
|
);
|
||||||
Padding(
|
},
|
||||||
padding: const EdgeInsets.symmetric(horizontal: constants.padding),
|
|
||||||
child: Row(
|
|
||||||
children: [
|
|
||||||
Material(
|
|
||||||
color: Colors.transparent,
|
|
||||||
child: InkWell(
|
|
||||||
borderRadius: BorderRadius.circular(constants.borderRadius),
|
|
||||||
onTap: () {
|
|
||||||
Navigator.of(context).pop();
|
|
||||||
},
|
|
||||||
child: Ink(
|
|
||||||
width: 40,
|
|
||||||
height: 40,
|
|
||||||
decoration: BoxDecoration(
|
|
||||||
color: scheme.surface.withValues(alpha: 0.40),
|
|
||||||
borderRadius: BorderRadius.circular(
|
|
||||||
constants.borderRadius,
|
|
||||||
),
|
|
||||||
border: Border.all(
|
|
||||||
color: scheme.outlineVariant.withValues(alpha: 0.08),
|
|
||||||
width: 1,
|
|
||||||
),
|
|
||||||
boxShadow: [
|
|
||||||
BoxShadow(
|
|
||||||
color: Colors.black.withValues(alpha: 0.22),
|
|
||||||
blurRadius: constants.borderRadius,
|
|
||||||
offset: Offset(0, constants.borderRadius),
|
|
||||||
),
|
|
||||||
],
|
|
||||||
),
|
|
||||||
child: const Icon(Icons.arrow_back),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
const SizedBox(width: constants.padding),
|
|
||||||
Expanded(
|
|
||||||
child: Text(
|
|
||||||
widget.title,
|
|
||||||
maxLines: 1,
|
|
||||||
overflow: TextOverflow.ellipsis,
|
|
||||||
style: textTheme.headlineSmall?.copyWith(
|
|
||||||
fontWeight: FontWeight.w700,
|
|
||||||
letterSpacing: 0.2,
|
|
||||||
color: scheme.onSurface.withValues(alpha: 0.96),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
const SizedBox(width: constants.padding),
|
|
||||||
ClipRRect(
|
|
||||||
borderRadius: BorderRadius.circular(constants.borderRadius),
|
|
||||||
child: BackdropFilter(
|
|
||||||
filter: ImageFilter.blur(
|
|
||||||
sigmaX: constants.borderRadius,
|
|
||||||
sigmaY: constants.borderRadius,
|
|
||||||
),
|
|
||||||
child: Container(
|
|
||||||
height: 40,
|
|
||||||
padding: const EdgeInsets.symmetric(horizontal: 6),
|
|
||||||
decoration: BoxDecoration(
|
|
||||||
color: scheme.surface.withValues(alpha: 0.40),
|
|
||||||
borderRadius: BorderRadius.circular(
|
|
||||||
constants.borderRadius,
|
|
||||||
),
|
|
||||||
border: Border.all(
|
|
||||||
color: scheme.outlineVariant.withValues(alpha: 0.08),
|
|
||||||
width: 1,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
child: Consumer<Auth>(
|
|
||||||
builder: (context, auth, _) {
|
|
||||||
return IconButton(
|
|
||||||
tooltip: 'Log out',
|
|
||||||
icon: const Icon(Icons.logout),
|
|
||||||
onPressed: () {
|
|
||||||
auth.logoff();
|
|
||||||
},
|
|
||||||
);
|
|
||||||
},
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
],
|
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
const SizedBox(height: constants.padding),
|
),
|
||||||
Expanded(
|
|
||||||
child: Padding(
|
|
||||||
padding: const EdgeInsets.symmetric(
|
|
||||||
horizontal: constants.padding,
|
|
||||||
),
|
|
||||||
child: ClipRRect(
|
|
||||||
borderRadius: BorderRadius.circular(constants.borderRadius),
|
|
||||||
child: FutureBuilder<Map<String, dynamic>>(
|
|
||||||
future: _grabSettings(),
|
|
||||||
initialData: const <String, dynamic>{},
|
|
||||||
builder: (context, snapshot) {
|
|
||||||
if (!snapshot.hasData) {
|
|
||||||
return const Center(child: CircularProgressIndicator());
|
|
||||||
}
|
|
||||||
|
|
||||||
return UISettingsWidget(
|
|
||||||
origSettings: jsonDecode(
|
|
||||||
jsonEncode(snapshot.requireData),
|
|
||||||
),
|
|
||||||
settings: snapshot.requireData,
|
|
||||||
showAdvanced: false,
|
|
||||||
);
|
|
||||||
},
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
const SizedBox(height: constants.padding),
|
|
||||||
],
|
|
||||||
),
|
),
|
||||||
]);
|
const SizedBox(height: constants.padding),
|
||||||
|
], showBack: true);
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<Map<String, dynamic>> _grabSettings() async {
|
Future<Map<String, dynamic>> _grabSettings() async {
|
||||||
|
@@ -1,12 +1,8 @@
|
|||||||
// home_screen.dart
|
// home_screen.dart
|
||||||
|
|
||||||
import 'dart:ui';
|
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:provider/provider.dart';
|
|
||||||
import 'package:repertory/constants.dart' as constants;
|
import 'package:repertory/constants.dart' as constants;
|
||||||
import 'package:repertory/helpers.dart';
|
import 'package:repertory/helpers.dart';
|
||||||
import 'package:repertory/models/auth.dart';
|
|
||||||
import 'package:repertory/models/settings.dart';
|
|
||||||
import 'package:repertory/widgets/mount_list_widget.dart';
|
import 'package:repertory/widgets/mount_list_widget.dart';
|
||||||
|
|
||||||
class HomeScreen extends StatefulWidget {
|
class HomeScreen extends StatefulWidget {
|
||||||
@@ -21,129 +17,16 @@ class _HomeScreeState extends State<HomeScreen> {
|
|||||||
@override
|
@override
|
||||||
Widget build(context) {
|
Widget build(context) {
|
||||||
final scheme = Theme.of(context).colorScheme;
|
final scheme = Theme.of(context).colorScheme;
|
||||||
final textTheme = Theme.of(context).textTheme;
|
|
||||||
|
|
||||||
return createCommonScaffold(
|
return createCommonScaffold(
|
||||||
|
context,
|
||||||
|
widget.title,
|
||||||
[
|
[
|
||||||
Column(
|
Expanded(
|
||||||
crossAxisAlignment: CrossAxisAlignment.stretch,
|
child: Padding(
|
||||||
children: [
|
padding: const EdgeInsets.symmetric(horizontal: constants.padding),
|
||||||
const SizedBox(height: constants.padding),
|
child: const MountListWidget(),
|
||||||
Padding(
|
),
|
||||||
padding: const EdgeInsets.symmetric(
|
|
||||||
horizontal: constants.padding,
|
|
||||||
),
|
|
||||||
child: Row(
|
|
||||||
children: [
|
|
||||||
SizedBox(
|
|
||||||
width: 40,
|
|
||||||
height: 40,
|
|
||||||
child: Image.asset(
|
|
||||||
'assets/images/repertory.png',
|
|
||||||
fit: BoxFit.contain,
|
|
||||||
errorBuilder: (_, _, _) {
|
|
||||||
return Icon(
|
|
||||||
Icons.folder,
|
|
||||||
color: scheme.primary,
|
|
||||||
size: 32,
|
|
||||||
);
|
|
||||||
},
|
|
||||||
),
|
|
||||||
),
|
|
||||||
const SizedBox(width: constants.padding),
|
|
||||||
Expanded(
|
|
||||||
child: Text(
|
|
||||||
widget.title,
|
|
||||||
maxLines: 1,
|
|
||||||
overflow: TextOverflow.ellipsis,
|
|
||||||
style: textTheme.headlineSmall?.copyWith(
|
|
||||||
fontWeight: FontWeight.w700,
|
|
||||||
letterSpacing: 0.2,
|
|
||||||
color: scheme.onSurface.withValues(alpha: 0.96),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
const SizedBox(width: constants.padding),
|
|
||||||
ClipRRect(
|
|
||||||
borderRadius: BorderRadius.circular(constants.borderRadius),
|
|
||||||
child: BackdropFilter(
|
|
||||||
filter: ImageFilter.blur(
|
|
||||||
sigmaX: constants.borderRadius,
|
|
||||||
sigmaY: constants.borderRadius,
|
|
||||||
),
|
|
||||||
child: Container(
|
|
||||||
height: 40,
|
|
||||||
padding: const EdgeInsets.symmetric(horizontal: 6),
|
|
||||||
decoration: BoxDecoration(
|
|
||||||
color: scheme.surface.withValues(alpha: 0.40),
|
|
||||||
borderRadius: BorderRadius.circular(
|
|
||||||
constants.borderRadius,
|
|
||||||
),
|
|
||||||
border: Border.all(
|
|
||||||
color: scheme.outlineVariant.withValues(
|
|
||||||
alpha: 0.08,
|
|
||||||
),
|
|
||||||
width: 1,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
child: Row(
|
|
||||||
children: [
|
|
||||||
const Text("Auto-start"),
|
|
||||||
Consumer<Settings>(
|
|
||||||
builder: (context, settings, _) {
|
|
||||||
return IconButton(
|
|
||||||
icon: Icon(
|
|
||||||
settings.autoStart
|
|
||||||
? Icons.toggle_on
|
|
||||||
: Icons.toggle_off,
|
|
||||||
),
|
|
||||||
color: settings.autoStart
|
|
||||||
? scheme.primary
|
|
||||||
: scheme.onSurface.withValues(
|
|
||||||
alpha: 0.70,
|
|
||||||
),
|
|
||||||
onPressed: () => settings.setAutoStart(
|
|
||||||
!settings.autoStart,
|
|
||||||
),
|
|
||||||
);
|
|
||||||
},
|
|
||||||
),
|
|
||||||
IconButton(
|
|
||||||
tooltip: 'Settings',
|
|
||||||
icon: const Icon(Icons.settings),
|
|
||||||
onPressed: () {
|
|
||||||
Navigator.pushNamed(context, '/settings');
|
|
||||||
},
|
|
||||||
),
|
|
||||||
Consumer<Auth>(
|
|
||||||
builder: (context, auth, _) {
|
|
||||||
return IconButton(
|
|
||||||
tooltip: 'Log out',
|
|
||||||
icon: const Icon(Icons.logout),
|
|
||||||
onPressed: () {
|
|
||||||
auth.logoff();
|
|
||||||
},
|
|
||||||
);
|
|
||||||
},
|
|
||||||
),
|
|
||||||
],
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
],
|
|
||||||
),
|
|
||||||
),
|
|
||||||
const SizedBox(height: constants.padding),
|
|
||||||
Expanded(
|
|
||||||
child: Padding(
|
|
||||||
padding: const EdgeInsets.symmetric(
|
|
||||||
horizontal: constants.padding,
|
|
||||||
),
|
|
||||||
child: const MountListWidget(),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
],
|
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
floatingActionButton: Padding(
|
floatingActionButton: Padding(
|
||||||
|
@@ -10,7 +10,7 @@ import 'package:repertory/widgets/app_dropdown.dart';
|
|||||||
import 'package:settings_ui/settings_ui.dart';
|
import 'package:settings_ui/settings_ui.dart';
|
||||||
|
|
||||||
void createBooleanSetting(
|
void createBooleanSetting(
|
||||||
context,
|
BuildContext context,
|
||||||
List<Widget> list,
|
List<Widget> list,
|
||||||
Map<String, dynamic> settings,
|
Map<String, dynamic> settings,
|
||||||
String key,
|
String key,
|
||||||
@@ -38,7 +38,7 @@ void createBooleanSetting(
|
|||||||
}
|
}
|
||||||
|
|
||||||
void createIntListSetting(
|
void createIntListSetting(
|
||||||
context,
|
BuildContext context,
|
||||||
List<Widget> list,
|
List<Widget> list,
|
||||||
Map<String, dynamic> settings,
|
Map<String, dynamic> settings,
|
||||||
String key,
|
String key,
|
||||||
@@ -76,7 +76,7 @@ void createIntListSetting(
|
|||||||
}
|
}
|
||||||
|
|
||||||
void createIntSetting(
|
void createIntSetting(
|
||||||
context,
|
BuildContext context,
|
||||||
List<Widget> list,
|
List<Widget> list,
|
||||||
Map<String, dynamic> settings,
|
Map<String, dynamic> settings,
|
||||||
String key,
|
String key,
|
||||||
@@ -139,7 +139,7 @@ void createIntSetting(
|
|||||||
}
|
}
|
||||||
|
|
||||||
void createPasswordSetting(
|
void createPasswordSetting(
|
||||||
context,
|
BuildContext context,
|
||||||
List<Widget> list,
|
List<Widget> list,
|
||||||
Map<String, dynamic> settings,
|
Map<String, dynamic> settings,
|
||||||
String key,
|
String key,
|
||||||
@@ -267,7 +267,11 @@ void createPasswordSetting(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Widget createSettingTitle(context, String key, String? description) {
|
Widget createSettingTitle(
|
||||||
|
BuildContext context,
|
||||||
|
String key,
|
||||||
|
String? description,
|
||||||
|
) {
|
||||||
if (description == null) {
|
if (description == null) {
|
||||||
return Text(key);
|
return Text(key);
|
||||||
}
|
}
|
||||||
@@ -288,7 +292,7 @@ Widget createSettingTitle(context, String key, String? description) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void createStringListSetting(
|
void createStringListSetting(
|
||||||
context,
|
BuildContext context,
|
||||||
List<Widget> list,
|
List<Widget> list,
|
||||||
Map<String, dynamic> settings,
|
Map<String, dynamic> settings,
|
||||||
String key,
|
String key,
|
||||||
@@ -319,7 +323,7 @@ void createStringListSetting(
|
|||||||
}
|
}
|
||||||
|
|
||||||
void createStringSetting(
|
void createStringSetting(
|
||||||
context,
|
BuildContext context,
|
||||||
List<Widget> list,
|
List<Widget> list,
|
||||||
Map<String, dynamic> settings,
|
Map<String, dynamic> settings,
|
||||||
String key,
|
String key,
|
||||||
|
@@ -7,9 +7,12 @@ class MountConfig {
|
|||||||
String path = '';
|
String path = '';
|
||||||
Map<String, dynamic> _settings = {};
|
Map<String, dynamic> _settings = {};
|
||||||
final String _type;
|
final String _type;
|
||||||
MountConfig({required name, required type, Map<String, dynamic>? settings})
|
MountConfig({
|
||||||
: _name = name,
|
required String name,
|
||||||
_type = type {
|
required String type,
|
||||||
|
Map<String, dynamic>? settings,
|
||||||
|
}) : _name = name,
|
||||||
|
_type = type {
|
||||||
if (settings != null) {
|
if (settings != null) {
|
||||||
_settings = settings;
|
_settings = settings;
|
||||||
}
|
}
|
||||||
|
@@ -190,16 +190,6 @@ class _MountWidgetState extends State<MountWidget>
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
String _formatType(String type) {
|
|
||||||
if (type.toUpperCase() == 'S3') {
|
|
||||||
return 'S3';
|
|
||||||
}
|
|
||||||
if (type.isEmpty) {
|
|
||||||
return type;
|
|
||||||
}
|
|
||||||
return type[0].toUpperCase() + type.substring(1).toLowerCase();
|
|
||||||
}
|
|
||||||
|
|
||||||
String _prettyPath(Mount mount) {
|
String _prettyPath(Mount mount) {
|
||||||
if (mount.path.isEmpty && mount.mounted == null) {
|
if (mount.path.isEmpty && mount.mounted == null) {
|
||||||
return 'loading...';
|
return 'loading...';
|
||||||
@@ -271,6 +261,7 @@ class _MountWidgetState extends State<MountWidget>
|
|||||||
return location;
|
return location;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ignore: use_build_context_synchronously
|
||||||
return editMountLocation(context, await mount.getAvailableLocations());
|
return editMountLocation(context, await mount.getAvailableLocations());
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -294,14 +285,8 @@ class _FramedBox extends StatelessWidget {
|
|||||||
final IconData icon;
|
final IconData icon;
|
||||||
final VoidCallback? onTap;
|
final VoidCallback? onTap;
|
||||||
final Color? iconColor;
|
final Color? iconColor;
|
||||||
final double iconSize;
|
|
||||||
|
|
||||||
const _FramedBox({
|
const _FramedBox({required this.icon, this.onTap, this.iconColor});
|
||||||
required this.icon,
|
|
||||||
this.onTap,
|
|
||||||
this.iconColor,
|
|
||||||
this.iconSize = 32,
|
|
||||||
});
|
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
@@ -337,7 +322,7 @@ class _FramedBox extends StatelessWidget {
|
|||||||
child: Icon(
|
child: Icon(
|
||||||
icon,
|
icon,
|
||||||
color: iconColor ?? scheme.onSurface.withValues(alpha: 0.92),
|
color: iconColor ?? scheme.onSurface.withValues(alpha: 0.92),
|
||||||
size: iconSize,
|
size: 32.0,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
Reference in New Issue
Block a user