From cd775f0823184bcbb1504c815c2dfa9ae7af7b2a Mon Sep 17 00:00:00 2001 From: Xavier Paquet-Rapold Date: Fri, 25 Oct 2024 18:30:17 -0400 Subject: [PATCH 01/19] Remove flutter siren and feature discovery --- lib/constants/update_code.dart | 5 - lib/features/app/navigation/router.dart | 4 +- .../app/startup/startup_viewmodel.dart | 99 +--- .../app/storage/siren_flutter_service.dart | 48 -- lib/features/app/widgets/bottom_bar.dart | 35 +- lib/features/app/widgets/navigation_rail.dart | 36 +- lib/features/dashboard/dashboard_view.dart | 40 +- .../dashboard/dashboard_viewmodel.dart | 72 --- lib/features/more/more_view.dart | 77 +-- lib/features/more/more_viewmodel.dart | 32 -- lib/features/schedule/schedule_view.dart | 47 +- lib/features/schedule/schedule_viewmodel.dart | 29 - .../grade_details/grade_details_view.dart | 7 - .../grades_details_viewmodel.dart | 28 - lib/features/student/grades/grades_view.dart | 18 +- .../student/grades/grades_viewmodel.dart | 28 - .../student/grades/widgets/grade_button.dart | 28 +- .../grades/widgets/grade_evaluation_tile.dart | 39 +- lib/features/student/student_view.dart | 38 +- .../discovery/discovery_components.dart | 499 ------------------ .../welcome/discovery/models/discovery.dart | 15 - .../discovery/models/discovery_ids.dart | 29 - .../discovery/models/group_discovery.dart | 12 - lib/main.dart | 6 +- lib/utils/locator.dart | 2 - pubspec.lock | 24 - pubspec.yaml | 2 - test/common/helpers.dart | 12 - .../app/startup/startup_viewmodel_test.dart | 197 +------ .../mocks/siren_flutter_service_mock.dart | 30 -- .../features/app/widgets/bottom_bar_test.dart | 15 +- .../dashboard/dashboard_view_test.dart | 25 +- 32 files changed, 52 insertions(+), 1526 deletions(-) delete mode 100644 lib/constants/update_code.dart delete mode 100644 lib/features/app/storage/siren_flutter_service.dart delete mode 100644 lib/features/welcome/discovery/discovery_components.dart delete mode 100644 lib/features/welcome/discovery/models/discovery.dart delete mode 100644 lib/features/welcome/discovery/models/discovery_ids.dart delete mode 100644 lib/features/welcome/discovery/models/group_discovery.dart delete mode 100644 test/features/app/storage/mocks/siren_flutter_service_mock.dart diff --git a/lib/constants/update_code.dart b/lib/constants/update_code.dart deleted file mode 100644 index c83469a96..000000000 --- a/lib/constants/update_code.dart +++ /dev/null @@ -1,5 +0,0 @@ -enum UpdateCode { - none, - ask, - force, -} diff --git a/lib/features/app/navigation/router.dart b/lib/features/app/navigation/router.dart index fa4473472..185848893 100644 --- a/lib/features/app/navigation/router.dart +++ b/lib/features/app/navigation/router.dart @@ -2,7 +2,6 @@ import 'package:flutter/material.dart'; // Project imports: -import 'package:notredame/constants/update_code.dart'; import 'package:notredame/features/app/error/not_found/not_found_view.dart'; import 'package:notredame/features/app/error/outage/outage_view.dart'; import 'package:notredame/features/app/navigation/router_paths.dart'; @@ -51,13 +50,12 @@ Route generateRoute(RouteSettings routeSettings) { builder: (_) => FaqView(backgroundColor: routeSettings.arguments! as Color)); case RouterPaths.dashboard: - final code = (routeSettings.arguments as UpdateCode?) ?? UpdateCode.none; return PageRouteBuilder( settings: RouteSettings( name: routeSettings.name, arguments: routeSettings.arguments), transitionsBuilder: (_, animation, ___, child) => rootPagesAnimation(animation, child), - pageBuilder: (_, __, ___) => DashboardView(updateCode: code)); + pageBuilder: (_, __, ___) => const DashboardView()); case RouterPaths.schedule: return PageRouteBuilder( settings: RouteSettings(name: routeSettings.name), diff --git a/lib/features/app/startup/startup_viewmodel.dart b/lib/features/app/startup/startup_viewmodel.dart index 56b559693..e749ca748 100644 --- a/lib/features/app/startup/startup_viewmodel.dart +++ b/lib/features/app/startup/startup_viewmodel.dart @@ -3,15 +3,10 @@ import 'package:stacked/stacked.dart'; // Project imports: import 'package:notredame/constants/preferences_flags.dart'; -import 'package:notredame/constants/update_code.dart'; -import 'package:notredame/features/app/analytics/analytics_service.dart'; -import 'package:notredame/features/app/error/internal_info_service.dart'; import 'package:notredame/features/app/integration/networking_service.dart'; import 'package:notredame/features/app/navigation/navigation_service.dart'; import 'package:notredame/features/app/navigation/router_paths.dart'; import 'package:notredame/features/app/repository/user_repository.dart'; -import 'package:notredame/features/app/storage/preferences_service.dart'; -import 'package:notredame/features/app/storage/siren_flutter_service.dart'; import 'package:notredame/features/more/settings/settings_manager.dart'; import 'package:notredame/utils/locator.dart'; @@ -19,10 +14,6 @@ class StartUpViewModel extends BaseViewModel { /// Manage the settings final SettingsManager _settingsManager = locator(); - /// Preferences service - /// TODO remove when everyone is moved to 4.4.6 - final PreferencesService _preferencesService = locator(); - /// Used to authenticate the user final UserRepository _userRepository = locator(); @@ -32,54 +23,14 @@ class StartUpViewModel extends BaseViewModel { /// Used to redirect on the dashboard. final NavigationService _navigationService = locator(); - /// Used to access the lib siren for updates - final SirenFlutterService _sirenFlutterService = - locator(); - - /// Internal Info Service - final InternalInfoService _internalInfoService = - locator(); - - /// Analytics - final AnalyticsService _analyticsService = locator(); - /// Try to silent authenticate the user then redirect to [LoginView] or [DashboardView] Future handleStartUp() async { if (await handleConnectivityIssues()) return; - final bool hasTheSameVersionAsBefore = await hasSameSemanticVersion(); - if (!hasTheSameVersionAsBefore) { - // TODO remove when everyone is moved to 4.4.6 - final flagsToCheck = [ - PreferencesFlag.discoveryDashboard, - PreferencesFlag.discoverySchedule, - PreferencesFlag.discoveryStudentGrade, - PreferencesFlag.discoveryGradeDetails, - PreferencesFlag.discoveryStudentProfile, - PreferencesFlag.discoveryETS, - PreferencesFlag.discoveryMore, - PreferencesFlag.languageChoice - ]; - - for (final PreferencesFlag flag in flagsToCheck) { - final Object? object = - await _preferencesService.getPreferencesFlag(flag); - - if (object is String) { - _preferencesService.removePreferencesFlag(flag); - _settingsManager.setBool(flag, object == 'true'); - } - } - - setSemanticVersionInPrefs(); - } - final bool isLogin = await _userRepository.silentAuthenticate(); if (isLogin) { - final updateStatus = await checkUpdateStatus(); - _navigationService.pushNamedAndRemoveUntil( - RouterPaths.dashboard, RouterPaths.dashboard, updateStatus); + _navigationService.pushNamedAndRemoveUntil(RouterPaths.dashboard); } else { if (await _settingsManager.getBool(PreferencesFlag.languageChoice) == null) { @@ -105,52 +56,4 @@ class StartUpViewModel extends BaseViewModel { } return false; } - - /// Check whether prefs contains the right version - Future hasSameSemanticVersion() async { - final currentVersion = - (await _internalInfoService.getPackageInfo()).version; - final versionSaved = - await _settingsManager.getString(PreferencesFlag.appVersion); - - if (versionSaved != null) { - return versionSaved == currentVersion; - } - return false; - } - - /// Set the version in the prefs to be able to retrieve it and match them together - Future setSemanticVersionInPrefs() async { - final currentVersion = - (await _internalInfoService.getPackageInfo()).version; - await _settingsManager.setString( - PreferencesFlag.appVersion, currentVersion); - } - - /// Check if the user has a new version of the app and show a message to - /// prompt him to update it. Returns the [UpdateCode] that can be used to - /// handle the update. - Future checkUpdateStatus() async { - bool isUpdateAvailable = false; - try { - isUpdateAvailable = await _sirenFlutterService.updateIsAvailable(); - } catch (e) { - _analyticsService.logError( - "Error while checking for update", e.toString()); - } - if (isUpdateAvailable) { - final latestVersion = await _sirenFlutterService.storeVersion; - final localVersion = await _sirenFlutterService.localVersion; - - if (latestVersion.major != localVersion.major || - latestVersion.minor != localVersion.minor) { - return UpdateCode.ask; - } else if (latestVersion.major == localVersion.major && - latestVersion.minor == localVersion.minor && - latestVersion.patch != localVersion.patch) { - return UpdateCode.force; - } - } - return UpdateCode.none; - } } diff --git a/lib/features/app/storage/siren_flutter_service.dart b/lib/features/app/storage/siren_flutter_service.dart deleted file mode 100644 index ce0fcbe41..000000000 --- a/lib/features/app/storage/siren_flutter_service.dart +++ /dev/null @@ -1,48 +0,0 @@ -// Flutter imports: -import 'package:flutter/cupertino.dart'; - -// Package imports: -import 'package:flutter_siren_2/flutter_siren_2.dart'; -import 'package:pub_semver/pub_semver.dart'; - -// SERVICES - -class SirenFlutterService { - late Siren _siren; - - SirenFlutterService() { - _siren = Siren(); - } - - // Check if update is available - Future updateIsAvailable() async { - return _siren.updateIsAvailable(); - } - - // The local version of the app coming from Siren package - Future get localVersion async { - final local = await _siren.localVersion; - return Version.parse(local.toString()); - } - - // The store version of the app coming from Siren package - Future get storeVersion async { - final store = await _siren.storeVersion; - return Version.parse(store.toString()); - } - - // Relay prompt update info to Siren package - Future promptUpdate(BuildContext context, - {required String title, - required String message, - String buttonUpgradeText = 'Upgrade', - String buttonCancelText = 'Cancel', - bool forceUpgrade = false}) async { - return _siren.promptUpdate(context, - title: title, - message: message, - buttonUpgradeText: buttonUpgradeText, - buttonCancelText: buttonCancelText, - forceUpgrade: forceUpgrade); - } -} diff --git a/lib/features/app/widgets/bottom_bar.dart b/lib/features/app/widgets/bottom_bar.dart index 7ea1e3752..46ff279bb 100644 --- a/lib/features/app/widgets/bottom_bar.dart +++ b/lib/features/app/widgets/bottom_bar.dart @@ -2,16 +2,12 @@ import 'package:flutter/material.dart'; // Package imports: -import 'package:feature_discovery_fork/feature_discovery.dart'; import 'package:flutter_gen/gen_l10n/app_localizations.dart'; // Project imports: import 'package:notredame/features/app/analytics/analytics_service.dart'; import 'package:notredame/features/app/navigation/navigation_service.dart'; import 'package:notredame/features/app/navigation/router_paths.dart'; -import 'package:notredame/features/welcome/discovery/discovery_components.dart'; -import 'package:notredame/features/welcome/discovery/models/discovery_ids.dart'; -import 'package:notredame/utils/app_theme.dart'; import 'package:notredame/utils/locator.dart'; /// Bottom navigation bar for the application. @@ -94,42 +90,21 @@ class _BottomBarState extends State { List _buildItems(BuildContext context) { return [ BottomNavigationBarItem( - icon: _buildDiscoveryFeatureDescriptionWidget( - context, RouterPaths.dashboard, Icons.dashboard_outlined), + icon: const Icon(Icons.dashboard_outlined), label: AppIntl.of(context)!.title_dashboard), BottomNavigationBarItem( - icon: _buildDiscoveryFeatureDescriptionWidget( - context, RouterPaths.schedule, Icons.schedule_outlined), + icon: const Icon(Icons.schedule_outlined), label: AppIntl.of(context)!.title_schedule), BottomNavigationBarItem( - icon: _buildDiscoveryFeatureDescriptionWidget( - context, RouterPaths.student, Icons.school_outlined), + icon: const Icon(Icons.school_outlined), label: AppIntl.of(context)!.title_student), BottomNavigationBarItem( - icon: _buildDiscoveryFeatureDescriptionWidget( - context, RouterPaths.ets, Icons.account_balance_outlined), + icon: const Icon(Icons.account_balance_outlined), label: AppIntl.of(context)!.title_ets), BottomNavigationBarItem( - icon: _buildDiscoveryFeatureDescriptionWidget( - context, RouterPaths.more, Icons.menu_outlined), + icon: const Icon(Icons.menu_outlined), label: AppIntl.of(context)!.title_more), ]; } - DescribedFeatureOverlay _buildDiscoveryFeatureDescriptionWidget( - BuildContext context, String routerPath, IconData icon) { - final discovery = - getDiscoveryByPath(context, DiscoveryGroupIds.bottomBar, routerPath); - - return DescribedFeatureOverlay( - overflowMode: OverflowMode.wrapBackground, - featureId: discovery.featureId, - title: Text(discovery.title, textAlign: TextAlign.justify), - description: discovery.details, - backgroundColor: AppTheme.appletsDarkPurple, - tapTarget: Icon(icon, color: AppTheme.etsBlack), - pulseDuration: const Duration(seconds: 5), - child: Icon(icon), - ); - } } diff --git a/lib/features/app/widgets/navigation_rail.dart b/lib/features/app/widgets/navigation_rail.dart index 4da67908d..5bd7b3668 100644 --- a/lib/features/app/widgets/navigation_rail.dart +++ b/lib/features/app/widgets/navigation_rail.dart @@ -2,16 +2,12 @@ import 'package:flutter/material.dart'; // Package imports: -import 'package:feature_discovery_fork/feature_discovery.dart'; import 'package:flutter_gen/gen_l10n/app_localizations.dart'; // Project imports: import 'package:notredame/features/app/analytics/analytics_service.dart'; import 'package:notredame/features/app/navigation/navigation_service.dart'; import 'package:notredame/features/app/navigation/router_paths.dart'; -import 'package:notredame/features/welcome/discovery/discovery_components.dart'; -import 'package:notredame/features/welcome/discovery/models/discovery_ids.dart'; -import 'package:notredame/utils/app_theme.dart'; import 'package:notredame/utils/locator.dart'; /// Bottom navigation bar for the application. @@ -93,42 +89,20 @@ class _NavRailState extends State { List _buildItems(BuildContext context) { return [ NavigationRailDestination( - icon: _buildDiscoveryFeatureDescriptionWidget( - context, RouterPaths.dashboard, Icons.dashboard_outlined), + icon: const Icon(Icons.dashboard_outlined), label: Text(AppIntl.of(context)!.title_dashboard)), NavigationRailDestination( - icon: _buildDiscoveryFeatureDescriptionWidget( - context, RouterPaths.schedule, Icons.schedule_outlined), + icon: const Icon(Icons.schedule_outlined), label: Text(AppIntl.of(context)!.title_schedule)), NavigationRailDestination( - icon: _buildDiscoveryFeatureDescriptionWidget( - context, RouterPaths.student, Icons.school_outlined), + icon: const Icon(Icons.school_outlined), label: Text(AppIntl.of(context)!.title_student)), NavigationRailDestination( - icon: _buildDiscoveryFeatureDescriptionWidget( - context, RouterPaths.ets, Icons.account_balance_outlined), + icon: const Icon(Icons.account_balance_outlined), label: Text(AppIntl.of(context)!.title_ets)), NavigationRailDestination( - icon: _buildDiscoveryFeatureDescriptionWidget( - context, RouterPaths.more, Icons.menu_outlined), + icon: const Icon(Icons.menu_outlined), label: Text(AppIntl.of(context)!.title_more)), ]; } - - DescribedFeatureOverlay _buildDiscoveryFeatureDescriptionWidget( - BuildContext context, String routerPath, IconData icon) { - final discovery = - getDiscoveryByPath(context, DiscoveryGroupIds.bottomBar, routerPath); - - return DescribedFeatureOverlay( - overflowMode: OverflowMode.wrapBackground, - featureId: discovery.featureId, - title: Text(discovery.title, textAlign: TextAlign.justify), - description: discovery.details, - backgroundColor: AppTheme.appletsDarkPurple, - tapTarget: Icon(icon, color: AppTheme.etsBlack), - pulseDuration: const Duration(seconds: 5), - child: Icon(icon), - ); - } } diff --git a/lib/features/dashboard/dashboard_view.dart b/lib/features/dashboard/dashboard_view.dart index e899ca225..b9e921a2f 100644 --- a/lib/features/dashboard/dashboard_view.dart +++ b/lib/features/dashboard/dashboard_view.dart @@ -1,10 +1,8 @@ // Flutter imports: import 'package:flutter/material.dart'; -import 'package:flutter/scheduler.dart'; // Package imports: import 'package:auto_size_text/auto_size_text.dart'; -import 'package:feature_discovery_fork/feature_discovery.dart'; import 'package:flutter_gen/gen_l10n/app_localizations.dart'; import 'package:font_awesome_flutter/font_awesome_flutter.dart'; import 'package:skeletonizer/skeletonizer.dart'; @@ -12,7 +10,6 @@ import 'package:stacked/stacked.dart'; // Project imports: import 'package:notredame/constants/preferences_flags.dart'; -import 'package:notredame/constants/update_code.dart'; import 'package:notredame/constants/urls.dart'; import 'package:notredame/features/app/analytics/analytics_service.dart'; import 'package:notredame/features/app/navigation/navigation_service.dart'; @@ -26,16 +23,13 @@ import 'package:notredame/features/dashboard/progress_bar_text_options.dart'; import 'package:notredame/features/dashboard/widgets/course_activity_tile.dart'; import 'package:notredame/features/dashboard/widgets/haptics_container.dart'; import 'package:notredame/features/student/grades/widgets/grade_button.dart'; -import 'package:notredame/features/welcome/discovery/discovery_components.dart'; -import 'package:notredame/features/welcome/discovery/models/discovery_ids.dart'; import 'package:notredame/utils/app_theme.dart'; import 'package:notredame/utils/loading.dart'; import 'package:notredame/utils/locator.dart'; import 'package:notredame/utils/utils.dart'; class DashboardView extends StatefulWidget { - final UpdateCode updateCode; - const DashboardView({super.key, required this.updateCode}); + const DashboardView({super.key}); @override _DashboardViewState createState() => _DashboardViewState(); @@ -51,10 +45,6 @@ class _DashboardViewState extends State @override void initState() { super.initState(); - SchedulerBinding.instance.addPostFrameCallback((Duration duration) { - DashboardViewModel.startDiscovery(context); - DashboardViewModel.promptUpdate(context, widget.updateCode); - }); DashboardViewModel.launchInAppReview(); } @@ -68,11 +58,7 @@ class _DashboardViewState extends State appBar: AppBar( title: Text(AppIntl.of(context)!.title_dashboard), centerTitle: false, - automaticallyImplyLeading: false, - actions: [ - _buildDiscoveryFeatureDescriptionWidget( - context, Icons.restore, model), - ]), + automaticallyImplyLeading: false), body: model.cards == null ? buildLoading() : RefreshIndicator( @@ -556,26 +542,4 @@ class _DashboardViewState extends State model.setOrder(elementMoved, newIndex); } - - DescribedFeatureOverlay _buildDiscoveryFeatureDescriptionWidget( - BuildContext context, IconData icon, DashboardViewModel model) { - final discovery = getDiscoveryByFeatureId(context, - DiscoveryGroupIds.bottomBar, DiscoveryIds.bottomBarDashboardRestore); - - return DescribedFeatureOverlay( - overflowMode: OverflowMode.wrapBackground, - contentLocation: ContentLocation.below, - featureId: discovery.featureId, - title: Text(discovery.title, textAlign: TextAlign.justify), - description: discovery.details, - backgroundColor: AppTheme.appletsDarkPurple, - tapTarget: Icon(icon, color: AppTheme.etsBlack), - onComplete: () => model.discoveryCompleted(), - pulseDuration: const Duration(seconds: 5), - child: IconButton( - icon: Icon(icon), - onPressed: model.setAllCardsVisible, - ), - ); - } } diff --git a/lib/features/dashboard/dashboard_viewmodel.dart b/lib/features/dashboard/dashboard_viewmodel.dart index 6ff25d414..c7d3ba874 100644 --- a/lib/features/dashboard/dashboard_viewmodel.dart +++ b/lib/features/dashboard/dashboard_viewmodel.dart @@ -5,7 +5,6 @@ import 'dart:collection'; import 'package:flutter/material.dart'; // Package imports: -import 'package:feature_discovery_fork/feature_discovery.dart'; import 'package:flutter_gen/gen_l10n/app_localizations.dart'; import 'package:fluttertoast/fluttertoast.dart'; import 'package:shared_preferences/shared_preferences.dart'; @@ -13,7 +12,6 @@ import 'package:stacked/stacked.dart'; // Project imports: import 'package:notredame/constants/preferences_flags.dart'; -import 'package:notredame/constants/update_code.dart'; import 'package:notredame/features/app/analytics/analytics_service.dart'; import 'package:notredame/features/app/analytics/remote_config_service.dart'; import 'package:notredame/features/app/integration/launch_url_service.dart'; @@ -24,12 +22,9 @@ import 'package:notredame/features/app/signets-api/models/course.dart'; import 'package:notredame/features/app/signets-api/models/course_activity.dart'; import 'package:notredame/features/app/signets-api/models/session.dart'; import 'package:notredame/features/app/storage/preferences_service.dart'; -import 'package:notredame/features/app/storage/siren_flutter_service.dart'; import 'package:notredame/features/dashboard/progress_bar_text_options.dart'; import 'package:notredame/features/more/feedback/in_app_review_service.dart'; import 'package:notredame/features/more/settings/settings_manager.dart'; -import 'package:notredame/features/welcome/discovery/discovery_components.dart'; -import 'package:notredame/features/welcome/discovery/models/discovery_ids.dart'; import 'package:notredame/utils/activity_code.dart'; import 'package:notredame/utils/locator.dart'; @@ -48,9 +43,6 @@ class DashboardViewModel extends FutureViewModel> { /// Localization class of the application. final AppIntl _appIntl; - /// Update code that must be used to prompt user for update if necessary. - UpdateCode? updateCode; - /// Cards to display on dashboard List? _cardsToDisplay; @@ -417,28 +409,6 @@ class DashboardViewModel extends FutureViewModel> { bool isSameDay(DateTime a, DateTime b) => a.year == b.year && a.month == b.month && a.day == b.day; - /// Start discovery is needed - static Future startDiscovery(BuildContext context) async { - final SettingsManager settingsManager = locator(); - if (await settingsManager.getBool(PreferencesFlag.discoveryDashboard) == - null) { - if (!context.mounted) return; - final List ids = - findDiscoveriesByGroupName(context, DiscoveryGroupIds.bottomBar) - .map((e) => e.featureId) - .toList(); - - FeatureDiscovery.discoverFeatures(context, ids); - } - } - - /// Mark as complete the discovery step - Future discoveryCompleted() async { - await _settingsManager.setBool(PreferencesFlag.discoveryDashboard, true); - - return true; - } - /// Get the list of courses for the Grades card. Future> futureToRunGrades() async { if (!busy(courses)) { @@ -484,48 +454,6 @@ class DashboardViewModel extends FutureViewModel> { return courses; } - /// Prompt the update for the app if the navigation service arguments passed - /// is not none. When [UpdateCode] is forced, the user will be force to update. - /// If [UpdateCode] is not forced, the user will be prompted to update. - static Future promptUpdate( - BuildContext context, UpdateCode? updateCode) async { - if (updateCode != null && updateCode != UpdateCode.none) { - final appIntl = AppIntl.of(context); - - bool isAForcedUpdate = false; - String message = ''; - switch (updateCode) { - case UpdateCode.force: - isAForcedUpdate = true; - message = appIntl!.update_version_message_force; - case UpdateCode.ask: - isAForcedUpdate = false; - message = appIntl!.update_version_message; - case UpdateCode.none: - return; - } - final prefService = locator(); - final sirenService = locator(); - - final storeVersion = await sirenService.storeVersion; - - final versionStoredInPrefs = - await prefService.getString(PreferencesFlag.updateAskedVersion); - - if (versionStoredInPrefs != storeVersion.toString()) { - // ignore: use_build_context_synchronously - await sirenService.promptUpdate(context, - title: appIntl.update_version_title, - message: message, - buttonUpgradeText: appIntl.update_version_button_text, - buttonCancelText: appIntl.close_button_text, - forceUpgrade: isAForcedUpdate); - } - prefService.setString( - PreferencesFlag.updateAskedVersion, storeVersion.toString()); - } - } - Future futureToRunBroadcast() async { setBusyForObject(broadcastMessage, true); setBusyForObject(broadcastTitle, true); diff --git a/lib/features/more/more_view.dart b/lib/features/more/more_view.dart index 8369907fa..5260b1b12 100644 --- a/lib/features/more/more_view.dart +++ b/lib/features/more/more_view.dart @@ -1,10 +1,8 @@ // Flutter imports: import 'package:flutter/gestures.dart'; import 'package:flutter/material.dart'; -import 'package:flutter/scheduler.dart'; // Package imports: -import 'package:feature_discovery_fork/feature_discovery.dart'; import 'package:flutter_gen/gen_l10n/app_localizations.dart'; import 'package:stacked/stacked.dart'; @@ -13,8 +11,6 @@ import 'package:notredame/features/app/analytics/analytics_service.dart'; import 'package:notredame/features/app/navigation/router_paths.dart'; import 'package:notredame/features/app/widgets/base_scaffold.dart'; import 'package:notredame/features/more/more_viewmodel.dart'; -import 'package:notredame/features/welcome/discovery/discovery_components.dart'; -import 'package:notredame/features/welcome/discovery/models/discovery_ids.dart'; import 'package:notredame/utils/app_theme.dart'; import 'package:notredame/utils/locator.dart'; import 'package:notredame/utils/utils.dart'; @@ -29,15 +25,6 @@ class _MoreViewState extends State { static const String tag = "MoreView"; bool isDiscoveryOverlayActive = false; - @override - void initState() { - super.initState(); - - SchedulerBinding.instance.addPostFrameCallback((Duration duration) { - MoreViewModel.startDiscovery(context); - }); - } - /// Returns right icon color for discovery depending on theme. Widget getProperIconAccordingToTheme(IconData icon) { return (Theme.of(context).brightness == Brightness.dark && @@ -85,9 +72,7 @@ class _MoreViewState extends State { children: [ ListTile( title: Text(AppIntl.of(context)!.more_about_applets_title), - leading: _buildDiscoveryFeatureDescriptionWidget( - context, - Hero( + leading: Hero( tag: 'about', child: Image.asset( "assets/images/favicon_applets.png", @@ -95,20 +80,13 @@ class _MoreViewState extends State { width: 24, ), ), - DiscoveryIds.detailsMoreThankYou, - model), onTap: () { _analyticsService.logEvent(tag, "About App|ETS clicked"); model.navigationService.pushNamed(RouterPaths.about); }), ListTile( title: Text(AppIntl.of(context)!.more_report_bug), - leading: _buildDiscoveryFeatureDescriptionWidget( - context, - getProperIconAccordingToTheme( - Icons.bug_report_outlined), - DiscoveryIds.detailsMoreBugReport, - model), + leading: getProperIconAccordingToTheme(Icons.bug_report_outlined), onTap: () { _analyticsService.logEvent(tag, "Report a bug clicked"); model.navigationService.pushNamed(RouterPaths.feedback); @@ -122,11 +100,7 @@ class _MoreViewState extends State { }), ListTile( title: Text(AppIntl.of(context)!.more_contributors), - leading: _buildDiscoveryFeatureDescriptionWidget( - context, - getProperIconAccordingToTheme(Icons.people_outline), - DiscoveryIds.detailsMoreContributors, - model), + leading: getProperIconAccordingToTheme(Icons.people_outline), onTap: () { _analyticsService.logEvent(tag, "Contributors clicked"); model.navigationService @@ -167,12 +141,7 @@ class _MoreViewState extends State { }), ListTile( title: Text(AppIntl.of(context)!.need_help), - leading: _buildDiscoveryFeatureDescriptionWidget( - context, - getProperIconAccordingToTheme( - Icons.question_answer_outlined), - DiscoveryIds.detailsMoreFaq, - model), + leading: getProperIconAccordingToTheme(Icons.question_answer_outlined), onTap: () { _analyticsService.logEvent(tag, "FAQ clicked"); model.navigationService.pushNamed(RouterPaths.faq, @@ -181,11 +150,7 @@ class _MoreViewState extends State { }), ListTile( title: Text(AppIntl.of(context)!.settings_title), - leading: _buildDiscoveryFeatureDescriptionWidget( - context, - getProperIconAccordingToTheme(Icons.settings_outlined), - DiscoveryIds.detailsMoreSettings, - model), + leading: getProperIconAccordingToTheme(Icons.settings_outlined), onTap: () { _analyticsService.logEvent(tag, "Settings clicked"); model.navigationService.pushNamed(RouterPaths.settings); @@ -224,36 +189,4 @@ class _MoreViewState extends State { ); }); } - - DescribedFeatureOverlay _buildDiscoveryFeatureDescriptionWidget( - BuildContext context, - Widget icon, - String featuredId, - MoreViewModel model) { - final discovery = getDiscoveryByFeatureId( - context, DiscoveryGroupIds.pageMore, featuredId); - - return DescribedFeatureOverlay( - overflowMode: OverflowMode.wrapBackground, - contentLocation: ContentLocation.below, - featureId: discovery.featureId, - title: Text(discovery.title, textAlign: TextAlign.justify), - description: discovery.details, - backgroundColor: AppTheme.appletsDarkPurple, - tapTarget: icon, - pulseDuration: const Duration(seconds: 5), - child: icon, - onComplete: () { - setState(() { - isDiscoveryOverlayActive = false; - }); - return model.discoveryCompleted(); - }, - onOpen: () async { - setState(() { - isDiscoveryOverlayActive = true; - }); - return true; - }); - } } diff --git a/lib/features/more/more_viewmodel.dart b/lib/features/more/more_viewmodel.dart index cddeecb75..e2d3a391c 100644 --- a/lib/features/more/more_viewmodel.dart +++ b/lib/features/more/more_viewmodel.dart @@ -2,7 +2,6 @@ import 'package:flutter/material.dart'; // Package imports: -import 'package:feature_discovery_fork/feature_discovery.dart'; import 'package:flutter_gen/gen_l10n/app_localizations.dart'; import 'package:fluttertoast/fluttertoast.dart'; import 'package:package_info_plus/package_info_plus.dart'; @@ -20,8 +19,6 @@ import 'package:notredame/features/app/storage/cache_manager.dart'; import 'package:notredame/features/app/storage/preferences_service.dart'; import 'package:notredame/features/more/feedback/in_app_review_service.dart'; import 'package:notredame/features/more/settings/settings_manager.dart'; -import 'package:notredame/features/welcome/discovery/discovery_components.dart'; -import 'package:notredame/features/welcome/discovery/models/discovery_ids.dart'; import 'package:notredame/utils/locator.dart'; class MoreViewModel extends FutureViewModel { @@ -102,35 +99,6 @@ class MoreViewModel extends FutureViewModel { setBusy(false); } - /// Start the discovery of this page if needed - static Future startDiscovery(BuildContext context) async { - final SettingsManager settingsManager = locator(); - - if (await settingsManager.getBool(PreferencesFlag.discoveryMore) == null) { - if (!context.mounted) return; - final List ids = - findDiscoveriesByGroupName(context, DiscoveryGroupIds.pageMore) - .map((e) => e.featureId) - .toList(); - - Future.delayed( - const Duration(milliseconds: 700), - () => { - if (context.mounted) - {FeatureDiscovery.discoverFeatures(context, ids)} - }); - - settingsManager.setBool(PreferencesFlag.discoveryMore, true); - } - } - - /// Mark the discovery of this page completed - Future discoveryCompleted() async { - await _settingsManager.setBool(PreferencesFlag.discoveryMore, true); - - return true; - } - static Future launchInAppReview() async { final PreferencesService preferencesService = locator(); final InAppReviewService inAppReviewService = locator(); diff --git a/lib/features/schedule/schedule_view.dart b/lib/features/schedule/schedule_view.dart index b74ccc7b8..2ef926e8c 100644 --- a/lib/features/schedule/schedule_view.dart +++ b/lib/features/schedule/schedule_view.dart @@ -1,13 +1,12 @@ // Flutter imports: import 'package:flutter/material.dart'; -import 'package:flutter/scheduler.dart'; import 'package:flutter/services.dart'; // Package imports: import 'package:calendar_view/calendar_view.dart' as calendar_view; -import 'package:feature_discovery_fork/feature_discovery.dart'; import 'package:flutter_gen/gen_l10n/app_localizations.dart'; import 'package:intl/intl.dart'; +import 'package:notredame/features/schedule/widgets/schedule_settings.dart'; import 'package:notredame/utils/calendar_utils.dart'; import 'package:stacked/stacked.dart'; import 'package:table_calendar/table_calendar.dart'; @@ -21,9 +20,6 @@ import 'package:notredame/features/dashboard/widgets/course_activity_tile.dart'; import 'package:notredame/features/schedule/schedule_viewmodel.dart'; import 'package:notredame/features/schedule/widgets/calendar_selector.dart'; import 'package:notredame/features/schedule/widgets/schedule_calendar_tile.dart'; -import 'package:notredame/features/schedule/widgets/schedule_settings.dart'; -import 'package:notredame/features/welcome/discovery/discovery_components.dart'; -import 'package:notredame/features/welcome/discovery/models/discovery_ids.dart'; import 'package:notredame/utils/app_theme.dart'; import 'package:notredame/utils/locator.dart'; @@ -62,10 +58,6 @@ class _ScheduleViewState extends State ); _animationController.forward(); - - SchedulerBinding.instance.addPostFrameCallback((Duration duration) { - ScheduleViewModel.startDiscovery(context); - }); } @override @@ -585,35 +577,7 @@ class _ScheduleViewState extends State monthViewKey.currentState?.animateToMonth(DateTime(DateTime.now().year, DateTime.now().month)); } })), - _buildDiscoveryFeatureDescriptionWidget( - context, - Icons.settings_outlined, - model, - ), - ]; - - DescribedFeatureOverlay _buildDiscoveryFeatureDescriptionWidget( - BuildContext context, IconData icon, ScheduleViewModel model) { - final discovery = getDiscoveryByFeatureId( - context, - DiscoveryGroupIds.pageSchedule, - DiscoveryIds.detailsScheduleSettings, - ); - - return DescribedFeatureOverlay( - overflowMode: OverflowMode.wrapBackground, - contentLocation: ContentLocation.below, - featureId: discovery.featureId, - title: Text(discovery.title, textAlign: TextAlign.justify), - description: discovery.details, - backgroundColor: AppTheme.appletsDarkPurple, - tapTarget: Icon(icon, color: AppTheme.etsBlack), - pulseDuration: const Duration(seconds: 5), - onComplete: () => model.discoveryCompleted(), - child: IconButton( - icon: const Icon(Icons.settings_outlined), - onPressed: () async { - _analyticsService.logEvent(tag, "Settings clicked"); + IconButton(icon: const Icon(Icons.settings_outlined), onPressed: () async { await showModalBottomSheet( shape: const RoundedRectangleBorder( borderRadius: BorderRadius.vertical( @@ -624,8 +588,7 @@ class _ScheduleViewState extends State isScrollControlled: true, builder: (context) => const ScheduleSettings()); model.loadSettings(); - }, - ), - ); - } + }), + ]; + } diff --git a/lib/features/schedule/schedule_viewmodel.dart b/lib/features/schedule/schedule_viewmodel.dart index dada87452..eb528038b 100644 --- a/lib/features/schedule/schedule_viewmodel.dart +++ b/lib/features/schedule/schedule_viewmodel.dart @@ -5,7 +5,6 @@ import 'package:flutter/material.dart'; import 'package:calendar_view/calendar_view.dart'; import 'package:collection/collection.dart'; import 'package:enum_to_string/enum_to_string.dart'; -import 'package:feature_discovery_fork/feature_discovery.dart'; import 'package:flutter_gen/gen_l10n/app_localizations.dart'; import 'package:fluttertoast/fluttertoast.dart'; import 'package:stacked/stacked.dart'; @@ -18,8 +17,6 @@ import 'package:notredame/features/app/signets-api/models/course.dart'; import 'package:notredame/features/app/signets-api/models/course_activity.dart'; import 'package:notredame/features/app/signets-api/models/schedule_activity.dart'; import 'package:notredame/features/more/settings/settings_manager.dart'; -import 'package:notredame/features/welcome/discovery/discovery_components.dart'; -import 'package:notredame/features/welcome/discovery/models/discovery_ids.dart'; import 'package:notredame/utils/activity_code.dart'; import 'package:notredame/utils/app_theme.dart'; import 'package:notredame/utils/locator.dart'; @@ -471,30 +468,4 @@ class ScheduleViewModel extends FutureViewModel> { return !isThisMonthSelected; } - - /// Start Discovery if needed. - static Future startDiscovery(BuildContext context) async { - final SettingsManager settingsManager = locator(); - - if (await settingsManager.getBool(PreferencesFlag.discoverySchedule) == - null) { - if (!context.mounted) return; - final List ids = - findDiscoveriesByGroupName(context, DiscoveryGroupIds.pageSchedule) - .map((e) => e.featureId) - .toList(); - - Future.delayed(const Duration(milliseconds: 700), () { - if (!context.mounted) return; - FeatureDiscovery.discoverFeatures(context, ids); - }); - } - } - - /// Mark the discovery of this view completed - Future discoveryCompleted() async { - await _settingsManager.setBool(PreferencesFlag.discoverySchedule, true); - - return true; - } } diff --git a/lib/features/student/grades/grade_details/grade_details_view.dart b/lib/features/student/grades/grade_details/grade_details_view.dart index 0e71aef9f..81e80aae4 100644 --- a/lib/features/student/grades/grade_details/grade_details_view.dart +++ b/lib/features/student/grades/grade_details/grade_details_view.dart @@ -1,6 +1,5 @@ // Flutter imports: import 'package:flutter/material.dart'; -import 'package:flutter/scheduler.dart'; // Package imports: import 'package:flutter_gen/gen_l10n/app_localizations.dart'; @@ -44,10 +43,6 @@ class _GradesDetailsViewState extends State }); } }); - - SchedulerBinding.instance.addPostFrameCallback((Duration duration) { - GradesDetailsViewModel.startDiscovery(context); - }); } @override @@ -257,8 +252,6 @@ class _GradesDetailsViewState extends State evaluation, completed: _completed, key: Key("GradeEvaluationTile_${evaluation.title}"), - isFirstEvaluation: - evaluation == model.course.summary?.evaluations.first, ), const SizedBox(height: 24) ]), diff --git a/lib/features/student/grades/grade_details/grades_details_viewmodel.dart b/lib/features/student/grades/grade_details/grades_details_viewmodel.dart index 2d4245a5a..947526553 100644 --- a/lib/features/student/grades/grade_details/grades_details_viewmodel.dart +++ b/lib/features/student/grades/grade_details/grades_details_viewmodel.dart @@ -1,20 +1,12 @@ -// Flutter imports: -import 'package:flutter/material.dart'; - // Package imports: -import 'package:feature_discovery_fork/feature_discovery.dart'; import 'package:flutter_gen/gen_l10n/app_localizations.dart'; import 'package:fluttertoast/fluttertoast.dart'; import 'package:stacked/stacked.dart'; // Project imports: -import 'package:notredame/constants/preferences_flags.dart'; import 'package:notredame/features/app/repository/course_repository.dart'; import 'package:notredame/features/app/signets-api/models/course.dart'; import 'package:notredame/features/app/signets-api/models/signets_errors.dart'; -import 'package:notredame/features/more/settings/settings_manager.dart'; -import 'package:notredame/features/welcome/discovery/discovery_components.dart'; -import 'package:notredame/features/welcome/discovery/models/discovery_ids.dart'; import 'package:notredame/utils/api_exception.dart'; import 'package:notredame/utils/locator.dart'; @@ -71,24 +63,4 @@ class GradesDetailsViewModel extends FutureViewModel { setBusyForObject(course, false); } } - - /// Start the discovery process of this page if needed - static Future startDiscovery(BuildContext context) async { - final SettingsManager settingsManager = locator(); - if (await settingsManager.getBool(PreferencesFlag.discoveryGradeDetails) == - null) { - if (!context.mounted) return; - final List ids = findDiscoveriesByGroupName( - context, DiscoveryGroupIds.pageGradeDetails) - .map((e) => e.featureId) - .toList(); - - Future.delayed(const Duration(seconds: 1), () { - if (!context.mounted) return; - FeatureDiscovery.discoverFeatures(context, ids); - }); - - settingsManager.setBool(PreferencesFlag.discoveryGradeDetails, true); - } - } } diff --git a/lib/features/student/grades/grades_view.dart b/lib/features/student/grades/grades_view.dart index 1ad5248b3..9d82b64d5 100644 --- a/lib/features/student/grades/grades_view.dart +++ b/lib/features/student/grades/grades_view.dart @@ -1,6 +1,5 @@ // Flutter imports: import 'package:flutter/material.dart'; -import 'package:flutter/scheduler.dart'; // Package imports: import 'package:flutter_gen/gen_l10n/app_localizations.dart'; @@ -8,7 +7,6 @@ import 'package:flutter_staggered_animations/flutter_staggered_animations.dart'; import 'package:stacked/stacked.dart'; // Project imports: -import 'package:notredame/features/app/analytics/analytics_service.dart'; import 'package:notredame/features/app/navigation/navigation_service.dart'; import 'package:notredame/features/app/navigation/router_paths.dart'; import 'package:notredame/features/app/signets-api/models/course.dart'; @@ -24,22 +22,9 @@ class GradesView extends StatefulWidget { } class _GradesViewState extends State { - final AnalyticsService _analyticsService = locator(); - /// Used to redirect on the dashboard. final NavigationService _navigationService = locator(); - @override - void initState() { - super.initState(); - - SchedulerBinding.instance.addPostFrameCallback((Duration duration) { - GradesViewModel.startDiscovery(context); - }); - - _analyticsService.logEvent("GradesView", "Opened"); - } - @override Widget build(BuildContext context) { return ViewModelBuilder.reactive( @@ -120,8 +105,7 @@ class _GradesViewState extends State { const SizedBox(height: 16.0), Wrap( children: courses - .map((course) => - GradeButton(course, showDiscovery: index == 0)) + .map((course) => GradeButton(course)) .toList(), ), ], diff --git a/lib/features/student/grades/grades_viewmodel.dart b/lib/features/student/grades/grades_viewmodel.dart index 44670ec0f..57bf283b5 100644 --- a/lib/features/student/grades/grades_viewmodel.dart +++ b/lib/features/student/grades/grades_viewmodel.dart @@ -1,20 +1,12 @@ -// Flutter imports: -import 'package:flutter/material.dart'; - // Package imports: -import 'package:feature_discovery_fork/feature_discovery.dart'; import 'package:flutter_gen/gen_l10n/app_localizations.dart'; import 'package:fluttertoast/fluttertoast.dart'; import 'package:stacked/stacked.dart'; // Project imports: -import 'package:notredame/constants/preferences_flags.dart'; import 'package:notredame/features/app/repository/course_repository.dart'; import 'package:notredame/features/app/signets-api/models/course.dart'; -import 'package:notredame/features/more/settings/settings_manager.dart'; import 'package:notredame/features/student/semester_codes.dart'; -import 'package:notredame/features/welcome/discovery/discovery_components.dart'; -import 'package:notredame/features/welcome/discovery/models/discovery_ids.dart'; import 'package:notredame/utils/locator.dart'; class GradesViewModel extends FutureViewModel>> { @@ -111,24 +103,4 @@ class GradesViewModel extends FutureViewModel>> { return -1; }); } - - static Future startDiscovery(BuildContext context) async { - final SettingsManager settingsManager = locator(); - - if (await settingsManager.getBool(PreferencesFlag.discoveryStudentGrade) == - null) { - if (!context.mounted) return; - final List ids = - findDiscoveriesByGroupName(context, DiscoveryGroupIds.pageStudent) - .map((e) => e.featureId) - .toList(); - - Future.delayed(const Duration(seconds: 1), () { - if (!context.mounted) return; - FeatureDiscovery.discoverFeatures(context, ids); - }); - - settingsManager.setBool(PreferencesFlag.discoveryStudentGrade, true); - } - } } diff --git a/lib/features/student/grades/widgets/grade_button.dart b/lib/features/student/grades/widgets/grade_button.dart index 5be14876d..a29c9e05e 100644 --- a/lib/features/student/grades/widgets/grade_button.dart +++ b/lib/features/student/grades/widgets/grade_button.dart @@ -2,7 +2,6 @@ import 'package:flutter/material.dart'; // Package imports: -import 'package:feature_discovery_fork/feature_discovery.dart'; import 'package:flutter_gen/gen_l10n/app_localizations.dart'; import 'package:skeletonizer/skeletonizer.dart'; @@ -12,14 +11,11 @@ import 'package:notredame/features/app/navigation/navigation_service.dart'; import 'package:notredame/features/app/navigation/router_paths.dart'; import 'package:notredame/features/app/signets-api/models/course.dart'; import 'package:notredame/features/more/settings/settings_manager.dart'; -import 'package:notredame/features/welcome/discovery/discovery_components.dart'; -import 'package:notredame/features/welcome/discovery/models/discovery_ids.dart'; import 'package:notredame/utils/app_theme.dart'; import 'package:notredame/utils/locator.dart'; class GradeButton extends StatelessWidget { final Course course; - final bool showDiscovery; final Color? color; /// Used to redirect on the dashboard. @@ -28,7 +24,7 @@ class GradeButton extends StatelessWidget { /// Settings manager final SettingsManager _settingsManager = locator(); - GradeButton(this.course, {this.color, this.showDiscovery = false}); + GradeButton(this.course, {this.color}); @override Widget build(BuildContext context) => Card( @@ -45,10 +41,7 @@ class GradeButton extends StatelessWidget { arguments: course); } }, - child: showDiscovery - ? _buildDiscoveryFeatureDescriptionWidget( - context, _buildGradeButton(context)) - : _buildGradeButton(context), + child: _buildGradeButton(context), ), ); @@ -121,21 +114,4 @@ class GradeButton extends StatelessWidget { ), ); } - - DescribedFeatureOverlay _buildDiscoveryFeatureDescriptionWidget( - BuildContext context, Widget gradeButton) { - final discovery = getDiscoveryByFeatureId(context, - DiscoveryGroupIds.pageStudent, DiscoveryIds.detailsStudentGradeButton); - - return DescribedFeatureOverlay( - overflowMode: OverflowMode.wrapBackground, - contentLocation: ContentLocation.below, - featureId: discovery.featureId, - title: Text(discovery.title, textAlign: TextAlign.justify), - description: discovery.details, - backgroundColor: AppTheme.appletsDarkPurple, - tapTarget: gradeButton, - pulseDuration: const Duration(seconds: 5), - child: gradeButton); - } } diff --git a/lib/features/student/grades/widgets/grade_evaluation_tile.dart b/lib/features/student/grades/widgets/grade_evaluation_tile.dart index d0dc63f1c..0c27b2c3c 100644 --- a/lib/features/student/grades/widgets/grade_evaluation_tile.dart +++ b/lib/features/student/grades/widgets/grade_evaluation_tile.dart @@ -5,25 +5,21 @@ import 'dart:math'; import 'package:flutter/material.dart'; // Package imports: -import 'package:feature_discovery_fork/feature_discovery.dart'; import 'package:flutter_gen/gen_l10n/app_localizations.dart'; import 'package:intl/intl.dart'; // Project imports: import 'package:notredame/features/app/signets-api/models/course_evaluation.dart'; import 'package:notredame/features/student/grades/widgets/grade_circular_progress.dart'; -import 'package:notredame/features/welcome/discovery/discovery_components.dart'; -import 'package:notredame/features/welcome/discovery/models/discovery_ids.dart'; import 'package:notredame/utils/app_theme.dart'; import 'package:notredame/utils/utils.dart'; class GradeEvaluationTile extends StatefulWidget { final bool completed; final CourseEvaluation evaluation; - final bool isFirstEvaluation; const GradeEvaluationTile(this.evaluation, - {super.key, this.completed = false, this.isFirstEvaluation = false}); + {super.key, this.completed = false}); @override _GradeEvaluationTileState createState() => _GradeEvaluationTileState(); @@ -84,9 +80,7 @@ class _GradeEvaluationTileState extends State leading: FractionallySizedBox( heightFactor: 1.3, child: LayoutBuilder( - builder: (context, constraints) { - final GradeCircularProgress circularProgress = - GradeCircularProgress( + builder: (context, constraints) => GradeCircularProgress( constraints.maxHeight / 100, completed: widget.completed, key: Key( @@ -99,17 +93,7 @@ class _GradeEvaluationTileState extends State widget.evaluation.passMark, widget.evaluation.correctedEvaluationOutOfFormatted, ), - ); - - if (widget.isFirstEvaluation) { - return _buildDiscoveryFeatureDescriptionWidget( - context, - circularProgress, - DiscoveryIds.detailsGradeDetailsEvaluations); - } - - return circularProgress; - }, + ), ), ), title: Padding( @@ -256,21 +240,4 @@ class _GradeEvaluationTileState extends State return AppIntl.of(context)!.grades_grade_with_percentage( double.parse(formattedResult), maxGrade, percentage); } - - DescribedFeatureOverlay _buildDiscoveryFeatureDescriptionWidget( - BuildContext context, Widget circularProgressBar, String featuredId) { - final discovery = getDiscoveryByFeatureId( - context, DiscoveryGroupIds.pageGradeDetails, featuredId); - - return DescribedFeatureOverlay( - overflowMode: OverflowMode.wrapBackground, - contentLocation: ContentLocation.below, - featureId: discovery.featureId, - title: Text(discovery.title, textAlign: TextAlign.justify), - description: discovery.details, - backgroundColor: AppTheme.appletsDarkPurple, - tapTarget: circularProgressBar, - pulseDuration: const Duration(seconds: 5), - child: circularProgressBar); - } } diff --git a/lib/features/student/student_view.dart b/lib/features/student/student_view.dart index c9ea376d7..7996b8098 100644 --- a/lib/features/student/student_view.dart +++ b/lib/features/student/student_view.dart @@ -2,16 +2,12 @@ import 'package:flutter/material.dart'; // Package imports: -import 'package:feature_discovery_fork/feature_discovery.dart'; import 'package:flutter_gen/gen_l10n/app_localizations.dart'; // Project imports: import 'package:notredame/features/app/widgets/base_scaffold.dart'; import 'package:notredame/features/student/grades/grades_view.dart'; import 'package:notredame/features/student/profile/profile_view.dart'; -import 'package:notredame/features/welcome/discovery/discovery_components.dart'; -import 'package:notredame/features/welcome/discovery/models/discovery_ids.dart'; -import 'package:notredame/utils/app_theme.dart'; class StudentView extends StatefulWidget { @override @@ -54,12 +50,7 @@ class _StudentViewState extends State { : Colors.black, tabs: List.generate( tabs.length, - (index) => index == 1 - ? _buildDiscoveryFeatureDescriptionWidget( - context, tabs, index) - : Tab( - text: tabs[index], - ), + (index) => Tab(text: tabs[index]), ), ), ), @@ -76,31 +67,4 @@ class _StudentViewState extends State { ), ); } - - DescribedFeatureOverlay _buildDiscoveryFeatureDescriptionWidget( - BuildContext context, List tabs, int index) { - final discovery = getDiscoveryByFeatureId(context, - DiscoveryGroupIds.pageStudent, DiscoveryIds.detailsStudentProfile); - - return DescribedFeatureOverlay( - overflowMode: OverflowMode.wrapBackground, - contentLocation: ContentLocation.below, - featureId: discovery.featureId, - title: Text(discovery.title, textAlign: TextAlign.justify), - description: discovery.details, - backgroundColor: AppTheme.appletsDarkPurple, - tapTarget: Tab( - child: Text( - tabs[index], - style: (Theme.of(context).brightness == Brightness.dark) - ? const TextStyle(color: Colors.black) - : null, - ), - ), - pulseDuration: const Duration(seconds: 5), - child: Tab( - text: tabs[index], - ), - ); - } } diff --git a/lib/features/welcome/discovery/discovery_components.dart b/lib/features/welcome/discovery/discovery_components.dart deleted file mode 100644 index 88155023b..000000000 --- a/lib/features/welcome/discovery/discovery_components.dart +++ /dev/null @@ -1,499 +0,0 @@ -// Flutter imports: -import 'package:flutter/material.dart'; - -// Package imports: -import 'package:feature_discovery_fork/feature_discovery.dart'; -import 'package:flutter_gen/gen_l10n/app_localizations.dart'; - -// Project imports: -import 'package:notredame/constants/preferences_flags.dart'; -import 'package:notredame/features/app/navigation/router_paths.dart'; -import 'package:notredame/features/more/settings/settings_manager.dart'; -import 'package:notredame/features/welcome/discovery/models/discovery.dart'; -import 'package:notredame/features/welcome/discovery/models/discovery_ids.dart'; -import 'package:notredame/features/welcome/discovery/models/group_discovery.dart'; -import 'package:notredame/utils/app_theme.dart'; -import 'package:notredame/utils/locator.dart'; - -List discoveryComponents(BuildContext context) { - return [ - GroupDiscovery(name: DiscoveryGroupIds.bottomBar, discoveries: [ - Discovery( - path: RouterPaths.dashboard, - featureId: DiscoveryIds.bottomBarDashboard, - title: "", - details: ConstrainedBox( - constraints: BoxConstraints( - maxHeight: MediaQuery.of(context).size.height * 0.6), - child: Column( - children: [ - _buildHeader( - AppIntl.of(context)!.discovery_navbar_dashboard_title, - context), - Expanded( - child: ListView( - padding: EdgeInsets.zero, - children: [ - Text(AppIntl.of(context)! - .discovery_navbar_dashboard_details), - const Text('\n'), - if (AppIntl.of(context)!.localeName == "fr") - Image.asset( - 'assets/animations/discovery/fr/dashboard_swipe.gif') - else - Image.asset( - 'assets/animations/discovery/en/dashboard_swipe.gif'), - ], - ), - ), - ], - ), - ), - ), - Discovery( - path: '', - featureId: DiscoveryIds.bottomBarDashboardRestore, - title: AppIntl.of(context)!.dashboard_restore_all_cards_title, - details: ConstrainedBox( - constraints: BoxConstraints( - maxHeight: MediaQuery.of(context).size.height * 0.4), - child: Column( - children: [ - Expanded( - child: ListView( - padding: EdgeInsets.zero, - children: [ - _buildSkipDiscoveryButton(context), - Text( - AppIntl.of(context)!.discovery_page_dashboard_restore, - ), - const Text('\n'), - if (AppIntl.of(context)!.localeName == "fr") - Image.asset( - 'assets/animations/discovery/fr/dashboard_restore.gif') - else - Image.asset( - 'assets/animations/discovery/en/dashboard_restore.gif'), - ], - ), - ), - ], - ), - ), - ), - Discovery( - path: RouterPaths.schedule, - featureId: DiscoveryIds.bottomBarSchedule, - title: "", - details: ConstrainedBox( - constraints: BoxConstraints( - maxHeight: MediaQuery.of(context).size.height * 0.6), - child: Column( - children: [ - _buildHeader(AppIntl.of(context)!.discovery_navbar_schedule_title, - context), - Expanded( - child: ListView( - padding: EdgeInsets.zero, - children: [ - Text(AppIntl.of(context)!.discovery_navbar_schedule_details, - textAlign: TextAlign.justify), - const Text('\n'), - if (AppIntl.of(context)!.localeName == "fr") - Image.asset( - 'assets/animations/discovery/fr/schedule_calendar.png') - else - Image.asset( - 'assets/animations/discovery/en/schedule_calendar.png'), - ], - ), - ), - ], - ), - ), - ), - Discovery( - path: RouterPaths.student, - featureId: DiscoveryIds.bottomBarStudent, - title: "", - details: ConstrainedBox( - constraints: BoxConstraints( - maxHeight: MediaQuery.of(context).size.height * 0.6), - child: Column( - children: [ - _buildHeader( - AppIntl.of(context)!.discovery_navbar_student_title, context), - Expanded( - child: ListView( - padding: EdgeInsets.zero, - children: [ - Text(AppIntl.of(context)!.discovery_navbar_student_details, - textAlign: TextAlign.justify), - const Text('\n'), - if (AppIntl.of(context)!.localeName == "fr") - Image.asset( - 'assets/animations/discovery/fr/grade_details.gif') - else - Image.asset( - 'assets/animations/discovery/en/grade_details.gif'), - ], - ), - ), - ], - ), - ), - ), - Discovery( - path: RouterPaths.ets, - featureId: DiscoveryIds.bottomBarETS, - title: "", - details: ConstrainedBox( - constraints: BoxConstraints( - maxHeight: MediaQuery.of(context).size.height * 0.6), - child: Column( - children: [ - _buildHeader( - AppIntl.of(context)!.discovery_navbar_ets_title, context), - Expanded( - child: ListView( - padding: EdgeInsets.zero, - children: [ - Text(AppIntl.of(context)!.discovery_navbar_ets_details, - textAlign: TextAlign.justify), - const Text('\n'), - if (AppIntl.of(context)!.localeName == "fr") - Image.asset('assets/animations/discovery/fr/ets_link.gif') - else - Image.asset( - 'assets/animations/discovery/en/ets_link.gif'), - ], - ), - ), - ], - ), - ), - ), - Discovery( - path: RouterPaths.more, - featureId: DiscoveryIds.bottomBarMore, - title: "", - details: ConstrainedBox( - constraints: BoxConstraints( - maxHeight: MediaQuery.of(context).size.height * 0.6), - child: Column( - children: [ - _buildHeader( - AppIntl.of(context)!.discovery_navbar_more_title, context), - Expanded( - child: ListView( - padding: EdgeInsets.zero, - children: [ - Text(AppIntl.of(context)!.discovery_navbar_more_details, - textAlign: TextAlign.justify), - const Text('\n'), - if (AppIntl.of(context)!.localeName == "fr") - Image.asset('assets/animations/discovery/fr/more.jpg') - else - Image.asset('assets/animations/discovery/en/more.jpg'), - ], - ), - ), - ], - ), - ), - ), - ]), - GroupDiscovery(name: DiscoveryGroupIds.pageSchedule, discoveries: [ - Discovery( - path: '', - featureId: DiscoveryIds.detailsScheduleSettings, - title: AppIntl.of(context)!.schedule_settings_title, - details: ConstrainedBox( - constraints: BoxConstraints( - maxHeight: MediaQuery.of(context).size.height * 0.6), - child: Column( - children: [ - Expanded( - child: ListView( - padding: EdgeInsets.zero, - children: [ - _buildSkipDiscoveryButton(context), - Text(AppIntl.of(context)!.discovery_navbar_schedule_details, - textAlign: TextAlign.justify), - const Text('\n'), - if (AppIntl.of(context)!.localeName == "fr") - Image.asset( - 'assets/animations/discovery/fr/schedule_settings.gif') - else - Image.asset( - 'assets/animations/discovery/en/schedule_settings.gif'), - ], - ), - ), - ], - ), - ), - ), - ]), - GroupDiscovery(name: DiscoveryGroupIds.pageStudent, discoveries: [ - Discovery( - path: '', - featureId: DiscoveryIds.detailsStudentGradeButton, - title: AppIntl.of(context)!.grades_title, - details: ConstrainedBox( - constraints: BoxConstraints( - maxHeight: MediaQuery.of(context).size.height * 0.25), - child: Column( - children: [ - Expanded( - child: ListView( - padding: EdgeInsets.zero, - children: [ - _buildSkipDiscoveryButton(context), - Text( - AppIntl.of(context)! - .discovery_page_student_grades_session, - textAlign: TextAlign.justify), - const Text('\n'), - Text( - AppIntl.of(context)! - .discovery_page_student_grades_grade_button, - textAlign: TextAlign.justify), - ], - ), - ), - ], - ), - ), - ), - Discovery( - path: '', - featureId: DiscoveryIds.detailsStudentProfile, - title: AppIntl.of(context)!.profile_title, - details: ConstrainedBox( - constraints: BoxConstraints( - maxHeight: MediaQuery.of(context).size.height * 0.2), - child: Column( - children: [ - Expanded( - child: ListView( - padding: EdgeInsets.zero, - children: [ - _buildSkipDiscoveryButton(context), - Text(AppIntl.of(context)!.discovery_page_student_profile, - textAlign: TextAlign.justify), - ], - ), - ), - ], - ), - ), - ), - ]), - GroupDiscovery(name: DiscoveryGroupIds.pageGradeDetails, discoveries: [ - Discovery( - path: '', - featureId: DiscoveryIds.detailsGradeDetailsEvaluations, - title: "", - details: ConstrainedBox( - constraints: BoxConstraints( - maxHeight: MediaQuery.of(context).size.height * 0.2), - child: Column( - children: [ - Expanded( - child: ListView( - padding: EdgeInsets.zero, - children: [ - _buildSkipDiscoveryButton(context), - Text(AppIntl.of(context)!.discovery_page_grade_details, - textAlign: TextAlign.justify), - ], - ), - ), - ], - ), - ), - ), - ]), - GroupDiscovery(name: DiscoveryGroupIds.pageMore, discoveries: [ - Discovery( - path: '', - featureId: DiscoveryIds.detailsMoreBugReport, - title: AppIntl.of(context)!.more_report_bug, - details: ConstrainedBox( - constraints: BoxConstraints( - maxHeight: MediaQuery.of(context).size.height * 0.2), - child: Column( - children: [ - Expanded( - child: ListView( - padding: EdgeInsets.zero, - children: [ - _buildSkipDiscoveryButton(context), - Text(AppIntl.of(context)!.discovery_page_more_report_bug, - textAlign: TextAlign.justify), - ], - ), - ), - ], - ), - ), - ), - Discovery( - path: '', - featureId: DiscoveryIds.detailsMoreContributors, - title: AppIntl.of(context)!.more_contributors, - details: ConstrainedBox( - constraints: BoxConstraints( - maxHeight: MediaQuery.of(context).size.height * 0.2), - child: Column( - children: [ - Expanded( - child: ListView( - padding: EdgeInsets.zero, - children: [ - _buildSkipDiscoveryButton(context), - Text(AppIntl.of(context)!.discovery_page_more_contributors, - textAlign: TextAlign.justify), - ], - ), - ), - ], - ), - ), - ), - Discovery( - path: '', - featureId: DiscoveryIds.detailsMoreFaq, - title: AppIntl.of(context)!.need_help, - details: ConstrainedBox( - constraints: BoxConstraints( - maxHeight: MediaQuery.of(context).size.height * 0.2), - child: Column( - children: [ - Expanded( - child: ListView( - padding: EdgeInsets.zero, - children: [ - _buildSkipDiscoveryButton(context), - Text(AppIntl.of(context)!.discovery_page_faq, - textAlign: TextAlign.justify), - ], - ), - ), - ], - ), - ), - ), - Discovery( - path: '', - featureId: DiscoveryIds.detailsMoreSettings, - title: AppIntl.of(context)!.more_settings, - details: ConstrainedBox( - constraints: BoxConstraints( - maxHeight: MediaQuery.of(context).size.height * 0.2), - child: Column( - children: [ - Expanded( - child: ListView( - padding: EdgeInsets.zero, - children: [ - _buildSkipDiscoveryButton(context), - Text(AppIntl.of(context)!.discovery_page_more_settings, - textAlign: TextAlign.justify), - ], - ), - ), - ], - ), - ), - ), - Discovery( - path: '', - featureId: DiscoveryIds.detailsMoreThankYou, - title: AppIntl.of(context)!.title_ets_mobile, - details: ConstrainedBox( - constraints: BoxConstraints( - maxHeight: MediaQuery.of(context).size.height * 0.2), - child: Column( - children: [ - Expanded( - child: ListView( - padding: EdgeInsets.zero, - children: [ - _buildSkipDiscoveryButton(context), - Text(AppIntl.of(context)!.discovery_page_thankyou_message, - textAlign: TextAlign.justify), - ], - ), - ), - ], - ), - ), - ), - ]), - ]; -} - -Padding _buildHeader(String title, BuildContext context) { - return Padding( - padding: const EdgeInsets.only(bottom: 8.0), - child: Row( - mainAxisAlignment: MainAxisAlignment.spaceBetween, - children: [ - Text(title, - style: Theme.of(context) - .textTheme - .titleLarge! - .copyWith(color: Colors.white)), - _buildSkipDiscoveryButton(context) - ], - ), - ); -} - -Align _buildSkipDiscoveryButton(BuildContext context) { - return Align( - alignment: Alignment.topRight, - child: TextButton( - onPressed: () => dismissDiscovery(context), - child: Text(AppIntl.of(context)!.skip_discovery, - style: const TextStyle(color: AppTheme.etsLightRed)), - ), - ); -} - -void dismissDiscovery(BuildContext context) { - final SettingsManager settingsManager = locator(); - - FeatureDiscovery.dismissAll(context); - - settingsManager.setBool(PreferencesFlag.discoveryDashboard, true); - settingsManager.setBool(PreferencesFlag.discoverySchedule, true); - settingsManager.setBool(PreferencesFlag.discoveryStudentGrade, true); - settingsManager.setBool(PreferencesFlag.discoveryGradeDetails, true); - settingsManager.setBool(PreferencesFlag.discoveryStudentProfile, true); - settingsManager.setBool(PreferencesFlag.discoveryMore, true); -} - -Discovery getDiscoveryByPath(BuildContext context, String group, String path) { - return discoveryComponents(context) - .firstWhere((element) => element.name == group) - .discoveries - .firstWhere((element) => element.path == path); -} - -Discovery getDiscoveryByFeatureId( - BuildContext context, String group, String featureId) { - return discoveryComponents(context) - .firstWhere((element) => element.name == group) - .discoveries - .firstWhere((element) => element.featureId == featureId); -} - -List findDiscoveriesByGroupName( - BuildContext context, String groupName) { - return discoveryComponents(context) - .firstWhere((element) => element.name == groupName) - .discoveries; -} diff --git a/lib/features/welcome/discovery/models/discovery.dart b/lib/features/welcome/discovery/models/discovery.dart deleted file mode 100644 index a91385cd6..000000000 --- a/lib/features/welcome/discovery/models/discovery.dart +++ /dev/null @@ -1,15 +0,0 @@ -// Flutter imports: -import 'package:flutter/material.dart'; - -class Discovery { - final String path; - final String featureId; - final String title; - final Widget details; - - Discovery( - {required this.path, - required this.featureId, - required this.title, - required this.details}); -} diff --git a/lib/features/welcome/discovery/models/discovery_ids.dart b/lib/features/welcome/discovery/models/discovery_ids.dart deleted file mode 100644 index 2212de49e..000000000 --- a/lib/features/welcome/discovery/models/discovery_ids.dart +++ /dev/null @@ -1,29 +0,0 @@ -class DiscoveryGroupIds { - static const String bottomBar = "bottomBar"; - static const String pageSchedule = "pageSchedule"; - static const String pageStudent = "pageStudent"; - static const String pageGradeDetails = "pageGradeDetails"; - static const String pageMore = "pageMore"; -} - -class DiscoveryIds { - static const String bottomBarDashboard = "bottomBar_dashboard"; - static const String bottomBarDashboardRestore = "bottomBar_dashboard_restore"; - static const String bottomBarSchedule = "bottomBar_schedule"; - static const String bottomBarStudent = "bottomBar_students"; - static const String bottomBarETS = "bottomBar_ets"; - static const String bottomBarMore = "bottomBar_more"; - - static const String detailsScheduleSettings = "page_schedule_settings"; - - static const String detailsStudentGradeButton = "page_student_grade_button"; - static const String detailsGradeDetailsEvaluations = - "page_grade_details_evaluations"; - static const String detailsStudentProfile = "page_student_profile"; - - static const String detailsMoreBugReport = "page_more_bug_report"; - static const String detailsMoreContributors = "page_more_contributors"; - static const String detailsMoreFaq = "page_more_faq"; - static const String detailsMoreSettings = "page_more_settings"; - static const String detailsMoreThankYou = "page_more_thank_you"; -} diff --git a/lib/features/welcome/discovery/models/group_discovery.dart b/lib/features/welcome/discovery/models/group_discovery.dart deleted file mode 100644 index ac4793746..000000000 --- a/lib/features/welcome/discovery/models/group_discovery.dart +++ /dev/null @@ -1,12 +0,0 @@ -// Project imports: -import 'package:notredame/features/welcome/discovery/models/discovery.dart'; - -class GroupDiscovery { - final String name; - final List discoveries; - - GroupDiscovery({ - required this.name, - required this.discoveries, - }); -} diff --git a/lib/main.dart b/lib/main.dart index 4b9baa075..ca554ca59 100644 --- a/lib/main.dart +++ b/lib/main.dart @@ -7,7 +7,6 @@ import 'package:flutter/material.dart'; // Package imports: import 'package:calendar_view/calendar_view.dart'; -import 'package:feature_discovery_fork/feature_discovery.dart'; import 'package:feedback/feedback.dart'; import 'package:firebase_core/firebase_core.dart'; import 'package:firebase_crashlytics/firebase_crashlytics.dart'; @@ -89,9 +88,7 @@ class ETSMobile extends StatelessWidget { CustomFeedbackLocalizationsDelegate(), ], localeOverride: model.locale, - child: FeatureDiscovery( - recordStepsInSharedPreferences: false, - child: CalendarControllerProvider( + child: CalendarControllerProvider( controller: EventController(), child: MaterialApp( title: 'ÉTS Mobile', @@ -115,7 +112,6 @@ class ETSMobile extends StatelessWidget { onGenerateRoute: generateRoute, ), ), - ), ); }), ); diff --git a/lib/utils/locator.dart b/lib/utils/locator.dart index 6997cae94..d5c0b9ea0 100644 --- a/lib/utils/locator.dart +++ b/lib/utils/locator.dart @@ -20,7 +20,6 @@ import 'package:notredame/features/app/repository/user_repository.dart'; import 'package:notredame/features/app/signets-api/signets_api_client.dart'; import 'package:notredame/features/app/storage/cache_manager.dart'; import 'package:notredame/features/app/storage/preferences_service.dart'; -import 'package:notredame/features/app/storage/siren_flutter_service.dart'; import 'package:notredame/features/ets/events/api-client/hello_api_client.dart'; import 'package:notredame/features/more/feedback/in_app_review_service.dart'; import 'package:notredame/features/more/settings/settings_manager.dart'; @@ -36,7 +35,6 @@ void setupLocator() { locator.registerLazySingleton(() => const FlutterSecureStorage()); locator.registerLazySingleton(() => PreferencesService()); locator.registerLazySingleton(() => NetworkingService()); - locator.registerLazySingleton(() => SirenFlutterService()); locator.registerLazySingleton(() => InAppReviewService()); locator.registerLazySingleton(() => RemoteConfigService()); locator.registerLazySingleton(() => LaunchUrlService()); diff --git a/pubspec.lock b/pubspec.lock index c183e4b00..7dc9bc371 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -310,14 +310,6 @@ packages: url: "https://pub.dev" source: hosted version: "1.3.1" - feature_discovery_fork: - dependency: "direct main" - description: - name: feature_discovery_fork - sha256: "01eaf9d5be20f4b438a1c9bca8b24595fed449a7ed36ab5e3cb9fd23797643ce" - url: "https://pub.dev" - source: hosted - version: "0.14.2" feedback: dependency: "direct main" description: @@ -576,14 +568,6 @@ packages: url: "https://pub.dev" source: hosted version: "3.1.2" - flutter_siren_2: - dependency: "direct main" - description: - name: flutter_siren_2 - sha256: f61cd52b8b24f37160226997d8abb620bb2fb82b78ae293014260fa12a0d33c3 - url: "https://pub.dev" - source: hosted - version: "1.2.2" flutter_staggered_animations: dependency: "direct main" description: @@ -1551,14 +1535,6 @@ packages: url: "https://pub.dev" source: hosted version: "2.1.4" - version: - dependency: transitive - description: - name: version - sha256: "3d4140128e6ea10d83da32fef2fa4003fccbf6852217bb854845802f04191f94" - url: "https://pub.dev" - source: hosted - version: "3.0.2" vm_service: dependency: transitive description: diff --git a/pubspec.yaml b/pubspec.yaml index 92c915a26..1df057303 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -38,7 +38,6 @@ dependencies: percent_indicator: ^4.2.3 feedback: ^3.0.0 flutter_staggered_animations: ^1.1.1 - flutter_siren_2: ^1.2.2 # Other flutter_cache_manager: ^3.0.1 @@ -49,7 +48,6 @@ dependencies: google_maps_flutter: ^2.5.3 github: ^9.1.0 package_info_plus: ^5.0.1 - feature_discovery_fork: ^0.14.2 connectivity_plus: ^6.0.1 flutter_svg: ^2.0.9 font_awesome_flutter: ^10.7.0 diff --git a/test/common/helpers.dart b/test/common/helpers.dart index bf4a838d8..cbc2091c8 100644 --- a/test/common/helpers.dart +++ b/test/common/helpers.dart @@ -26,7 +26,6 @@ import 'package:notredame/features/app/repository/user_repository.dart'; import 'package:notredame/features/app/signets-api/signets_api_client.dart'; import 'package:notredame/features/app/storage/cache_manager.dart'; import 'package:notredame/features/app/storage/preferences_service.dart'; -import 'package:notredame/features/app/storage/siren_flutter_service.dart'; import 'package:notredame/features/more/feedback/in_app_review_service.dart'; import 'package:notredame/features/more/settings/settings_manager.dart'; import 'package:notredame/utils/locator.dart'; @@ -47,7 +46,6 @@ import '../features/app/signets_api/mocks/signets_api_mock.dart'; import '../features/app/storage/mocks/cache_manager_mock.dart'; import '../features/app/storage/mocks/flutter_secure_storage_mock.dart'; import '../features/app/storage/mocks/preferences_service_mock.dart'; -import '../features/app/storage/mocks/siren_flutter_service_mock.dart'; import '../features/more/feedback/mocks/in_app_review_service_mock.dart'; import '../features/more/settings/mocks/settings_manager_mock.dart'; @@ -147,16 +145,6 @@ InternalInfoServiceMock setupInternalInfoServiceMock() { return service; } -/// Load a mock of the [SirenFlutterService] -SirenFlutterServiceMock setupSirenFlutterServiceMock() { - unregister(); - final service = SirenFlutterServiceMock(); - - locator.registerSingleton(service); - - return service; -} - void setupFlutterToastMock([WidgetTester? tester]) { const MethodChannel channel = MethodChannel('PonnamKarthik/fluttertoast'); diff --git a/test/features/app/startup/startup_viewmodel_test.dart b/test/features/app/startup/startup_viewmodel_test.dart index e68f56b64..55b02b7f9 100644 --- a/test/features/app/startup/startup_viewmodel_test.dart +++ b/test/features/app/startup/startup_viewmodel_test.dart @@ -1,17 +1,14 @@ // Package imports: import 'package:flutter_test/flutter_test.dart'; import 'package:mockito/mockito.dart'; -import 'package:pub_semver/pub_semver.dart'; // Project imports: import 'package:notredame/constants/preferences_flags.dart'; -import 'package:notredame/constants/update_code.dart'; import 'package:notredame/features/app/navigation/navigation_service.dart'; import 'package:notredame/features/app/navigation/router_paths.dart'; import 'package:notredame/features/app/repository/user_repository.dart'; import 'package:notredame/features/app/startup/startup_viewmodel.dart'; import 'package:notredame/features/app/storage/preferences_service.dart'; -import 'package:notredame/features/app/storage/siren_flutter_service.dart'; import 'package:notredame/features/more/settings/settings_manager.dart'; import '../../../common/helpers.dart'; import '../../more/settings/mocks/settings_manager_mock.dart'; @@ -19,17 +16,13 @@ import '../error/mocks/internal_info_service_mock.dart'; import '../integration/mocks/networking_service_mock.dart'; import '../navigation/mocks/navigation_service_mock.dart'; import '../repository/mocks/user_repository_mock.dart'; -import '../storage/mocks/preferences_service_mock.dart'; -import '../storage/mocks/siren_flutter_service_mock.dart'; void main() { late NavigationServiceMock navigationServiceMock; late UserRepositoryMock userRepositoryMock; late SettingsManagerMock settingsManagerMock; - late PreferencesServiceMock preferencesServiceMock; late NetworkingServiceMock networkingServiceMock; late InternalInfoServiceMock internalInfoServiceMock; - late SirenFlutterServiceMock sirenFlutterServiceMock; late StartUpViewModel viewModel; @@ -38,16 +31,12 @@ void main() { setupAnalyticsServiceMock(); navigationServiceMock = setupNavigationServiceMock(); settingsManagerMock = setupSettingsManagerMock(); - preferencesServiceMock = setupPreferencesServiceMock(); userRepositoryMock = setupUserRepositoryMock(); networkingServiceMock = setupNetworkingServiceMock(); internalInfoServiceMock = setupInternalInfoServiceMock(); - sirenFlutterServiceMock = setupSirenFlutterServiceMock(); setupLogger(); viewModel = StartUpViewModel(); - - SirenFlutterServiceMock.stubUpdateIsAvailable(sirenFlutterServiceMock); }); tearDown(() { @@ -55,7 +44,6 @@ void main() { unregister(); unregister(); unregister(); - unregister(); }); group('handleStartUp - ', () { @@ -71,8 +59,7 @@ void main() { await viewModel.handleStartUp(); - verify(navigationServiceMock.pushNamedAndRemoveUntil( - RouterPaths.dashboard, RouterPaths.dashboard, UpdateCode.none)); + verify(navigationServiceMock.pushNamedAndRemoveUntil(RouterPaths.dashboard)); }); test( @@ -82,11 +69,6 @@ void main() { toReturn: false); UserRepositoryMock.stubWasPreviouslyLoggedIn(userRepositoryMock); NetworkingServiceMock.stubHasConnectivity(networkingServiceMock); - InternalInfoServiceMock.stubGetPackageInfo(internalInfoServiceMock, - version: "4.0.0"); - SettingsManagerMock.stubGetString( - settingsManagerMock, PreferencesFlag.appVersion, - toReturn: "4.0.0"); SettingsManagerMock.stubGetBool( settingsManagerMock, PreferencesFlag.languageChoice, @@ -110,11 +92,6 @@ void main() { toReturn: false); UserRepositoryMock.stubWasPreviouslyLoggedIn(userRepositoryMock); NetworkingServiceMock.stubHasConnectivity(networkingServiceMock); - InternalInfoServiceMock.stubGetPackageInfo(internalInfoServiceMock, - version: "4.0.0"); - SettingsManagerMock.stubGetString( - settingsManagerMock, PreferencesFlag.appVersion, - toReturn: "4.0.0"); await viewModel.handleStartUp(); @@ -126,178 +103,6 @@ void main() { verifyNoMoreInteractions(navigationServiceMock); }); - - test('verify discovery flags are bool if version mismatch', () async { - const String versionToSave = "4.1.0"; - UserRepositoryMock.stubSilentAuthenticate(userRepositoryMock); - UserRepositoryMock.stubWasPreviouslyLoggedIn(userRepositoryMock); - NetworkingServiceMock.stubHasConnectivity(networkingServiceMock); - InternalInfoServiceMock.stubGetPackageInfo(internalInfoServiceMock, - version: versionToSave); - SettingsManagerMock.stubGetString( - settingsManagerMock, PreferencesFlag.appVersion, - toReturn: "4.0.0"); - SettingsManagerMock.stubSetString( - settingsManagerMock, PreferencesFlag.appVersion); - PreferencesServiceMock.stubGetPreferencesFlag( - preferencesServiceMock, PreferencesFlag.discoveryDashboard, - toReturn: 'true'); - PreferencesServiceMock.stubGetPreferencesFlag( - preferencesServiceMock, PreferencesFlag.discoverySchedule, - toReturn: 'false'); - PreferencesServiceMock.stubGetPreferencesFlag( - preferencesServiceMock, PreferencesFlag.discoveryStudentGrade, - toReturn: 'true'); - PreferencesServiceMock.stubGetPreferencesFlag( - preferencesServiceMock, PreferencesFlag.discoveryGradeDetails, - toReturn: 'true'); - PreferencesServiceMock.stubGetPreferencesFlag( - preferencesServiceMock, PreferencesFlag.discoveryStudentProfile); - PreferencesServiceMock.stubGetPreferencesFlag( - preferencesServiceMock, PreferencesFlag.discoveryETS); - - await viewModel.handleStartUp(); - - verify(preferencesServiceMock.getPreferencesFlag(any)).called(8); - - verifyInOrder([ - settingsManagerMock.getString(PreferencesFlag.appVersion), - preferencesServiceMock - .removePreferencesFlag(PreferencesFlag.discoveryDashboard), - settingsManagerMock.setBool(PreferencesFlag.discoveryDashboard, true), - preferencesServiceMock - .removePreferencesFlag(PreferencesFlag.discoverySchedule), - settingsManagerMock.setBool(PreferencesFlag.discoverySchedule, false), - preferencesServiceMock - .removePreferencesFlag(PreferencesFlag.discoveryStudentGrade), - settingsManagerMock.setBool( - PreferencesFlag.discoveryStudentGrade, true), - preferencesServiceMock - .removePreferencesFlag(PreferencesFlag.discoveryGradeDetails), - settingsManagerMock.setBool( - PreferencesFlag.discoveryGradeDetails, true), - settingsManagerMock.setString( - PreferencesFlag.appVersion, versionToSave) - ]); - }); - - test('verify discovery flags are not changed for same version', () async { - UserRepositoryMock.stubSilentAuthenticate(userRepositoryMock); - UserRepositoryMock.stubWasPreviouslyLoggedIn(userRepositoryMock); - NetworkingServiceMock.stubHasConnectivity(networkingServiceMock); - InternalInfoServiceMock.stubGetPackageInfo(internalInfoServiceMock, - version: "4.0.0"); - SettingsManagerMock.stubGetString( - settingsManagerMock, PreferencesFlag.appVersion, - toReturn: "4.0.0"); - - await viewModel.handleStartUp(); - - verifyNever(preferencesServiceMock.getPreferencesFlag(any)); - verifyNever(settingsManagerMock.setBool(any, any)); - verifyNever( - settingsManagerMock.setString(PreferencesFlag.appVersion, "4.0.1")); - }); - - test('verify discovery flags are bool is trigger for no present version', - () async { - UserRepositoryMock.stubSilentAuthenticate(userRepositoryMock); - UserRepositoryMock.stubWasPreviouslyLoggedIn(userRepositoryMock); - NetworkingServiceMock.stubHasConnectivity(networkingServiceMock); - InternalInfoServiceMock.stubGetPackageInfo(internalInfoServiceMock, - version: "4.0.0"); - SettingsManagerMock.stubSetString( - settingsManagerMock, PreferencesFlag.appVersion); - PreferencesServiceMock.stubGetPreferencesFlag( - preferencesServiceMock, PreferencesFlag.discoveryDashboard, - toReturn: 'true'); - PreferencesServiceMock.stubGetPreferencesFlag( - preferencesServiceMock, PreferencesFlag.discoverySchedule, - toReturn: 'false'); - PreferencesServiceMock.stubGetPreferencesFlag( - preferencesServiceMock, PreferencesFlag.discoveryStudentGrade, - toReturn: 'true'); - PreferencesServiceMock.stubGetPreferencesFlag( - preferencesServiceMock, PreferencesFlag.discoveryGradeDetails, - toReturn: 'true'); - PreferencesServiceMock.stubGetPreferencesFlag( - preferencesServiceMock, PreferencesFlag.discoveryStudentProfile); - PreferencesServiceMock.stubGetPreferencesFlag( - preferencesServiceMock, PreferencesFlag.discoveryETS); - - await viewModel.handleStartUp(); - - verify(preferencesServiceMock.getPreferencesFlag(any)).called(8); - - verifyInOrder([ - settingsManagerMock.getString(PreferencesFlag.appVersion), - preferencesServiceMock - .removePreferencesFlag(PreferencesFlag.discoveryDashboard), - settingsManagerMock.setBool(PreferencesFlag.discoveryDashboard, true), - preferencesServiceMock - .removePreferencesFlag(PreferencesFlag.discoverySchedule), - settingsManagerMock.setBool(PreferencesFlag.discoverySchedule, false), - preferencesServiceMock - .removePreferencesFlag(PreferencesFlag.discoveryStudentGrade), - settingsManagerMock.setBool( - PreferencesFlag.discoveryStudentGrade, true), - preferencesServiceMock - .removePreferencesFlag(PreferencesFlag.discoveryGradeDetails), - settingsManagerMock.setBool( - PreferencesFlag.discoveryGradeDetails, true), - settingsManagerMock.setString(PreferencesFlag.appVersion, "4.0.0") - ]); - }); - }); - - group('checkUpdateStatus - ', () { - test('should return UpdateCode.none if update is not available', - () async { - SirenFlutterServiceMock.stubUpdateIsAvailable(sirenFlutterServiceMock); - - final result = await viewModel.checkUpdateStatus(); - - expect(result, UpdateCode.none); - }); - - test( - "should return UpdateCode.ask if update is available and it's a minor or major changes", - () async { - SirenFlutterServiceMock.stubUpdateIsAvailable(sirenFlutterServiceMock, - valueToReturn: true); - SirenFlutterServiceMock.stubLocalVersion(sirenFlutterServiceMock, - valueToReturn: Version(4, 0, 0)); - SirenFlutterServiceMock.stubStoreVersion(sirenFlutterServiceMock, - valueToReturn: Version(4, 1, 0)); - - var result = await viewModel.checkUpdateStatus(); - - expect(result, UpdateCode.ask); - - SirenFlutterServiceMock.stubLocalVersion(sirenFlutterServiceMock, - valueToReturn: Version(4, 0, 0)); - SirenFlutterServiceMock.stubStoreVersion(sirenFlutterServiceMock, - valueToReturn: Version(5, 0, 0)); - - result = await viewModel.checkUpdateStatus(); - - expect(result, UpdateCode.ask); - }); - - test( - "should return UpdateCode.force if update is available and it's a revision changes", - () async { - SirenFlutterServiceMock.stubUpdateIsAvailable(sirenFlutterServiceMock, - valueToReturn: true); - SirenFlutterServiceMock.stubLocalVersion(sirenFlutterServiceMock, - valueToReturn: Version(4, 0, 0)); - SirenFlutterServiceMock.stubStoreVersion(sirenFlutterServiceMock, - valueToReturn: Version(4, 0, 1)); - - final result = await viewModel.checkUpdateStatus(); - - expect(result, UpdateCode.force); - }); }); }); } diff --git a/test/features/app/storage/mocks/siren_flutter_service_mock.dart b/test/features/app/storage/mocks/siren_flutter_service_mock.dart deleted file mode 100644 index 9d03be2f3..000000000 --- a/test/features/app/storage/mocks/siren_flutter_service_mock.dart +++ /dev/null @@ -1,30 +0,0 @@ -// Package imports: -import 'package:mockito/annotations.dart'; -import 'package:mockito/mockito.dart'; -import 'package:pub_semver/pub_semver.dart'; - -// Project imports: -import 'package:notredame/features/app/storage/siren_flutter_service.dart'; -import 'siren_flutter_service_mock.mocks.dart'; - -/// Mock for the [SirenFlutterService] -@GenerateNiceMocks([MockSpec()]) -class SirenFlutterServiceMock extends MockSirenFlutterService { - /// Stub the updateIsAvailable function of [SirenFlutterService] - static void stubUpdateIsAvailable(SirenFlutterServiceMock mock, - {bool valueToReturn = false}) { - when(mock.updateIsAvailable()).thenAnswer((_) async => valueToReturn); - } - - /// Stub the localVersion function of [SirenFlutterService] - static void stubLocalVersion(SirenFlutterServiceMock mock, - {required Version valueToReturn}) { - when(mock.localVersion).thenAnswer((_) async => valueToReturn); - } - - /// Stub the storeVersion function of [SirenFlutterService] - static void stubStoreVersion(SirenFlutterServiceMock mock, - {required Version valueToReturn}) { - when(mock.storeVersion).thenAnswer((_) async => valueToReturn); - } -} diff --git a/test/features/app/widgets/bottom_bar_test.dart b/test/features/app/widgets/bottom_bar_test.dart index 0c3cf8d9b..bc2df6fcd 100644 --- a/test/features/app/widgets/bottom_bar_test.dart +++ b/test/features/app/widgets/bottom_bar_test.dart @@ -2,7 +2,6 @@ import 'package:flutter/material.dart'; // Package imports: -import 'package:feature_discovery_fork/feature_discovery.dart'; import 'package:flutter_test/flutter_test.dart'; import 'package:mockito/mockito.dart'; @@ -35,7 +34,7 @@ void main() { 'has five sections with icons and titles (dashboard, schedule, student, ets and more)', (WidgetTester tester) async { await tester.pumpWidget( - localizedWidget(child: FeatureDiscovery(child: BottomBar()))); + localizedWidget(child: BottomBar())); await tester.pumpAndSettle(); final texts = find.byType(Text); @@ -48,7 +47,7 @@ void main() { testWidgets('not navigate when tapped multiple times', (WidgetTester tester) async { await tester.pumpWidget( - localizedWidget(child: FeatureDiscovery(child: BottomBar()))); + localizedWidget(child: BottomBar())); await tester.pumpAndSettle(); await tester.tap(find.byIcon(Icons.school_outlined)); @@ -65,7 +64,7 @@ void main() { group('navigate when tapped to - ', () { testWidgets('dashboard', (WidgetTester tester) async { await tester.pumpWidget( - localizedWidget(child: FeatureDiscovery(child: BottomBar()))); + localizedWidget(child: BottomBar())); await tester.pumpAndSettle(); await tester.tap(find.byIcon(Icons.schedule_outlined)); @@ -76,7 +75,7 @@ void main() { testWidgets('schedule', (WidgetTester tester) async { await tester.pumpWidget( - localizedWidget(child: FeatureDiscovery(child: BottomBar()))); + localizedWidget(child: BottomBar())); await tester.pumpAndSettle(); await tester.tap(find.byIcon(Icons.schedule_outlined)); @@ -86,7 +85,7 @@ void main() { testWidgets('student', (WidgetTester tester) async { await tester.pumpWidget( - localizedWidget(child: FeatureDiscovery(child: BottomBar()))); + localizedWidget(child: BottomBar())); await tester.pumpAndSettle(); await tester.tap(find.byIcon(Icons.school_outlined)); @@ -96,7 +95,7 @@ void main() { testWidgets('ets', (WidgetTester tester) async { await tester.pumpWidget( - localizedWidget(child: FeatureDiscovery(child: BottomBar()))); + localizedWidget(child: BottomBar())); await tester.pumpAndSettle(); await tester.tap(find.byIcon(Icons.account_balance_outlined)); @@ -106,7 +105,7 @@ void main() { testWidgets('more', (WidgetTester tester) async { await tester.pumpWidget( - localizedWidget(child: FeatureDiscovery(child: BottomBar()))); + localizedWidget(child: BottomBar())); await tester.pumpAndSettle(); await tester.tap(find.byIcon(Icons.menu_outlined)); diff --git a/test/features/dashboard/dashboard_view_test.dart b/test/features/dashboard/dashboard_view_test.dart index c512c4c05..11c8b4419 100644 --- a/test/features/dashboard/dashboard_view_test.dart +++ b/test/features/dashboard/dashboard_view_test.dart @@ -9,7 +9,6 @@ import 'package:shared_preferences/shared_preferences.dart'; // Project imports: import 'package:notredame/constants/preferences_flags.dart'; -import 'package:notredame/constants/update_code.dart'; import 'package:notredame/features/app/signets-api/models/course.dart'; import 'package:notredame/features/app/signets-api/models/course_activity.dart'; import 'package:notredame/features/app/signets-api/models/session.dart'; @@ -156,7 +155,7 @@ void main() { await tester.pumpWidget(localizedWidget( child: FeatureDiscovery( - child: const DashboardView(updateCode: UpdateCode.none)))); + child: const DashboardView()))); await tester.pumpAndSettle(); // Find schedule card in second position by its title @@ -233,7 +232,7 @@ void main() { await tester.pumpWidget(localizedWidget( child: FeatureDiscovery( - child: const DashboardView(updateCode: UpdateCode.none)))); + child: const DashboardView()))); await tester.pumpAndSettle(); // Find Dashboard Title @@ -266,7 +265,7 @@ void main() { await tester.pumpWidget(localizedWidget( child: FeatureDiscovery( - child: const DashboardView(updateCode: UpdateCode.none)))); + child: const DashboardView()))); await tester.pumpAndSettle(); // Find aboutUs card @@ -373,7 +372,7 @@ void main() { await tester.pumpWidget(localizedWidget( child: FeatureDiscovery( - child: const DashboardView(updateCode: UpdateCode.none)))); + child: const DashboardView()))); await tester.pumpAndSettle(); // Find Dismissible Cards @@ -426,7 +425,7 @@ void main() { await tester.pumpWidget(localizedWidget( child: FeatureDiscovery( - child: const DashboardView(updateCode: UpdateCode.none)))); + child: const DashboardView()))); await tester.pumpAndSettle(); // Find Dismissible Cards @@ -487,7 +486,7 @@ void main() { await tester.pumpWidget(localizedWidget( child: FeatureDiscovery( - child: const DashboardView(updateCode: UpdateCode.none)))); + child: const DashboardView()))); await tester.pumpAndSettle(); // Find Dismissible Cards @@ -528,7 +527,7 @@ void main() { await tester.pumpWidget(localizedWidget( child: FeatureDiscovery( - child: const DashboardView(updateCode: UpdateCode.none)))); + child: const DashboardView()))); await tester.pumpAndSettle(); // Find grades card @@ -561,7 +560,7 @@ void main() { await tester.pumpWidget(localizedWidget( child: FeatureDiscovery( - child: const DashboardView(updateCode: UpdateCode.none)))); + child: const DashboardView()))); await tester.pumpAndSettle(); // Find grades card @@ -596,7 +595,7 @@ void main() { await tester.pumpWidget(localizedWidget( child: FeatureDiscovery( - child: const DashboardView(updateCode: UpdateCode.none)))); + child: const DashboardView()))); await tester.pumpAndSettle(); // Find Dismissible Cards @@ -639,7 +638,7 @@ void main() { await tester.pumpWidget(localizedWidget( child: FeatureDiscovery( - child: const DashboardView(updateCode: UpdateCode.none)))); + child: const DashboardView()))); await tester.pumpAndSettle(); // Find progress card @@ -662,7 +661,7 @@ void main() { await tester.pumpWidget(localizedWidget( child: FeatureDiscovery( - child: const DashboardView(updateCode: UpdateCode.none)))); + child: const DashboardView()))); await tester.pumpAndSettle(); // Find Dismissible Cards @@ -702,7 +701,7 @@ void main() { await tester.pumpWidget(localizedWidget( child: FeatureDiscovery( - child: const DashboardView(updateCode: UpdateCode.none)))); + child: const DashboardView()))); await tester.pumpAndSettle(); // Find Dismissible Cards From b789878daa9b905941a36897d693800a0d7d3f67 Mon Sep 17 00:00:00 2001 From: Xavier Paquet-Rapold Date: Fri, 25 Oct 2024 19:50:58 -0400 Subject: [PATCH 02/19] Update dependencies --- pubspec.lock | 152 +++++++++++++++++++++++++-------------------------- pubspec.yaml | 74 ++++++++++++++----------- 2 files changed, 117 insertions(+), 109 deletions(-) diff --git a/pubspec.lock b/pubspec.lock index 7dc9bc371..0684730f5 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -13,10 +13,10 @@ packages: dependency: transitive description: name: _flutterfire_internals - sha256: "4eec93681221723a686ad580c2e7d960e1017cf1a4e0a263c2573c2c6b0bf5cd" + sha256: "5534e701a2c505fed1f0799e652dd6ae23bd4d2c4cf797220e5ced5764a7c1c2" url: "https://pub.dev" source: hosted - version: "1.3.25" + version: "1.3.44" _macros: dependency: transitive description: dart @@ -202,10 +202,10 @@ packages: dependency: "direct main" description: name: connectivity_plus - sha256: db7a4e143dc72cc3cb2044ef9b052a7ebfe729513e6a82943bc3526f784365b8 + sha256: "876849631b0c7dc20f8b471a2a03142841b482438e3b707955464f5ffca3e4c3" url: "https://pub.dev" source: hosted - version: "6.0.3" + version: "6.1.0" connectivity_plus_platform_interface: dependency: transitive description: @@ -226,10 +226,10 @@ packages: dependency: transitive description: name: cross_file - sha256: fedaadfa3a6996f75211d835aaeb8fede285dae94262485698afd832371b9a5e + sha256: "7caf6a750a0c04effbb52a676dce9a4a592e10ad35c34d6d2d0e4811160d5670" url: "https://pub.dev" source: hosted - version: "0.3.3+8" + version: "0.3.4+2" crypto: dependency: transitive description: @@ -274,10 +274,10 @@ packages: dependency: "direct main" description: name: device_info_plus - sha256: "77f757b789ff68e4eaf9c56d1752309bd9f7ad557cb105b938a7f8eb89e59110" + sha256: c4af09051b4f0508f6c1dc0a5c085bf014d5c9a4a0678ce1799c2b4d716387a0 url: "https://pub.dev" source: hosted - version: "9.1.2" + version: "11.1.0" device_info_plus_platform_interface: dependency: transitive description: @@ -338,34 +338,34 @@ packages: dependency: "direct main" description: name: firebase_analytics - sha256: b13cbf1ee78744ca5e6b762e9218db3bd3967a0edfed75f58339907892a2ccb9 + sha256: "2c4e7b548d41b46e8aa08bc3bd1163146be7e6d48f678f2e6dd3114994e42458" url: "https://pub.dev" source: hosted - version: "10.8.9" + version: "11.3.3" firebase_analytics_platform_interface: dependency: transitive description: name: firebase_analytics_platform_interface - sha256: "416b33d62033db5ecd2df719fcb657ad04e9995fa0fc392ffdab4ca0e76cb679" + sha256: c259ae890c7d4c5d1675d35936be0b1fcd587fce9645948982cd87ad08df6222 url: "https://pub.dev" source: hosted - version: "3.9.9" + version: "4.2.5" firebase_analytics_web: dependency: transitive description: name: firebase_analytics_web - sha256: "9dca9d8d468172444ef18cabb73fe99f7aae24733bfad67115bd36bffd2d65c1" + sha256: "5988d1fd022e55515c2a14811c9b5104c32acde115874a9a69ff7c77c4c05cd9" url: "https://pub.dev" source: hosted - version: "0.5.5+21" + version: "0.5.10+2" firebase_core: dependency: "direct main" description: name: firebase_core - sha256: "53316975310c8af75a96e365f9fccb67d1c544ef0acdbf0d88bbe30eedd1c4f9" + sha256: "51dfe2fbf3a984787a2e7b8592f2f05c986bfedd6fdacea3f9e0a7beb334de96" url: "https://pub.dev" source: hosted - version: "2.27.0" + version: "3.6.0" firebase_core_platform_interface: dependency: transitive description: @@ -378,50 +378,50 @@ packages: dependency: transitive description: name: firebase_core_web - sha256: c8e1d59385eee98de63c92f961d2a7062c5d9a65e7f45bdc7f1b0b205aab2492 + sha256: f967a7138f5d2ffb1ce15950e2a382924239eaa521150a8f144af34e68b3b3e5 url: "https://pub.dev" source: hosted - version: "2.11.5" + version: "2.18.1" firebase_crashlytics: dependency: "direct main" description: name: firebase_crashlytics - sha256: c4f1b723d417bc9c4774810e774ff91df8fb0032d33fb2888b2c887e865581b8 + sha256: "6899800fff1af819955aef740f18c4c8600f8b952a2a1ea97bc0872ebb257387" url: "https://pub.dev" source: hosted - version: "3.4.18" + version: "4.1.3" firebase_crashlytics_platform_interface: dependency: transitive description: name: firebase_crashlytics_platform_interface - sha256: c5a11fca3df76a98e3fa68fde8b10a08aacb9a7639f619fbfd4dad6c67a08643 + sha256: "97c47b0a1779a3d4118416a3f0c6c564cc59ad89095e899893204d4b2ad08f4c" url: "https://pub.dev" source: hosted - version: "3.6.25" + version: "3.6.44" firebase_remote_config: dependency: "direct main" description: name: firebase_remote_config - sha256: b085a72c007bd8f177a7ab98b8292d764659b07fb6b0561b84125239ee656efc + sha256: "8985e55900060437136a11f794f430d810a95f93e4a422117c474326feedc2c6" url: "https://pub.dev" source: hosted - version: "4.3.17" + version: "5.1.3" firebase_remote_config_platform_interface: dependency: transitive description: name: firebase_remote_config_platform_interface - sha256: c589e007156b2c9f903253764c108abb96c1b56dd17cf0b91afc4b72ccab7bb6 + sha256: ecde097c286b5967b9338f0374725655e2af71e685a8567f9b4700bbeec04ab8 url: "https://pub.dev" source: hosted - version: "1.4.25" + version: "1.4.44" firebase_remote_config_web: dependency: transitive description: name: firebase_remote_config_web - sha256: "92443c70e2721ab9d4beb23eb1d9f971da7381332451daee04f619b0f9204569" + sha256: e4dc0f7a63150181c800b8bd4fa9f50ce252479f1935f47e7a2845100239eb0a url: "https://pub.dev" source: hosted - version: "1.4.25" + version: "1.7.2" fixnum: dependency: transitive description: @@ -439,10 +439,10 @@ packages: dependency: "direct main" description: name: flutter_cache_manager - sha256: a77f77806a790eb9ba0118a5a3a936e81c4fea2b61533033b2b0c3d50bbde5ea + sha256: "400b6592f16a4409a7f2bb929a9a7e38c72cceb8ffb99ee57bbf2cb2cecf8386" url: "https://pub.dev" source: hosted - version: "3.4.0" + version: "3.4.1" flutter_config: dependency: "direct dev" description: @@ -508,10 +508,10 @@ packages: dependency: "direct main" description: name: flutter_markdown - sha256: bd9c475d9aae256369edacafc29d1e74c81f78a10cdcdacbbbc9e3c43d009e4a + sha256: f0e599ba89c9946c8e051780f0ec99aba4ba15895e0380a7ab68f420046fc44e url: "https://pub.dev" source: hosted - version: "0.7.4" + version: "0.7.4+1" flutter_plugin_android_lifecycle: dependency: transitive description: @@ -606,10 +606,10 @@ packages: dependency: "direct main" description: name: fluttertoast - sha256: "81b68579e23fcbcada2db3d50302813d2371664afe6165bc78148050ab94bf66" + sha256: "95f349437aeebe524ef7d6c9bde3e6b4772717cf46a0eb6a3ceaddc740b297cc" url: "https://pub.dev" source: hosted - version: "8.2.5" + version: "8.2.8" font_awesome_flutter: dependency: "direct main" description: @@ -654,18 +654,18 @@ packages: dependency: transitive description: name: google_maps - sha256: "555d5d736339b0478e821167ac521c810d7b51c3b2734e6802a9f046b64ea37a" + sha256: "4d6e199c561ca06792c964fa24b2bac7197bf4b401c2e1d23e345e5f9939f531" url: "https://pub.dev" source: hosted - version: "6.3.0" + version: "8.1.1" google_maps_flutter: dependency: "direct main" description: name: google_maps_flutter - sha256: ae66fef3e71261d7df2eff29b2a119e190b2884325ecaa55321b1e17b5504066 + sha256: "2e302fa3aaf4e2a297f0342d83ebc5e8e9f826e9a716aef473fe7f404ec630a7" url: "https://pub.dev" source: hosted - version: "2.5.3" + version: "2.9.0" google_maps_flutter_android: dependency: transitive description: @@ -694,10 +694,10 @@ packages: dependency: transitive description: name: google_maps_flutter_web - sha256: "6245721c160d6f531c1ef568cf9bef8d660cd585a982aa75121269030163785a" + sha256: ff39211bd25d7fad125d19f757eba85bd154460907cd4d135e07e3d0f98a4130 url: "https://pub.dev" source: hosted - version: "0.5.4+3" + version: "0.5.10" graphs: dependency: transitive description: @@ -718,10 +718,10 @@ packages: dependency: transitive description: name: http - sha256: a2bbf9d017fcced29139daa8ed2bba4ece450ab222871df93ca9eec6f80c34ba + sha256: b9c29a161230ee03d3ccf545097fccd9b87a5264228c5d348202e0f0c28f9010 url: "https://pub.dev" source: hosted - version: "1.2.0" + version: "1.2.2" http_multi_server: dependency: transitive description: @@ -802,14 +802,6 @@ packages: url: "https://pub.dev" source: hosted version: "0.6.7" - js_wrapping: - dependency: transitive - description: - name: js_wrapping - sha256: e385980f7c76a8c1c9a560dfb623b890975841542471eade630b2871d243851c - url: "https://pub.dev" - source: hosted - version: "0.7.4" json_annotation: dependency: transitive description: @@ -910,10 +902,10 @@ packages: dependency: transitive description: name: mime - sha256: "801fd0b26f14a4a58ccb09d5892c3fbdeff209594300a542492cf13fba9d247a" + sha256: "41a20518f0cb1256669420fdba0cd90d21561e560ac240f26ef8322e45bb7ed6" url: "https://pub.dev" source: hosted - version: "1.0.6" + version: "2.0.0" mockito: dependency: "direct dev" description: @@ -950,18 +942,18 @@ packages: dependency: "direct main" description: name: package_info_plus - sha256: "88bc797f44a94814f2213db1c9bd5badebafdfb8290ca9f78d4b9ee2a3db4d79" + sha256: df3eb3e0aed5c1107bb0fdb80a8e82e778114958b1c5ac5644fb1ac9cae8a998 url: "https://pub.dev" source: hosted - version: "5.0.1" + version: "8.1.0" package_info_plus_platform_interface: dependency: transitive description: name: package_info_plus_platform_interface - sha256: "9bc8ba46813a4cc42c66ab781470711781940780fd8beddd0c3da62506d3a6c6" + sha256: ac1f4a4847f1ade8e6a87d1f39f5d7c67490738642e2542f559ec38c37489a66 url: "https://pub.dev" source: hosted - version: "2.0.1" + version: "3.0.1" path: dependency: transitive description: @@ -974,10 +966,10 @@ packages: dependency: transitive description: name: path_parsing - sha256: e3e67b1629e6f7e8100b367d3db6ba6af4b1f0bb80f64db18ef1fbabd2fa9ccf + sha256: "45f7d6bba1128761de5540f39d5ca000ea8a1f22f06b76b61094a60a2997bd0e" url: "https://pub.dev" source: hosted - version: "1.0.1" + version: "1.0.2" path_provider: dependency: transitive description: @@ -1118,26 +1110,26 @@ packages: dependency: "direct main" description: name: share_plus - sha256: "3ef39599b00059db0990ca2e30fca0a29d8b37aae924d60063f8e0184cf20900" + sha256: "3af2cda1752e5c24f2fc04b6083b40f013ffe84fb90472f30c6499a9213d5442" url: "https://pub.dev" source: hosted - version: "7.2.2" + version: "10.1.1" share_plus_platform_interface: dependency: transitive description: name: share_plus_platform_interface - sha256: "251eb156a8b5fa9ce033747d73535bf53911071f8d3b6f4f0b578505ce0d4496" + sha256: c57c0bbfec7142e3a0f55633be504b796af72e60e3c791b44d5a017b985f7a48 url: "https://pub.dev" source: hosted - version: "3.4.0" + version: "5.0.1" shared_preferences: dependency: "direct main" description: name: shared_preferences - sha256: d3bbe5553a986e83980916ded2f0b435ef2e1893dfaa29d5a7a790d0eca12180 + sha256: "746e5369a43170c25816cc472ee016d3a66bc13fcf430c0bc41ad7b4b2922051" url: "https://pub.dev" source: hosted - version: "2.2.3" + version: "2.3.2" shared_preferences_android: dependency: transitive description: @@ -1174,10 +1166,10 @@ packages: dependency: transitive description: name: shared_preferences_web - sha256: "7b15ffb9387ea3e237bb7a66b8a23d2147663d391cafc5c8f37b2e7b4bde5d21" + sha256: d2ca4132d3946fec2184261726b355836a82c33d7d5b67af32692aff18a4684e url: "https://pub.dev" source: hosted - version: "2.2.2" + version: "2.4.2" shared_preferences_windows: dependency: transitive description: @@ -1443,10 +1435,10 @@ packages: dependency: transitive description: name: url_launcher_android - sha256: "8fc3bae0b68c02c47c5c86fa8bfa74471d42687b0eded01b78de87872db745e2" + sha256: "0dea215895a4d254401730ca0ba8204b29109a34a99fb06ae559a2b60988d2de" url: "https://pub.dev" source: hosted - version: "6.3.12" + version: "6.3.13" url_launcher_ios: dependency: transitive description: @@ -1483,10 +1475,10 @@ packages: dependency: transitive description: name: url_launcher_web - sha256: fff0932192afeedf63cdd50ecbb1bc825d31aed259f02bb8dba0f3b729a5e88b + sha256: "772638d3b34c779ede05ba3d38af34657a05ac55b06279ea6edd409e323dca8e" url: "https://pub.dev" source: hosted - version: "2.2.3" + version: "2.3.3" url_launcher_windows: dependency: transitive description: @@ -1555,18 +1547,26 @@ packages: dependency: transitive description: name: web - sha256: "4188706108906f002b3a293509234588823c8c979dc83304e229ff400c996b05" + sha256: cd3543bd5798f6ad290ea73d210f423502e71900302dde696f8bff84bf89a1cb url: "https://pub.dev" source: hosted - version: "0.4.2" + version: "1.1.0" + web_socket: + dependency: transitive + description: + name: web_socket + sha256: "3c12d96c0c9a4eec095246debcea7b86c0324f22df69893d538fcc6f1b8cce83" + url: "https://pub.dev" + source: hosted + version: "0.1.6" web_socket_channel: dependency: transitive description: name: web_socket_channel - sha256: "939ab60734a4f8fa95feacb55804fa278de28bdeef38e616dc08e44a84adea23" + sha256: "9f187088ed104edd8662ca07af4b124465893caf063ba29758f97af57e61da8f" url: "https://pub.dev" source: hosted - version: "2.4.3" + version: "3.0.1" webview_flutter: dependency: "direct main" description: @@ -1603,10 +1603,10 @@ packages: dependency: transitive description: name: win32 - sha256: "2294c64768987ea280b43a3d8357d42d5679f3e2b5b69b602be45b2abbd165b0" + sha256: e1d0cc62e65dc2561f5071fcbccecf58ff20c344f8f3dc7d4922df372a11df1f url: "https://pub.dev" source: hosted - version: "5.6.1" + version: "5.7.1" win32_registry: dependency: transitive description: diff --git a/pubspec.yaml b/pubspec.yaml index 1df057303..1f1b08979 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -5,7 +5,7 @@ description: The 4th generation of ÉTSMobile, the main gateway between the Éco # pub.dev using `pub publish`. This is preferred for private packages. publish_to: 'none' # Remove this line if you wish to publish to pub.dev -version: 4.53.1+1 +version: 4.53.2 environment: sdk: '>=3.3.0 <4.0.0' @@ -17,55 +17,63 @@ dependencies: sdk: flutter # Architecture - get_it: ^7.6.7 + get_it: ^7.1.4 provider: ^6.1.2 - stacked: ^3.4.2 + stacked: ^3.4.3 # Firebase - firebase_core: ^2.3.0 - firebase_analytics: ^10.0.6 - firebase_crashlytics: ^3.0.6 - firebase_remote_config: ^4.3.13 + firebase_core: ^3.6.0 + firebase_analytics: ^11.3.3 + firebase_crashlytics: ^4.1.3 + firebase_remote_config: ^5.1.3 - # Utils - logger: ^2.3.0 + # Web url_launcher: ^6.3.1 + webview_flutter: ^4.10.0 + flutter_custom_tabs: ^2.1.0 + + # Utils + logger: ^2.4.0 enum_to_string: ^2.0.1 - fluttertoast: ^8.2.4 + fluttertoast: ^8.2.8 # Widgets - table_calendar: ^3.0.9 + table_calendar: ^3.1.2 percent_indicator: ^4.2.3 - feedback: ^3.0.0 + feedback: ^3.1.0 + + # Animations flutter_staggered_animations: ^1.1.1 + shimmer: ^3.0.0 + skeletonizer: ^1.4.2 - # Other - flutter_cache_manager: ^3.0.1 - flutter_secure_storage: ^9.0.0 - shared_preferences: ^2.2.2 - webview_flutter: ^4.7.0 - flutter_custom_tabs: ^2.0.0+1 - google_maps_flutter: ^2.5.3 - github: ^9.1.0 - package_info_plus: ^5.0.1 - connectivity_plus: ^6.0.1 - flutter_svg: ^2.0.9 + # Google + google_maps_flutter: ^2.9.0 + shared_preferences: ^2.3.2 + pub_semver: ^2.1.4 + flutter_markdown: ^0.7.4 + + # flutter community + package_info_plus: ^8.1.0 + connectivity_plus: ^6.1.0 + flutter_svg: ^2.0.10 font_awesome_flutter: ^10.7.0 + device_info_plus: ^11.1.0 + share_plus: ^10.1.1 + + # Other + flutter_cache_manager: ^3.4.1 + flutter_secure_storage: ^9.2.2 + github: ^9.24.0 in_app_review: ^2.0.9 - device_info_plus: ^9.1.2 - pub_semver: ^2.1.4 auto_size_text: ^3.0.0 easter_egg_trigger: ^1.0.1 - timeago: ^3.3.0 - calendar_view: ^1.1.0 + timeago: ^3.7.0 + calendar_view: ^1.2.0 carousel_slider: ^5.0.0 reorderable_grid_view: ^2.2.8 - shimmer: ^3.0.0 infinite_scroll_pagination: ^4.0.0 - device_calendar: ^4.3.1 - share_plus: ^7.2.2 - flutter_markdown: ^0.7.1 - skeletonizer: ^1.3.0 + device_calendar: ^4.3.3 dev_dependencies: flutter_test: @@ -74,7 +82,7 @@ dev_dependencies: mockito: ^5.4.4 flutter_config: ^2.0.2 flutter_launcher_icons: ^0.14.1 - build_runner: ^2.4.8 + build_runner: ^2.4.13 import_sorter: ^4.6.0 flutter_icons: From a1078f95581594d6606de1d69641f06d48f202a9 Mon Sep 17 00:00:00 2001 From: Xavier Paquet-Rapold Date: Fri, 25 Oct 2024 20:12:33 -0400 Subject: [PATCH 03/19] First test fix --- .../app/widgets/base_scaffold_test.dart | 18 +++------ .../dashboard/dashboard_view_test.dart | 37 ++++++------------- test/features/ets/ets_view_test.dart | 3 +- .../ets/quick-link/quick_links_view_test.dart | 3 +- test/features/more/more_view_test.dart | 21 +++++------ .../more/settings/settings_view_test.dart | 13 +++---- .../features/schedule/schedule_view_test.dart | 3 +- .../grades_details_view_test.dart | 18 +++------ .../student/grades/grades_view_test.dart | 8 ++-- .../widgets/grade_evaluation_tile_test.dart | 7 +--- test/features/student/student_view_test.dart | 3 +- 11 files changed, 49 insertions(+), 85 deletions(-) diff --git a/test/features/app/widgets/base_scaffold_test.dart b/test/features/app/widgets/base_scaffold_test.dart index dc5a73c5e..ae85b073b 100644 --- a/test/features/app/widgets/base_scaffold_test.dart +++ b/test/features/app/widgets/base_scaffold_test.dart @@ -2,7 +2,6 @@ import 'package:flutter/material.dart'; // Package imports: -import 'package:feature_discovery_fork/feature_discovery.dart'; import 'package:flutter_test/flutter_test.dart'; // Project imports: @@ -30,8 +29,7 @@ void main() { 'has a loading overlay (without the loading visible) widget and a bottom bar', (WidgetTester tester) async { await tester.pumpWidget(localizedWidget( - child: FeatureDiscovery(child: const BaseScaffold(body: SizedBox())), - useScaffold: false)); + child: const BaseScaffold(body: SizedBox()))); await tester.pumpAndSettle(); expect(find.byType(NavigationRail), findsOneWidget); @@ -41,10 +39,9 @@ void main() { group('loading - ', () { testWidgets('the loading is displayed if isLoading is true', (WidgetTester tester) async { - await tester.pumpWidget(FeatureDiscovery( - child: const MaterialApp( + await tester.pumpWidget(const MaterialApp( home: BaseScaffold( - body: SizedBox(), isLoading: true, showBottomBar: false)))); + body: SizedBox(), isLoading: true, showBottomBar: false))); expect(find.byType(CircularProgressIndicator), findsOneWidget); }); @@ -52,8 +49,7 @@ void main() { testWidgets("the loading isn't displayed if isLoading is false", (WidgetTester tester) async { await tester.pumpWidget(localizedWidget( - child: - FeatureDiscovery(child: const BaseScaffold(body: SizedBox())), + child: const BaseScaffold(body: SizedBox()), useScaffold: false)); await tester.pumpAndSettle(); @@ -65,8 +61,7 @@ void main() { testWidgets("by default doesn't have an appBar if appBar is set", (WidgetTester tester) async { await tester.pumpWidget(localizedWidget( - child: - FeatureDiscovery(child: const BaseScaffold(body: SizedBox())), + child: const BaseScaffold(body: SizedBox()), useScaffold: false)); await tester.pumpAndSettle(); @@ -78,8 +73,7 @@ void main() { testWidgets('has an appBar if appBar is set', (WidgetTester tester) async { await tester.pumpWidget(localizedWidget( - child: FeatureDiscovery( - child: BaseScaffold(appBar: AppBar(), body: const SizedBox())), + child: BaseScaffold(appBar: AppBar(), body: const SizedBox()), useScaffold: false)); await tester.pumpAndSettle(); diff --git a/test/features/dashboard/dashboard_view_test.dart b/test/features/dashboard/dashboard_view_test.dart index 11c8b4419..3d278107d 100644 --- a/test/features/dashboard/dashboard_view_test.dart +++ b/test/features/dashboard/dashboard_view_test.dart @@ -2,7 +2,6 @@ import 'package:flutter/material.dart'; // Package imports: -import 'package:feature_discovery_fork/feature_discovery.dart'; import 'package:flutter_gen/gen_l10n/app_localizations.dart'; import 'package:flutter_test/flutter_test.dart'; import 'package:shared_preferences/shared_preferences.dart'; @@ -154,8 +153,7 @@ void main() { SettingsManagerMock.stubDateTimeNow(settingsManagerMock, toReturn: now); await tester.pumpWidget(localizedWidget( - child: FeatureDiscovery( - child: const DashboardView()))); + child: const DashboardView())); await tester.pumpAndSettle(); // Find schedule card in second position by its title @@ -231,8 +229,7 @@ void main() { toReturn: dashboard); await tester.pumpWidget(localizedWidget( - child: FeatureDiscovery( - child: const DashboardView()))); + child: const DashboardView())); await tester.pumpAndSettle(); // Find Dashboard Title @@ -264,8 +261,7 @@ void main() { toReturn: dashboard); await tester.pumpWidget(localizedWidget( - child: FeatureDiscovery( - child: const DashboardView()))); + child: const DashboardView())); await tester.pumpAndSettle(); // Find aboutUs card @@ -371,8 +367,7 @@ void main() { settingsManagerMock, PreferencesFlag.progressBarCard); await tester.pumpWidget(localizedWidget( - child: FeatureDiscovery( - child: const DashboardView()))); + child: const DashboardView())); await tester.pumpAndSettle(); // Find Dismissible Cards @@ -424,8 +419,7 @@ void main() { settingsManagerMock, PreferencesFlag.progressBarCard); await tester.pumpWidget(localizedWidget( - child: FeatureDiscovery( - child: const DashboardView()))); + child: const DashboardView())); await tester.pumpAndSettle(); // Find Dismissible Cards @@ -485,8 +479,7 @@ void main() { toReturn: dashboard); await tester.pumpWidget(localizedWidget( - child: FeatureDiscovery( - child: const DashboardView()))); + child: const DashboardView())); await tester.pumpAndSettle(); // Find Dismissible Cards @@ -526,8 +519,7 @@ void main() { toReturn: dashboard); await tester.pumpWidget(localizedWidget( - child: FeatureDiscovery( - child: const DashboardView()))); + child: const DashboardView())); await tester.pumpAndSettle(); // Find grades card @@ -559,8 +551,7 @@ void main() { toReturn: dashboard); await tester.pumpWidget(localizedWidget( - child: FeatureDiscovery( - child: const DashboardView()))); + child: const DashboardView())); await tester.pumpAndSettle(); // Find grades card @@ -594,8 +585,7 @@ void main() { toReturn: dashboard); await tester.pumpWidget(localizedWidget( - child: FeatureDiscovery( - child: const DashboardView()))); + child: const DashboardView())); await tester.pumpAndSettle(); // Find Dismissible Cards @@ -637,8 +627,7 @@ void main() { toReturn: dashboard); await tester.pumpWidget(localizedWidget( - child: FeatureDiscovery( - child: const DashboardView()))); + child: const DashboardView())); await tester.pumpAndSettle(); // Find progress card @@ -660,8 +649,7 @@ void main() { toReturn: dashboard); await tester.pumpWidget(localizedWidget( - child: FeatureDiscovery( - child: const DashboardView()))); + child: const DashboardView())); await tester.pumpAndSettle(); // Find Dismissible Cards @@ -700,8 +688,7 @@ void main() { toReturn: dashboard); await tester.pumpWidget(localizedWidget( - child: FeatureDiscovery( - child: const DashboardView()))); + child: const DashboardView())); await tester.pumpAndSettle(); // Find Dismissible Cards diff --git a/test/features/ets/ets_view_test.dart b/test/features/ets/ets_view_test.dart index 5c4826dfb..8cfa318ca 100644 --- a/test/features/ets/ets_view_test.dart +++ b/test/features/ets/ets_view_test.dart @@ -2,7 +2,6 @@ import 'package:flutter/material.dart'; // Package imports: -import 'package:feature_discovery_fork/feature_discovery.dart'; import 'package:flutter_test/flutter_test.dart'; // Project imports: @@ -150,7 +149,7 @@ void main() { testWidgets('has Tab bar and sliverAppBar and BaseScaffold', (WidgetTester tester) async { await tester.pumpWidget( - localizedWidget(child: FeatureDiscovery(child: ETSView()))); + localizedWidget(child: ETSView())); await tester.pumpAndSettle(const Duration(seconds: 1)); expect(find.byType(TabBar), findsOneWidget); diff --git a/test/features/ets/quick-link/quick_links_view_test.dart b/test/features/ets/quick-link/quick_links_view_test.dart index 7a190fa4b..3e5813b75 100644 --- a/test/features/ets/quick-link/quick_links_view_test.dart +++ b/test/features/ets/quick-link/quick_links_view_test.dart @@ -1,5 +1,4 @@ // Package imports: -import 'package:feature_discovery_fork/feature_discovery.dart'; import 'package:flutter_gen/gen_l10n/app_localizations.dart'; import 'package:flutter_test/flutter_test.dart'; @@ -49,7 +48,7 @@ void main() { group('UI - ', () { testWidgets('has X cards', (WidgetTester tester) async { await tester.pumpWidget(localizedWidget( - child: FeatureDiscovery(child: QuickLinksView()), + child: QuickLinksView(), useScaffold: false)); await tester.pumpAndSettle(); diff --git a/test/features/more/more_view_test.dart b/test/features/more/more_view_test.dart index 4c03bfb44..da555562c 100644 --- a/test/features/more/more_view_test.dart +++ b/test/features/more/more_view_test.dart @@ -2,7 +2,6 @@ import 'package:flutter/material.dart'; // Package imports: -import 'package:feature_discovery_fork/feature_discovery.dart'; import 'package:flutter_gen/gen_l10n/app_localizations.dart'; import 'package:flutter_test/flutter_test.dart'; import 'package:mockito/mockito.dart'; @@ -58,7 +57,7 @@ void main() { remoteConfigServiceMock, toReturn: false); await tester.pumpWidget( - localizedWidget(child: FeatureDiscovery(child: MoreView()))); + localizedWidget(child: MoreView())); await tester.pumpAndSettle(const Duration(seconds: 1)); final listview = find.byType(ListView); @@ -71,7 +70,7 @@ void main() { testWidgets('has 1 listView and 9 listTiles when privacy policy enabled', (WidgetTester tester) async { await tester.pumpWidget( - localizedWidget(child: FeatureDiscovery(child: MoreView()))); + localizedWidget(child: MoreView())); await tester.pumpAndSettle(const Duration(seconds: 1)); final listview = find.byType(ListView); @@ -87,7 +86,7 @@ void main() { remoteConfigServiceMock, toReturn: false); await tester.pumpWidget( - localizedWidget(child: FeatureDiscovery(child: MoreView()))); + localizedWidget(child: MoreView())); await tester.pumpAndSettle(const Duration(seconds: 1)); // Tap the button. @@ -108,7 +107,7 @@ void main() { toReturn: false); await tester.pumpWidget( - localizedWidget(child: FeatureDiscovery(child: MoreView()))); + localizedWidget(child: MoreView())); await tester.pumpAndSettle(); // Tap the button. @@ -129,7 +128,7 @@ void main() { InAppReviewServiceMock.stubIsAvailable(inAppReviewServiceMock); await tester.pumpWidget( - localizedWidget(child: FeatureDiscovery(child: MoreView()))); + localizedWidget(child: MoreView())); await tester.pumpAndSettle(); // Tap the button. @@ -149,7 +148,7 @@ void main() { remoteConfigServiceMock, toReturn: false); await tester.pumpWidget( - localizedWidget(child: FeatureDiscovery(child: MoreView()))); + localizedWidget(child: MoreView())); await tester.pumpAndSettle(const Duration(seconds: 1)); // Tap the button. @@ -168,7 +167,7 @@ void main() { remoteConfigServiceMock, toReturn: false); await tester.pumpWidget( - localizedWidget(child: FeatureDiscovery(child: MoreView()))); + localizedWidget(child: MoreView())); await tester.pumpAndSettle(const Duration(seconds: 1)); // Tap the button. @@ -188,7 +187,7 @@ void main() { remoteConfigServiceMock, toReturn: false); await tester.pumpWidget( - localizedWidget(child: FeatureDiscovery(child: MoreView()))); + localizedWidget(child: MoreView())); await tester.pumpAndSettle(const Duration(seconds: 1)); // Tap the button. @@ -207,7 +206,7 @@ void main() { remoteConfigServiceMock, toReturn: false); await tester.pumpWidget( - localizedWidget(child: FeatureDiscovery(child: MoreView()))); + localizedWidget(child: MoreView())); await tester.pumpAndSettle(const Duration(seconds: 1)); // Tap the button. @@ -225,7 +224,7 @@ void main() { remoteConfigServiceMock, toReturn: false); await tester.pumpWidget( - localizedWidget(child: FeatureDiscovery(child: MoreView()))); + localizedWidget(child: MoreView())); await tester.pumpAndSettle(const Duration(seconds: 1)); // Tap the button. diff --git a/test/features/more/settings/settings_view_test.dart b/test/features/more/settings/settings_view_test.dart index 44ef2ec28..5d819b854 100644 --- a/test/features/more/settings/settings_view_test.dart +++ b/test/features/more/settings/settings_view_test.dart @@ -2,7 +2,6 @@ import 'package:flutter/material.dart'; // Package imports: -import 'package:feature_discovery_fork/feature_discovery.dart'; import 'package:flutter_gen/gen_l10n/app_localizations.dart'; import 'package:flutter_test/flutter_test.dart'; @@ -34,7 +33,7 @@ void main() { testWidgets('has 1 listView and 4 listTiles and 1 divider', (WidgetTester tester) async { await tester.pumpWidget( - localizedWidget(child: FeatureDiscovery(child: SettingsView()))); + localizedWidget(child: SettingsView())); await tester.pumpAndSettle(); final listview = find.byType(ListView); @@ -50,7 +49,7 @@ void main() { group('Theme button - ', () { testWidgets('light theme', (WidgetTester tester) async { await tester.pumpWidget( - localizedWidget(child: FeatureDiscovery(child: SettingsView()))); + localizedWidget(child: SettingsView())); await tester.pumpAndSettle(); // Tap the button. @@ -73,7 +72,7 @@ void main() { testWidgets('dark theme', (WidgetTester tester) async { await tester.pumpWidget( - localizedWidget(child: FeatureDiscovery(child: SettingsView()))); + localizedWidget(child: SettingsView())); await tester.pumpAndSettle(); // Tap the button. @@ -96,7 +95,7 @@ void main() { testWidgets('system theme', (WidgetTester tester) async { await tester.pumpWidget( - localizedWidget(child: FeatureDiscovery(child: SettingsView()))); + localizedWidget(child: SettingsView())); await tester.pumpAndSettle(); // Tap the button. @@ -121,7 +120,7 @@ void main() { group('Language button - ', () { testWidgets('french', (WidgetTester tester) async { await tester.pumpWidget( - localizedWidget(child: FeatureDiscovery(child: SettingsView()))); + localizedWidget(child: SettingsView())); await tester.pumpAndSettle(); // Tap the button. @@ -144,7 +143,7 @@ void main() { testWidgets('english', (WidgetTester tester) async { await tester.pumpWidget( - localizedWidget(child: FeatureDiscovery(child: SettingsView()))); + localizedWidget(child: SettingsView())); await tester.pumpAndSettle(); // Tap the button. diff --git a/test/features/schedule/schedule_view_test.dart b/test/features/schedule/schedule_view_test.dart index 2361a3d82..2f1389208 100644 --- a/test/features/schedule/schedule_view_test.dart +++ b/test/features/schedule/schedule_view_test.dart @@ -2,7 +2,6 @@ import 'package:flutter/material.dart'; // Package imports: -import 'package:feature_discovery_fork/feature_discovery.dart'; import 'package:flutter_test/flutter_test.dart'; import 'package:notredame/utils/calendar_utils.dart'; import 'package:shared_preferences/shared_preferences.dart'; @@ -105,7 +104,7 @@ void main() { await tester.runAsync(() async { await tester.pumpWidget(localizedWidget( - child: FeatureDiscovery(child: const ScheduleView()))); + child: const ScheduleView())); await tester.pumpAndSettle(); }).then((value) async { expect(find.byType(ScheduleSettings), findsNothing, diff --git a/test/features/student/grades/grade_details/grades_details_view_test.dart b/test/features/student/grades/grade_details/grades_details_view_test.dart index ad7aa104d..d6a2e711b 100644 --- a/test/features/student/grades/grade_details/grades_details_view_test.dart +++ b/test/features/student/grades/grade_details/grades_details_view_test.dart @@ -2,7 +2,6 @@ import 'package:flutter/material.dart'; // Package imports: -import 'package:feature_discovery_fork/feature_discovery.dart'; import 'package:flutter_test/flutter_test.dart'; import 'package:shared_preferences/shared_preferences.dart'; @@ -126,8 +125,7 @@ void main() { toReturn: course); await tester.runAsync(() async { await tester.pumpWidget(localizedWidget( - child: - FeatureDiscovery(child: GradesDetailsView(course: course)))); + child: GradesDetailsView(course: course))); await tester.pumpAndSettle(const Duration(seconds: 2)); }).then( (value) { @@ -160,8 +158,7 @@ void main() { toReturn: course); await tester.runAsync(() async { await tester.pumpWidget(localizedWidget( - child: FeatureDiscovery( - child: GradesDetailsView(course: courseWithoutSummary)))); + child: GradesDetailsView(course: courseWithoutSummary))); await tester.pumpAndSettle(); }).then((value) { expect(find.byType(SliverAppBar), findsOneWidget); @@ -184,8 +181,7 @@ void main() { await tester.runAsync(() async { await tester.pumpWidget(localizedWidget( - child: FeatureDiscovery( - child: GradesDetailsView(course: courseWithoutSummary)))); + child: GradesDetailsView(course: courseWithoutSummary))); await tester.pumpAndSettle(); }).then((value) async { final gesture = await tester @@ -207,8 +203,7 @@ void main() { toReturn: courseWithoutSummary); await tester.pumpWidget(localizedWidget( - child: FeatureDiscovery( - child: GradesDetailsView(course: courseWithoutSummary)))); + child: GradesDetailsView(course: courseWithoutSummary))); await tester.pumpAndSettle(const Duration(seconds: 1)); expect(find.byKey(const Key("GradeNotAvailable")), findsOneWidget); @@ -223,9 +218,8 @@ void main() { toReturn: courseWithEvaluationNotCompleted); await tester.pumpWidget(localizedWidget( - child: FeatureDiscovery( - child: GradesDetailsView( - course: courseWithEvaluationNotCompleted)))); + child: GradesDetailsView( + course: courseWithEvaluationNotCompleted))); await tester.pumpAndSettle(const Duration(seconds: 1)); expect(find.byKey(const Key("EvaluationNotCompleted")), findsOneWidget); diff --git a/test/features/student/grades/grades_view_test.dart b/test/features/student/grades/grades_view_test.dart index 587aa5bf6..0765f2e38 100644 --- a/test/features/student/grades/grades_view_test.dart +++ b/test/features/student/grades/grades_view_test.dart @@ -2,7 +2,6 @@ import 'package:flutter/material.dart'; // Package imports: -import 'package:feature_discovery_fork/feature_discovery.dart'; import 'package:flutter_gen/gen_l10n/app_localizations.dart'; import 'package:flutter_test/flutter_test.dart'; import 'package:shared_preferences/shared_preferences.dart'; @@ -92,7 +91,7 @@ void main() { tester.view.physicalSize = const Size(800, 1410); await tester.pumpWidget( - localizedWidget(child: FeatureDiscovery(child: GradesView()))); + localizedWidget(child: GradesView())); await tester.pumpAndSettle(const Duration(seconds: 1)); expect(find.text(intl.grades_msg_no_grades), findsOneWidget); @@ -111,9 +110,8 @@ void main() { tester.view.physicalSize = const Size(800, 1410); await tester.runAsync(() async { await tester.pumpWidget(localizedWidget( - child: FeatureDiscovery( - child: GradesView(), - ))); + child: GradesView(), + )); await tester.pumpAndSettle(const Duration(seconds: 10)); }).then((value) { // Check the summer session list of grades. diff --git a/test/features/student/grades/widgets/grade_evaluation_tile_test.dart b/test/features/student/grades/widgets/grade_evaluation_tile_test.dart index 0fbfae9e0..b917e3979 100644 --- a/test/features/student/grades/widgets/grade_evaluation_tile_test.dart +++ b/test/features/student/grades/widgets/grade_evaluation_tile_test.dart @@ -4,7 +4,6 @@ import 'package:flutter/material.dart'; // Package imports: -import 'package:feature_discovery_fork/feature_discovery.dart'; import 'package:flutter_gen/gen_l10n/app_localizations.dart'; import 'package:flutter_test/flutter_test.dart'; @@ -67,8 +66,7 @@ void main() { final evaluation = courseSummary.evaluations.first; await tester.pumpWidget(localizedWidget( - child: FeatureDiscovery( - child: GradeEvaluationTile(evaluation, completed: true)))); + child: GradeEvaluationTile(evaluation, completed: true))); await tester.pumpAndSettle(); final circularPercentIndicator = find.byType(GradeCircularProgress); @@ -86,8 +84,7 @@ void main() { final evaluation = courseSummary.evaluations.last; final widget = localizedWidget( - child: FeatureDiscovery( - child: GradeEvaluationTile(evaluation, completed: true))); + child: GradeEvaluationTile(evaluation, completed: true)); await tester.pumpWidget(widget); diff --git a/test/features/student/student_view_test.dart b/test/features/student/student_view_test.dart index e23aecc56..b3a0e492d 100644 --- a/test/features/student/student_view_test.dart +++ b/test/features/student/student_view_test.dart @@ -2,7 +2,6 @@ import 'package:flutter/material.dart'; // Package imports: -import 'package:feature_discovery_fork/feature_discovery.dart'; import 'package:flutter_test/flutter_test.dart'; // Project imports: @@ -43,7 +42,7 @@ void main() { testWidgets('has Tab bar and sliverAppBar and BaseScaffold', (WidgetTester tester) async { await tester.pumpWidget( - localizedWidget(child: FeatureDiscovery(child: StudentView()))); + localizedWidget(child: StudentView())); await tester.pumpAndSettle(const Duration(seconds: 1)); expect(find.byType(TabBar), findsOneWidget); From 60766e858410be745197b2336e61eb435dd0cbb1 Mon Sep 17 00:00:00 2001 From: Xavier Paquet-Rapold Date: Fri, 25 Oct 2024 21:14:41 -0400 Subject: [PATCH 04/19] Fix last tests --- lib/features/dashboard/dashboard_view.dart | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/lib/features/dashboard/dashboard_view.dart b/lib/features/dashboard/dashboard_view.dart index b9e921a2f..5ff0dad3b 100644 --- a/lib/features/dashboard/dashboard_view.dart +++ b/lib/features/dashboard/dashboard_view.dart @@ -58,6 +58,12 @@ class _DashboardViewState extends State appBar: AppBar( title: Text(AppIntl.of(context)!.title_dashboard), centerTitle: false, + actions: [ + IconButton( + icon: const Icon(Icons.restore), + onPressed: () => model.setAllCardsVisible(), + ) + ], automaticallyImplyLeading: false), body: model.cards == null ? buildLoading() From 6493261841a7b3c38d7df8b469a9ea59d370f23d Mon Sep 17 00:00:00 2001 From: Xavier Paquet-Rapold Date: Fri, 25 Oct 2024 21:37:23 -0400 Subject: [PATCH 05/19] Fix analyze --- .../widgets/security-info/security_view.dart | 1 + .../widgets/security-info/security_viewmodel.dart | 13 +++++-------- 2 files changed, 6 insertions(+), 8 deletions(-) diff --git a/lib/features/ets/quick-link/widgets/security-info/security_view.dart b/lib/features/ets/quick-link/widgets/security-info/security_view.dart index 64455c1e5..da1362ad3 100644 --- a/lib/features/ets/quick-link/widgets/security-info/security_view.dart +++ b/lib/features/ets/quick-link/widgets/security-info/security_view.dart @@ -44,6 +44,7 @@ class _SecurityViewState extends State { height: 250, child: GoogleMap( initialCameraPosition: _etsLocation, + style: model.mapStyle, zoomControlsEnabled: false, markers: model.getSecurityMarkersForMaps(model.markersList), diff --git a/lib/features/ets/quick-link/widgets/security-info/security_viewmodel.dart b/lib/features/ets/quick-link/widgets/security-info/security_viewmodel.dart index 995eea47d..d13912f94 100644 --- a/lib/features/ets/quick-link/widgets/security-info/security_viewmodel.dart +++ b/lib/features/ets/quick-link/widgets/security-info/security_viewmodel.dart @@ -14,6 +14,7 @@ import 'package:notredame/features/ets/quick-link/widgets/security-info/models/e class SecurityViewModel extends BaseViewModel { GoogleMapController? controller; + String? mapStyle; final List emergencyProcedureList; @@ -39,16 +40,12 @@ class SecurityViewModel extends BaseViewModel { } /// Used to change the color of the map based on the brightness - void changeMapMode(BuildContext context) { + Future changeMapMode(BuildContext context) async { if (Theme.of(context).brightness == Brightness.dark) { - getJsonFile("assets/dark_map_style.json").then(setMapStyle); + mapStyle = await getJsonFile("assets/dark_map_style.json"); } else { - getJsonFile("assets/normal_map_style.json").then(setMapStyle); + mapStyle = await getJsonFile("assets/normal_map_style.json"); } - } - - /// Used to set the color of the map - void setMapStyle(String mapStyle) { - controller?.setMapStyle(mapStyle); + notifyListeners(); } } From 47b3d0195f393bff636f8e11c8aef79142f4a369 Mon Sep 17 00:00:00 2001 From: XavierPaquet-Rapold Date: Sat, 26 Oct 2024 01:44:06 +0000 Subject: [PATCH 06/19] [BOT] Applying pod update. --- ios/Podfile.lock | 277 ++++++++++++++++++++++++----------------------- 1 file changed, 140 insertions(+), 137 deletions(-) diff --git a/ios/Podfile.lock b/ios/Podfile.lock index ed8fb9440..02eb87ee2 100644 --- a/ios/Podfile.lock +++ b/ios/Podfile.lock @@ -6,92 +6,95 @@ PODS: - Flutter - device_info_plus (0.0.1): - Flutter - - Firebase/Analytics (10.22.0): + - Firebase/Analytics (11.2.0): - Firebase/Core - - Firebase/Core (10.22.0): + - Firebase/Core (11.2.0): - Firebase/CoreOnly - - FirebaseAnalytics (~> 10.22.0) - - Firebase/CoreOnly (10.22.0): - - FirebaseCore (= 10.22.0) - - Firebase/Crashlytics (10.22.0): + - FirebaseAnalytics (~> 11.2.0) + - Firebase/CoreOnly (11.2.0): + - FirebaseCore (= 11.2.0) + - Firebase/Crashlytics (11.2.0): - Firebase/CoreOnly - - FirebaseCrashlytics (~> 10.22.0) - - Firebase/RemoteConfig (10.22.0): + - FirebaseCrashlytics (~> 11.2.0) + - Firebase/RemoteConfig (11.2.0): - Firebase/CoreOnly - - FirebaseRemoteConfig (~> 10.22.0) - - firebase_analytics (10.8.9): - - Firebase/Analytics (= 10.22.0) + - FirebaseRemoteConfig (~> 11.2.0) + - firebase_analytics (11.3.3): + - Firebase/Analytics (= 11.2.0) - firebase_core - Flutter - - firebase_core (2.27.0): - - Firebase/CoreOnly (= 10.22.0) + - firebase_core (3.6.0): + - Firebase/CoreOnly (= 11.2.0) - Flutter - - firebase_crashlytics (3.4.18): - - Firebase/Crashlytics (= 10.22.0) + - firebase_crashlytics (4.1.3): + - Firebase/Crashlytics (= 11.2.0) - firebase_core - Flutter - - firebase_remote_config (4.3.17): - - Firebase/RemoteConfig (= 10.22.0) + - firebase_remote_config (5.1.3): + - Firebase/RemoteConfig (= 11.2.0) - firebase_core - Flutter - - FirebaseABTesting (10.29.0): - - FirebaseCore (~> 10.0) - - FirebaseAnalytics (10.22.0): - - FirebaseAnalytics/AdIdSupport (= 10.22.0) - - FirebaseCore (~> 10.0) - - FirebaseInstallations (~> 10.0) - - GoogleUtilities/AppDelegateSwizzler (~> 7.11) - - GoogleUtilities/MethodSwizzler (~> 7.11) - - GoogleUtilities/Network (~> 7.11) - - "GoogleUtilities/NSData+zlib (~> 7.11)" - - nanopb (< 2.30911.0, >= 2.30908.0) - - FirebaseAnalytics/AdIdSupport (10.22.0): - - FirebaseCore (~> 10.0) - - FirebaseInstallations (~> 10.0) - - GoogleAppMeasurement (= 10.22.0) - - GoogleUtilities/AppDelegateSwizzler (~> 7.11) - - GoogleUtilities/MethodSwizzler (~> 7.11) - - GoogleUtilities/Network (~> 7.11) - - "GoogleUtilities/NSData+zlib (~> 7.11)" - - nanopb (< 2.30911.0, >= 2.30908.0) - - FirebaseCore (10.22.0): - - FirebaseCoreInternal (~> 10.0) - - GoogleUtilities/Environment (~> 7.12) - - GoogleUtilities/Logger (~> 7.12) - - FirebaseCoreExtension (10.29.0): - - FirebaseCore (~> 10.0) - - FirebaseCoreInternal (10.29.0): - - "GoogleUtilities/NSData+zlib (~> 7.8)" - - FirebaseCrashlytics (10.22.0): - - FirebaseCore (~> 10.5) - - FirebaseInstallations (~> 10.0) - - FirebaseSessions (~> 10.5) - - GoogleDataTransport (~> 9.2) - - GoogleUtilities/Environment (~> 7.8) - - nanopb (< 2.30911.0, >= 2.30908.0) - - PromisesObjC (~> 2.1) - - FirebaseInstallations (10.29.0): - - FirebaseCore (~> 10.0) - - GoogleUtilities/Environment (~> 7.8) - - GoogleUtilities/UserDefaults (~> 7.8) - - PromisesObjC (~> 2.1) - - FirebaseRemoteConfig (10.22.0): - - FirebaseABTesting (~> 10.0) - - FirebaseCore (~> 10.0) - - FirebaseInstallations (~> 10.0) - - FirebaseSharedSwift (~> 10.0) - - GoogleUtilities/Environment (~> 7.8) - - "GoogleUtilities/NSData+zlib (~> 7.8)" - - FirebaseSessions (10.29.0): - - FirebaseCore (~> 10.5) - - FirebaseCoreExtension (~> 10.0) - - FirebaseInstallations (~> 10.0) - - GoogleDataTransport (~> 9.2) - - GoogleUtilities/Environment (~> 7.13) - - GoogleUtilities/UserDefaults (~> 7.13) - - nanopb (< 2.30911.0, >= 2.30908.0) + - FirebaseABTesting (11.4.0): + - FirebaseCore (~> 11.0) + - FirebaseAnalytics (11.2.0): + - FirebaseAnalytics/AdIdSupport (= 11.2.0) + - FirebaseCore (~> 11.0) + - FirebaseInstallations (~> 11.0) + - GoogleUtilities/AppDelegateSwizzler (~> 8.0) + - GoogleUtilities/MethodSwizzler (~> 8.0) + - GoogleUtilities/Network (~> 8.0) + - "GoogleUtilities/NSData+zlib (~> 8.0)" + - nanopb (~> 3.30910.0) + - FirebaseAnalytics/AdIdSupport (11.2.0): + - FirebaseCore (~> 11.0) + - FirebaseInstallations (~> 11.0) + - GoogleAppMeasurement (= 11.2.0) + - GoogleUtilities/AppDelegateSwizzler (~> 8.0) + - GoogleUtilities/MethodSwizzler (~> 8.0) + - GoogleUtilities/Network (~> 8.0) + - "GoogleUtilities/NSData+zlib (~> 8.0)" + - nanopb (~> 3.30910.0) + - FirebaseCore (11.2.0): + - FirebaseCoreInternal (~> 11.0) + - GoogleUtilities/Environment (~> 8.0) + - GoogleUtilities/Logger (~> 8.0) + - FirebaseCoreExtension (11.4.1): + - FirebaseCore (~> 11.0) + - FirebaseCoreInternal (11.4.2): + - "GoogleUtilities/NSData+zlib (~> 8.0)" + - FirebaseCrashlytics (11.2.0): + - FirebaseCore (~> 11.0) + - FirebaseInstallations (~> 11.0) + - FirebaseRemoteConfigInterop (~> 11.0) + - FirebaseSessions (~> 11.0) + - GoogleDataTransport (~> 10.0) + - GoogleUtilities/Environment (~> 8.0) + - nanopb (~> 3.30910.0) + - PromisesObjC (~> 2.4) + - FirebaseInstallations (11.4.0): + - FirebaseCore (~> 11.0) + - GoogleUtilities/Environment (~> 8.0) + - GoogleUtilities/UserDefaults (~> 8.0) + - PromisesObjC (~> 2.4) + - FirebaseRemoteConfig (11.2.0): + - FirebaseABTesting (~> 11.0) + - FirebaseCore (~> 11.0) + - FirebaseInstallations (~> 11.0) + - FirebaseRemoteConfigInterop (~> 11.0) + - FirebaseSharedSwift (~> 11.0) + - GoogleUtilities/Environment (~> 8.0) + - "GoogleUtilities/NSData+zlib (~> 8.0)" + - FirebaseRemoteConfigInterop (11.4.0) + - FirebaseSessions (11.3.0): + - FirebaseCore (~> 11.0) + - FirebaseCoreExtension (~> 11.0) + - FirebaseInstallations (~> 11.0) + - GoogleDataTransport (~> 10.0) + - GoogleUtilities/Environment (~> 8.0) + - GoogleUtilities/UserDefaults (~> 8.0) + - nanopb (~> 3.30910.0) - PromisesSwift (~> 2.1) - - FirebaseSharedSwift (10.29.0) + - FirebaseSharedSwift (11.4.0) - Flutter (1.0.0) - flutter_config (0.0.1): - Flutter @@ -108,70 +111,68 @@ PODS: - Flutter - Google-Maps-iOS-Utils (< 7.0, >= 5.0) - GoogleMaps (< 10.0, >= 8.4) - - GoogleAppMeasurement (10.22.0): - - GoogleAppMeasurement/AdIdSupport (= 10.22.0) - - GoogleUtilities/AppDelegateSwizzler (~> 7.11) - - GoogleUtilities/MethodSwizzler (~> 7.11) - - GoogleUtilities/Network (~> 7.11) - - "GoogleUtilities/NSData+zlib (~> 7.11)" - - nanopb (< 2.30911.0, >= 2.30908.0) - - GoogleAppMeasurement/AdIdSupport (10.22.0): - - GoogleAppMeasurement/WithoutAdIdSupport (= 10.22.0) - - GoogleUtilities/AppDelegateSwizzler (~> 7.11) - - GoogleUtilities/MethodSwizzler (~> 7.11) - - GoogleUtilities/Network (~> 7.11) - - "GoogleUtilities/NSData+zlib (~> 7.11)" - - nanopb (< 2.30911.0, >= 2.30908.0) - - GoogleAppMeasurement/WithoutAdIdSupport (10.22.0): - - GoogleUtilities/AppDelegateSwizzler (~> 7.11) - - GoogleUtilities/MethodSwizzler (~> 7.11) - - GoogleUtilities/Network (~> 7.11) - - "GoogleUtilities/NSData+zlib (~> 7.11)" - - nanopb (< 2.30911.0, >= 2.30908.0) - - GoogleDataTransport (9.4.1): - - GoogleUtilities/Environment (~> 7.7) - - nanopb (< 2.30911.0, >= 2.30908.0) - - PromisesObjC (< 3.0, >= 1.2) + - GoogleAppMeasurement (11.2.0): + - GoogleAppMeasurement/AdIdSupport (= 11.2.0) + - GoogleUtilities/AppDelegateSwizzler (~> 8.0) + - GoogleUtilities/MethodSwizzler (~> 8.0) + - GoogleUtilities/Network (~> 8.0) + - "GoogleUtilities/NSData+zlib (~> 8.0)" + - nanopb (~> 3.30910.0) + - GoogleAppMeasurement/AdIdSupport (11.2.0): + - GoogleAppMeasurement/WithoutAdIdSupport (= 11.2.0) + - GoogleUtilities/AppDelegateSwizzler (~> 8.0) + - GoogleUtilities/MethodSwizzler (~> 8.0) + - GoogleUtilities/Network (~> 8.0) + - "GoogleUtilities/NSData+zlib (~> 8.0)" + - nanopb (~> 3.30910.0) + - GoogleAppMeasurement/WithoutAdIdSupport (11.2.0): + - GoogleUtilities/AppDelegateSwizzler (~> 8.0) + - GoogleUtilities/MethodSwizzler (~> 8.0) + - GoogleUtilities/Network (~> 8.0) + - "GoogleUtilities/NSData+zlib (~> 8.0)" + - nanopb (~> 3.30910.0) + - GoogleDataTransport (10.1.0): + - nanopb (~> 3.30910.0) + - PromisesObjC (~> 2.4) - GoogleMaps (8.4.0): - GoogleMaps/Maps (= 8.4.0) - GoogleMaps/Base (8.4.0) - GoogleMaps/Maps (8.4.0): - GoogleMaps/Base - - GoogleUtilities/AppDelegateSwizzler (7.13.3): + - GoogleUtilities/AppDelegateSwizzler (8.0.2): - GoogleUtilities/Environment - GoogleUtilities/Logger - GoogleUtilities/Network - GoogleUtilities/Privacy - - GoogleUtilities/Environment (7.13.3): + - GoogleUtilities/Environment (8.0.2): - GoogleUtilities/Privacy - - PromisesObjC (< 3.0, >= 1.2) - - GoogleUtilities/Logger (7.13.3): + - GoogleUtilities/Logger (8.0.2): - GoogleUtilities/Environment - GoogleUtilities/Privacy - - GoogleUtilities/MethodSwizzler (7.13.3): + - GoogleUtilities/MethodSwizzler (8.0.2): - GoogleUtilities/Logger - GoogleUtilities/Privacy - - GoogleUtilities/Network (7.13.3): + - GoogleUtilities/Network (8.0.2): - GoogleUtilities/Logger - "GoogleUtilities/NSData+zlib" - GoogleUtilities/Privacy - GoogleUtilities/Reachability - - "GoogleUtilities/NSData+zlib (7.13.3)": + - "GoogleUtilities/NSData+zlib (8.0.2)": - GoogleUtilities/Privacy - - GoogleUtilities/Privacy (7.13.3) - - GoogleUtilities/Reachability (7.13.3): + - GoogleUtilities/Privacy (8.0.2) + - GoogleUtilities/Reachability (8.0.2): - GoogleUtilities/Logger - GoogleUtilities/Privacy - - GoogleUtilities/UserDefaults (7.13.3): + - GoogleUtilities/UserDefaults (8.0.2): - GoogleUtilities/Logger - GoogleUtilities/Privacy - in_app_review (0.2.0): - Flutter - - nanopb (2.30910.0): - - nanopb/decode (= 2.30910.0) - - nanopb/encode (= 2.30910.0) - - nanopb/decode (2.30910.0) - - nanopb/encode (2.30910.0) + - nanopb (3.30910.0): + - nanopb/decode (= 3.30910.0) + - nanopb/encode (= 3.30910.0) + - nanopb/decode (3.30910.0) + - nanopb/encode (3.30910.0) - package_info_plus (0.4.5): - Flutter - path_provider_foundation (0.0.1): @@ -231,6 +232,7 @@ SPEC REPOS: - FirebaseCrashlytics - FirebaseInstallations - FirebaseRemoteConfig + - FirebaseRemoteConfigInterop - FirebaseSessions - FirebaseSharedSwift - Google-Maps-iOS-Utils @@ -295,42 +297,43 @@ CHECKOUT OPTIONS: :git: https://github.com/yahoojapan/SwiftyXMLParser.git SPEC CHECKSUMS: - connectivity_plus: ddd7f30999e1faaef5967c23d5b6d503d10434db + connectivity_plus: 4c41c08fc6d7c91f63bc7aec70ffe3730b04f563 device_calendar: 9cb33f88a02e19652ec7b8b122ca778f751b1f7b - device_info_plus: c6fb39579d0f423935b0c9ce7ee2f44b71b9fce6 - Firebase: 797fd7297b7e1be954432743a0b3f90038e45a71 - firebase_analytics: b9ce200bfc2c54629076bb22d6a510f31c296ab8 - firebase_core: 100945864b4aedce3cfef0c62ab864858bf013cf - firebase_crashlytics: 2b9ca6246501a03427eb43280be7615027e32142 - firebase_remote_config: 5ebb1bf2503404f6b24e64f117dc6c22c0498d4c - FirebaseABTesting: d87f56707159bae64e269757a6e963d490f2eebe - FirebaseAnalytics: 8d0ff929c63b7f72260f332b86ccf569776b75d3 - FirebaseCore: 0326ec9b05fbed8f8716cddbf0e36894a13837f7 - FirebaseCoreExtension: 705ca5b14bf71d2564a0ddc677df1fc86ffa600f - FirebaseCoreInternal: df84dd300b561c27d5571684f389bf60b0a5c934 - FirebaseCrashlytics: e568d68ce89117c80cddb04073ab9018725fbb8c - FirebaseInstallations: 913cf60d0400ebd5d6b63a28b290372ab44590dd - FirebaseRemoteConfig: e1b992a94d3674dddbcaf5d0d31a0312156ceb1c - FirebaseSessions: dbd14adac65ce996228652c1fc3a3f576bdf3ecc - FirebaseSharedSwift: 20530f495084b8d840f78a100d8c5ee613375f6e + device_info_plus: bf2e3232933866d73fe290f2942f2156cdd10342 + Firebase: 98e6bf5278170668a7983e12971a66b2cd57fc8c + firebase_analytics: fbc57838bdb94eef1e0ff504f127d974ff2981ad + firebase_core: 2bedc3136ec7c7b8561c6123ed0239387b53f2af + firebase_crashlytics: 37d104d457b51760b48504a93a12b3bf70995d77 + firebase_remote_config: d522653d828836503715498f1662901a6efcd809 + FirebaseABTesting: aef1719704fade00b200827e7973f352efc4caee + FirebaseAnalytics: c36efd5710c60c17558650fa58c2066eca7e9265 + FirebaseCore: a282032ae9295c795714ded2ec9c522fc237f8da + FirebaseCoreExtension: f1bc67a4702931a7caa097d8e4ac0a1b0d16720e + FirebaseCoreInternal: 35731192cab10797b88411be84940d2beb33a238 + FirebaseCrashlytics: cfc69af5b53565dc6a5e563788809b5778ac4eac + FirebaseInstallations: 6ef4a1c7eb2a61ee1f74727d7f6ce2e72acf1414 + FirebaseRemoteConfig: fca0b2d017fc1de52b28a4e5bcf2007c1a840457 + FirebaseRemoteConfigInterop: e76f46ffa4d6a65e273d4dfebb6a79e588cec136 + FirebaseSessions: 655ff17f3cc1a635cbdc2d69b953878001f9e25b + FirebaseSharedSwift: 505dae2d05969dbf6d43749a642bb1bf230f0252 Flutter: e0871f40cf51350855a761d2e70bf5af5b9b5de7 flutter_config: f48f0d47a284f1791aacce2687eabb3309ba7a41 flutter_custom_tabs_ios: a651b18786388923b62de8c0537607de87c2eccf flutter_secure_storage: d33dac7ae2ea08509be337e775f6b59f1ff45f12 - fluttertoast: 9f2f8e81bb5ce18facb9748d7855bf5a756fe3db + fluttertoast: e9a18c7be5413da53898f660530c56f35edfba9c Google-Maps-iOS-Utils: 66d6de12be1ce6d3742a54661e7a79cb317a9321 google_maps_flutter_ios: e31555a04d1986ab130f2b9f24b6cdc861acc6d3 - GoogleAppMeasurement: ccefe3eac9b0aa27f96066809fb1a7fe4b462626 - GoogleDataTransport: 6c09b596d841063d76d4288cc2d2f42cc36e1e2a + GoogleAppMeasurement: 76d4f8b36b03bd8381fa9a7fe2cc7f99c0a2e93a + GoogleDataTransport: aae35b7ea0c09004c3797d53c8c41f66f219d6a7 GoogleMaps: 8939898920281c649150e0af74aa291c60f2e77d - GoogleUtilities: ea963c370a38a8069cc5f7ba4ca849a60b6d7d15 + GoogleUtilities: 26a3abef001b6533cf678d3eb38fd3f614b7872d in_app_review: 318597b3a06c22bb46dc454d56828c85f444f99d - nanopb: 438bc412db1928dac798aa6fd75726007be04262 - package_info_plus: 115f4ad11e0698c8c1c5d8a689390df880f47e85 + nanopb: fad817b59e0457d11a5dfbde799381cd727c1275 + package_info_plus: c0502532a26c7662a62a356cebe2692ec5fe4ec4 path_provider_foundation: 2b6b4c569c0fb62ec74538f866245ac84301af46 PromisesObjC: f5707f49cb48b9636751c5b2e7d227e43fba9f47 PromisesSwift: 9d77319bbe72ebf6d872900551f7eeba9bce2851 - share_plus: c3fef564749587fc939ef86ffb283ceac0baf9f5 + share_plus: 8b6f8b3447e494cca5317c8c3073de39b3600d1f shared_preferences_foundation: fcdcbc04712aee1108ac7fda236f363274528f78 sqflite_darwin: a553b1fd6fe66f53bbb0fe5b4f5bab93f08d7a13 SwiftyXMLParser: 027d9e6fb54a38d95dccec025bcea9693f699c47 From 44c4b7b98e3e92325c62b54ff3ad897baa87aac8 Mon Sep 17 00:00:00 2001 From: Xavier Paquet-Rapold Date: Fri, 25 Oct 2024 22:18:27 -0400 Subject: [PATCH 07/19] Remove last discovery references --- .../discovery/en/dashboard_restore.gif | Bin 1155741 -> 0 bytes .../discovery/en/dashboard_swipe.gif | Bin 1835919 -> 0 bytes assets/animations/discovery/en/ets_link.gif | Bin 2719528 -> 0 bytes .../animations/discovery/en/grade_details.gif | Bin 2422997 -> 0 bytes assets/animations/discovery/en/more.jpg | Bin 49865 -> 0 bytes .../discovery/en/schedule_calendar.png | Bin 113608 -> 0 bytes .../discovery/en/schedule_settings.gif | Bin 1305840 -> 0 bytes .../discovery/fr/dashboard_restore.gif | Bin 393900 -> 0 bytes .../discovery/fr/dashboard_swipe.gif | Bin 829876 -> 0 bytes assets/animations/discovery/fr/ets_link.gif | Bin 2133908 -> 0 bytes .../animations/discovery/fr/grade_details.gif | Bin 1909697 -> 0 bytes assets/animations/discovery/fr/more.jpg | Bin 53633 -> 0 bytes .../discovery/fr/schedule_calendar.png | Bin 109768 -> 0 bytes .../discovery/fr/schedule_settings.gif | Bin 1009039 -> 0 bytes l10n/intl_en.arb | 30 ---------------- l10n/intl_fr.arb | 30 ---------------- lib/constants/preferences_flags.dart | 13 ------- .../app/storage/preferences_service.dart | 7 ---- lib/features/more/more_view.dart | 8 ++--- .../student/grades/widgets/grade_button.dart | 17 ++-------- pubspec.yaml | 2 -- .../app/startup/startup_viewmodel_test.dart | 24 +------------ .../app/storage/preferences_service_test.dart | 6 +--- .../dashboard/dashboard_view_test.dart | 4 --- test/features/more/more_view_test.dart | 9 +---- .../grades/widgets/grade_button_test.dart | 32 ------------------ 26 files changed, 8 insertions(+), 174 deletions(-) delete mode 100644 assets/animations/discovery/en/dashboard_restore.gif delete mode 100644 assets/animations/discovery/en/dashboard_swipe.gif delete mode 100644 assets/animations/discovery/en/ets_link.gif delete mode 100644 assets/animations/discovery/en/grade_details.gif delete mode 100644 assets/animations/discovery/en/more.jpg delete mode 100644 assets/animations/discovery/en/schedule_calendar.png delete mode 100644 assets/animations/discovery/en/schedule_settings.gif delete mode 100644 assets/animations/discovery/fr/dashboard_restore.gif delete mode 100644 assets/animations/discovery/fr/dashboard_swipe.gif delete mode 100644 assets/animations/discovery/fr/ets_link.gif delete mode 100644 assets/animations/discovery/fr/grade_details.gif delete mode 100644 assets/animations/discovery/fr/more.jpg delete mode 100644 assets/animations/discovery/fr/schedule_calendar.png delete mode 100644 assets/animations/discovery/fr/schedule_settings.gif diff --git a/assets/animations/discovery/en/dashboard_restore.gif b/assets/animations/discovery/en/dashboard_restore.gif deleted file mode 100644 index cd487e145dc4907f60c925c1022bee5cc88cb96d..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1155741 zcmV(&K;gefNk%w1VE_s;1^1NzqEk?+WNNNUMy^s?u2f;NV`{ZiT(?wUxm8@cOH#W` zQM*r3yh&5MN>#j1SiMP7zerBNad*LQdBSUR!g77YUT4NtVaG~P$xK(uM^Va%kjz?A z%#W1OMorU~meh=t)t*1rOjg!+UFA7KYg+y8>_1HHJV)+(gYN0>?>tEFt+DVtM({jG@L6Q=gpTl~sqpOa z@jXZJJxK9FOY!gZ@;gTIJW2AVuJYdC^N*MFnV<90*YusI^}xgSxxe?XxcBh&__e(F z?eqEa`1$nt`S$kt`1$(E&ieNI`uP0&_4E7p`TO|%{K3im-sSxE{rvg<{Q3X=(b)aj z-u>m~{p;=h_Wk|%{{8v>{rmp@y#)Th0G?uKqiI5>jeV_bG`eV7yK+#xfhoL$K+cIO z-=7`dqb=Xb%;DJG?WPy?o)!9}1pBK5{Iv=GwE)vJJ>}ium7T7=z|PUo)~Bw$_4NGn z`~LCx{u(x58#G@VHC-DuVH`AF9W+@TG+P}tU>-A8A2eVgHCrMxQ6e-}BspOwHdrS# zPA4@~DLYy&L1ZvHQ!zhWH$qxBMq@ZiYd=U^Kuu;qQE^66Ye`yoN>OJ@SaC~DSxZxC zOkaOaQ)pFRb5&t_R%C!&YJy#Ejc0L#X?T=sc8qU+mvx1rcz%(1gP44LhWe~Y7l zhLnJboPvp%gp{y`lBbN8s*j$zn4`I#sk@%6#G|pxsj|hYxzMt_&9cDQy1>r7#@WHl z;K9!3$kgP>*X_#8*wNeX(%0qJ)h)7-RJh>?fvBE^yTgN<@5gQ_WqJ*I<9X} zwNqcZS3t^zNcp1x=Doz{y~XQPUF}t0@<~&*RA1uW;pE=r=HBF>dxPWL;d*;|)XUMl zDKLC{djS6cA^!_bMO0HmK~P09E-(WD0000X`2+deV=r_Y{1e+mssbg0pyNRKK_%5cHfHqjFXkVFn?WRXZ7sbrE&F3Des@1ZCqiz~YLqLWQ#iRG4BcFEm#$y+DWUe)SBxqx$wR#Z@l!*Yj3^y-m7oE{O(I3y6MhpDZB0VYp}luCyemI3OCH~ z!wyFb@x&5q2ymh@aJn!st&p?;#^2;#e$#Kv~|EzS=A3u#`RAaAF8b)jQeHXHgb$P{>8wlcdh4*iE_>{> z&;GjUr)M1PUA6aayYImNE`0FB4{to@xCf4Ui>mWJ^XkV(U;OmaS5N)*)@P4>jLGL- zDdyUTzrFb6k8ghY=%26tjNN;0C-~{dzyAF4*H8cb_UDhk^Zd83ysYrkp8)qazycER zfCfw;0vG4MbOlg>5L{pcCn&)RQt*Nn3|9mHC#45s@Pioyp$J1r!V#LVgjw2PojiEL z7NXFFFnpm5V@SgpN~L`OjGGN>$ip4_u!lhWp%DLrsKOJm&~QW?q7swH#3eehiBPmx z5dm|=Ct5LzSiGVZv&h9Qs%%a?fR%izh(s@T@r-6nBO2GJ#x`0Ehg8%d8|Uc8I@0lu zcFZFlzcfWhkP&)%4CEdKNytGOvXE(nV_*JQMnpRDk&uj}BqvG91BTIMj0EH%H(5ze zda{$C{N(H|iAgy=FO;YhWhz&x%2u*ceWWbqv|dTeTH5lKxXh(4y*9K=YI2vZ3??v# zDa>LL(@?QYW|UCi%U>Gvna6~tG^0t)X)Z~b@M)$qtI17kcJrIw3@14IM^0>-^F7+! zra0F*PIkJpo$!2TInN2kbjmZH_`Ih+^U43ueQE_(_Vi~z2P)8l67--3r6*$onoxu~ zw4o4vs6?T;P*a{#ofFL{MkC5mje4}B2CL{SFWShDniQlbO({xOy1BeCl%+6LsZ3)^ z)0tY5ATQl$Np;H8o%*z=K>evugG$t)8nviMJ*rZZ%G9MgwW&~js#K#&)u~#ws#v|M zRts#jvSGwA@u6V7OT<^-)y!y4T zfc_8Qp23f8cQJ*;90McBkTcCnCstYjlgq{dG6vXsTFW;4s#Cs}s0pzW+^LrdDx zcI>o7NG57mOP9}<_O+&kt!!gU+amwCcDA^!t!{J6TejY|x4_-4aDz)+g8sI+$Q`b7 zlgr#)9=EyBU9NPaOI=7lx4PJ!u6DD_T`OLgUsY5JNd{+esEWtOywtAxys>9GL~1otc`K*vL+{vQfb7W*d9fz2-Hj zNiFPZ58K+EnQ9k#dq z?2wOq+AX$ibvs`2&8d9HEsuG$cYgApZ<*yae|gZy9qy=S+1$%LfR#%C?hB?^({`klL{CWTT;78!* zSr=~Rr+wh}Ps^7a%~yKgCwAE!w*o8x4>_O(Fj#;2M+Y=mgEn}B`v-%*w|D+$cny$m6?lOUa)8F+ zfuy&9A(({XXCo5WeohF4N+=z%76LW!ggJ+AK`2T~XN6Y?ZpjvfB^ZVzC_pEOg6|i5 z@fU+Kc!O!shHm(VaEOEZmjgR^0zJ5LQ0RR~D1z=mgu!8i0(gXiIEV?Dh2eK0uvP<# z=mI3rh>rj0h>VDZdT4=Sk%)`lnRE?@y($a6yYiJ<5@uf~X(_;e_!iKy6#dpL$- z*oyYkgeqr-E0~5?u!d}?2Dq4uy10vRXoGX;dv|DfstAUB=zx*uhrZEp=%#gE*o@Zq zjGIS@lz500Vu_4s1lZUFAE1rf*aX@=#AW%f+7Hp;3kg77>Y~Sj?}n) zu2usikd451kHCkH>KKjg=!*Wxinr5nv51Z*(1P-Ze{sl*3b~L9d4D>%0(KaTk~oR| zh(yTP8_M{D8YyvHxN#n-fy@|=t2j@^Sdx?{1N4ZES+E6G(2`#8k}#PCO+W%0;Bd$` zlF0vIi9yf=E6I{B>5^FBjU=Fm6#0%OX_PzCY&(esKRJ7{$C5$0kA`@Z0Qrwr88zfr z0V#L_PC$#cCriSWoE7nvI<*O6G4mwJhp zSGbWtD3Ulym5ah`*SL~k&;@Len2M>GSdfkt7l`b56^Xc%F1eVB=>;;Gj^7rUbJ>|l zS&{Mh5y-ZaEoqsT`I1pNk#hN&RoR+XIXQPZkRH&LiusjdnU=Vzmb%%C`e~}h*+1kF^Z&EiW0D#QKyeq_nfBabUt`^c_?e1DVS|?Y>dd1hk1~@#|2s7m>~ZM znxclBJlUPzS$j#)n45T$Y_dt4w#lWpDTjZmrK-x7@!*?< zN2u0WsZ?pED#oWg>60)Se~3wYu^Ox{D6GC$tS!g_EJ&vyI;+AtoF!_j{P}A2NS}V1 zrB@)Rv^t|SN`*VQsP_kl^JfJf0IA;gqtF_pmKvJqdPA9-1essS6c6f3k`0E`m3 zu^hWE+cvFUV70wSvX5!9*om?}dy8fuuK8K6Od3cq`?I<@v;3yE_KLH7+qYITnr4Wq zsfwGO%C$t>l2F-`ip#4IJGc!Qv`h=8{|C0u8X;19O616rW}Bc28V0O-r0R*R5vj3H z+p!*tsARjjaOeXZFaag2pEk>_-Kx57__pJ!q^}0Gx*MNcsHt|Fi+C%exofk2o3q9% zwx&9*E6}!Ex~dGydxzVT=2(u@%ad!$tF`I4s~WCuDV-2Uua*CMAeZ|*I?0{1+qq+j zrSJ;5bm*2}dvCB7zI$7e-sS=!`@1yAx~`kHQ^|Zbps43tf3k|ZbE`+a>#q2lzg}>= z=T@l1Tf7i_yuX5Sq&S;CaK32?tDY*o)0?IqoTdWt!5&=h zD+_}V>9h@O#7gzTBN4-inZP&9xy_5iz1g%-$HGr+y0!mSzxS)9L`=Dc3YtjFydx{G z;H$-$+$9Gbv%I;)1(3(Xo5@`~%3JIpTPUT1YsF)HmSv2eQklijHkuFHwtx()hFpC7 zn8-)L$D--SDl5o=49uMxtH0^J;}*6*%twrz#E#s$HD__htgXhFsIyCdyg9&^tjoJA z%E?R~o1DN{EVq$N%H&+i$a`!Xkh;I@2CNLZEt#4w@V|iRcsi-3rHR2Q+_fG6oIb40 z1#B6-+{+nY1C5NeoC~i8-O25nk2LGD-K@#WT(;JHw$6;pdb|`tY^30-1=t+T4*k#m z%*_vN9^b6WZ5YnAD$?b=(k%UluVw-2jK8e>qFetEm9GrTZ6|?otdcK@&vopm#tf=c z70?`k&IHZO27R?kt<*C6yrP?q^XkCc3@IRs)D%6r7A?&>LCscO$uU~9lT^|&>&c)z z&Mj@uXgx8=md+_C!?papm^qW}InPO`d6&4Wlswit`j*0b(IfqHx)!ZQUC>S4qK19g zh)u@|?Ur$i%u_AWV@ueTJh?@z)m)a*6YbRv{m~%(*dguNf4x+7Ytjn5&!61aW}Vim zeb)OzcOqcED9oT{4Ape~tae?PRlCl>+XgxurjVT4p^a04E!f=J)e4P!$er9sd$oGK zz)U>PpsmQ27t^Gzzk6T+mF>hf!PQ_8gVz7r(Krp<(LLTOZB?VK*9?r>pUv8<-QK18 z(x~jOSStr?u%5JC+d}xpDw@}8$eG)~-!s|7 z+AZCZ7ug1mi*vvN&Yazr-E){--QX?N;yvNy-PtAH!s|Wao_*d5ZOQ7b;_Myc?oHKF ztd(5p(*lf{_Z_J?S=Uvqxw>7)E5O$;4&x{85d(e~1mn=yDhlLboYYI)*eMNt; zsOL~teZQ{NRqd@~z2OG1fy185VEExC?cZNLdcNN0*V*gkNA1Cz7FfR4aPTf^v%(z_nqGT!bpesV9}*7DulTQ1>yzU}6ED>W+Fy-3y?8SXrl$OKJete^V}xX_kQy)KW{yTY{|3r*e_Fcw#~>c( z&RFu0FXt%U?H+jec%S%sfA##f`F_dydEc;m|M<{&_n$v&k#G1U&vb#_-~NvIOaJ;z z|0zRC0hVrmge%+iPWQ37v66pescxhA%-e%s`eLsVWN+6{Pulbyo)qtV`pwgbdFz7i zx}%P{mGAispmEwy=p_Fh`qT-R%HF^5&Gl!`%EMpy3XuNlpKM$J{MY3Rr?ZCki+<;JBu*KS?BclGAwyVq}D zz<&h?COp`1VZ?_OCuY3Zabw7jB}b+_*>Yvfmo;bRyxDVS(4R$zCOz78Y1F4xr)Is{ zb!*tKWyhvH+jjqLjWAeRAfaK48LCyq)XBP)E0`=INLcu3lVk3O9v!4Ka58Ap=g>Pc zF@nVk7%gptYc0;z355d##3IE}7A9KlX>psq!NkUm_w)5*%(B08qdTiMwhJ7C0zi59>~3QN=&1MBqvnU2G1< z_==>E4GcA0(vT!hP!2>NrJORw4cc6q=>k_iL~v&XifQ%QpLG3ch6r-fO+)k1pNJ z4dQC8V@{j8q2u28;tG~_+a^K_H~j35Ii0S6W}#j~s}8|>iamMpJ@#|YLkE3y(Mu=& zbkkEueRb7aXZ>~8V~2fq*=r~AGlUc>I&l zKY!^XnEqpNu`N}0s#wZgmWBL*!3zuApUVWtwXR{RNC+Fyx_aiMpw***21FqK6uAFC zC!9cpbW57zA~qMNWuXh<8K2b9^Q82s=wjaCAO7aHCq~6jfQxG!$_|)75F+n}5IoiL zb~vaW+E0W_T!H?4@I)v!afC07VGc*uG^ce33tQyk7Bki@4OZs>N(5p9jZnULHAhoq z>tGP~H$oB)PK+O5fgISExv;E9d)}j6ANlx4KL!$zgA`;T33*6ECK8d0RAeI=`N+8V zM+E4q;Bd;rhBBSWgv_HLaDd}3L;;DlJc9Z!K^@+KyqxB@uV4Trcqp+jc*v~v;% zl}*w>02F0Rc{Z~P3w`6!{5QBF>acA|EGEVh+RS?1GoSCWqC{m0lx(i7i7bHPGQ$%G zl;$8F8s&gK#Tmfv`Evx#qv3aK+Q8%yz+)1SX6}%w&;{NyqTsU{JT3auj4lwI(=Q=qlRj__ltYIbVSj}2iVRtC_Opl+V z1gLoI+J*Pc)lm}CV#1<|NBCK@m9BcFRllk)TC&d!Ld8}qW5g13LRJ5I#o&XRFT_;nsXIJ(q>J*-U%_jk?7Y;S*hJ-Yo>P zh}hhgd$U{K<4Tc)1ONa4oLWbJjcQcK$?H(9cUBOiHN+zpafwNMViTtr#Vb~Ei&-qY z`SFI5>f%}ZLZ~^K?Uy3DsjF}}l$?_2b+3P$aSQRP;OZF`drSXj@?e=dtPkm<)U@Bf`y++v$+z>cV?XFqR z#yxJCXd5M#=oh?OeqK7ypw2$D6H58;KodEuW;WAT3lVN97?s<(6c##a&&)@s87