refactor ui
All checks were successful
BlockStorage/repertory/pipeline/head This commit looks good

This commit is contained in:
2025-09-04 15:22:01 -05:00
parent 5f92801860
commit 25e3562300
6 changed files with 183 additions and 194 deletions

View File

@@ -10,6 +10,7 @@ import 'package:provider/provider.dart';
import 'package:repertory/constants.dart' as constants; import 'package:repertory/constants.dart' as constants;
import 'package:repertory/models/auth.dart'; import 'package:repertory/models/auth.dart';
import 'package:repertory/models/settings.dart'; import 'package:repertory/models/settings.dart';
import 'package:repertory/widgets/app_dropdown.dart';
import 'package:repertory/widgets/aurora_sweep.dart'; import 'package:repertory/widgets/aurora_sweep.dart';
import 'package:sodium_libs/sodium_libs.dart' show SecureKey, StringX; import 'package:sodium_libs/sodium_libs.dart' show SecureKey, StringX;
@@ -414,16 +415,12 @@ Future<String?> editMountLocation(
controller: controller, controller: controller,
onChanged: (value) => setState(() => currentLocation = value), onChanged: (value) => setState(() => currentLocation = value),
) )
: DropdownButton<String>( : AppDropdownFormField<String>(
hint: const Text("Select drive"), labelText: "Select drive",
labelOf: (s) => s,
value: currentLocation, value: currentLocation,
onChanged: (value) => setState(() => currentLocation = value), onChanged: (value) => setState(() => currentLocation = value),
items: available.map<DropdownMenuItem<String>>((item) { values: available.toList(),
return DropdownMenuItem<String>(
value: item,
child: Text(item),
);
}).toList(),
), ),
title: const Text('Mount Location', textAlign: TextAlign.center), title: const Text('Mount Location', textAlign: TextAlign.center),
); );
@@ -432,47 +429,49 @@ Future<String?> editMountLocation(
); );
} }
Scaffold createCommonScaffold(Widget child, {Widget? floatingActionButton}) => Scaffold createCommonScaffold(
Scaffold( List<Widget> children, {
body: SafeArea( Widget? floatingActionButton,
child: Stack( }) => Scaffold(
children: [ body: SafeArea(
Container( child: Stack(
width: double.infinity, children: [
height: double.infinity, Container(
decoration: const BoxDecoration( width: double.infinity,
gradient: LinearGradient( height: double.infinity,
begin: Alignment.topLeft, decoration: const BoxDecoration(
end: Alignment.bottomRight, gradient: LinearGradient(
colors: constants.gradientColors, begin: Alignment.topLeft,
), end: Alignment.bottomRight,
), colors: constants.gradientColors,
), ),
Consumer<Settings>( ),
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,
],
), ),
), Consumer<Settings>(
floatingActionButton: floatingActionButton, 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)),
),
),
...children,
],
),
),
floatingActionButton: floatingActionButton,
);
InputDecoration createCommonDecoration( InputDecoration createCommonDecoration(
ColorScheme colorScheme, ColorScheme colorScheme,
String label, String label, {
IconData icon, { IconData? icon,
bool filled = true, bool filled = true,
}) => InputDecoration( }) => InputDecoration(
labelText: label, labelText: label,
prefixIcon: Icon(icon), prefixIcon: icon == null ? null : Icon(icon),
filled: filled, filled: filled,
fillColor: colorScheme.primary.withValues(alpha: constants.primaryAlpha), fillColor: colorScheme.primary.withValues(alpha: constants.primaryAlpha),
border: OutlineInputBorder( border: OutlineInputBorder(

View File

@@ -10,6 +10,7 @@ import 'package:repertory/models/auth.dart';
import 'package:repertory/models/mount.dart'; import 'package:repertory/models/mount.dart';
import 'package:repertory/models/mount_list.dart'; import 'package:repertory/models/mount_list.dart';
import 'package:repertory/types/mount_config.dart'; import 'package:repertory/types/mount_config.dart';
import 'package:repertory/widgets/app_dropdown.dart';
import 'package:repertory/widgets/mount_settings.dart'; import 'package:repertory/widgets/mount_settings.dart';
class AddMountScreen extends StatefulWidget { class AddMountScreen extends StatefulWidget {
@@ -44,7 +45,7 @@ class _AddMountScreenState extends State<AddMountScreen> {
final scheme = Theme.of(context).colorScheme; final scheme = Theme.of(context).colorScheme;
final textTheme = Theme.of(context).textTheme; final textTheme = Theme.of(context).textTheme;
return createCommonScaffold( return createCommonScaffold([
Padding( Padding(
padding: const EdgeInsets.all(constants.padding), padding: const EdgeInsets.all(constants.padding),
child: Column( child: Column(
@@ -128,41 +129,21 @@ class _AddMountScreenState extends State<AddMountScreen> {
], ],
), ),
const SizedBox(height: constants.padding), const SizedBox(height: constants.padding),
UnconstrainedBox( AppDropdownFormField<String>(
alignment: Alignment.centerLeft, labelText: 'Provider Type',
child: IntrinsicWidth( prefixIcon: Icons.extension,
stepWidth: 250.0, values: constants.providerTypeList,
child: DropdownButtonFormField<String>( value: _mountType.isEmpty ? null : _mountType,
initialValue: _mountType.isEmpty ? null : _mountType, labelOf: (s) => s,
isExpanded: false, onChanged: (mountType) {
decoration: createCommonDecoration( _handleChange(
scheme, Provider.of<Auth>(context, listen: false),
"Provider Type", mountType ?? '',
Icons.storage, );
), },
dropdownColor: scheme.primary.withValues(alpha: 0.8), constrainToIntrinsic: true,
style: textTheme.bodyMedium?.copyWith( widthMultiplier: 2.0,
color: scheme.onSurface.withValues(alpha: 0.96), isExpanded: false,
),
items: constants.providerTypeList.map((item) {
return DropdownMenuItem<String>(
value: item,
child: Text(
item,
style: textTheme.bodyMedium?.copyWith(
color: scheme.onSurface.withValues(alpha: 0.96),
),
),
);
}).toList(),
onChanged: (mountType) {
_handleChange(
Provider.of<Auth>(context, listen: false),
mountType ?? '',
);
},
),
),
), ),
if (_mountType.isNotEmpty && _mountType != 'Remote') ...[ if (_mountType.isNotEmpty && _mountType != 'Remote') ...[
const SizedBox(height: constants.padding), const SizedBox(height: constants.padding),
@@ -180,7 +161,7 @@ class _AddMountScreenState extends State<AddMountScreen> {
decoration: createCommonDecoration( decoration: createCommonDecoration(
scheme, scheme,
'Configuration Name', 'Configuration Name',
Icons.drive_file_rename_outline, icon: Icons.drive_file_rename_outline,
).copyWith(hintText: 'Enter a unique name'), ).copyWith(hintText: 'Enter a unique name'),
), ),
], ],
@@ -324,7 +305,7 @@ class _AddMountScreenState extends State<AddMountScreen> {
], ],
), ),
), ),
); ]);
} }
void _handleChange(Auth auth, String mountType) { void _handleChange(Auth auth, String mountType) {

View File

@@ -233,7 +233,7 @@ class _AuthScreenState extends State<AuthScreen> {
decoration: createCommonDecoration( decoration: createCommonDecoration(
scheme, scheme,
'Username', 'Username',
Icons.person, icon: Icons.person,
), ),
validator: (v) { validator: (v) {
if (v == null || v.trim().isEmpty) { if (v == null || v.trim().isEmpty) {
@@ -255,7 +255,7 @@ class _AuthScreenState extends State<AuthScreen> {
createCommonDecoration( createCommonDecoration(
scheme, scheme,
'Password', 'Password',
Icons.lock, icon: Icons.lock,
).copyWith( ).copyWith(
suffixIcon: IconButton( suffixIcon: IconButton(
tooltip: _obscure tooltip: _obscure

View File

@@ -27,7 +27,7 @@ class _EditMountScreenState extends State<EditMountScreen> {
final scheme = Theme.of(context).colorScheme; final scheme = Theme.of(context).colorScheme;
final textTheme = Theme.of(context).textTheme; final textTheme = Theme.of(context).textTheme;
return createCommonScaffold( return createCommonScaffold([
Column( Column(
crossAxisAlignment: CrossAxisAlignment.stretch, crossAxisAlignment: CrossAxisAlignment.stretch,
children: [ children: [
@@ -215,7 +215,7 @@ class _EditMountScreenState extends State<EditMountScreen> {
const SizedBox(height: constants.padding), const SizedBox(height: constants.padding),
], ],
), ),
); ]);
} }
@override @override

View File

@@ -25,7 +25,7 @@ class _EditSettingsScreenState extends State<EditSettingsScreen> {
final scheme = Theme.of(context).colorScheme; final scheme = Theme.of(context).colorScheme;
final textTheme = Theme.of(context).textTheme; final textTheme = Theme.of(context).textTheme;
return createCommonScaffold( return createCommonScaffold([
Column( Column(
crossAxisAlignment: CrossAxisAlignment.stretch, crossAxisAlignment: CrossAxisAlignment.stretch,
children: [ children: [
@@ -174,7 +174,7 @@ class _EditSettingsScreenState extends State<EditSettingsScreen> {
const SizedBox(height: constants.padding), const SizedBox(height: constants.padding),
], ],
), ),
); ]);
} }
Future<Map<String, dynamic>> _grabSettings() async { Future<Map<String, dynamic>> _grabSettings() async {

View File

@@ -24,119 +24,128 @@ class _HomeScreeState extends State<HomeScreen> {
final textTheme = Theme.of(context).textTheme; final textTheme = Theme.of(context).textTheme;
return createCommonScaffold( return createCommonScaffold(
Column( [
crossAxisAlignment: CrossAxisAlignment.stretch, Column(
children: [ crossAxisAlignment: CrossAxisAlignment.stretch,
const SizedBox(height: constants.padding), children: [
Padding( const SizedBox(height: constants.padding),
padding: const EdgeInsets.symmetric(horizontal: constants.padding), Padding(
child: Row(
children: [
SizedBox(
width: 40,
height: 40,
child: Image.asset(
'assets/images/repertory.png',
fit: BoxFit.contain,
errorBuilder: (_, _, _) {
return Icon(
Icons.folder,
color: scheme.primary,
size: 32,
);
},
),
),
const SizedBox(width: constants.padding),
Expanded(
child: Text(
widget.title,
maxLines: 1,
overflow: TextOverflow.ellipsis,
style: textTheme.headlineSmall?.copyWith(
fontWeight: FontWeight.w700,
letterSpacing: 0.2,
color: scheme.onSurface.withValues(alpha: 0.96),
),
),
),
const SizedBox(width: constants.padding),
ClipRRect(
borderRadius: BorderRadius.circular(constants.borderRadius),
child: BackdropFilter(
filter: ImageFilter.blur(
sigmaX: constants.borderRadius,
sigmaY: constants.borderRadius,
),
child: Container(
height: 40,
padding: const EdgeInsets.symmetric(horizontal: 6),
decoration: BoxDecoration(
color: scheme.surface.withValues(alpha: 0.40),
borderRadius: BorderRadius.circular(
constants.borderRadius,
),
border: Border.all(
color: scheme.outlineVariant.withValues(alpha: 0.08),
width: 1,
),
),
child: Row(
children: [
const Text("Auto-start"),
Consumer<Settings>(
builder: (context, settings, _) {
return IconButton(
icon: Icon(
settings.autoStart
? Icons.toggle_on
: Icons.toggle_off,
),
color: settings.autoStart
? scheme.primary
: scheme.onSurface.withValues(alpha: 0.70),
onPressed: () =>
settings.setAutoStart(!settings.autoStart),
);
},
),
IconButton(
tooltip: 'Settings',
icon: const Icon(Icons.settings),
onPressed: () {
Navigator.pushNamed(context, '/settings');
},
),
Consumer<Auth>(
builder: (context, auth, _) {
return IconButton(
tooltip: 'Log out',
icon: const Icon(Icons.logout),
onPressed: () {
auth.logoff();
},
);
},
),
],
),
),
),
),
],
),
),
const SizedBox(height: constants.padding),
Expanded(
child: Padding(
padding: const EdgeInsets.symmetric( padding: const EdgeInsets.symmetric(
horizontal: constants.padding, horizontal: constants.padding,
), ),
child: const MountListWidget(), child: Row(
children: [
SizedBox(
width: 40,
height: 40,
child: Image.asset(
'assets/images/repertory.png',
fit: BoxFit.contain,
errorBuilder: (_, _, _) {
return Icon(
Icons.folder,
color: scheme.primary,
size: 32,
);
},
),
),
const SizedBox(width: constants.padding),
Expanded(
child: Text(
widget.title,
maxLines: 1,
overflow: TextOverflow.ellipsis,
style: textTheme.headlineSmall?.copyWith(
fontWeight: FontWeight.w700,
letterSpacing: 0.2,
color: scheme.onSurface.withValues(alpha: 0.96),
),
),
),
const SizedBox(width: constants.padding),
ClipRRect(
borderRadius: BorderRadius.circular(constants.borderRadius),
child: BackdropFilter(
filter: ImageFilter.blur(
sigmaX: constants.borderRadius,
sigmaY: constants.borderRadius,
),
child: Container(
height: 40,
padding: const EdgeInsets.symmetric(horizontal: 6),
decoration: BoxDecoration(
color: scheme.surface.withValues(alpha: 0.40),
borderRadius: BorderRadius.circular(
constants.borderRadius,
),
border: Border.all(
color: scheme.outlineVariant.withValues(
alpha: 0.08,
),
width: 1,
),
),
child: Row(
children: [
const Text("Auto-start"),
Consumer<Settings>(
builder: (context, settings, _) {
return IconButton(
icon: Icon(
settings.autoStart
? Icons.toggle_on
: Icons.toggle_off,
),
color: settings.autoStart
? scheme.primary
: scheme.onSurface.withValues(
alpha: 0.70,
),
onPressed: () => settings.setAutoStart(
!settings.autoStart,
),
);
},
),
IconButton(
tooltip: 'Settings',
icon: const Icon(Icons.settings),
onPressed: () {
Navigator.pushNamed(context, '/settings');
},
),
Consumer<Auth>(
builder: (context, auth, _) {
return IconButton(
tooltip: 'Log out',
icon: const Icon(Icons.logout),
onPressed: () {
auth.logoff();
},
);
},
),
],
),
),
),
),
],
),
), ),
), const SizedBox(height: constants.padding),
], Expanded(
), child: Padding(
padding: const EdgeInsets.symmetric(
horizontal: constants.padding,
),
child: const MountListWidget(),
),
),
],
),
],
floatingActionButton: Padding( floatingActionButton: Padding(
padding: const EdgeInsets.all(constants.padding), padding: const EdgeInsets.all(constants.padding),
child: Hero( child: Hero(