feat(legacy-ui): add animated transitions for dialogs and navigation
This commit is contained in:
@@ -100,7 +100,7 @@ class AccountSettingsScreen extends ConsumerWidget {
|
||||
_item(
|
||||
context,
|
||||
onPressed: () {
|
||||
showDialog<void>(
|
||||
showLegacyDialog<void>(
|
||||
context: context,
|
||||
builder: (_) => Dialog(
|
||||
backgroundColor: Colors.transparent,
|
||||
|
||||
@@ -128,7 +128,7 @@ class AppUserCard extends ConsumerWidget {
|
||||
),
|
||||
child: IconButton(
|
||||
onPressed: () {
|
||||
showDialog(
|
||||
showLegacyDialog(
|
||||
context: context,
|
||||
builder: (context) => Dialog(
|
||||
child: Container(
|
||||
|
||||
@@ -141,7 +141,7 @@ class _RequestCancelSection extends ConsumerWidget {
|
||||
}
|
||||
|
||||
if (!context.mounted) return;
|
||||
showDialog<void>(
|
||||
showLegacyDialog<void>(
|
||||
context: context,
|
||||
builder: (_) => ConfirmDialog(navigationContract: navigationContract),
|
||||
);
|
||||
|
||||
@@ -129,7 +129,7 @@ class _LinkedDeviceCard extends StatelessWidget {
|
||||
borderRadius: const BorderRadius.all(Radius.circular(12)),
|
||||
),
|
||||
child: IconButton(
|
||||
onPressed: () => showDialog<void>(
|
||||
onPressed: () => showLegacyDialog<void>(
|
||||
context: context,
|
||||
builder: (_) => Dialog(child: DeleteDeviceDialog(device: device)),
|
||||
),
|
||||
@@ -145,7 +145,7 @@ class _LinkedDeviceCard extends StatelessWidget {
|
||||
child: IconButton(
|
||||
onPressed: () => Navigator.push(
|
||||
context,
|
||||
MaterialPageRoute<void>(
|
||||
LegacyPageRoute<void>(
|
||||
builder: (_) => EditLinkedDeviceScreen(device: device),
|
||||
),
|
||||
),
|
||||
|
||||
@@ -76,7 +76,7 @@ class CustomerServiceScreen extends ConsumerWidget {
|
||||
onPressed: () {
|
||||
Navigator.push(
|
||||
context,
|
||||
MaterialPageRoute(
|
||||
LegacyPageRoute(
|
||||
builder: (_) =>
|
||||
ContactScreen(navigationContract: navigationContract),
|
||||
),
|
||||
|
||||
@@ -21,14 +21,16 @@ class BackgroundImageScreen extends ConsumerWidget {
|
||||
final primaryColor = context.sfColors.legacyPrimary;
|
||||
final device = ref.watch(selectedDeviceProvider).value;
|
||||
final photosAsync = ref.watch(backgroundImagePhotosProvider);
|
||||
final isSaving = ref
|
||||
.watch(backgroundImageControllerProvider.select((s) => s.isLoading));
|
||||
final isSaving = ref.watch(
|
||||
backgroundImageControllerProvider.select((s) => s.isLoading),
|
||||
);
|
||||
|
||||
ref.listen(backgroundImageControllerProvider, (prev, next) async {
|
||||
if (prev == null || !prev.isLoading || next.isLoading) return;
|
||||
if (next.hasError) {
|
||||
final action =
|
||||
ref.read(backgroundImageControllerProvider.notifier).lastAction;
|
||||
final action = ref
|
||||
.read(backgroundImageControllerProvider.notifier)
|
||||
.lastAction;
|
||||
final key = switch (action) {
|
||||
BackgroundImageAction.uploaded => I18n.errorBackgroundImageUpload,
|
||||
BackgroundImageAction.backgroundSet => I18n.errorBackgroundImageSet,
|
||||
@@ -37,8 +39,9 @@ class BackgroundImageScreen extends ConsumerWidget {
|
||||
await showErrorDialog(context, key);
|
||||
return;
|
||||
}
|
||||
final action =
|
||||
ref.read(backgroundImageControllerProvider.notifier).lastAction;
|
||||
final action = ref
|
||||
.read(backgroundImageControllerProvider.notifier)
|
||||
.lastAction;
|
||||
final key = switch (action) {
|
||||
BackgroundImageAction.uploaded => I18n.backgroundImageUploaded,
|
||||
BackgroundImageAction.backgroundSet => I18n.backgroundImageSet,
|
||||
@@ -64,7 +67,7 @@ class BackgroundImageScreen extends ConsumerWidget {
|
||||
),
|
||||
),
|
||||
title: Text(
|
||||
context.translate(I18n.customBackground).toUpperCase(),
|
||||
context.translate(I18n.customBackground),
|
||||
style: TextStyle(
|
||||
fontSize: SizeUtils.getByScreen(small: 20, big: 19),
|
||||
fontWeight: FontWeight.w500,
|
||||
@@ -242,8 +245,7 @@ class _PhotoGrid extends StatelessWidget {
|
||||
child: Icon(
|
||||
Icons.image_outlined,
|
||||
size: 48,
|
||||
color:
|
||||
Theme.of(context).colorScheme.outline,
|
||||
color: Theme.of(context).colorScheme.outline,
|
||||
),
|
||||
),
|
||||
),
|
||||
|
||||
@@ -56,7 +56,7 @@ class LocateDeviceScreen extends ConsumerWidget {
|
||||
),
|
||||
child: PrimaryButton(
|
||||
onPressed: () {
|
||||
showDialog<void>(
|
||||
showLegacyDialog<void>(
|
||||
context: context,
|
||||
builder: (_) => const Dialog(child: LocateDeviceDialog()),
|
||||
);
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
import 'package:legacy_ui/legacy_ui.dart';
|
||||
import 'package:design_system/design_system.dart';
|
||||
import 'package:device_management/src/features/scheduled_activities/domain/entities/scheduled_activity_entity.dart';
|
||||
import 'package:device_management/src/features/scheduled_activities/presentation/providers/scheduled_activities_controller.dart';
|
||||
@@ -197,7 +198,7 @@ class _ActivityTimelineCard extends ConsumerWidget {
|
||||
onPressed: () async {
|
||||
if (!await guardDeviceCommand(context, ref)) return;
|
||||
if (!context.mounted) return;
|
||||
final confirmed = await showDialog<bool>(
|
||||
final confirmed = await showLegacyDialog<bool>(
|
||||
context: context,
|
||||
builder: (dialogContext) => AlertDialog(
|
||||
title: Text(
|
||||
|
||||
@@ -1,9 +1,10 @@
|
||||
import 'package:legacy_ui/legacy_ui.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:sf_localizations/sf_localizations.dart';
|
||||
import 'package:utils/utils.dart';
|
||||
|
||||
void showActivationCodeDialog(BuildContext context) {
|
||||
showDialog(
|
||||
showLegacyDialog(
|
||||
context: context,
|
||||
builder: (context) => Dialog(
|
||||
shape: RoundedRectangleBorder(
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
import 'package:legacy_ui/legacy_ui.dart';
|
||||
import 'package:design_system/design_system.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
||||
@@ -119,7 +120,7 @@ class _LegacyRequestRecoveryScreenState
|
||||
if (updated.recoveryRequested) {
|
||||
Navigator.push(
|
||||
context,
|
||||
MaterialPageRoute(
|
||||
LegacyPageRoute(
|
||||
builder: (_) => LegacySentScreen(
|
||||
navigationContract:
|
||||
widget.navigationContract,
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
import 'package:legacy_ui/legacy_ui.dart';
|
||||
import 'package:legacy_auth/src/features/recover_password/presentation/new_password/new_password_screen.dart';
|
||||
import 'package:legacy_theme/legacy_theme.dart';
|
||||
import 'package:design_system/design_system.dart';
|
||||
@@ -99,7 +100,7 @@ class LegacySentScreen extends ConsumerWidget {
|
||||
child: PrimaryButton(
|
||||
onPressed: () => Navigator.push(
|
||||
context,
|
||||
MaterialPageRoute(
|
||||
LegacyPageRoute(
|
||||
builder: (_) => LegacyNewPasswordScreen(
|
||||
navigationContract: navigationContract,
|
||||
),
|
||||
|
||||
@@ -31,6 +31,8 @@ dependencies:
|
||||
path: ../../../../packages/sf_tracking
|
||||
legacy_device_state:
|
||||
path: ../../packages/legacy_device_state
|
||||
legacy_ui:
|
||||
path: ../../packages/legacy_ui
|
||||
fonts:
|
||||
path: ../../../../packages/fonts
|
||||
#dependencies go here
|
||||
@@ -47,6 +49,7 @@ dependencies:
|
||||
json_serializable: ^6.11.2
|
||||
uuid: ^4.5.3
|
||||
mobile_scanner: ^7.1.4
|
||||
url_launcher: ^6.3.1
|
||||
dio_cookie_manager: ^3.3.0
|
||||
cookie_jar: ^4.0.8
|
||||
path_provider: ^2.1.5
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
import 'package:legacy_ui/legacy_ui.dart';
|
||||
import 'package:design_system/design_system.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
||||
@@ -26,10 +27,7 @@ class AlarmScreen extends ConsumerWidget {
|
||||
|
||||
ref.listen(alarmControllerProvider, (prev, next) {
|
||||
next.showErrorOn(context);
|
||||
if (prev != null &&
|
||||
prev.isLoading &&
|
||||
!next.isLoading &&
|
||||
!next.hasError) {
|
||||
if (prev != null && prev.isLoading && !next.isLoading && !next.hasError) {
|
||||
ref.read(alarmsEditorProvider.notifier).clear();
|
||||
}
|
||||
});
|
||||
@@ -85,11 +83,7 @@ class AlarmScreen extends ConsumerWidget {
|
||||
return;
|
||||
}
|
||||
if (!context.mounted) return;
|
||||
_openForm(
|
||||
context,
|
||||
ref,
|
||||
fetchedAlarms: fetchedAlarms,
|
||||
);
|
||||
_openForm(context, ref, fetchedAlarms: fetchedAlarms);
|
||||
},
|
||||
icon: Icon(
|
||||
Icons.add,
|
||||
@@ -130,8 +124,10 @@ class AlarmScreen extends ConsumerWidget {
|
||||
),
|
||||
bottomNavigationBar: alarms.isNotEmpty
|
||||
? Padding(
|
||||
padding:
|
||||
const EdgeInsets.symmetric(horizontal: 24, vertical: 10),
|
||||
padding: const EdgeInsets.symmetric(
|
||||
horizontal: 24,
|
||||
vertical: 10,
|
||||
),
|
||||
child: isSaving
|
||||
? const Center(child: CircularProgressIndicator())
|
||||
: PrimaryButton(
|
||||
@@ -142,13 +138,9 @@ class AlarmScreen extends ConsumerWidget {
|
||||
.read(alarmControllerProvider.notifier)
|
||||
.save(deviceId: device.id, alarms: alarms);
|
||||
if (!context.mounted) return;
|
||||
final state =
|
||||
ref.read(alarmControllerProvider);
|
||||
final state = ref.read(alarmControllerProvider);
|
||||
if (state.hasError) return;
|
||||
await showSuccessDialog(
|
||||
context,
|
||||
I18n.alarmSaved,
|
||||
);
|
||||
await showSuccessDialog(context, I18n.alarmSaved);
|
||||
},
|
||||
text: context.translate(I18n.alarmSave),
|
||||
color: primaryColor,
|
||||
@@ -181,7 +173,7 @@ class AlarmScreen extends ConsumerWidget {
|
||||
),
|
||||
),
|
||||
title: Text(
|
||||
context.translate(I18n.alarm).toUpperCase(),
|
||||
context.translate(I18n.alarm),
|
||||
style: TextStyle(
|
||||
fontSize: SizeUtils.getByScreen(small: 20, big: 19),
|
||||
fontWeight: FontWeight.w500,
|
||||
@@ -203,7 +195,7 @@ class AlarmScreen extends ConsumerWidget {
|
||||
|
||||
Future<bool?> _confirmDelete(BuildContext context) {
|
||||
final theme = Theme.of(context);
|
||||
return showDialog<bool>(
|
||||
return showLegacyDialog<bool>(
|
||||
context: context,
|
||||
builder: (dialogContext) => AlertDialog(
|
||||
icon: Icon(
|
||||
@@ -243,11 +235,7 @@ class AlarmScreen extends ConsumerWidget {
|
||||
onSave: (result) {
|
||||
final editor = ref.read(alarmsEditorProvider.notifier);
|
||||
if (index != null) {
|
||||
editor.replace(
|
||||
current: fetchedAlarms,
|
||||
index: index,
|
||||
alarm: result,
|
||||
);
|
||||
editor.replace(current: fetchedAlarms, index: index, alarm: result);
|
||||
} else {
|
||||
editor.add(current: fetchedAlarms, alarm: result);
|
||||
}
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
import 'package:legacy_ui/legacy_ui.dart';
|
||||
import 'package:design_system/design_system.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
||||
@@ -137,7 +138,7 @@ class BlockPhoneScreen extends ConsumerWidget {
|
||||
),
|
||||
),
|
||||
title: Text(
|
||||
context.translate(I18n.blockPhone).toUpperCase(),
|
||||
context.translate(I18n.blockPhone),
|
||||
style: TextStyle(
|
||||
fontSize: SizeUtils.getByScreen(small: 20, big: 19),
|
||||
fontWeight: FontWeight.w500,
|
||||
@@ -172,7 +173,7 @@ class BlockPhoneScreen extends ConsumerWidget {
|
||||
|
||||
Future<bool?> _confirmDelete(BuildContext context, String name) {
|
||||
final theme = Theme.of(context);
|
||||
return showDialog<bool>(
|
||||
return showLegacyDialog<bool>(
|
||||
context: context,
|
||||
builder: (dialogContext) => AlertDialog(
|
||||
icon: Icon(
|
||||
@@ -282,8 +283,7 @@ class _ContactList extends StatelessWidget {
|
||||
context.translate(I18n.whitelistDescription),
|
||||
style: TextStyle(
|
||||
fontSize: SizeUtils.getByScreen(small: 14, big: 15),
|
||||
color:
|
||||
Theme.of(context).colorScheme.onSurface.withAlpha(178),
|
||||
color: Theme.of(context).colorScheme.onSurface.withAlpha(178),
|
||||
),
|
||||
),
|
||||
),
|
||||
|
||||
@@ -34,7 +34,7 @@ class RemoteManagementScreen extends ConsumerWidget {
|
||||
}) async {
|
||||
if (!await guardDeviceCommand(context, ref)) return;
|
||||
if (!context.mounted) return;
|
||||
await showDialog<void>(
|
||||
await showLegacyDialog<void>(
|
||||
context: context,
|
||||
builder: (_) => ConfirmDialog(
|
||||
title: title,
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
import 'package:legacy_ui/legacy_ui.dart';
|
||||
import 'package:design_system/design_system.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
||||
@@ -347,7 +348,7 @@ class _Body extends ConsumerWidget {
|
||||
if (!context.mounted) return;
|
||||
final primaryColor = context.sfColors.legacyPrimary;
|
||||
|
||||
showDialog<void>(
|
||||
showLegacyDialog<void>(
|
||||
context: context,
|
||||
builder: (dialogContext) => AlertDialog(
|
||||
title: Text(context.translate(I18n.removeWifiNetwork)),
|
||||
|
||||
@@ -5,3 +5,4 @@ export 'src/widgets/pulsing_location_marker.dart';
|
||||
export 'src/widgets/refreshable_error_state.dart';
|
||||
export 'src/widgets/week_day_chips.dart';
|
||||
export 'src/providers/map_style_provider.dart';
|
||||
export 'src/transitions/legacy_transitions.dart';
|
||||
|
||||
@@ -0,0 +1,64 @@
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
const _duration = Duration(milliseconds: 300);
|
||||
const _dialogDuration = Duration(milliseconds: 500);
|
||||
|
||||
Future<T?> showLegacyDialog<T>({
|
||||
required BuildContext context,
|
||||
required WidgetBuilder builder,
|
||||
bool barrierDismissible = true,
|
||||
}) {
|
||||
return showGeneralDialog<T>(
|
||||
context: context,
|
||||
barrierDismissible: barrierDismissible,
|
||||
barrierLabel: MaterialLocalizations.of(context).modalBarrierDismissLabel,
|
||||
barrierColor: Colors.black54,
|
||||
transitionDuration: _dialogDuration,
|
||||
pageBuilder: (dialogContext, __, ___) => builder(dialogContext),
|
||||
transitionBuilder: (_, animation, __, child) {
|
||||
final fadeCurved = CurvedAnimation(
|
||||
parent: animation,
|
||||
curve: Curves.easeOut,
|
||||
reverseCurve: Curves.easeIn,
|
||||
);
|
||||
final scaleCurved = CurvedAnimation(
|
||||
parent: animation,
|
||||
curve: Curves.easeOutBack,
|
||||
reverseCurve: Curves.easeInCubic,
|
||||
);
|
||||
return FadeTransition(
|
||||
opacity: fadeCurved,
|
||||
child: ScaleTransition(
|
||||
scale: Tween<double>(begin: 0.6, end: 1.0).animate(scaleCurved),
|
||||
child: child,
|
||||
),
|
||||
);
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
class LegacyPageRoute<T> extends PageRouteBuilder<T> {
|
||||
LegacyPageRoute({required WidgetBuilder builder})
|
||||
: super(
|
||||
transitionDuration: _duration,
|
||||
reverseTransitionDuration: _duration,
|
||||
pageBuilder: (context, _, __) => builder(context),
|
||||
transitionsBuilder: (_, animation, __, child) {
|
||||
final curved = CurvedAnimation(
|
||||
parent: animation,
|
||||
curve: Curves.easeOutCubic,
|
||||
reverseCurve: Curves.easeInCubic,
|
||||
);
|
||||
return FadeTransition(
|
||||
opacity: curved,
|
||||
child: SlideTransition(
|
||||
position: Tween<Offset>(
|
||||
begin: const Offset(1, 0),
|
||||
end: Offset.zero,
|
||||
).animate(curved),
|
||||
child: child,
|
||||
),
|
||||
);
|
||||
},
|
||||
);
|
||||
}
|
||||
@@ -46,7 +46,7 @@ class LegacyPageLayout extends StatelessWidget {
|
||||
)
|
||||
: null,
|
||||
title: Text(
|
||||
title.toUpperCase(),
|
||||
title,
|
||||
style: TextStyle(
|
||||
fontSize: SizeUtils.getByScreen(small: 20, big: 19),
|
||||
fontWeight: FontWeight.w500,
|
||||
|
||||
Reference in New Issue
Block a user