[ui] UI theme should match repertory blue #61
All checks were successful
BlockStorage/repertory/pipeline/head This commit looks good

This commit is contained in:
2025-09-05 07:53:47 -05:00
parent da0e2ddb46
commit cd28953324
10 changed files with 130 additions and 75 deletions

View File

@@ -468,13 +468,15 @@ Scaffold createCommonScaffold(
InputDecoration createCommonDecoration(
ColorScheme colorScheme,
String label, {
IconData? icon,
bool filled = true,
String? hintText,
IconData? icon,
}) => InputDecoration(
labelText: label,
prefixIcon: icon == null ? null : Icon(icon),
filled: filled,
fillColor: colorScheme.primary.withValues(alpha: constants.primaryAlpha),
hintText: hintText,
border: OutlineInputBorder(
borderRadius: BorderRadius.circular(constants.borderRadiusSmall),
borderSide: BorderSide.none,

View File

@@ -10,6 +10,7 @@ import 'package:repertory/models/auth.dart';
import 'package:repertory/models/mount.dart';
import 'package:repertory/models/mount_list.dart';
import 'package:repertory/types/mount_config.dart';
import 'package:repertory/utils/safe_set_state_mixin.dart';
import 'package:repertory/widgets/app_dropdown.dart';
import 'package:repertory/widgets/mount_settings.dart';
@@ -21,7 +22,8 @@ class AddMountScreen extends StatefulWidget {
State<AddMountScreen> createState() => _AddMountScreenState();
}
class _AddMountScreenState extends State<AddMountScreen> {
class _AddMountScreenState extends State<AddMountScreen>
with SafeSetState<AddMountScreen> {
Mount? _mount;
final _mountNameController = TextEditingController();
String _mountType = "";
@@ -161,8 +163,9 @@ class _AddMountScreenState extends State<AddMountScreen> {
decoration: createCommonDecoration(
scheme,
'Configuration Name',
hintText: 'Enter a unique name',
icon: Icons.drive_file_rename_outline,
).copyWith(hintText: 'Enter a unique name'),
),
),
],
if (_mount != null) ...[
@@ -323,10 +326,4 @@ class _AddMountScreenState extends State<AddMountScreen> {
success ? "Success" : "Provider settings are invalid!",
);
}
@override
void setState(VoidCallback fn) {
if (!mounted) return;
super.setState(fn);
}
}

View File

@@ -7,6 +7,7 @@ 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/app_text_field.dart';
import 'package:repertory/widgets/aurora_sweep.dart';
class AuthScreen extends StatefulWidget {
@@ -226,15 +227,12 @@ class _AuthScreenState extends State<AuthScreen> {
const SizedBox(
height: constants.padding * 2.0,
),
TextFormField(
AppTextField(
autofocus: true,
controller: _userController,
icon: Icons.person,
labelText: 'Username',
textInputAction: TextInputAction.next,
decoration: createCommonDecoration(
scheme,
'Username',
icon: Icons.person,
),
validator: (v) {
if (v == null || v.trim().isEmpty) {
return 'Enter your username';
@@ -246,33 +244,27 @@ class _AuthScreenState extends State<AuthScreen> {
},
),
const SizedBox(height: constants.padding),
TextFormField(
AppTextField(
controller: _passwordController,
icon: Icons.lock,
labelText: 'Password',
obscureText: _obscure,
suffixIcon: IconButton(
tooltip: _obscure
? 'Show password'
: 'Hide password',
icon: Icon(
_obscure
? Icons.visibility
: Icons.visibility_off,
),
onPressed: () {
setState(() {
_obscure = !_obscure;
});
},
),
textInputAction: TextInputAction.go,
decoration:
createCommonDecoration(
scheme,
'Password',
icon: Icons.lock,
).copyWith(
suffixIcon: IconButton(
tooltip: _obscure
? 'Show password'
: 'Hide password',
icon: Icon(
_obscure
? Icons.visibility
: Icons.visibility_off,
),
onPressed: () {
setState(() {
_obscure = !_obscure;
});
},
),
),
validator: (v) {
if (v == null || v.isEmpty) {
return 'Enter your password';

View File

@@ -8,6 +8,7 @@ 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';
class EditMountScreen extends StatefulWidget {
@@ -19,7 +20,8 @@ class EditMountScreen extends StatefulWidget {
State<EditMountScreen> createState() => _EditMountScreenState();
}
class _EditMountScreenState extends State<EditMountScreen> {
class _EditMountScreenState extends State<EditMountScreen>
with SafeSetState<EditMountScreen> {
bool _showAdvanced = false;
@override
@@ -186,10 +188,4 @@ class _EditMountScreenState extends State<EditMountScreen> {
),
]);
}
@override
void setState(VoidCallback fn) {
if (!mounted) return;
super.setState(fn);
}
}

View File

@@ -9,6 +9,7 @@ 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/utils/safe_set_state_mixin.dart';
import 'package:repertory/widgets/ui_settings.dart';
class EditSettingsScreen extends StatefulWidget {
@@ -19,7 +20,8 @@ class EditSettingsScreen extends StatefulWidget {
State<EditSettingsScreen> createState() => _EditSettingsScreenState();
}
class _EditSettingsScreenState extends State<EditSettingsScreen> {
class _EditSettingsScreenState extends State<EditSettingsScreen>
with SafeSetState<EditSettingsScreen> {
@override
Widget build(BuildContext context) {
final scheme = Theme.of(context).colorScheme;
@@ -174,12 +176,4 @@ class _EditSettingsScreenState extends State<EditSettingsScreen> {
return {};
}
@override
void setState(VoidCallback fn) {
if (!mounted) {
return;
}
super.setState(fn);
}
}

View File

@@ -0,0 +1,14 @@
// safe_set_state_mixin.dart
import 'package:flutter/widgets.dart';
mixin SafeSetState<T extends StatefulWidget> on State<T> {
@override
void setState(VoidCallback fn) {
if (!mounted) {
return;
}
super.setState(fn);
}
}

View File

@@ -0,0 +1,66 @@
import 'package:flutter/material.dart';
import 'package:repertory/helpers.dart' as helpers;
class AppTextField extends StatelessWidget {
const AppTextField({
super.key,
this.autofocus = false,
this.controller,
this.enabled = true,
this.hintText,
this.icon,
this.keyboardType,
this.labelText,
this.maxLines = 1,
this.obscureText = false,
this.onChanged,
this.onFieldSubmitted,
this.suffixIcon,
this.textInputAction,
this.validator,
});
final bool autofocus;
final TextEditingController? controller;
final bool enabled;
final String? hintText;
final IconData? icon;
final TextInputType? keyboardType;
final String? labelText;
final int? maxLines;
final bool obscureText;
final ValueChanged<String>? onChanged;
final ValueChanged<String>? onFieldSubmitted;
final Widget? suffixIcon;
final TextInputAction? textInputAction;
final FormFieldValidator<String>? validator;
@override
Widget build(BuildContext context) {
final scheme = Theme.of(context).colorScheme;
final decoration = helpers
.createCommonDecoration(
scheme,
filled: true,
hintText: hintText,
icon: icon,
labelText ?? '',
)
.copyWith(suffixIcon: suffixIcon);
return TextFormField(
autofocus: autofocus,
controller: controller,
decoration: decoration,
enabled: enabled,
keyboardType: keyboardType,
maxLines: maxLines,
obscureText: obscureText,
onChanged: onChanged,
onFieldSubmitted: onFieldSubmitted,
textInputAction: textInputAction,
validator: validator,
);
}
}

View File

@@ -1042,8 +1042,14 @@ class _MountSettingsWidgetState extends State<MountSettingsWidget> {
@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);
}
}

View File

@@ -6,6 +6,7 @@ import 'package:provider/provider.dart';
import 'package:repertory/constants.dart' as constants;
import 'package:repertory/helpers.dart';
import 'package:repertory/models/mount.dart';
import 'package:repertory/utils/safe_set_state_mixin.dart';
class MountWidget extends StatefulWidget {
const MountWidget({super.key});
@@ -14,7 +15,8 @@ class MountWidget extends StatefulWidget {
State<MountWidget> createState() => _MountWidgetState();
}
class _MountWidgetState extends State<MountWidget> {
class _MountWidgetState extends State<MountWidget>
with SafeSetState<MountWidget> {
bool _enabled = true;
bool _editEnabled = true;
Timer? _timer;
@@ -286,14 +288,6 @@ class _MountWidgetState extends State<MountWidget> {
_timer = null;
super.dispose();
}
@override
void setState(VoidCallback fn) {
if (!mounted) {
return;
}
super.setState(fn);
}
}
class _FramedBox extends StatelessWidget {

View File

@@ -17,6 +17,7 @@ import 'package:repertory/helpers.dart'
trimNotEmptyValidator;
import 'package:repertory/models/auth.dart';
import 'package:repertory/settings.dart';
import 'package:repertory/utils/safe_set_state_mixin.dart';
import 'package:settings_ui/settings_ui.dart';
class UISettingsWidget extends StatefulWidget {
@@ -34,7 +35,8 @@ class UISettingsWidget extends StatefulWidget {
State<UISettingsWidget> createState() => _UISettingsWidgetState();
}
class _UISettingsWidgetState extends State<UISettingsWidget> {
class _UISettingsWidgetState extends State<UISettingsWidget>
with SafeSetState<UISettingsWidget> {
@override
Widget build(BuildContext context) {
final scheme = Theme.of(context).colorScheme;
@@ -164,12 +166,4 @@ class _UISettingsWidgetState extends State<UISettingsWidget> {
super.dispose();
}
@override
void setState(VoidCallback fn) {
if (!mounted) {
return;
}
super.setState(fn);
}
}