feat(legacy): replace CircularProgressIndicator with animated GIF loading
Add LegacyLoadingIndicator widget using a transparent GIF animation for all full-page loading states across legacy modules. Also fix HealthController crash by deferring provider mutation during build.
This commit is contained in:
@@ -40,7 +40,7 @@ class AppUsersScreen extends ConsumerWidget {
|
||||
SizedBox(height: SizeUtils.getByScreen(small: 18, big: 17)),
|
||||
itemCount: users.length,
|
||||
),
|
||||
loading: () => const Center(child: CircularProgressIndicator()),
|
||||
loading: () => const LegacyLoadingIndicator(),
|
||||
error: (_, __) => const SizedBox.shrink(),
|
||||
),
|
||||
),
|
||||
|
||||
@@ -60,7 +60,7 @@ class LinkedDevicesScreen extends ConsumerWidget {
|
||||
itemCount: devices.length,
|
||||
),
|
||||
),
|
||||
loading: () => const Center(child: CircularProgressIndicator()),
|
||||
loading: () => const LegacyLoadingIndicator(),
|
||||
error: (_, __) => const SizedBox.shrink(),
|
||||
),
|
||||
);
|
||||
|
||||
@@ -20,7 +20,7 @@ class PersonalDataScreen extends ConsumerWidget {
|
||||
data: (user) => _PersonalDataForm(user: user),
|
||||
loading: () => Scaffold(
|
||||
backgroundColor: Theme.of(context).colorScheme.surface,
|
||||
body: const Center(child: CircularProgressIndicator()),
|
||||
body: const LegacyLoadingIndicator(),
|
||||
),
|
||||
error: (_, __) => LegacyPageLayout(
|
||||
title: context.translate(I18n.personalData),
|
||||
|
||||
@@ -40,7 +40,7 @@ class ControlPanelScreen extends ConsumerWidget {
|
||||
backgroundColor: Theme.of(context).colorScheme.surface,
|
||||
body: asyncState.when(
|
||||
skipLoadingOnReload: true,
|
||||
loading: () => const Center(child: CircularProgressIndicator()),
|
||||
loading: () => const LegacyLoadingIndicator(),
|
||||
error: (error, _) => RefreshableErrorState(
|
||||
message: formatErrorMessage(error),
|
||||
onRefresh: () async {
|
||||
|
||||
@@ -10,6 +10,7 @@ import 'package:device_management/src/features/activity_meter/presentation/widge
|
||||
import 'package:device_management/src/features/activity_meter/presentation/widgets/steps_bar_chart.dart';
|
||||
import 'package:device_management/src/features/activity_meter/presentation/widgets/steps_history_section.dart';
|
||||
import 'package:device_management/src/features/activity_meter/presentation/widgets/steps_progress_ring.dart';
|
||||
import 'package:design_system/design_system.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
||||
import 'package:legacy_ui/legacy_ui.dart';
|
||||
@@ -27,7 +28,7 @@ class ActivityMeterScreen extends ConsumerWidget {
|
||||
return LegacyPageLayout(
|
||||
title: context.translate(I18n.activityMeter),
|
||||
body: isLoading
|
||||
? const Center(child: CircularProgressIndicator())
|
||||
? const LegacyLoadingIndicator()
|
||||
: const _ActivityMeterBody(),
|
||||
);
|
||||
}
|
||||
|
||||
@@ -2,6 +2,7 @@ import 'package:device_management/src/core/presentation/widgets/time_range_selec
|
||||
import 'package:device_management/src/features/apps_use/presentation/providers/apps_use_controller.dart';
|
||||
import 'package:device_management/src/features/apps_use/presentation/widgets/daily_app_usage_section.dart';
|
||||
import 'package:device_management/src/features/apps_use/presentation/widgets/top_apps_section.dart';
|
||||
import 'package:design_system/design_system.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
||||
import 'package:legacy_ui/legacy_ui.dart';
|
||||
@@ -29,7 +30,7 @@ class AppsUseScreen extends ConsumerWidget {
|
||||
return LegacyPageLayout(
|
||||
title: context.translate(I18n.appsUse),
|
||||
body: state.isLoading
|
||||
? const Center(child: CircularProgressIndicator())
|
||||
? const LegacyLoadingIndicator()
|
||||
: SingleChildScrollView(
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.stretch,
|
||||
|
||||
@@ -105,13 +105,13 @@ class BackgroundImageScreen extends ConsumerWidget {
|
||||
body: SafeArea(
|
||||
top: false,
|
||||
child: photosAsync.when(
|
||||
loading: () => const Center(child: CircularProgressIndicator()),
|
||||
loading: () => const LegacyLoadingIndicator(),
|
||||
error: (_, __) => Center(
|
||||
child: Text(context.translate(I18n.errorBackgroundImageLoad)),
|
||||
),
|
||||
data: (photos) {
|
||||
if (isSaving) {
|
||||
return const Center(child: CircularProgressIndicator());
|
||||
return const LegacyLoadingIndicator();
|
||||
}
|
||||
if (photos.isEmpty) {
|
||||
return _EmptyState(
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
import 'package:device_management/src/features/call_history/data/call_history_entity.dart';
|
||||
import 'package:device_management/src/features/call_history/presentation/providers/call_history_filter_provider.dart';
|
||||
import 'package:device_management/src/features/call_history/presentation/providers/call_history_provider.dart';
|
||||
import 'package:design_system/design_system.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
||||
import 'package:legacy_theme/legacy_theme.dart';
|
||||
@@ -28,7 +29,7 @@ class CallHistoryScreen extends ConsumerWidget {
|
||||
return LegacyPageLayout(
|
||||
title: context.translate(I18n.callHistory),
|
||||
body: callsAsync.when(
|
||||
loading: () => const Center(child: CircularProgressIndicator()),
|
||||
loading: () => const LegacyLoadingIndicator(),
|
||||
error: (err, _) => Center(
|
||||
child: Column(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
|
||||
@@ -57,14 +57,14 @@ class ContactsScreen extends ConsumerWidget {
|
||||
showEdit: true,
|
||||
onEditChange: ref.read(contactsEditingModeProvider.notifier).toggle,
|
||||
body: userAsync.when(
|
||||
loading: () => const Center(child: CircularProgressIndicator()),
|
||||
loading: () => const LegacyLoadingIndicator(),
|
||||
error: (_, __) => Center(
|
||||
child: Text(context.translate(I18n.errorGeneric)),
|
||||
),
|
||||
data: (user) {
|
||||
final contactsAsync = ref.watch(contactsProvider(user.id));
|
||||
return contactsAsync.when(
|
||||
loading: () => const Center(child: CircularProgressIndicator()),
|
||||
loading: () => const LegacyLoadingIndicator(),
|
||||
error: (_, __) => Center(
|
||||
child: Text(context.translate(I18n.errorGeneric)),
|
||||
),
|
||||
|
||||
@@ -26,7 +26,7 @@ class EditContactScreen extends ConsumerWidget {
|
||||
backgroundColor: Theme.of(context).colorScheme.surface,
|
||||
body: SafeArea(
|
||||
child: userAsync.when(
|
||||
loading: () => const Center(child: CircularProgressIndicator()),
|
||||
loading: () => const LegacyLoadingIndicator(),
|
||||
error: (_, __) => Center(
|
||||
child: Text(context.translate(I18n.errorGeneric)),
|
||||
),
|
||||
@@ -34,7 +34,7 @@ class EditContactScreen extends ConsumerWidget {
|
||||
final contactsAsync = ref.watch(contactsProvider(user.id));
|
||||
return contactsAsync.when(
|
||||
loading: () =>
|
||||
const Center(child: CircularProgressIndicator()),
|
||||
const LegacyLoadingIndicator(),
|
||||
error: (_, __) => Center(
|
||||
child: Text(context.translate(I18n.errorGeneric)),
|
||||
),
|
||||
|
||||
@@ -35,7 +35,7 @@ class DoNotDisturbScreen extends ConsumerWidget {
|
||||
if (device == null) {
|
||||
return LegacyPageLayout(
|
||||
title: context.translate(I18n.doNotDisturb),
|
||||
body: const Center(child: CircularProgressIndicator()),
|
||||
body: const LegacyLoadingIndicator(),
|
||||
);
|
||||
}
|
||||
|
||||
@@ -50,7 +50,7 @@ class DoNotDisturbScreen extends ConsumerWidget {
|
||||
return LegacyPageLayout(
|
||||
title: context.translate(I18n.doNotDisturb),
|
||||
body: periodsAsync.when(
|
||||
loading: () => const Center(child: CircularProgressIndicator()),
|
||||
loading: () => const LegacyLoadingIndicator(),
|
||||
error: (_, __) => Center(
|
||||
child: Text(context.translate(I18n.doNotDisturbError)),
|
||||
),
|
||||
|
||||
@@ -80,7 +80,7 @@ class _HealthScreenState extends ConsumerState<HealthScreen>
|
||||
return LegacyPageLayout(
|
||||
title: context.translate(I18n.healthTitle),
|
||||
body: state.isLoading
|
||||
? const Center(child: CircularProgressIndicator())
|
||||
? const LegacyLoadingIndicator()
|
||||
: state.isMeasuringCountdown
|
||||
? _MeasuringOverlay(
|
||||
remainingSeconds: state.measureRemainingSeconds,
|
||||
|
||||
@@ -36,7 +36,9 @@ class HealthController extends _$HealthController {
|
||||
|
||||
final remaining = endTime.difference(DateTime.now()).inSeconds;
|
||||
if (remaining <= 0) {
|
||||
ref.read(measureEndTimeProvider.notifier).set(null);
|
||||
Future.microtask(() {
|
||||
ref.read(measureEndTimeProvider.notifier).set(null);
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
@@ -27,7 +27,7 @@ class RemoteCameraScreen extends ConsumerWidget {
|
||||
if (device == null) {
|
||||
return LegacyPageLayout(
|
||||
title: context.translate(I18n.remoteCamera),
|
||||
body: const Center(child: CircularProgressIndicator()),
|
||||
body: const LegacyLoadingIndicator(),
|
||||
);
|
||||
}
|
||||
|
||||
@@ -37,14 +37,14 @@ class RemoteCameraScreen extends ConsumerWidget {
|
||||
|
||||
Widget body;
|
||||
if (cameraState.isTakingPicture) {
|
||||
body = const Center(child: CircularProgressIndicator());
|
||||
body = const LegacyLoadingIndicator();
|
||||
} else if (cameraState.isWaitingForPhoto) {
|
||||
body = _WaitingForPhotoOverlay(
|
||||
remainingSeconds: cameraState.photoCountdown,
|
||||
);
|
||||
} else {
|
||||
body = picturesAsync.when(
|
||||
loading: () => const Center(child: CircularProgressIndicator()),
|
||||
loading: () => const LegacyLoadingIndicator(),
|
||||
error: (_, __) =>
|
||||
Center(child: Text(context.translate(I18n.errorFetchPhotos))),
|
||||
data: (pictures) => _GallerySection(pictures: pictures),
|
||||
|
||||
@@ -2,6 +2,7 @@ import 'package:device_management/src/features/scheduled_activities/presentation
|
||||
import 'package:device_management/src/features/scheduled_activities/presentation/providers/scheduled_activities_provider.dart';
|
||||
import 'package:device_management/src/features/scheduled_activities/presentation/widgets/activity_form_sheet.dart';
|
||||
import 'package:device_management/src/features/scheduled_activities/presentation/widgets/day_timeline.dart';
|
||||
import 'package:design_system/design_system.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
||||
import 'package:legacy_device_state/legacy_device_state.dart';
|
||||
@@ -82,7 +83,7 @@ class _ScheduledActivitiesScreenState
|
||||
if (device == null) {
|
||||
return LegacyPageLayout(
|
||||
title: context.translate(I18n.activityScheduleTitle),
|
||||
body: const Center(child: CircularProgressIndicator()),
|
||||
body: const LegacyLoadingIndicator(),
|
||||
);
|
||||
}
|
||||
|
||||
@@ -92,7 +93,7 @@ class _ScheduledActivitiesScreenState
|
||||
return LegacyPageLayout(
|
||||
title: context.translate(I18n.activityScheduleTitle),
|
||||
body: activitiesAsync.when(
|
||||
loading: () => const Center(child: CircularProgressIndicator()),
|
||||
loading: () => const LegacyLoadingIndicator(),
|
||||
error: (err, _) => Center(child: Text(err.toString())),
|
||||
data: (activities) => Column(
|
||||
children: [
|
||||
|
||||
@@ -31,7 +31,7 @@ class VolumeControlScreen extends ConsumerWidget {
|
||||
if (device == null) {
|
||||
return LegacyPageLayout(
|
||||
title: context.translate(I18n.volumeControl),
|
||||
body: const Center(child: CircularProgressIndicator()),
|
||||
body: const LegacyLoadingIndicator(),
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
import 'package:design_system/design_system.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
||||
import 'package:legacy_device_state/legacy_device_state.dart';
|
||||
@@ -48,7 +49,7 @@ class LocationScreen extends ConsumerWidget {
|
||||
title: context.translate(I18n.mapTitle),
|
||||
showBack: false,
|
||||
body: isLoading
|
||||
? const Center(child: CircularProgressIndicator())
|
||||
? const LegacyLoadingIndicator()
|
||||
: deviceState == null
|
||||
? RefreshableErrorState(
|
||||
onRefresh: () async {
|
||||
|
||||
@@ -50,7 +50,7 @@ class AlarmScreen extends ConsumerWidget {
|
||||
return alarmsAsync.when(
|
||||
loading: () => Scaffold(
|
||||
appBar: _appBar(context, navigationContract, primaryColor),
|
||||
body: const Center(child: CircularProgressIndicator()),
|
||||
body: const LegacyLoadingIndicator(),
|
||||
),
|
||||
error: (_, __) => Scaffold(
|
||||
appBar: _appBar(context, navigationContract, primaryColor),
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
import 'package:design_system/design_system.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
||||
import 'package:legacy_device_state/legacy_device_state.dart';
|
||||
@@ -46,7 +47,7 @@ class BlockPhoneScreen extends ConsumerWidget {
|
||||
return contactsAsync.when(
|
||||
loading: () => Scaffold(
|
||||
appBar: _appBar(context, navigationContract, primaryColor),
|
||||
body: const Center(child: CircularProgressIndicator()),
|
||||
body: const LegacyLoadingIndicator(),
|
||||
),
|
||||
error: (_, __) => Scaffold(
|
||||
appBar: _appBar(context, navigationContract, primaryColor),
|
||||
|
||||
@@ -40,7 +40,7 @@ class DisableFunctionsScreen extends ConsumerWidget {
|
||||
return LegacyPageLayout(
|
||||
title: context.translate(I18n.disableFunctions),
|
||||
body: device == null
|
||||
? const Center(child: CircularProgressIndicator())
|
||||
? const LegacyLoadingIndicator()
|
||||
: Padding(
|
||||
padding: EdgeInsets.symmetric(
|
||||
horizontal: SizeUtils.getByScreen(small: 16, big: 14),
|
||||
|
||||
@@ -2,6 +2,7 @@ import 'package:settings/src/core/domain/entities/notification_entity.dart';
|
||||
import 'package:settings/src/features/notifications/presentation/providers/notifications_feed_provider.dart';
|
||||
import 'package:settings/src/features/notifications/presentation/providers/notifications_filter_provider.dart';
|
||||
import 'package:settings/src/features/notifications/presentation/widgets/notification_card.dart';
|
||||
import 'package:design_system/design_system.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
||||
import 'package:legacy_theme/legacy_theme.dart';
|
||||
@@ -216,7 +217,7 @@ class _FilteredNotificationsScreen extends ConsumerWidget {
|
||||
),
|
||||
),
|
||||
body: feedAsync.when(
|
||||
loading: () => const Center(child: CircularProgressIndicator()),
|
||||
loading: () => const LegacyLoadingIndicator(),
|
||||
error: (_, __) => Center(
|
||||
child: Text(context.translate(I18n.alertsLoadError)),
|
||||
),
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
import 'package:design_system/design_system.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
||||
import 'package:legacy_theme/legacy_theme.dart';
|
||||
@@ -48,7 +49,7 @@ class SosContactsScreen extends ConsumerWidget {
|
||||
return contactsAsync.when(
|
||||
loading: () => Scaffold(
|
||||
appBar: _appBar(context, navigationContract, primaryColor),
|
||||
body: const Center(child: CircularProgressIndicator()),
|
||||
body: const LegacyLoadingIndicator(),
|
||||
),
|
||||
error: (_, __) => Scaffold(
|
||||
appBar: _appBar(context, navigationContract, primaryColor),
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
import 'package:design_system/design_system.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
||||
import 'package:legacy_device_state/legacy_device_state.dart';
|
||||
@@ -97,7 +98,7 @@ class _WifiSettingsScreenState extends ConsumerState<WifiSettingsScreen> {
|
||||
body: SafeArea(
|
||||
top: false,
|
||||
child: savedAsync.when(
|
||||
loading: () => const Center(child: CircularProgressIndicator()),
|
||||
loading: () => const LegacyLoadingIndicator(),
|
||||
error: (_, __) => Center(
|
||||
child: Text(context.translate(I18n.wifiLoadError)),
|
||||
),
|
||||
|
||||
BIN
packages/design_system/assets/animations/loading_legacy.gif
Normal file
BIN
packages/design_system/assets/animations/loading_legacy.gif
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 516 KiB |
@@ -15,5 +15,6 @@ export 'src/containers/section_container.dart';
|
||||
export 'src/containers/footer_container.dart';
|
||||
export 'src/rows/editable_row.dart';
|
||||
export 'src/loading/app_loading_indicator.dart';
|
||||
export 'src/loading/legacy_loading_indicator.dart';
|
||||
export 'src/confetti/confetti_overlay.dart';
|
||||
export 'src/dialogs/contacts_permission_dialog.dart';
|
||||
|
||||
@@ -0,0 +1,18 @@
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
class LegacyLoadingIndicator extends StatelessWidget {
|
||||
final double size;
|
||||
|
||||
const LegacyLoadingIndicator({super.key, this.size = 120});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Center(
|
||||
child: Image.asset(
|
||||
'packages/design_system/assets/animations/loading_legacy.gif',
|
||||
width: size,
|
||||
height: size,
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user