💄 Optimized loading style

This commit is contained in:
2025-12-21 02:49:45 +08:00
parent f5fb5d8a98
commit 46a773cfe9
2 changed files with 152 additions and 156 deletions

View File

@@ -30,7 +30,10 @@ class DashboardScreen extends HookConsumerWidget {
@override @override
Widget build(BuildContext context, WidgetRef ref) { Widget build(BuildContext context, WidgetRef ref) {
return AppScaffold(body: Center(child: DashboardGrid())); return AppScaffold(
isNoBackground: false,
body: Center(child: DashboardGrid()),
);
} }
} }

View File

@@ -96,28 +96,28 @@ void showLoadingModal(BuildContext context) {
if (_loadingOverlay != null) return; if (_loadingOverlay != null) return;
_loadingOverlay = OverlayEntry( _loadingOverlay = OverlayEntry(
builder: builder: (context) => _FadeOverlay(
(context) => _FadeOverlay( key: _loadingOverlayKey,
key: _loadingOverlayKey, child: Material(
child: Material( color: Colors.black54,
color: Colors.black54, child: Center(
child: Center( child: AlertDialog(
child: Material( content: Row(
color: Theme.of(context).colorScheme.surface, mainAxisSize: MainAxisSize.min,
borderRadius: BorderRadius.circular(8), children: [
elevation: 4, CircularProgressIndicator(
child: Column( year2023: false,
mainAxisSize: MainAxisSize.min, padding: EdgeInsets.zero,
children: [ ).width(28).height(28).padding(horizontal: 8),
CircularProgressIndicator(year2023: false), const Gap(16),
const Gap(24), Text('loading'.tr()),
Text('loading'.tr()), ],
],
).padding(all: 32),
),
), ),
contentPadding: EdgeInsets.symmetric(horizontal: 32, vertical: 24),
), ),
), ),
),
),
); );
Overlay.of(context).insert(_loadingOverlay!); Overlay.of(context).insert(_loadingOverlay!);
@@ -187,40 +187,39 @@ Future<T?> showOverlayDialog<T>({
} }
entry = OverlayEntry( entry = OverlayEntry(
builder: builder: (context) => _FadeOverlay(
(context) => _FadeOverlay( key: key,
key: key, duration: const Duration(milliseconds: 150),
duration: const Duration(milliseconds: 150), curve: Curves.easeOut,
curve: Curves.easeOut, builder: (context, animation) {
builder: (context, animation) { return Stack(
return Stack( children: [
children: [ Positioned.fill(
Positioned.fill( child: FadeTransition(
child: FadeTransition( opacity: animation,
opacity: animation, child: GestureDetector(
child: GestureDetector( onTap: barrierDismissible ? () => close(null) : null,
onTap: barrierDismissible ? () => close(null) : null, behavior: HitTestBehavior.opaque,
behavior: HitTestBehavior.opaque, child: const ColoredBox(color: Colors.black54),
child: const ColoredBox(color: Colors.black54),
),
),
), ),
Center( ),
child: SlideTransition( ),
position: Tween<Offset>( Center(
begin: const Offset(0, 0.05), child: SlideTransition(
end: Offset.zero, position: Tween<Offset>(
).animate(animation), begin: const Offset(0, 0.05),
child: FadeTransition( end: Offset.zero,
opacity: animation, ).animate(animation),
child: builder(context, close), child: FadeTransition(
), opacity: animation,
), child: builder(context, close),
), ),
], ),
); ),
}, ],
), );
},
),
); );
_activeOverlayDialogs.add(() => close(null)); _activeOverlayDialogs.add(() => close(null));
@@ -252,77 +251,75 @@ void showErrorAlert(dynamic err, {IconData? icon}) {
}; };
showOverlayDialog<void>( showOverlayDialog<void>(
builder: builder: (context, close) => ConstrainedBox(
(context, close) => ConstrainedBox( constraints: const BoxConstraints(maxWidth: kDialogMaxWidth),
constraints: const BoxConstraints(maxWidth: kDialogMaxWidth), child: AlertDialog(
child: AlertDialog( title: null,
title: null, titlePadding: EdgeInsets.zero,
titlePadding: EdgeInsets.zero, contentPadding: const EdgeInsets.fromLTRB(24, 24, 24, 0),
contentPadding: const EdgeInsets.fromLTRB(24, 24, 24, 0), content: Column(
content: Column( mainAxisSize: MainAxisSize.min,
mainAxisSize: MainAxisSize.min, crossAxisAlignment: CrossAxisAlignment.start,
crossAxisAlignment: CrossAxisAlignment.start, children: [
children: [ Icon(
Icon( icon ?? Icons.error_outline_rounded,
icon ?? Icons.error_outline_rounded, size: 48,
size: 48, color: Theme.of(context).colorScheme.error,
color: Theme.of(context).colorScheme.error,
),
const Gap(16),
Text(
'somethingWentWrong'.tr(),
style: Theme.of(context).textTheme.titleLarge,
),
const Gap(8),
Text(text),
const Gap(8),
],
), ),
actions: [ const Gap(16),
TextButton( Text(
onPressed: () => close(null), 'somethingWentWrong'.tr(),
child: Text(MaterialLocalizations.of(context).okButtonLabel), style: Theme.of(context).textTheme.titleLarge,
), ),
], const Gap(8),
), Text(text),
const Gap(8),
],
), ),
actions: [
TextButton(
onPressed: () => close(null),
child: Text(MaterialLocalizations.of(context).okButtonLabel),
),
],
),
),
); );
} }
void showInfoAlert(String message, String title, {IconData? icon}) { void showInfoAlert(String message, String title, {IconData? icon}) {
showOverlayDialog<void>( showOverlayDialog<void>(
builder: builder: (context, close) => ConstrainedBox(
(context, close) => ConstrainedBox( constraints: const BoxConstraints(maxWidth: kDialogMaxWidth),
constraints: const BoxConstraints(maxWidth: kDialogMaxWidth), child: AlertDialog(
child: AlertDialog( title: null,
title: null, titlePadding: EdgeInsets.zero,
titlePadding: EdgeInsets.zero, contentPadding: const EdgeInsets.fromLTRB(24, 24, 24, 0),
contentPadding: const EdgeInsets.fromLTRB(24, 24, 24, 0), content: Column(
content: Column( mainAxisSize: MainAxisSize.min,
mainAxisSize: MainAxisSize.min, crossAxisAlignment: CrossAxisAlignment.start,
crossAxisAlignment: CrossAxisAlignment.start, children: [
children: [ Icon(
Icon( icon ?? Symbols.info_rounded,
icon ?? Symbols.info_rounded, fill: 1,
fill: 1, size: 48,
size: 48, color: Theme.of(context).colorScheme.primary,
color: Theme.of(context).colorScheme.primary,
),
const Gap(16),
Text(title, style: Theme.of(context).textTheme.titleLarge),
const Gap(8),
Text(message),
const Gap(8),
],
), ),
actions: [ const Gap(16),
TextButton( Text(title, style: Theme.of(context).textTheme.titleLarge),
onPressed: () => close(null), const Gap(8),
child: Text(MaterialLocalizations.of(context).okButtonLabel), Text(message),
), const Gap(8),
], ],
),
), ),
actions: [
TextButton(
onPressed: () => close(null),
child: Text(MaterialLocalizations.of(context).okButtonLabel),
),
],
),
),
); );
} }
@@ -333,50 +330,46 @@ Future<bool> showConfirmAlert(
bool isDanger = false, bool isDanger = false,
}) async { }) async {
final result = await showOverlayDialog<bool>( final result = await showOverlayDialog<bool>(
builder: builder: (context, close) => ConstrainedBox(
(context, close) => ConstrainedBox( constraints: const BoxConstraints(maxWidth: kDialogMaxWidth),
constraints: const BoxConstraints(maxWidth: kDialogMaxWidth), child: AlertDialog(
child: AlertDialog( title: null,
title: null, titlePadding: EdgeInsets.zero,
titlePadding: EdgeInsets.zero, contentPadding: const EdgeInsets.fromLTRB(24, 24, 24, 0),
contentPadding: const EdgeInsets.fromLTRB(24, 24, 24, 0), content: Column(
content: Column( mainAxisSize: MainAxisSize.min,
mainAxisSize: MainAxisSize.min, crossAxisAlignment: CrossAxisAlignment.start,
crossAxisAlignment: CrossAxisAlignment.start, children: [
children: [ Icon(
Icon( icon ?? Symbols.help_rounded,
icon ?? Symbols.help_rounded, size: 48,
size: 48, fill: 1,
fill: 1, color: Theme.of(context).colorScheme.primary,
color: Theme.of(context).colorScheme.primary,
),
const Gap(16),
Text(title, style: Theme.of(context).textTheme.titleLarge),
const Gap(8),
Text(message),
const Gap(8),
],
), ),
actions: [ const Gap(16),
TextButton( Text(title, style: Theme.of(context).textTheme.titleLarge),
onPressed: () => close(false), const Gap(8),
child: Text( Text(message),
MaterialLocalizations.of(context).cancelButtonLabel, const Gap(8),
), ],
),
TextButton(
onPressed: () => close(true),
style:
isDanger
? TextButton.styleFrom(
foregroundColor: Theme.of(context).colorScheme.error,
)
: null,
child: Text(MaterialLocalizations.of(context).okButtonLabel),
),
],
),
), ),
actions: [
TextButton(
onPressed: () => close(false),
child: Text(MaterialLocalizations.of(context).cancelButtonLabel),
),
TextButton(
onPressed: () => close(true),
style: isDanger
? TextButton.styleFrom(
foregroundColor: Theme.of(context).colorScheme.error,
)
: null,
child: Text(MaterialLocalizations.of(context).okButtonLabel),
),
],
),
),
); );
return result ?? false; return result ?? false;
} }