From d1183c00afa52a681bf5e944d6811c22daa1ebf9 Mon Sep 17 00:00:00 2001 From: "Scott E. Graves" Date: Thu, 4 Sep 2025 10:59:36 -0500 Subject: [PATCH] [ui] UI theme should match repertory blue #61 --- web/repertory/lib/helpers.dart | 58 ++ .../lib/screens/add_mount_screen.dart | 612 ++++++++---------- web/repertory/lib/screens/auth_screen.dart | 28 +- .../lib/screens/edit_mount_screen.dart | 398 +++++------- .../lib/screens/edit_settings_screen.dart | 314 ++++----- web/repertory/lib/screens/home_screen.dart | 241 +++---- web/repertory/lib/widgets/mount_settings.dart | 31 +- web/repertory/lib/widgets/mount_widget.dart | 1 - web/repertory/lib/widgets/ui_settings.dart | 11 +- 9 files changed, 750 insertions(+), 944 deletions(-) diff --git a/web/repertory/lib/helpers.dart b/web/repertory/lib/helpers.dart index 6eedca38..81edb7e6 100644 --- a/web/repertory/lib/helpers.dart +++ b/web/repertory/lib/helpers.dart @@ -1,11 +1,16 @@ // helpers.dart +import 'dart:ui'; + import 'package:convert/convert.dart'; import 'package:collection/collection.dart'; import 'package:flutter/foundation.dart'; import 'package:flutter/material.dart'; +import 'package:provider/provider.dart'; import 'package:repertory/constants.dart' as constants; import 'package:repertory/models/auth.dart'; +import 'package:repertory/models/settings.dart'; +import 'package:repertory/widgets/aurora_sweep.dart'; import 'package:sodium_libs/sodium_libs.dart' show SecureKey, StringX; Future doShowDialog(BuildContext context, Widget child) => showDialog( @@ -426,3 +431,56 @@ Future editMountLocation( ), ); } + +Scaffold createCommonScaffold(Widget child, {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, + ), + ), + ), + 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)), + ), + ), + child, + ], + ), + ), + floatingActionButton: floatingActionButton, + ); + +InputDecoration createCommonDecoration( + ColorScheme colorScheme, + String label, + IconData icon, +) => InputDecoration( + labelText: label, + prefixIcon: Icon(icon), + filled: true, + fillColor: colorScheme.primary.withValues(alpha: constants.primaryAlpha), + border: OutlineInputBorder( + borderRadius: BorderRadius.circular(constants.borderRadiusSmall), + borderSide: BorderSide.none, + ), + focusedBorder: OutlineInputBorder( + borderRadius: BorderRadius.circular(constants.borderRadiusSmall), + borderSide: BorderSide(color: colorScheme.primary, width: 2), + ), + contentPadding: const EdgeInsets.all(constants.paddingSmall), +); diff --git a/web/repertory/lib/screens/add_mount_screen.dart b/web/repertory/lib/screens/add_mount_screen.dart index d6443fa7..309f96c9 100644 --- a/web/repertory/lib/screens/add_mount_screen.dart +++ b/web/repertory/lib/screens/add_mount_screen.dart @@ -9,9 +9,7 @@ import 'package:repertory/helpers.dart'; import 'package:repertory/models/auth.dart'; import 'package:repertory/models/mount.dart'; import 'package:repertory/models/mount_list.dart'; -import 'package:repertory/models/settings.dart'; import 'package:repertory/types/mount_config.dart'; -import 'package:repertory/widgets/aurora_sweep.dart'; import 'package:repertory/widgets/mount_settings.dart'; class AddMountScreen extends StatefulWidget { @@ -46,367 +44,273 @@ class _AddMountScreenState extends State { final scheme = Theme.of(context).colorScheme; final textTheme = Theme.of(context).textTheme; - Widget glassTile({required Widget child, EdgeInsets? padding}) { - return Container( - decoration: BoxDecoration( - color: scheme.primary.withValues(alpha: constants.primaryAlpha), - borderRadius: BorderRadius.circular(constants.borderRadius), - border: Border.all( - color: scheme.outlineVariant.withValues(alpha: 0.08), - width: 1, - ), - gradient: const LinearGradient( - begin: Alignment.topCenter, - end: Alignment.bottomCenter, - colors: constants.gradientColors2, - ), - boxShadow: [ - BoxShadow( - color: Colors.black.withValues(alpha: 0.22), - blurRadius: constants.borderRadius, - offset: Offset(0, constants.borderRadius), - ), - ], - ), - child: ClipRRect( - borderRadius: BorderRadius.circular(constants.borderRadius), - child: Padding( - padding: padding ?? const EdgeInsets.all(constants.padding), - child: child, - ), - ), - ); - } - - return Scaffold( - body: SafeArea( - child: Stack( + return createCommonScaffold( + Padding( + padding: const EdgeInsets.all(constants.padding), + child: Column( + crossAxisAlignment: CrossAxisAlignment.stretch, 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, _) { - return AuroraSweep(enabled: settings.enableAnimations); - }, - ), - 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: [ - 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( + // Header + 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, ), - 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(); - }, - ); - }, - ), - ), + border: Border.all( + color: scheme.outlineVariant.withValues(alpha: 0.08), + width: 1, ), - ), - ], - ), - const SizedBox(height: constants.padding), - glassTile( - child: Row( - crossAxisAlignment: CrossAxisAlignment.center, - children: [ - Text( - 'Provider Type', - style: textTheme.titleMedium?.copyWith( - fontWeight: FontWeight.w600, - ), - ), - const SizedBox(width: constants.padding), - DropdownButton( - value: _mountType.isEmpty ? null : _mountType, - autofocus: true, - underline: const SizedBox.shrink(), - onChanged: (mountType) { - _handleChange( - Provider.of(context, listen: false), - mountType ?? '', - ); - }, - items: constants.providerTypeList - .map>((item) { - return DropdownMenuItem( - value: item, - child: Text(item), - ); - }) - .toList(), - ), - ], - ), - ), - if (_mountType.isNotEmpty && _mountType != 'Remote') ...[ - const SizedBox(height: constants.padding), - glassTile( - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Text( - 'Configuration Name', - style: textTheme.titleMedium?.copyWith( - fontWeight: FontWeight.w600, - ), - ), - const SizedBox(height: 8), - TextField( - autofocus: true, - controller: _mountNameController, - keyboardType: TextInputType.text, - inputFormatters: [ - FilteringTextInputFormatter.deny(RegExp(r'\s')), - ], - onChanged: (_) => _handleChange( - Provider.of(context, listen: false), - _mountType, - ), - decoration: InputDecoration( - hintText: 'Enter a unique name', - filled: true, - fillColor: scheme.surface.withValues(alpha: 0.30), - border: OutlineInputBorder( - borderRadius: BorderRadius.circular( - constants.borderRadius, - ), - borderSide: BorderSide.none, - ), - contentPadding: const EdgeInsets.symmetric( - horizontal: 12, - vertical: 12, - ), - ), + boxShadow: [ + BoxShadow( + color: Colors.black.withValues(alpha: 0.22), + blurRadius: constants.borderRadius, + offset: Offset(0, constants.borderRadius), ), ], ), + child: const Icon(Icons.arrow_back), ), - ], - if (_mount != null) ...[ - const SizedBox(height: constants.padding), - Expanded( - child: glassTile( - padding: EdgeInsets.zero, - child: Padding( - padding: const EdgeInsets.all(constants.padding), - child: MountSettingsWidget( - isAdd: true, - mount: _mount!, - settings: _settings[_mountType]!, - showAdvanced: false, - ), + ), + ), + 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), - 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); - }, - ), - ), - ], + ), + ), + ], + ), + const SizedBox(height: constants.padding), + DropdownButtonFormField( + initialValue: _mountType.isEmpty ? null : _mountType, + decoration: createCommonDecoration( + scheme, + 'Provider Type', + Icons.cloud_outlined, + ), + isExpanded: true, + items: constants.providerTypeList + .map>( + (item) => DropdownMenuItem( + value: item, + child: Text(item), ), - ], - ], + ) + .toList(), + onChanged: (mountType) => _handleChange( + Provider.of(context, listen: false), + mountType ?? '', ), ), + + // Configuration name (only when not Remote) + 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', + Icons.drive_file_rename_outline, + ).copyWith(hintText: 'Enter a unique name'), + ), + ], + + // Settings + Actions + if (_mount != null) ...[ + const SizedBox(height: constants.padding), + Expanded( + child: Container( + decoration: BoxDecoration( + color: scheme.primary.withValues( + alpha: constants.primaryAlpha, + ), + borderRadius: BorderRadius.circular(constants.borderRadius), + border: Border.all( + color: scheme.outlineVariant.withValues(alpha: 0.06), + width: 1, + ), + gradient: const LinearGradient( + begin: Alignment.topCenter, + end: Alignment.bottomCenter, + colors: constants.gradientColors2, + ), + boxShadow: [ + BoxShadow( + color: Colors.black.withValues(alpha: 0.22), + blurRadius: constants.borderRadius, + offset: Offset(0, constants.borderRadius), + ), + ], + ), + child: ClipRRect( + borderRadius: BorderRadius.circular(constants.borderRadius), + child: Padding( + padding: const EdgeInsets.all(constants.padding), + child: MountSettingsWidget( + isAdd: true, + mount: _mount!, + settings: _settings[_mountType]!, + showAdvanced: false, + ), + ), + ), + ), + ), + 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); + }, + ), + ), + ], + ), + ], ], ), ), @@ -440,14 +344,10 @@ class _AddMountScreenState extends State { } Future _handleProviderTest() async { - if (_mount == null) { - return; - } + if (_mount == null) return; final success = await _mount!.test(); - if (!mounted) { - return; - } + if (!mounted) return; displayErrorMessage( context, @@ -457,9 +357,7 @@ class _AddMountScreenState extends State { @override void setState(VoidCallback fn) { - if (!mounted) { - return; - } + if (!mounted) return; super.setState(fn); } } diff --git a/web/repertory/lib/screens/auth_screen.dart b/web/repertory/lib/screens/auth_screen.dart index 5c9e521d..42b0d797 100644 --- a/web/repertory/lib/screens/auth_screen.dart +++ b/web/repertory/lib/screens/auth_screen.dart @@ -4,6 +4,7 @@ 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/aurora_sweep.dart'; @@ -35,22 +36,6 @@ class _AuthScreenState extends State { Widget build(BuildContext context) { final scheme = Theme.of(context).colorScheme; - InputDecoration decoration(String label, IconData icon) => InputDecoration( - labelText: label, - prefixIcon: Icon(icon), - filled: true, - fillColor: scheme.primary.withValues(alpha: constants.primaryAlpha), - border: OutlineInputBorder( - borderRadius: BorderRadius.circular(constants.borderRadiusSmall), - borderSide: BorderSide.none, - ), - focusedBorder: OutlineInputBorder( - borderRadius: BorderRadius.circular(constants.borderRadiusSmall), - borderSide: BorderSide(color: scheme.primary, width: 2), - ), - contentPadding: const EdgeInsets.all(constants.paddingSmall), - ); - Future doLogin(Auth auth) async { if (!_enabled) { return; @@ -99,9 +84,8 @@ class _AuthScreenState extends State { ), ), Consumer( - builder: (_, settings, _) { - return AuroraSweep(enabled: settings.enableAnimations); - }, + builder: (_, settings, _) => + AuroraSweep(enabled: settings.enableAnimations), ), Positioned.fill( child: BackdropFilter( @@ -246,7 +230,8 @@ class _AuthScreenState extends State { autofocus: true, controller: _userController, textInputAction: TextInputAction.next, - decoration: decoration( + decoration: createCommonDecoration( + scheme, 'Username', Icons.person, ), @@ -267,7 +252,8 @@ class _AuthScreenState extends State { obscureText: _obscure, textInputAction: TextInputAction.go, decoration: - decoration( + createCommonDecoration( + scheme, 'Password', Icons.lock, ).copyWith( diff --git a/web/repertory/lib/screens/edit_mount_screen.dart b/web/repertory/lib/screens/edit_mount_screen.dart index 552c20f3..54deb61d 100644 --- a/web/repertory/lib/screens/edit_mount_screen.dart +++ b/web/repertory/lib/screens/edit_mount_screen.dart @@ -1,15 +1,13 @@ // 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/models/settings.dart'; -import 'package:repertory/widgets/aurora_sweep.dart'; import 'package:repertory/widgets/mount_settings.dart'; class EditMountScreen extends StatefulWidget { @@ -29,258 +27,200 @@ class _EditMountScreenState extends State { 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, _) { - return AuroraSweep(enabled: settings.enableAnimations); - }, - ), - Positioned.fill( - child: BackdropFilter( - filter: ImageFilter.blur(sigmaX: 6, sigmaY: 6), - child: Container(color: Colors.black.withValues(alpha: 0.06)), - ), - ), - Column( - crossAxisAlignment: CrossAxisAlignment.stretch, + return createCommonScaffold( + Column( + crossAxisAlignment: CrossAxisAlignment.stretch, + children: [ + const SizedBox(height: constants.padding), + Padding( + padding: const EdgeInsets.symmetric(horizontal: constants.padding), + child: Row( children: [ - const SizedBox(height: constants.padding), - Padding( - padding: const EdgeInsets.symmetric( - horizontal: constants.padding, + 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), + ), ), - 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( + ), + 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, ), - 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; - }); - }, - ), - ], - ), - ), + border: Border.all( + color: scheme.outlineVariant.withValues(alpha: 0.08), + width: 1, ), ), - const SizedBox(width: constants.padding), - ClipRRect( + 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, ), - 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(); - }, - ); - }, - ), - ), + 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: Material( + color: Colors.transparent, + child: Container( + decoration: BoxDecoration( + color: scheme.primary.withValues( + alpha: constants.primaryAlpha, + ), + borderRadius: BorderRadius.circular(constants.borderRadius), + border: Border.all( + color: scheme.outlineVariant.withValues(alpha: 0.06), + width: 1, + ), + gradient: const LinearGradient( + begin: Alignment.topCenter, + end: Alignment.bottomCenter, + colors: constants.gradientColors2, + ), + boxShadow: [ + BoxShadow( + color: Colors.black.withValues(alpha: 0.22), + blurRadius: constants.borderRadius, + offset: Offset(0, constants.borderRadius), + ), ], ), - ), - const SizedBox(height: constants.padding), - Expanded( - child: Padding( - padding: const EdgeInsets.symmetric( - horizontal: constants.padding, - ), - child: Material( - color: Colors.transparent, - child: Container( - decoration: BoxDecoration( - color: scheme.surface.withValues(alpha: 0.40), - borderRadius: BorderRadius.circular( - constants.borderRadius, - ), - border: Border.all( - color: scheme.outlineVariant.withValues( - alpha: 0.06, - ), - width: 1, - ), - gradient: const LinearGradient( - begin: Alignment.topCenter, - end: Alignment.bottomCenter, - colors: constants.gradientColors2, - ), - boxShadow: [ - BoxShadow( - color: Colors.black.withValues(alpha: 0.22), - blurRadius: constants.borderRadius, - offset: Offset(0, constants.borderRadius), - ), - ], - ), - 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: Padding( + padding: const EdgeInsets.all(constants.padding), + child: MountSettingsWidget( + mount: widget.mount, + settings: jsonDecode( + jsonEncode(widget.mount.mountConfig.settings), ), + showAdvanced: _showAdvanced, ), ), ), ), - - const SizedBox(height: constants.padding), - ], + ), ), - ], - ), + ), + + const SizedBox(height: constants.padding), + ], ), ); } @override void setState(VoidCallback fn) { - if (!mounted) { - return; - } + if (!mounted) return; super.setState(fn); } } diff --git a/web/repertory/lib/screens/edit_settings_screen.dart b/web/repertory/lib/screens/edit_settings_screen.dart index 15845eef..9a9670c5 100644 --- a/web/repertory/lib/screens/edit_settings_screen.dart +++ b/web/repertory/lib/screens/edit_settings_screen.dart @@ -9,8 +9,6 @@ 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/aurora_sweep.dart'; import 'package:repertory/widgets/ui_settings.dart'; class EditSettingsScreen extends StatefulWidget { @@ -27,198 +25,154 @@ class _EditSettingsScreenState extends State { 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, _) { - return AuroraSweep(enabled: settings.enableAnimations); - }, - ), - Positioned.fill( - child: BackdropFilter( - filter: ImageFilter.blur(sigmaX: 6, sigmaY: 6), - child: Container(color: Colors.black.withValues(alpha: 0.06)), - ), - ), - Column( - crossAxisAlignment: CrossAxisAlignment.stretch, + return createCommonScaffold( + Column( + crossAxisAlignment: CrossAxisAlignment.stretch, + children: [ + const SizedBox(height: constants.padding), + Padding( + padding: const EdgeInsets.symmetric(horizontal: constants.padding), + child: Row( 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( + 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, ), - 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(); - }, - ); - }, - ), - ), + 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(); + }, + ); + }, + ), + ), + ), + ), + ], + ), + ), + const SizedBox(height: constants.padding), + Expanded( + child: Padding( + padding: const EdgeInsets.symmetric( + horizontal: constants.padding, + ), + child: Material( + color: Colors.transparent, + child: Container( + decoration: BoxDecoration( + color: scheme.surface.withValues(alpha: 0.40), + borderRadius: BorderRadius.circular(constants.borderRadius), + border: Border.all( + color: scheme.outlineVariant.withValues(alpha: 0.06), + width: 1, + ), + gradient: const LinearGradient( + begin: Alignment.topCenter, + end: Alignment.bottomCenter, + colors: constants.gradientColors2, + ), + boxShadow: [ + BoxShadow( + color: Colors.black.withValues(alpha: 0.22), + blurRadius: constants.borderRadius, + offset: Offset(0, constants.borderRadius), ), ], ), - ), - const SizedBox(height: constants.padding), - Expanded( - child: Padding( - padding: const EdgeInsets.symmetric( - horizontal: constants.padding, - ), - child: Material( - color: Colors.transparent, - child: Container( - decoration: BoxDecoration( - color: scheme.surface.withValues(alpha: 0.40), - borderRadius: BorderRadius.circular( - constants.borderRadius, - ), - border: Border.all( - color: scheme.outlineVariant.withValues( - alpha: 0.06, - ), - width: 1, - ), - gradient: const LinearGradient( - begin: Alignment.topCenter, - end: Alignment.bottomCenter, - colors: constants.gradientColors2, - ), - boxShadow: [ - BoxShadow( - color: Colors.black.withValues(alpha: 0.22), - blurRadius: constants.borderRadius, - offset: Offset(0, constants.borderRadius), - ), - ], - ), - child: ClipRRect( - borderRadius: BorderRadius.circular( - constants.borderRadius, - ), - child: FutureBuilder>( - future: _grabSettings(), - initialData: const {}, - builder: (context, snapshot) { - if (!snapshot.hasData) { - return const Center( - child: CircularProgressIndicator(), - ); - } + 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, - ); - }, + return UISettingsWidget( + origSettings: jsonDecode( + jsonEncode(snapshot.requireData), ), - ), - ), + settings: snapshot.requireData, + showAdvanced: false, + ); + }, ), ), ), - const SizedBox(height: constants.padding), - ], + ), ), - ], - ), + ), + const SizedBox(height: constants.padding), + ], ), ); } diff --git a/web/repertory/lib/screens/home_screen.dart b/web/repertory/lib/screens/home_screen.dart index 52cfc784..7b204e6d 100644 --- a/web/repertory/lib/screens/home_screen.dart +++ b/web/repertory/lib/screens/home_screen.dart @@ -4,10 +4,10 @@ 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'; -import 'package:repertory/widgets/aurora_sweep.dart'; class HomeScreen extends StatefulWidget { final String title; @@ -23,156 +23,119 @@ class _HomeScreeState extends State { 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, _) { - return AuroraSweep(enabled: settings.enableAnimations); - }, - ), - Positioned.fill( - child: BackdropFilter( - filter: ImageFilter.blur(sigmaX: 6, sigmaY: 6), - child: Container(color: Colors.black.withValues(alpha: 0.06)), - ), - ), - Column( - crossAxisAlignment: CrossAxisAlignment.stretch, + return createCommonScaffold( + Column( + crossAxisAlignment: CrossAxisAlignment.stretch, + children: [ + const SizedBox(height: constants.padding), + Padding( + padding: const EdgeInsets.symmetric(horizontal: constants.padding), + child: Row( children: [ - const SizedBox(height: constants.padding), - Padding( - padding: const EdgeInsets.symmetric( - horizontal: constants.padding, + 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, + ); + }, ), - child: Row( - children: [ - SizedBox( - width: 48, - height: 48, - child: Image.asset( - 'assets/images/repertory.png', - fit: BoxFit.contain, - errorBuilder: (_, _, _) { - return Icon( - Icons.folder, - color: scheme.primary, - size: 40, - ); - }, - ), - ), - 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( + ), + 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, ), - 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(); - }, - ); - }, - ), - ], - ), - ), + border: Border.all( + color: scheme.outlineVariant.withValues(alpha: 0.08), + width: 1, ), ), - ], - ), - ), - const SizedBox(height: constants.padding), - Expanded( - child: Padding( - padding: const EdgeInsets.symmetric( - horizontal: constants.padding, + 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(); + }, + ); + }, + ), + ], + ), ), - child: const MountListWidget(), ), ), ], ), - ], - ), + ), + const SizedBox(height: constants.padding), + Expanded( + child: Padding( + padding: const EdgeInsets.symmetric( + horizontal: constants.padding, + ), + child: const MountListWidget(), + ), + ), + ], ), floatingActionButton: Padding( padding: const EdgeInsets.all(constants.padding), diff --git a/web/repertory/lib/widgets/mount_settings.dart b/web/repertory/lib/widgets/mount_settings.dart index 028a01fe..d916cbc4 100644 --- a/web/repertory/lib/widgets/mount_settings.dart +++ b/web/repertory/lib/widgets/mount_settings.dart @@ -39,10 +39,11 @@ class _MountSettingsWidgetState extends State { Widget build(BuildContext context) { final scheme = Theme.of(context).colorScheme; - // Theme SettingsList to your glass aesthetic (consistent with UISettingsWidget) final theme = SettingsThemeData( settingsListBackground: Colors.transparent, - settingsSectionBackground: scheme.surface.withValues(alpha: 0.30), + settingsSectionBackground: scheme.primary.withValues( + alpha: constants.primaryAlpha, + ), titleTextColor: scheme.onSurface.withValues(alpha: 0.96), trailingTextColor: scheme.onSurface.withValues(alpha: 0.80), tileDescriptionTextColor: scheme.onSurface.withValues(alpha: 0.68), @@ -394,6 +395,10 @@ class _MountSettingsWidgetState extends State { } }); + const sectionMargin = EdgeInsetsDirectional.symmetric( + vertical: constants.padding / 2, + ); + return SettingsList( shrinkWrap: false, platform: DevicePlatform.device, @@ -402,38 +407,48 @@ class _MountSettingsWidgetState extends State { sections: [ if (encryptConfigSettings.isNotEmpty) SettingsSection( + margin: sectionMargin, title: const Text('Encrypt Config'), tiles: encryptConfigSettings, ), if (hostConfigSettings.isNotEmpty) SettingsSection( + margin: sectionMargin, title: const Text('Host Config'), tiles: hostConfigSettings, ), if (remoteConfigSettings.isNotEmpty) SettingsSection( + margin: sectionMargin, title: const Text('Remote Config'), tiles: remoteConfigSettings, ), if (s3ConfigSettings.isNotEmpty) SettingsSection( + margin: sectionMargin, title: const Text('S3 Config'), tiles: s3ConfigSettings, ), if (siaConfigSettings.isNotEmpty) SettingsSection( + margin: sectionMargin, title: const Text('Sia Config'), tiles: siaConfigSettings, ), if (remoteMountSettings.isNotEmpty) SettingsSection( + margin: sectionMargin, title: const Text('Remote Mount'), tiles: (widget.settings['RemoteMount']['Enable'] as bool) ? remoteMountSettings : [remoteMountSettings[0]], ), if (commonSettings.isNotEmpty) - SettingsSection(title: const Text('Settings'), tiles: commonSettings), + SettingsSection( + margin: sectionMargin, + title: const Text('Settings'), + tiles: commonSettings, + ), ], ); } @@ -1017,24 +1032,18 @@ class _MountSettingsWidgetState extends State { }); return; } - mount.setValue(key, value); }); }); } } - super.dispose(); } @override void setState(VoidCallback fn) { - if (!mounted) { - return; - } - if (widget.onChanged != null) { - widget.onChanged!(); - } + if (!mounted) return; + if (widget.onChanged != null) widget.onChanged!(); super.setState(fn); } } diff --git a/web/repertory/lib/widgets/mount_widget.dart b/web/repertory/lib/widgets/mount_widget.dart index 1fe466dd..29696a70 100644 --- a/web/repertory/lib/widgets/mount_widget.dart +++ b/web/repertory/lib/widgets/mount_widget.dart @@ -272,7 +272,6 @@ class _MountWidgetState extends State { return location; } - // ignore: use_build_context_synchronously return editMountLocation(context, await mount.getAvailableLocations()); } diff --git a/web/repertory/lib/widgets/ui_settings.dart b/web/repertory/lib/widgets/ui_settings.dart index dc08ddf1..09cdf29c 100644 --- a/web/repertory/lib/widgets/ui_settings.dart +++ b/web/repertory/lib/widgets/ui_settings.dart @@ -39,18 +39,17 @@ class _UISettingsWidgetState extends State { Widget build(BuildContext context) { final scheme = Theme.of(context).colorScheme; - // Theme the SettingsList to align with your glass look final theme = SettingsThemeData( settingsListBackground: Colors.transparent, - tileDescriptionTextColor: scheme.onSurface.withValues(alpha: 0.68), - settingsSectionBackground: scheme.surface.withValues( - alpha: 0.30, - ), // slight glass base - tileHighlightColor: scheme.primary.withValues(alpha: 0.08), + settingsSectionBackground: scheme.primary.withValues( + alpha: constants.primaryAlpha, + ), titleTextColor: scheme.onSurface.withValues(alpha: 0.96), trailingTextColor: scheme.onSurface.withValues(alpha: 0.80), + tileDescriptionTextColor: scheme.onSurface.withValues(alpha: 0.68), leadingIconsColor: scheme.onSurface.withValues(alpha: 0.90), dividerColor: scheme.outlineVariant.withValues(alpha: 0.10), + tileHighlightColor: scheme.primary.withValues(alpha: 0.08), ); List commonSettings = [];