diff --git a/web/repertory/lib/helpers.dart b/web/repertory/lib/helpers.dart index e1053ca6..7fbf1ca0 100644 --- a/web/repertory/lib/helpers.dart +++ b/web/repertory/lib/helpers.dart @@ -96,7 +96,7 @@ createUriValidator({host, port}) { Uri.tryParse('http://${host ?? value}:${port ?? value}/') != null; } -createHostNameOrIpValidators() => [ +List createHostNameOrIpValidators() => [ trimNotEmptyValidator, 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) { return; } @@ -431,39 +435,166 @@ Future editMountLocation( } Scaffold createCommonScaffold( + BuildContext context, + String title, List children, { + Widget? advancedWidget, Widget? floatingActionButton, -}) => Scaffold( - body: SafeArea( - child: Stack( - children: [ - Container( - width: double.infinity, - height: double.infinity, - decoration: const BoxDecoration( - gradient: LinearGradient( - begin: Alignment.topLeft, - end: Alignment.bottomRight, - colors: constants.gradientColors, + bool showBack = false, +}) { + final scheme = Theme.of(context).colorScheme; + final textTheme = Theme.of(context).textTheme; + + return Scaffold( + body: SafeArea( + child: Stack( + children: [ + Container( + width: double.infinity, + height: double.infinity, + decoration: const BoxDecoration( + gradient: LinearGradient( + begin: Alignment.topLeft, + end: Alignment.bottomRight, + colors: constants.gradientColors, + ), ), ), - ), - Consumer( - builder: (_, settings, _) => - AuroraSweep(enabled: settings.enableAnimations), - ), - Positioned.fill( - child: BackdropFilter( - filter: ImageFilter.blur(sigmaX: 6, sigmaY: 6), - child: Container(color: Colors.black.withValues(alpha: 0.06)), + Consumer( + builder: (_, settings, _) => + AuroraSweep(enabled: settings.enableAnimations), ), - ), - ...children, - ], + Positioned.fill( + 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( + 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( + 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( ColorScheme colorScheme, diff --git a/web/repertory/lib/models/mount_list.dart b/web/repertory/lib/models/mount_list.dart index 979be535..502642ac 100644 --- a/web/repertory/lib/models/mount_list.dart +++ b/web/repertory/lib/models/mount_list.dart @@ -38,9 +38,9 @@ class MountList with ChangeNotifier { return (excludeName == null ? list : list.whereNot( - (item) => - item.name.toLowerCase() == excludeName.toLowerCase(), - )) + (item) => + item.name.toLowerCase() == excludeName.toLowerCase(), + )) .firstWhereOrNull((Mount item) { return item.bucket != null && item.bucket!.toLowerCase() == bucket.toLowerCase(); @@ -98,7 +98,7 @@ class MountList with ChangeNotifier { } } - void _sort(list) { + void _sort(List list) { list.sort((a, b) { final res = a.type.compareTo(b.type); if (res != 0) { diff --git a/web/repertory/lib/models/settings.dart b/web/repertory/lib/models/settings.dart index 1f3946d1..43ad7a0e 100644 --- a/web/repertory/lib/models/settings.dart +++ b/web/repertory/lib/models/settings.dart @@ -8,7 +8,7 @@ import 'package:repertory/models/auth.dart'; class Settings with ChangeNotifier { final Auth _auth; bool _autoStart = false; - bool _enableAnimations = true; + bool _enableAnimations = false; Settings(this._auth) { _auth.addListener(() { diff --git a/web/repertory/lib/screens/add_mount_screen.dart b/web/repertory/lib/screens/add_mount_screen.dart index 67705147..40df94c7 100644 --- a/web/repertory/lib/screens/add_mount_screen.dart +++ b/web/repertory/lib/screens/add_mount_screen.dart @@ -1,6 +1,5 @@ // add_mount_screen.dart -import 'dart:ui'; import 'package:flutter/material.dart'; import 'package:flutter/services.dart'; import 'package:provider/provider.dart'; @@ -45,248 +44,149 @@ class _AddMountScreenState extends State @override Widget build(BuildContext context) { final scheme = Theme.of(context).colorScheme; - final textTheme = Theme.of(context).textTheme; - return createCommonScaffold([ - Padding( - padding: const EdgeInsets.all(constants.padding), - child: Column( - crossAxisAlignment: CrossAxisAlignment.stretch, + return createCommonScaffold(context, widget.title, [ + AppDropdownFormField( + constrainToIntrinsic: true, + isExpanded: false, + labelOf: (s) => s, + labelText: 'Provider Type', + onChanged: (mountType) { + _handleChange( + Provider.of(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(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: [ - Row( - children: [ - Material( - color: Colors.transparent, - child: InkWell( + 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), - 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), + side: BorderSide( + color: scheme.outlineVariant.withValues(alpha: 0.15), + width: 1, ), ), ), - 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( - builder: (context, auth, _) => IconButton( - tooltip: 'Log out', - icon: const Icon(Icons.logout), - onPressed: auth.logoff, - ), - ), - ), - ), - ), - ], - ), - const SizedBox(height: constants.padding), - AppDropdownFormField( - constrainToIntrinsic: true, - isExpanded: false, - labelOf: (s) => s, - labelText: 'Provider Type', - onChanged: (mountType) { - _handleChange( - Provider.of(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(context, listen: false), - _mountType, - ), - decoration: createCommonDecoration( - scheme, - 'Configuration Name', - hintText: 'Enter a unique name', - icon: Icons.drive_file_rename_outline, - ), + onPressed: _handleProviderTest, ), - ], - if (_mount != null) ...[ - const SizedBox(height: constants.padding), - Expanded( - child: Padding( - padding: const EdgeInsets.symmetric( - horizontal: constants.padding, - ), - child: ClipRRect( + ), + 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), - child: MountSettingsWidget( - isAdd: true, - mount: _mount!, - settings: _settings[_mountType]!, - showAdvanced: false, - ), ), ), + onPressed: () async { + final mountList = Provider.of( + context, + listen: false, + ); + + List 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( - context, - listen: false, - ); - - List 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) { diff --git a/web/repertory/lib/screens/edit_mount_screen.dart b/web/repertory/lib/screens/edit_mount_screen.dart index f8a89158..3fc59653 100644 --- a/web/repertory/lib/screens/edit_mount_screen.dart +++ b/web/repertory/lib/screens/edit_mount_screen.dart @@ -1,12 +1,9 @@ // edit_mount_screen.dart import 'dart:convert'; -import 'dart:ui'; import 'package:flutter/material.dart'; -import 'package:provider/provider.dart'; import 'package:repertory/constants.dart' as constants; import 'package:repertory/helpers.dart'; -import 'package:repertory/models/auth.dart'; import 'package:repertory/models/mount.dart'; import 'package:repertory/utils/safe_set_state_mixin.dart'; import 'package:repertory/widgets/mount_settings.dart'; @@ -28,164 +25,48 @@ class _EditMountScreenState extends State Widget build(BuildContext context) { final scheme = Theme.of(context).colorScheme; final textTheme = Theme.of(context).textTheme; - - return createCommonScaffold([ - Column( - crossAxisAlignment: CrossAxisAlignment.stretch, - children: [ - const SizedBox(height: constants.padding), - Padding( + return createCommonScaffold( + context, + widget.title, + [ + Expanded( + child: 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: 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( - 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, + child: ClipRRect( + borderRadius: BorderRadius.circular(constants.borderRadius), + child: MountSettingsWidget( + mount: widget.mount, + settings: jsonDecode( + jsonEncode(widget.mount.mountConfig.settings), ), + 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), + ), ], ), - ]); + ); } } diff --git a/web/repertory/lib/screens/edit_settings_screen.dart b/web/repertory/lib/screens/edit_settings_screen.dart index 6197573f..ae010375 100644 --- a/web/repertory/lib/screens/edit_settings_screen.dart +++ b/web/repertory/lib/screens/edit_settings_screen.dart @@ -2,7 +2,6 @@ import 'dart:convert' show jsonDecode, jsonEncode; -import 'dart:ui'; import 'package:flutter/material.dart'; import 'package:http/http.dart' as http; import 'package:provider/provider.dart'; @@ -24,132 +23,32 @@ class _EditSettingsScreenState extends State with SafeSetState { @override Widget build(BuildContext context) { - final scheme = Theme.of(context).colorScheme; - final textTheme = Theme.of(context).textTheme; + return createCommonScaffold(context, widget.title, [ + Expanded( + child: Padding( + padding: const EdgeInsets.symmetric(horizontal: constants.padding), + child: ClipRRect( + borderRadius: BorderRadius.circular(constants.borderRadius), + child: FutureBuilder>( + future: _grabSettings(), + initialData: const {}, + builder: (context, snapshot) { + if (!snapshot.hasData) { + return const Center(child: CircularProgressIndicator()); + } - return createCommonScaffold([ - Column( - crossAxisAlignment: CrossAxisAlignment.stretch, - children: [ - 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( - builder: (context, auth, _) { - return IconButton( - tooltip: 'Log out', - icon: const Icon(Icons.logout), - onPressed: () { - auth.logoff(); - }, - ); - }, - ), - ), - ), - ), - ], + return UISettingsWidget( + origSettings: jsonDecode(jsonEncode(snapshot.requireData)), + settings: snapshot.requireData, + showAdvanced: false, + ); + }, ), ), - const SizedBox(height: constants.padding), - Expanded( - child: Padding( - padding: const EdgeInsets.symmetric( - horizontal: constants.padding, - ), - child: ClipRRect( - borderRadius: BorderRadius.circular(constants.borderRadius), - child: FutureBuilder>( - future: _grabSettings(), - initialData: const {}, - 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> _grabSettings() async { diff --git a/web/repertory/lib/screens/home_screen.dart b/web/repertory/lib/screens/home_screen.dart index a0c97d6c..23a81e73 100644 --- a/web/repertory/lib/screens/home_screen.dart +++ b/web/repertory/lib/screens/home_screen.dart @@ -1,12 +1,8 @@ // home_screen.dart -import 'dart:ui'; import 'package:flutter/material.dart'; -import 'package:provider/provider.dart'; import 'package:repertory/constants.dart' as constants; 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'; class HomeScreen extends StatefulWidget { @@ -21,129 +17,16 @@ class _HomeScreeState extends State { @override Widget build(context) { final scheme = Theme.of(context).colorScheme; - final textTheme = Theme.of(context).textTheme; return createCommonScaffold( + context, + widget.title, [ - Column( - crossAxisAlignment: CrossAxisAlignment.stretch, - children: [ - const SizedBox(height: constants.padding), - 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( - 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( - 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(), - ), - ), - ], + Expanded( + child: Padding( + padding: const EdgeInsets.symmetric(horizontal: constants.padding), + child: const MountListWidget(), + ), ), ], floatingActionButton: Padding( diff --git a/web/repertory/lib/settings.dart b/web/repertory/lib/settings.dart index 9a800b41..0d52bc1e 100644 --- a/web/repertory/lib/settings.dart +++ b/web/repertory/lib/settings.dart @@ -10,7 +10,7 @@ import 'package:repertory/widgets/app_dropdown.dart'; import 'package:settings_ui/settings_ui.dart'; void createBooleanSetting( - context, + BuildContext context, List list, Map settings, String key, @@ -38,7 +38,7 @@ void createBooleanSetting( } void createIntListSetting( - context, + BuildContext context, List list, Map settings, String key, @@ -76,7 +76,7 @@ void createIntListSetting( } void createIntSetting( - context, + BuildContext context, List list, Map settings, String key, @@ -139,7 +139,7 @@ void createIntSetting( } void createPasswordSetting( - context, + BuildContext context, List list, Map settings, 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) { return Text(key); } @@ -288,7 +292,7 @@ Widget createSettingTitle(context, String key, String? description) { } void createStringListSetting( - context, + BuildContext context, List list, Map settings, String key, @@ -319,7 +323,7 @@ void createStringListSetting( } void createStringSetting( - context, + BuildContext context, List list, Map settings, String key, diff --git a/web/repertory/lib/types/mount_config.dart b/web/repertory/lib/types/mount_config.dart index 631d4c7d..b9e5534a 100644 --- a/web/repertory/lib/types/mount_config.dart +++ b/web/repertory/lib/types/mount_config.dart @@ -7,9 +7,12 @@ class MountConfig { String path = ''; Map _settings = {}; final String _type; - MountConfig({required name, required type, Map? settings}) - : _name = name, - _type = type { + MountConfig({ + required String name, + required String type, + Map? settings, + }) : _name = name, + _type = type { if (settings != null) { _settings = settings; } diff --git a/web/repertory/lib/widgets/mount_widget.dart b/web/repertory/lib/widgets/mount_widget.dart index 49561dd9..102eac6c 100644 --- a/web/repertory/lib/widgets/mount_widget.dart +++ b/web/repertory/lib/widgets/mount_widget.dart @@ -190,16 +190,6 @@ class _MountWidgetState extends State ); } - 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) { if (mount.path.isEmpty && mount.mounted == null) { return 'loading...'; @@ -271,6 +261,7 @@ class _MountWidgetState extends State return location; } + // ignore: use_build_context_synchronously return editMountLocation(context, await mount.getAvailableLocations()); } @@ -294,14 +285,8 @@ class _FramedBox extends StatelessWidget { final IconData icon; final VoidCallback? onTap; final Color? iconColor; - final double iconSize; - const _FramedBox({ - required this.icon, - this.onTap, - this.iconColor, - this.iconSize = 32, - }); + const _FramedBox({required this.icon, this.onTap, this.iconColor}); @override Widget build(BuildContext context) { @@ -337,7 +322,7 @@ class _FramedBox extends StatelessWidget { child: Icon( icon, color: iconColor ?? scheme.onSurface.withValues(alpha: 0.92), - size: iconSize, + size: 32.0, ), ), ),