mirror of
https://gitlab.com/veilid/veilidchat.git
synced 2025-11-28 18:00:24 -05:00
account management update
This commit is contained in:
parent
01c6490ec4
commit
5e4f47d5a1
42 changed files with 1663 additions and 831 deletions
|
|
@ -30,6 +30,7 @@ class SliderTile extends StatelessWidget {
|
|||
this.endActions = const [],
|
||||
this.startActions = const [],
|
||||
this.onTap,
|
||||
this.onDoubleTap,
|
||||
this.icon,
|
||||
super.key});
|
||||
|
||||
|
|
@ -39,6 +40,7 @@ class SliderTile extends StatelessWidget {
|
|||
final List<SliderTileAction> endActions;
|
||||
final List<SliderTileAction> startActions;
|
||||
final GestureTapCallback? onTap;
|
||||
final GestureTapCallback? onDoubleTap;
|
||||
final IconData? icon;
|
||||
final String title;
|
||||
final String subtitle;
|
||||
|
|
@ -55,7 +57,9 @@ class SliderTile extends StatelessWidget {
|
|||
..add(ObjectFlagProperty<GestureTapCallback?>.has('onTap', onTap))
|
||||
..add(DiagnosticsProperty<IconData?>('icon', icon))
|
||||
..add(StringProperty('title', title))
|
||||
..add(StringProperty('subtitle', subtitle));
|
||||
..add(StringProperty('subtitle', subtitle))
|
||||
..add(ObjectFlagProperty<GestureTapCallback?>.has(
|
||||
'onDoubleTap', onDoubleTap));
|
||||
}
|
||||
|
||||
@override
|
||||
|
|
@ -138,18 +142,20 @@ class SliderTile extends StatelessWidget {
|
|||
padding: scaleConfig.useVisualIndicators
|
||||
? EdgeInsets.zero
|
||||
: const EdgeInsets.fromLTRB(0, 2, 0, 2),
|
||||
child: ListTile(
|
||||
onTap: onTap,
|
||||
dense: true,
|
||||
visualDensity: const VisualDensity(vertical: -4),
|
||||
title: Text(
|
||||
title,
|
||||
overflow: TextOverflow.fade,
|
||||
softWrap: false,
|
||||
),
|
||||
subtitle: subtitle.isNotEmpty ? Text(subtitle) : null,
|
||||
iconColor: textColor,
|
||||
textColor: textColor,
|
||||
leading: icon == null ? null : Icon(icon)))));
|
||||
child: GestureDetector(
|
||||
onDoubleTap: onDoubleTap,
|
||||
child: ListTile(
|
||||
onTap: onTap,
|
||||
dense: true,
|
||||
visualDensity: const VisualDensity(vertical: -4),
|
||||
title: Text(
|
||||
title,
|
||||
overflow: TextOverflow.fade,
|
||||
softWrap: false,
|
||||
),
|
||||
subtitle: subtitle.isNotEmpty ? Text(subtitle) : null,
|
||||
iconColor: textColor,
|
||||
textColor: textColor,
|
||||
leading: icon == null ? null : Icon(icon))))));
|
||||
}
|
||||
}
|
||||
|
|
|
|||
77
lib/theme/views/avatar_widget.dart
Normal file
77
lib/theme/views/avatar_widget.dart
Normal file
|
|
@ -0,0 +1,77 @@
|
|||
import 'package:awesome_extensions/awesome_extensions.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter/widgets.dart';
|
||||
|
||||
import '../theme.dart';
|
||||
|
||||
class AvatarWidget extends StatelessWidget {
|
||||
AvatarWidget({
|
||||
required String name,
|
||||
required double size,
|
||||
required Color borderColor,
|
||||
required Color foregroundColor,
|
||||
required Color backgroundColor,
|
||||
required ScaleConfig scaleConfig,
|
||||
required TextStyle textStyle,
|
||||
super.key,
|
||||
ImageProvider<Object>? imageProvider,
|
||||
}) : _name = name,
|
||||
_size = size,
|
||||
_borderColor = borderColor,
|
||||
_foregroundColor = foregroundColor,
|
||||
_backgroundColor = backgroundColor,
|
||||
_scaleConfig = scaleConfig,
|
||||
_textStyle = textStyle,
|
||||
_imageProvider = imageProvider;
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final abbrev = _name.split(' ').map((s) => s.isEmpty ? '' : s[0]).join();
|
||||
late final String shortname;
|
||||
if (abbrev.length >= 3) {
|
||||
shortname = abbrev[0] + abbrev[1] + abbrev[abbrev.length - 1];
|
||||
} else {
|
||||
shortname = abbrev;
|
||||
}
|
||||
|
||||
return Container(
|
||||
height: _size,
|
||||
width: _size,
|
||||
decoration: BoxDecoration(
|
||||
shape: BoxShape.circle,
|
||||
border: _scaleConfig.preferBorders
|
||||
? Border.all(
|
||||
color: _borderColor,
|
||||
width: 1 * (_size ~/ 32 + 1),
|
||||
strokeAlign: BorderSide.strokeAlignOutside)
|
||||
: null,
|
||||
color: _borderColor,
|
||||
),
|
||||
child: AvatarImage(
|
||||
//size: 32,
|
||||
backgroundImage: _imageProvider,
|
||||
backgroundColor:
|
||||
_scaleConfig.useVisualIndicators && !_scaleConfig.preferBorders
|
||||
? _foregroundColor
|
||||
: _backgroundColor,
|
||||
child: Text(
|
||||
shortname,
|
||||
style: _textStyle.copyWith(
|
||||
color: _scaleConfig.useVisualIndicators &&
|
||||
!_scaleConfig.preferBorders
|
||||
? _backgroundColor
|
||||
: _foregroundColor,
|
||||
),
|
||||
)));
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
final String _name;
|
||||
final double _size;
|
||||
final Color _borderColor;
|
||||
final Color _foregroundColor;
|
||||
final Color _backgroundColor;
|
||||
final ScaleConfig _scaleConfig;
|
||||
final TextStyle _textStyle;
|
||||
final ImageProvider<Object>? _imageProvider;
|
||||
}
|
||||
|
|
@ -50,6 +50,7 @@ class StyledDialog extends StatelessWidget {
|
|||
required Widget child}) async =>
|
||||
showDialog<T>(
|
||||
context: context,
|
||||
useRootNavigator: false,
|
||||
builder: (context) => StyledDialog(title: title, child: child));
|
||||
|
||||
final String title;
|
||||
|
|
|
|||
|
|
@ -12,15 +12,15 @@ class StyledScaffold extends StatelessWidget {
|
|||
final scale = theme.extension<ScaleScheme>()!;
|
||||
final scaleConfig = theme.extension<ScaleConfig>()!;
|
||||
|
||||
final scaffold = isDesktop
|
||||
? clipBorder(
|
||||
clipEnabled: true,
|
||||
borderEnabled: scaleConfig.useVisualIndicators,
|
||||
borderRadius: 16 * scaleConfig.borderRadiusScale,
|
||||
borderColor: scale.primaryScale.border,
|
||||
child: Scaffold(appBar: appBar, body: body, key: key))
|
||||
.paddingAll(32)
|
||||
: Scaffold(appBar: appBar, body: body, key: key);
|
||||
final enableBorder = !isMobileWidth(context);
|
||||
|
||||
final scaffold = clipBorder(
|
||||
clipEnabled: enableBorder,
|
||||
borderEnabled: scaleConfig.useVisualIndicators,
|
||||
borderRadius: 16 * scaleConfig.borderRadiusScale,
|
||||
borderColor: scale.primaryScale.border,
|
||||
child: Scaffold(appBar: appBar, body: body, key: key))
|
||||
.paddingAll(enableBorder ? 32 : 0);
|
||||
|
||||
return GestureDetector(
|
||||
onTap: () => FocusManager.instance.primaryFocus?.unfocus(),
|
||||
|
|
|
|||
|
|
@ -1,3 +1,4 @@
|
|||
export 'avatar_widget.dart';
|
||||
export 'brightness_preferences.dart';
|
||||
export 'color_preferences.dart';
|
||||
export 'enter_password.dart';
|
||||
|
|
|
|||
|
|
@ -41,6 +41,44 @@ extension ModalProgressExt on Widget {
|
|||
}
|
||||
}
|
||||
|
||||
extension LabelExt on Widget {
|
||||
Widget decoratorLabel(BuildContext context, String label,
|
||||
{ScaleColor? scale}) {
|
||||
final theme = Theme.of(context);
|
||||
final scaleScheme = theme.extension<ScaleScheme>()!;
|
||||
final scaleConfig = theme.extension<ScaleConfig>()!;
|
||||
scale = scale ?? scaleScheme.primaryScale;
|
||||
|
||||
final border = scale.border;
|
||||
final disabledBorder = scaleScheme.grayScale.border;
|
||||
final hoverBorder = scale.hoverBorder;
|
||||
final focusedErrorBorder = scaleScheme.errorScale.border;
|
||||
final errorBorder = scaleScheme.errorScale.primary;
|
||||
OutlineInputBorder makeBorder(Color color) => OutlineInputBorder(
|
||||
borderRadius:
|
||||
BorderRadius.circular(8 * scaleConfig.borderRadiusScale),
|
||||
borderSide: BorderSide(color: color),
|
||||
);
|
||||
OutlineInputBorder makeFocusedBorder(Color color) => OutlineInputBorder(
|
||||
borderRadius:
|
||||
BorderRadius.circular(8 * scaleConfig.borderRadiusScale),
|
||||
borderSide: BorderSide(width: 2, color: color),
|
||||
);
|
||||
return InputDecorator(
|
||||
decoration: InputDecoration(
|
||||
labelText: label,
|
||||
floatingLabelStyle: TextStyle(color: hoverBorder),
|
||||
border: makeBorder(border),
|
||||
enabledBorder: makeBorder(border),
|
||||
disabledBorder: makeBorder(disabledBorder),
|
||||
focusedBorder: makeFocusedBorder(hoverBorder),
|
||||
errorBorder: makeBorder(errorBorder),
|
||||
focusedErrorBorder: makeFocusedBorder(focusedErrorBorder),
|
||||
),
|
||||
child: this);
|
||||
}
|
||||
}
|
||||
|
||||
Widget buildProgressIndicator() => Builder(builder: (context) {
|
||||
final theme = Theme.of(context);
|
||||
final scale = theme.extension<ScaleScheme>()!;
|
||||
|
|
@ -292,6 +330,23 @@ Widget styledExpandingSliver(
|
|||
));
|
||||
}
|
||||
|
||||
Widget styledHeader({required BuildContext context, required Widget child}) {
|
||||
final theme = Theme.of(context);
|
||||
final scale = theme.extension<ScaleScheme>()!;
|
||||
final scaleConfig = theme.extension<ScaleConfig>()!;
|
||||
// final textTheme = theme.textTheme;
|
||||
|
||||
return DecoratedBox(
|
||||
decoration: ShapeDecoration(
|
||||
color: scale.primaryScale.border,
|
||||
shape: RoundedRectangleBorder(
|
||||
borderRadius: BorderRadius.only(
|
||||
topLeft: Radius.circular(12 * scaleConfig.borderRadiusScale),
|
||||
topRight:
|
||||
Radius.circular(12 * scaleConfig.borderRadiusScale)))),
|
||||
child: child);
|
||||
}
|
||||
|
||||
Widget styledTitleContainer({
|
||||
required BuildContext context,
|
||||
required String title,
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue