diff --git a/web/repertory/lib/constants.dart b/web/repertory/lib/constants.dart index 4faae41c..b0b4833e 100644 --- a/web/repertory/lib/constants.dart +++ b/web/repertory/lib/constants.dart @@ -9,20 +9,27 @@ const appLogonTitle = 'Repertory Portal Login'; const appSettingsTitle = 'Portal Settings'; const appTitle = 'Repertory Management Portal'; const borderRadius = 16.0; -const borderRadiusSmall = 8.0; +const borderRadiusSmall = borderRadius / 2.0; +const borderRadiusTiny = borderRadiusSmall / 2.0; const databaseTypeList = ['rocksdb', 'sqlite']; const downloadTypeList = ['default', 'direct', 'ring_buffer']; const eventLevelList = ['critical', 'error', 'warn', 'info', 'debug', 'trace']; const gradientColors = [Color(0xFF0A0F1F), Color(0xFF1B1C1F)]; const gradientColors2 = [Color(0x07FFFFFF), Color(0x00000000)]; +const highlightAlpha = 0.10; const logonWidth = 300.0; +const outlineAlpha = 0.15; const padding = 16.0; -const paddingSmall = 8.0; +const paddingSmall = padding / 2.0; +const primaryAlpha = 0.25; +const boxShadowAlpha = 0.20; +const primarySurfaceAlpha = 92.0; const protocolTypeList = ['http', 'https']; const providerTypeList = ['Encrypt', 'Remote', 'S3', 'Sia']; const ringBufferSizeList = ['128', '256', '512', '1024', '2048']; -const primaryAlpha = 0.25; -const secondaryAlpha = 0.50; +const secondaryAlpha = 0.45; +const largeIconSize = 32.0; +const secondarySurfaceAlpha = 70.0; const surfaceContainerLowDark = Color(0xFF292A2D); const surfaceDark = Color(0xFF202124); diff --git a/web/repertory/lib/helpers.dart b/web/repertory/lib/helpers.dart index 7d3f28e8..46ba6d78 100644 --- a/web/repertory/lib/helpers.dart +++ b/web/repertory/lib/helpers.dart @@ -7,6 +7,7 @@ import 'package:flutter/material.dart'; import 'package:repertory/constants.dart' as constants; import 'package:repertory/models/auth.dart'; import 'package:repertory/widgets/app_dropdown.dart'; +import 'package:settings_ui/settings_ui.dart'; import 'package:sodium_libs/sodium_libs.dart' show SecureKey, StringX; Future doShowDialog(BuildContext context, Widget child) => showDialog( @@ -24,7 +25,9 @@ Future doShowDialog(BuildContext context, Widget child) => showDialog( shape: RoundedRectangleBorder( borderRadius: BorderRadius.circular(constants.borderRadius), side: BorderSide( - color: scheme.outlineVariant.withValues(alpha: 0.08), + color: scheme.outlineVariant.withValues( + alpha: constants.outlineAlpha, + ), width: 1, ), ), @@ -462,3 +465,30 @@ IconData getProviderTypeIcon(String mountType) { return Icons.cloud_outlined; } } + +SettingsThemeData createSettingsTheme(ColorScheme scheme) { + return SettingsThemeData( + settingsListBackground: Colors.transparent, + settingsSectionBackground: scheme.primary.withValues( + alpha: constants.primaryAlpha, + ), + titleTextColor: scheme.onSurface.withValues( + alpha: constants.primarySurfaceAlpha, + ), + trailingTextColor: scheme.onSurface.withValues( + alpha: constants.primarySurfaceAlpha, + ), + tileDescriptionTextColor: scheme.onSurface.withValues( + alpha: constants.secondarySurfaceAlpha, + ), + leadingIconsColor: scheme.onSurface.withValues( + alpha: constants.primarySurfaceAlpha, + ), + dividerColor: scheme.outlineVariant.withValues( + alpha: constants.outlineAlpha, + ), + tileHighlightColor: scheme.primary.withValues( + alpha: constants.highlightAlpha, + ), + ); +} diff --git a/web/repertory/lib/screens/add_mount_screen.dart b/web/repertory/lib/screens/add_mount_screen.dart index 501affe8..f0bb1c5a 100644 --- a/web/repertory/lib/screens/add_mount_screen.dart +++ b/web/repertory/lib/screens/add_mount_screen.dart @@ -111,7 +111,9 @@ class _AddMountScreenState extends State label: const Text('Test'), icon: const Icon(Icons.check), style: ElevatedButton.styleFrom( - backgroundColor: scheme.primary.withValues(alpha: 0.18), + backgroundColor: scheme.primary.withValues( + alpha: constants.primaryAlpha, + ), foregroundColor: scheme.primary, elevation: 0, shape: RoundedRectangleBorder( @@ -119,7 +121,9 @@ class _AddMountScreenState extends State constants.borderRadius, ), side: BorderSide( - color: scheme.outlineVariant.withValues(alpha: 0.15), + color: scheme.outlineVariant.withValues( + alpha: constants.outlineAlpha, + ), width: 1, ), ), @@ -136,7 +140,9 @@ class _AddMountScreenState extends State backgroundColor: scheme.primary, foregroundColor: scheme.onPrimary, elevation: 8, - shadowColor: scheme.primary.withValues(alpha: 0.45), + shadowColor: scheme.primary.withValues( + alpha: constants.secondaryAlpha, + ), shape: RoundedRectangleBorder( borderRadius: BorderRadius.circular( constants.borderRadius, diff --git a/web/repertory/lib/screens/auth_screen.dart b/web/repertory/lib/screens/auth_screen.dart index 7a66ff6c..38d70174 100644 --- a/web/repertory/lib/screens/auth_screen.dart +++ b/web/repertory/lib/screens/auth_screen.dart @@ -85,8 +85,10 @@ class _AuthScreenState extends State { ), Positioned.fill( child: BackdropFilter( - filter: ImageFilter.blur(sigmaX: 10, sigmaY: 10), - child: Container(color: Colors.black.withValues(alpha: 0.10)), + filter: ImageFilter.blur(sigmaX: 6, sigmaY: 6), + child: Container( + color: Colors.black.withValues(alpha: constants.outlineAlpha), + ), ), ), Align( @@ -99,7 +101,9 @@ class _AuthScreenState extends State { shape: BoxShape.circle, gradient: RadialGradient( colors: [ - scheme.primary.withValues(alpha: 0.20), + scheme.primary.withValues( + alpha: constants.primaryAlpha, + ), Colors.transparent, ], stops: const [0.0, 1.0], @@ -137,7 +141,9 @@ class _AuthScreenState extends State { ), child: Card( elevation: constants.padding, - color: scheme.primary.withValues(alpha: 0.10), + color: scheme.primary.withValues( + alpha: constants.outlineAlpha, + ), shape: RoundedRectangleBorder( borderRadius: BorderRadius.circular( constants.borderRadius, @@ -162,18 +168,21 @@ class _AuthScreenState extends State { height: 64, decoration: BoxDecoration( color: scheme.primary.withValues( - alpha: 0.11, + alpha: constants.outlineAlpha, ), borderRadius: BorderRadius.circular( constants.borderRadiusSmall, ), boxShadow: [ BoxShadow( - color: scheme.primary.withValues( - alpha: 0.08, + color: Colors.black.withValues( + alpha: constants.boxShadowAlpha, + ), + blurRadius: constants.borderRadius, + offset: Offset( + 0, + constants.borderRadius, ), - blurRadius: 16, - spreadRadius: 1, ), ], ), @@ -213,11 +222,7 @@ class _AuthScreenState extends State { style: Theme.of(context) .textTheme .bodyMedium - ?.copyWith( - color: scheme.onSurface.withValues( - alpha: 0.72, - ), - ), + ?.copyWith(color: scheme.onSurface), ), const SizedBox( height: constants.padding * 2.0, @@ -283,9 +288,13 @@ class _AuthScreenState extends State { : null, style: ElevatedButton.styleFrom( backgroundColor: scheme.primary - .withValues(alpha: 0.45), + .withValues( + alpha: constants.secondaryAlpha, + ), disabledBackgroundColor: scheme.primary - .withValues(alpha: 0.15), + .withValues( + alpha: constants.outlineAlpha, + ), shape: RoundedRectangleBorder( borderRadius: BorderRadius.circular( constants.borderRadiusSmall, diff --git a/web/repertory/lib/screens/edit_mount_screen.dart b/web/repertory/lib/screens/edit_mount_screen.dart index 4b41aba7..62511cb9 100644 --- a/web/repertory/lib/screens/edit_mount_screen.dart +++ b/web/repertory/lib/screens/edit_mount_screen.dart @@ -33,17 +33,13 @@ class _EditMountScreenState extends State children: [ Text( "Advanced", - style: textTheme.labelLarge?.copyWith( - color: scheme.onSurface.withValues(alpha: 0.90), - ), + style: textTheme.labelLarge?.copyWith(color: scheme.onSurface), ), 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), + color: _showAdvanced ? scheme.primary : scheme.onSurface, onPressed: () => setState(() => _showAdvanced = !_showAdvanced), ), ], diff --git a/web/repertory/lib/screens/home_screen.dart b/web/repertory/lib/screens/home_screen.dart index f22ba6f5..83e3340a 100644 --- a/web/repertory/lib/screens/home_screen.dart +++ b/web/repertory/lib/screens/home_screen.dart @@ -34,7 +34,9 @@ class _HomeScreeState extends State { decoration: BoxDecoration( borderRadius: BorderRadius.circular(constants.borderRadius), border: Border.all( - color: scheme.outlineVariant.withValues(alpha: 0.06), + color: scheme.outlineVariant.withValues( + alpha: constants.outlineAlpha, + ), width: 1, ), gradient: const LinearGradient( @@ -44,7 +46,9 @@ class _HomeScreeState extends State { ), boxShadow: [ BoxShadow( - color: Colors.black.withValues(alpha: 0.22), + color: Colors.black.withValues( + alpha: constants.boxShadowAlpha, + ), blurRadius: constants.borderRadius, offset: Offset(0, constants.borderRadius), ), diff --git a/web/repertory/lib/widgets/app_dropdown.dart b/web/repertory/lib/widgets/app_dropdown.dart index 52e7dd30..b1277e28 100644 --- a/web/repertory/lib/widgets/app_dropdown.dart +++ b/web/repertory/lib/widgets/app_dropdown.dart @@ -63,9 +63,7 @@ class AppDropdown extends StatelessWidget { final scheme = theme.colorScheme; final effectiveStyle = textStyle ?? - theme.textTheme.bodyMedium?.copyWith( - color: scheme.onSurface.withValues(alpha: 0.96), - ); + theme.textTheme.bodyMedium?.copyWith(color: scheme.onSurface); final longest = values.isEmpty ? '' @@ -76,7 +74,7 @@ class AppDropdown extends StatelessWidget { final labelW = _measureTextWidth(context, longest, effectiveStyle); final prefixW = prefixIcon == null ? 0.0 : 48.0; - const arrowW = 32.0; + const arrowW = constants.largeIconSize; final pad = contentPadding ?? const EdgeInsets.all(constants.paddingSmall); final padW = (pad is EdgeInsets) ? (pad.left + pad.right) @@ -99,9 +97,7 @@ class AppDropdown extends StatelessWidget { final effectiveTextStyle = textStyle ?? - theme.textTheme.bodyMedium?.copyWith( - color: scheme.onSurface.withValues(alpha: 0.96), - ); + theme.textTheme.bodyMedium?.copyWith(color: scheme.onSurface); final items = values.map((v) { return DropdownMenuItem( @@ -122,7 +118,7 @@ class AppDropdown extends StatelessWidget { icon: prefixIcon, ), dropdownColor: dropdownColor ?? effectiveFill, - iconEnabledColor: scheme.onSurface.withValues(alpha: 0.90), + iconEnabledColor: scheme.onSurface, initialValue: value, isExpanded: isExpanded, items: items, diff --git a/web/repertory/lib/widgets/app_icon_button_framed.dart b/web/repertory/lib/widgets/app_icon_button_framed.dart index a70735ab..ba2b90c7 100644 --- a/web/repertory/lib/widgets/app_icon_button_framed.dart +++ b/web/repertory/lib/widgets/app_icon_button_framed.dart @@ -29,17 +29,19 @@ class AppIconButtonFramed extends StatelessWidget { width: 46, height: 46, decoration: BoxDecoration( - color: scheme.primary.withValues(alpha: 0.12), + color: scheme.primary.withValues(alpha: constants.outlineAlpha), borderRadius: radius, border: Border.all( - color: scheme.outlineVariant.withValues(alpha: 0.08), + color: scheme.outlineVariant.withValues( + alpha: constants.outlineAlpha, + ), width: 1, ), boxShadow: [ BoxShadow( - color: Colors.black.withValues(alpha: 0.24), - blurRadius: constants.borderRadiusSmall / 2.0, - offset: const Offset(0, 5), + color: Colors.black.withValues(alpha: constants.boxShadowAlpha), + blurRadius: constants.borderRadiusTiny, + offset: const Offset(0, constants.borderRadiusSmall), ), ], ), @@ -48,8 +50,8 @@ class AppIconButtonFramed extends StatelessWidget { scale: 0.90, child: Icon( icon, - color: iconColor ?? scheme.onSurface.withValues(alpha: 0.92), - size: 32.0, + color: iconColor ?? scheme.onSurface, + size: constants.largeIconSize, ), ), ), diff --git a/web/repertory/lib/widgets/app_scaffold.dart b/web/repertory/lib/widgets/app_scaffold.dart index fd50cb99..4ec6b4c9 100644 --- a/web/repertory/lib/widgets/app_scaffold.dart +++ b/web/repertory/lib/widgets/app_scaffold.dart @@ -40,6 +40,7 @@ class AppScaffold extends StatelessWidget { begin: Alignment.topLeft, end: Alignment.bottomRight, colors: constants.gradientColors, + stops: [0.0, 1.0], ), ), ), @@ -50,7 +51,9 @@ class AppScaffold extends StatelessWidget { Positioned.fill( child: BackdropFilter( filter: ImageFilter.blur(sigmaX: 6, sigmaY: 6), - child: Container(color: Colors.black.withValues(alpha: 0.06)), + child: Container( + color: Colors.black.withValues(alpha: constants.outlineAlpha), + ), ), ), Padding( @@ -90,19 +93,23 @@ class AppScaffold extends StatelessWidget { width: 40, height: 40, decoration: BoxDecoration( - color: scheme.surface.withValues(alpha: 0.40), + color: scheme.surface.withValues( + alpha: constants.secondaryAlpha, + ), borderRadius: BorderRadius.circular( constants.borderRadius, ), border: Border.all( color: scheme.outlineVariant.withValues( - alpha: 0.08, + alpha: constants.highlightAlpha, ), width: 1, ), boxShadow: [ BoxShadow( - color: Colors.black.withValues(alpha: 0.22), + color: Colors.black.withValues( + alpha: constants.boxShadowAlpha, + ), blurRadius: constants.borderRadius, offset: Offset(0, constants.borderRadius), ), @@ -122,7 +129,7 @@ class AppScaffold extends StatelessWidget { style: textTheme.headlineSmall?.copyWith( fontWeight: FontWeight.w700, letterSpacing: 0.2, - color: scheme.onSurface.withValues(alpha: 0.96), + color: scheme.onSurface, ), ), ), @@ -139,7 +146,7 @@ class AppScaffold extends StatelessWidget { ), color: settings.autoStart ? scheme.primary - : scheme.onSurface.withValues(alpha: 0.70), + : scheme.onSurface, onPressed: () => settings.setAutoStart(!settings.autoStart), ); diff --git a/web/repertory/lib/widgets/app_toggle_button_framed.dart b/web/repertory/lib/widgets/app_toggle_button_framed.dart index 99242617..8b913c05 100644 --- a/web/repertory/lib/widgets/app_toggle_button_framed.dart +++ b/web/repertory/lib/widgets/app_toggle_button_framed.dart @@ -19,13 +19,11 @@ class AppToggleButtonFramed extends StatelessWidget { final bool isOn = mounted ?? false; IconData icon = Icons.hourglass_top; - Color iconColor = scheme.onSurface.withValues(alpha: 0.60); + Color iconColor = scheme.onSurface; if (mounted != null) { icon = isOn ? Icons.toggle_on : Icons.toggle_off; - iconColor = isOn - ? scheme.primary - : scheme.onSurface.withValues(alpha: 0.55); + iconColor = isOn ? scheme.primary : scheme.onSurface; } return AppIconButtonFramed( diff --git a/web/repertory/lib/widgets/mount_settings.dart b/web/repertory/lib/widgets/mount_settings.dart index 81d65751..59345c88 100644 --- a/web/repertory/lib/widgets/mount_settings.dart +++ b/web/repertory/lib/widgets/mount_settings.dart @@ -8,7 +8,8 @@ import 'package:repertory/helpers.dart' convertAllToString, getChanged, getSettingDescription, - getSettingValidators; + getSettingValidators, + createSettingsTheme; import 'package:repertory/models/auth.dart'; import 'package:repertory/models/mount.dart'; import 'package:repertory/models/mount_list.dart'; @@ -38,19 +39,7 @@ class _MountSettingsWidgetState extends State { @override Widget build(BuildContext context) { final scheme = Theme.of(context).colorScheme; - - final theme = SettingsThemeData( - settingsListBackground: Colors.transparent, - 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), - ); + final theme = createSettingsTheme(scheme); List commonSettings = []; List encryptConfigSettings = []; diff --git a/web/repertory/lib/widgets/mount_widget.dart b/web/repertory/lib/widgets/mount_widget.dart index d928eaaf..96b452f6 100644 --- a/web/repertory/lib/widgets/mount_widget.dart +++ b/web/repertory/lib/widgets/mount_widget.dart @@ -31,11 +31,9 @@ class _MountWidgetState extends State final titleStyle = textTheme.titleMedium?.copyWith( fontWeight: FontWeight.w700, letterSpacing: 0.15, - color: scheme.onSurface.withValues(alpha: 0.96), - ); - final subStyle = textTheme.bodyMedium?.copyWith( - color: scheme.onSurface.withValues(alpha: 0.78), + color: scheme.onSurface, ); + final subStyle = textTheme.bodyMedium?.copyWith(color: scheme.onSurface); return ConstrainedBox( constraints: const BoxConstraints(minHeight: 120), @@ -46,7 +44,9 @@ class _MountWidgetState extends State shape: RoundedRectangleBorder( borderRadius: BorderRadius.circular(constants.borderRadiusSmall), side: BorderSide( - color: scheme.outlineVariant.withValues(alpha: 0.06), + color: scheme.outlineVariant.withValues( + alpha: constants.outlineAlpha, + ), width: 1, ), ), @@ -65,7 +65,9 @@ class _MountWidgetState extends State ), boxShadow: [ BoxShadow( - color: Colors.black.withValues(alpha: 0.22), + color: Colors.black.withValues( + alpha: constants.boxShadowAlpha, + ), blurRadius: constants.borderRadiusSmall, offset: const Offset(0, constants.borderRadiusSmall), ), @@ -180,9 +182,8 @@ class _MountWidgetState extends State child: Container( height: 1, decoration: BoxDecoration( - color: Theme.of( - context, - ).colorScheme.outlineVariant.withValues(alpha: 0.15), + color: Theme.of(context).colorScheme.outlineVariant + .withValues(alpha: constants.outlineAlpha), borderRadius: BorderRadius.circular(1), ), ), @@ -295,7 +296,7 @@ class _EditPathButton extends StatelessWidget { final scheme = Theme.of(context).colorScheme; return Opacity( - opacity: enabled ? 1.0 : 0.45, + opacity: enabled ? 1.0 : constants.secondaryAlpha, child: OutlinedButton.icon( onPressed: enabled ? onPressed : null, icon: const Icon(Icons.edit, size: 18), @@ -303,14 +304,16 @@ class _EditPathButton extends StatelessWidget { style: OutlinedButton.styleFrom( foregroundColor: scheme.primary, side: BorderSide( - color: scheme.primary.withValues(alpha: 0.55), + color: scheme.primary.withValues(alpha: constants.secondaryAlpha), width: 1.2, ), shape: RoundedRectangleBorder( borderRadius: BorderRadius.circular(constants.borderRadiusSmall), ), padding: const EdgeInsets.symmetric(horizontal: 14, vertical: 10), - backgroundColor: scheme.primary.withValues(alpha: 0.10), + backgroundColor: scheme.primary.withValues( + alpha: constants.outlineAlpha, + ), ), ), ); diff --git a/web/repertory/lib/widgets/ui_settings.dart b/web/repertory/lib/widgets/ui_settings.dart index 4b72f3a1..7028bbd5 100644 --- a/web/repertory/lib/widgets/ui_settings.dart +++ b/web/repertory/lib/widgets/ui_settings.dart @@ -9,6 +9,7 @@ import 'package:repertory/constants.dart' as constants; import 'package:repertory/helpers.dart' show convertAllToString, + createSettingsTheme, displayAuthError, getBaseUri, getChanged, @@ -40,19 +41,7 @@ class _UISettingsWidgetState extends State @override Widget build(BuildContext context) { final scheme = Theme.of(context).colorScheme; - - final theme = SettingsThemeData( - settingsListBackground: Colors.transparent, - 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), - ); + final theme = createSettingsTheme(scheme); List commonSettings = [];