diff --git a/.github/workflows/create_release_on_tag.yml b/.github/workflows/create_release_on_tag.yml index 61407422..c1cf0c60 100644 --- a/.github/workflows/create_release_on_tag.yml +++ b/.github/workflows/create_release_on_tag.yml @@ -10,15 +10,18 @@ jobs: name: Create Release and Upload APK runs-on: ubuntu-latest steps: - - name: Checkout code - uses: actions/checkout@master - - - name: Set up JDK 1.8 - uses: actions/setup-java@v4 + - uses: actions/checkout@v4 + - uses: actions/setup-java@v4 with: distribution: 'adopt' # See 'Supported distributions' for available options java-version: '17' + # - name: Set up JDK 17 + # uses: actions/setup-java@v4 + # with: + # distribution: 'adopt' # See 'Supported distributions' for available options + # java-version: '17' + - name: Cache Flutter id: cache-flutter uses: actions/cache@v3 @@ -28,6 +31,16 @@ jobs: ~/.pub-cache key: flutter-${{ hashFiles('**/pubspec.lock') }} + - name: Cache Gradle + id: cache-gradle + uses: actions/cache@v3 + with: + path: | + ~/.gradle/caches + ~/.gradle/wrapper/ + key: gradle-ubuntu-${{ hashFiles('**/*.gradle*', '**/gradle-wrapper.properties') }} + + - if: ${{ steps.cache-flutter.outputs.cache-hit != 'true' }} name: Install Flutter run: git clone https://github.com/flutter/flutter.git --depth 1 -b stable $FOLDER diff --git a/CHANGELOG.md b/CHANGELOG.md index 1760de8a..40280f63 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,7 @@ +## 4.2.0 + +* moving to carp_themes_package instead of research package themes + ## 4.1.1 - small visual fixes diff --git a/android/app/build.gradle b/android/app/build.gradle index e70b25af..bc2192c5 100644 --- a/android/app/build.gradle +++ b/android/app/build.gradle @@ -5,7 +5,7 @@ plugins { } def localProperties = new Properties() -def localPropertiesFile = rootProject.file('local.properties') +def localPropertiesFile = project.rootProject.file('local.properties') if (localPropertiesFile.exists()) { localPropertiesFile.withReader('UTF-8') { reader -> localProperties.load(reader) @@ -13,7 +13,7 @@ if (localPropertiesFile.exists()) { } def keyProperties = new Properties() -def keyPropertiesFile = rootProject.file('key.properties') +def keyPropertiesFile = project.rootProject.file('key.properties') def signingConfigExists = false if (keyPropertiesFile.exists()) { @@ -23,15 +23,8 @@ if (keyPropertiesFile.exists()) { } } -def flutterVersionCode = localProperties.getProperty('flutter.versionCode') -if (flutterVersionCode == null) { - flutterVersionCode = '1' -} - -def flutterVersionName = localProperties.getProperty('flutter.versionName') -if (flutterVersionName == null) { - flutterVersionName = '1.0' -} +def flutterVersionCode = localProperties.getProperty('flutter.versionCode') ?: '1' +def flutterVersionName = localProperties.getProperty('flutter.versionName') ?: '1.0' android { namespace "dk.carp.studies_app" @@ -88,10 +81,10 @@ android { debugSymbolLevel 'SYMBOL_TABLE' } if (signingConfigExists) { - logger.error('storeFile found, signing with release build.') + logger.info('storeFile found, signing with release build.') signingConfig signingConfigs.release } else { - logger.error('No storeFile found or null. Skipping signing of release build.') + logger.info('No storeFile found or null. Skipping signing of release build.') signingConfig signingConfigs.debug } } diff --git a/android/build.gradle b/android/build.gradle index a9e61289..1c67b3aa 100644 --- a/android/build.gradle +++ b/android/build.gradle @@ -12,8 +12,6 @@ allprojects { rootProject.buildDir = '../build' subprojects { project.buildDir = "${rootProject.buildDir}/${project.name}" -} -subprojects { project.evaluationDependsOn(':app') } diff --git a/assets/instructions/apple_health_preview.png b/assets/instructions/apple_health_preview.png new file mode 100644 index 00000000..89113a45 Binary files /dev/null and b/assets/instructions/apple_health_preview.png differ diff --git a/assets/instructions/google_health_connect_preview.png b/assets/instructions/google_health_connect_preview.png new file mode 100644 index 00000000..b0cb0528 Binary files /dev/null and b/assets/instructions/google_health_connect_preview.png differ diff --git a/assets/lang/da.json b/assets/lang/da.json index e08855bb..1d44c86c 100644 --- a/assets/lang/da.json +++ b/assets/lang/da.json @@ -97,9 +97,9 @@ "pages.profile.device_role": "Engedsrolle", "pages.profile.contact": "Kontakt forsker", "pages.profile.privacy": "Fortrolighedspolitik", - "pages.profile.study_website": "Studiw Hjemmeside", + "pages.profile.study_website": "Hjemmeside for studiet", "pages.profile.leave_study": "Forlad studie", - "pages.profile.log_out": "Log ud", + "pages.profile.log_out": "Forlad studie & Log ud", "pages.profile.log_out.confirmation": "Du er ved at forlade dette studie og logge af. Operativsystemet vil åbne en browser for at logge dig ud. Er du sikker?", "pages.profile.leave_study.confirmation": "Du er ved at forlade studiet. Du vil ikke længere deltage i dette studie. Er du sikker?", "announcements": "Annonceringer", diff --git a/assets/lang/en.json b/assets/lang/en.json index aae2fb09..1dce60f2 100644 --- a/assets/lang/en.json +++ b/assets/lang/en.json @@ -110,9 +110,9 @@ "pages.profile.device_id": "Device ID", "pages.profile.contact": "Contact researcher", "pages.profile.privacy": "Privacy policy", - "pages.profile.study_website": "Study Website", + "pages.profile.study_website": "Study website", "pages.profile.leave_study": "Leave study", - "pages.profile.log_out": "Log out", + "pages.profile.log_out": "Leave study & Log out", "pages.profile.log_out.confirmation": "You are about to leave this study and log out. The operating system will open a browser to log you out. Are you sure?", "pages.profile.leave_study.confirmation": "You are about to leave the study. You will no longer participate in this study. Are you sure?", "announcements": "Announcements", @@ -244,4 +244,4 @@ "tasks.participant_data.phone_number.country": "Country code", "tasks.participant_data.phone_number.phone_number": "Phone No.", "tasks.participant_data.review.title": "Review" -} +} \ No newline at end of file diff --git a/assets/lang/es.json b/assets/lang/es.json index b4f811b1..b9bf74db 100644 --- a/assets/lang/es.json +++ b/assets/lang/es.json @@ -58,8 +58,9 @@ "pages.profile.account_id": "Id Usuario", "pages.profile.contact": "Contactar investigador", "pages.profile.privacy": "Política de privacidad", + "pages.profile.study_website": "Página web del estudio", "pages.profile.leave_study": "Abandonar el estudio", - "pages.profile.log_out": "Cerrar sesión", + "pages.profile.log_out": "Cerrar estudio & sesión", "pages.profile.log_out.confirmation": "Estás a punto de cerrar sesión et abandonar el estudio. ¿Estás seguro?", "pages.profile.leave_study.confirmation": "Estás a punto de abandonar el estudio. Dejarás de participar en el es estudio. ¿Estás seguro?", "announcement": "Anuncio", @@ -121,4 +122,4 @@ "pages.devices.connection.step.confirm.title": "está conectado!", "pages.devices.connection.step.confirm.1": "El", "pages.devices.connection.step.confirm.2": " ha sido connectado satisfactoriamente al estudio y está listo para empezar a detectar." -} +} \ No newline at end of file diff --git a/ios/Podfile.lock b/ios/Podfile.lock index 0384b5ed..faec3eff 100644 --- a/ios/Podfile.lock +++ b/ios/Podfile.lock @@ -97,7 +97,7 @@ PODS: - sqflite_darwin (0.0.4): - Flutter - FlutterMacOS - - SwiftProtobuf (1.31.1) + - SwiftProtobuf (1.32.0) - url_launcher_ios (0.0.1): - Flutter - video_player_avfoundation (0.0.1): @@ -267,7 +267,7 @@ SPEC CHECKSUMS: oidc_ios: 16966cad509ce6850ca4ca1216c5138bef2a8726 open_settings_plus: d19f91e8a04649358a51c19b484ce2e637149d70 package_info_plus: af8e2ca6888548050f16fa2f1938db7b5a5df499 - path_provider_foundation: 080d55be775b7414fd5a5ef3ac137b97b097e564 + path_provider_foundation: bb55f6dbba17d0dccd6737fe6f7f34fbd0376880 pedometer: 1c5eaab0c6bce8eb7651f7095553b5081c9d06ed permission_handler_apple: 4ed2196e43d0651e8ff7ca3483a069d469701f2d PhoneNumberKit: ec00ab8cef5342c1dc49fadb99d23fa7e66cf0ef @@ -277,11 +277,11 @@ SPEC CHECKSUMS: RxSwift: 4e28be97cbcfeee614af26d83415febbf2bf6f45 screen_state: 52d6e997d31bddba6417c60d9cdd22effd0320a7 sensors_plus: 6a11ed0c2e1d0bd0b20b4029d3bad27d96e0c65b - shared_preferences_foundation: 9e1978ff2562383bd5676f64ec4e9aa8fa06a6f7 + shared_preferences_foundation: 7036424c3d8ec98dfe75ff1667cb0cd531ec82bb sqflite_darwin: 20b2a3a3b70e43edae938624ce550a3cbf66a3d0 - SwiftProtobuf: e02f51c8c2df5845657aee2d4de9d61bf50ef788 - url_launcher_ios: 694010445543906933d732453a59da0a173ae33d - video_player_avfoundation: 2cef49524dd1f16c5300b9cd6efd9611ce03639b + SwiftProtobuf: 81e341191afbddd64aa031bd12862dccfab2f639 + url_launcher_ios: 7a95fa5b60cc718a708b8f2966718e93db0cef1b + video_player_avfoundation: dd410b52df6d2466a42d28550e33e4146928280a Zip: b3fef584b147b6e582b2256a9815c897d60ddc67 PODFILE CHECKSUM: 0f233b2493d660073cf18073d2b24e7b319ab4a8 diff --git a/ios/Runner/Info.plist b/ios/Runner/Info.plist index 301e663d..9570d6a3 100644 --- a/ios/Runner/Info.plist +++ b/ios/Runner/Info.plist @@ -115,7 +115,5 @@ UIViewControllerBasedStatusBarAppearance - UIStatusBarHidden - diff --git a/lib/blocs/app_bloc.dart b/lib/blocs/app_bloc.dart index 18eca055..3fd87f5c 100644 --- a/lib/blocs/app_bloc.dart +++ b/lib/blocs/app_bloc.dart @@ -352,7 +352,9 @@ class StudyAppBLoC extends ChangeNotifier { /// Has the informed consent been accepted by the user? bool get hasInformedConsentBeenAccepted => - LocalSettings().participant?.hasInformedConsentBeenAccepted ?? false; + backend.getInformedConsentByRole( + study!.studyDeploymentId, study!.participantRoleName) != + null; set hasInformedConsentBeenAccepted(bool accepted) { var participant = LocalSettings().participant; @@ -380,6 +382,7 @@ class StudyAppBLoC extends ChangeNotifier { /// the Study Page of the app. Future refreshMessages() async { try { + _messages.clear(); _messages = await messageManager.getMessages(); _messages.sort((m1, m2) => m2.timestamp.compareTo(m1.timestamp)); info('Message list refreshed - count: ${_messages.length}'); @@ -478,14 +481,13 @@ class StudyAppBLoC extends ChangeNotifier { /// * resetting the informed consent flow /// * returning the user to select an invitation for another study /// - /// Note that study deployment information and data is not removed from the - /// phone. This is stored for later access. Or if the same deployment is - /// re-deployed on the phone, data from the previous deployment will be - /// available. + /// Note that study deployment information and data is removed from the + /// phone. If the same deployment is re-deployed on the phone, data from the + /// previous deployment will NOT be available. Future leaveStudy() async { - debug('$runtimeType --------- LEAVING STUDY ------------'); + info('Leaving study $study'); - // save and clear the UI data models + // clear the UI data models appViewModel.clear(); // stop sensing and remove all deployment info diff --git a/lib/carp_study_app.dart b/lib/carp_study_app.dart index 296c2360..43ac5389 100644 --- a/lib/carp_study_app.dart +++ b/lib/carp_study_app.dart @@ -183,7 +183,14 @@ class CarpStudyAppState extends State { @override Widget build(BuildContext context) { - final carpColors = Theme.of(context).extension(); + final studyAppColors = Theme.of(context).extension(); + + // Apply system overlay style after frame so Theme.of(context) is ready + WidgetsBinding.instance.addPostFrameCallback((_) { + SystemChrome.setSystemUIOverlayStyle(SystemUiOverlayStyle( + statusBarColor: Colors.transparent, + )); + }); return MaterialApp.router( scaffoldMessengerKey: bloc.scaffoldKey, supportedLocales: const [ @@ -211,14 +218,14 @@ class CarpStudyAppState extends State { return supportedLocales.first; // default to EN }, locale: bloc.localization?.locale, - theme: researchPackageTheme.copyWith( + theme: carpTheme.copyWith( extensions: [ - researchPackageTheme.extension()!.copyWith( - primary: carpColors?.primary, + carpTheme.extension()!.copyWith( + primary: studyAppColors?.primary, ), ], ), - darkTheme: researchPackageDarkTheme, + darkTheme: carpDarkTheme, debugShowCheckedModeBanner: true, routerConfig: _router, ); diff --git a/lib/data/carp_backend.dart b/lib/data/carp_backend.dart index 6f100fc3..3db20440 100644 --- a/lib/data/carp_backend.dart +++ b/lib/data/carp_backend.dart @@ -232,4 +232,11 @@ class CarpBackend { return uploadedConsent; } + + Future? getInformedConsentByRole( + String studyDeploymentId, String? role) async { + return await CarpParticipationService() + .participation(studyDeploymentId) + .getInformedConsentByRole(role); + } } diff --git a/lib/data/local_settings.dart b/lib/data/local_settings.dart index 086461d5..a5194c1a 100644 --- a/lib/data/local_settings.dart +++ b/lib/data/local_settings.dart @@ -14,9 +14,6 @@ class LocalSettings { /// See https://developer.android.com/health-and-fitness/guides/health-connect/develop/get-started#get-client static const healthConnectPackageName = 'com.google.android.apps.healthdata'; - bool isExpectedParticipantDataSet = false; - bool hasUserSeenDeviceConnectionInstructions = false; - // Keys for storing in shared preferences static const String userKey = 'user'; static const String participantKey = 'participant'; @@ -26,8 +23,6 @@ class LocalSettings { Participant? _participant; SmartphoneStudy? _study; - bool hasSeenBluetoothConnectionInstructions = false; - static final LocalSettings _instance = LocalSettings._(); factory LocalSettings() => _instance; LocalSettings._() : super(); @@ -109,11 +104,13 @@ class LocalSettings { ); } - bool get hasSeenConnectionInstructions => - hasSeenBluetoothConnectionInstructions; + bool get hasSeenBluetoothConnectionInstructions => + Settings() + .preferences + ?.getBool('hasSeenBluetoothConnectionInstructions') ?? + false; - set hasSeenConnectionInstructions(bool seen) { - hasSeenBluetoothConnectionInstructions = seen; + set hasSeenBluetoothConnectionInstructions(bool seen) { Settings().preferences?.setBool( 'hasSeenBluetoothConnectionInstructions', seen, diff --git a/lib/main.dart b/lib/main.dart index 904ffa4f..778eef6e 100644 --- a/lib/main.dart +++ b/lib/main.dart @@ -55,6 +55,7 @@ import 'package:cognition_package/cognition_package.dart'; import 'package:carp_health_package/health_package.dart'; // import 'package:health/health.dart'; import 'package:carp_movesense_package/carp_movesense_package.dart'; +import 'package:carp_themes_package/carp_themes_package.dart'; part 'blocs/app_bloc.dart'; part 'blocs/util.dart'; @@ -105,8 +106,7 @@ part 'ui/pages/devices_page.enable_bluetooth_dialog.dart'; part 'ui/pages/devices_page.bluetooth_connection_page.dart'; part 'ui/pages/devices_page.disconnection_dialog.dart'; part 'ui/pages/devices_page.list_title.dart'; -part 'ui/pages/devices_page.health_service_connect1.dart'; -part 'ui/pages/devices_page.health_service_connect2.dart'; +part 'ui/pages/devices_page.health_service_connect.dart'; part 'ui/tasks/audio_task_page.dart'; part 'ui/tasks/audio_page.dart'; diff --git a/lib/ui/cards/activity_card.dart b/lib/ui/cards/activity_card.dart index 51bb84c8..68fe931f 100644 --- a/lib/ui/cards/activity_card.dart +++ b/lib/ui/cards/activity_card.dart @@ -63,7 +63,7 @@ class ActivityCardState extends State { RPLocalizations locale = RPLocalizations.of(context)!; return StudiesMaterial( - backgroundColor: Theme.of(context).extension()!.white!, + backgroundColor: Theme.of(context).extension()!.white!, child: Padding( padding: const EdgeInsets.all(8.0), child: Column( @@ -72,16 +72,16 @@ class ActivityCardState extends State { children: [ Text( '${_walk! + _run! + _cycle!}', - style: dataVizCardTitleNumber.copyWith( - color: Theme.of(context).extension()!.grey900!, + style: fs28fw700.copyWith( + color: Theme.of(context).extension()!.grey900!, ), ), Padding( padding: const EdgeInsets.only(left: 4.0), child: Text( '${locale.translate('cards.activity.total.min')} ${_getDayName(touchedIndex)}', - style: dataVizCardTitleText.copyWith( - color: Theme.of(context).extension()!.grey600, + style: fs12fw700.copyWith( + color: Theme.of(context).extension()!.grey600, ), ), ), @@ -91,8 +91,8 @@ class ActivityCardState extends State { children: [ Text( "${widget.model.currentMonth} ${widget.model.startOfWeek} - ${int.parse(widget.model.endOfWeek) < int.parse(widget.model.startOfWeek) ? widget.model.nextMonth : widget.model.currentMonth} ${widget.model.endOfWeek}, ${widget.model.currentYear}", - style: dataVizCardTitleText.copyWith( - color: Theme.of(context).extension()!.grey600, + style: fs12fw700.copyWith( + color: Theme.of(context).extension()!.grey600, ), ), Spacer(), @@ -117,7 +117,7 @@ class ActivityCardState extends State { children: [ Text( '$_walk', - style: dataVizCardBottomNumber.copyWith( + style: fs22fw700.copyWith( color: widget.colors[0], ), ), @@ -125,9 +125,9 @@ class ActivityCardState extends State { padding: const EdgeInsets.all(4.0), child: Text( locale.translate('cards.activity.walking'), - style: dataVizCardBottomText.copyWith( + style: fs12fw700.copyWith( color: Theme.of(context) - .extension()! + .extension()! .grey800), ), ), @@ -141,7 +141,7 @@ class ActivityCardState extends State { padding: const EdgeInsets.only(left: 8.0), child: Text( '$_run', - style: dataVizCardBottomNumber.copyWith( + style: fs12fw700.copyWith( color: widget.colors[1], ), ), @@ -150,9 +150,9 @@ class ActivityCardState extends State { padding: const EdgeInsets.all(4.0), child: Text( locale.translate('cards.activity.running'), - style: dataVizCardBottomText.copyWith( + style: fs12fw700.copyWith( color: Theme.of(context) - .extension()! + .extension()! .grey800), ), ), @@ -165,7 +165,7 @@ class ActivityCardState extends State { children: [ Text( '$_cycle', - style: dataVizCardBottomNumber.copyWith( + style: fs22fw700.copyWith( color: widget.colors[2], ), ), @@ -173,9 +173,10 @@ class ActivityCardState extends State { padding: const EdgeInsets.only(left: 4.0), child: Text( locale.translate('cards.activity.cycling'), - style: dataVizCardBottomText.copyWith( - color: - Theme.of(context).extension()!.grey800, + style: fs12fw700.copyWith( + color: Theme.of(context) + .extension()! + .grey800, ), ), ), @@ -303,8 +304,8 @@ class ActivityCardState extends State { value.toInt() % meta.appliedInterval == 0 ? value.toInt().toString() : '', - style: dataCardRightTitleStyle.copyWith( - color: Theme.of(context).extension()!.grey600, + style: fs14ls1.copyWith( + color: Theme.of(context).extension()!.grey600, ), ), ); diff --git a/lib/ui/cards/anonymous_card.dart b/lib/ui/cards/anonymous_card.dart index 1c935295..c135d51a 100644 --- a/lib/ui/cards/anonymous_card.dart +++ b/lib/ui/cards/anonymous_card.dart @@ -8,7 +8,7 @@ class AnonymousCard extends StatelessWidget { RPLocalizations locale = RPLocalizations.of(context)!; return Card( - color: Theme.of(context).extension()!.grey50, + color: Theme.of(context).extension()!.grey50, elevation: 0, margin: const EdgeInsets.all(16.0), shape: RoundedRectangleBorder( @@ -45,8 +45,7 @@ class AnonymousCard extends StatelessWidget { child: Text( locale.translate('pages.about.anonymous.anonymous'), maxLines: 2, - style: aboutCardSubtitleStyle.copyWith( - color: CACHET.ANONYMOUS), + style: fs16fw600.copyWith(color: CACHET.ANONYMOUS), ), ), ], @@ -56,9 +55,9 @@ class AnonymousCard extends StatelessWidget { padding: const EdgeInsets.only(left: 16.0), child: Text( locale.translate('pages.about.anonymous.message'), - style: aboutCardSubtitleStyle.copyWith( + style: fs16fw600.copyWith( color: Theme.of(context) - .extension()! + .extension()! .grey900, fontSize: 14, ), diff --git a/lib/ui/cards/distance_card.dart b/lib/ui/cards/distance_card.dart index 92e06851..857ad3ae 100644 --- a/lib/ui/cards/distance_card.dart +++ b/lib/ui/cards/distance_card.dart @@ -33,7 +33,7 @@ class _DistanceCardState extends State { @override Widget build(BuildContext context) { return StudiesMaterial( - backgroundColor: Theme.of(context).extension()!.white!, + backgroundColor: Theme.of(context).extension()!.white!, child: Padding( padding: const EdgeInsets.all(8.0), child: Column( @@ -42,16 +42,16 @@ class _DistanceCardState extends State { children: [ Text( _distance, - style: dataVizCardTitleNumber.copyWith( - color: Theme.of(context).extension()!.grey900!, + style: fs28fw700.copyWith( + color: Theme.of(context).extension()!.grey900!, ), ), Padding( padding: const EdgeInsets.only(left: 4.0), child: Text( 'km ${_getDayName(touchedIndex)}', - style: dataVizCardTitleText.copyWith( - color: Theme.of(context).extension()!.grey600, + style: fs12fw700.copyWith( + color: Theme.of(context).extension()!.grey600, ), ), ), @@ -61,8 +61,8 @@ class _DistanceCardState extends State { children: [ Text( "${widget.model.currentMonth} ${widget.model.startOfWeek} - ${int.parse(widget.model.endOfWeek) < int.parse(widget.model.startOfWeek) ? widget.model.nextMonth : widget.model.currentMonth} ${widget.model.endOfWeek}, ${widget.model.currentYear}", - style: dataVizCardTitleText.copyWith( - color: Theme.of(context).extension()!.grey600, + style: fs12fw700.copyWith( + color: Theme.of(context).extension()!.grey600, ), ), Spacer(), @@ -174,8 +174,8 @@ class _DistanceCardState extends State { value.toInt() % meta.appliedInterval == 0 ? value.toInt().toString() : '', - style: dataCardRightTitleStyle.copyWith( - color: Theme.of(context).extension()!.grey600, + style: fs14ls1.copyWith( + color: Theme.of(context).extension()!.grey600, ), ), ); diff --git a/lib/ui/cards/heart_rate_card.dart b/lib/ui/cards/heart_rate_card.dart index abe6290a..570fc7de 100644 --- a/lib/ui/cards/heart_rate_card.dart +++ b/lib/ui/cards/heart_rate_card.dart @@ -42,7 +42,7 @@ class HeartRateCardWidgetState extends State @override Widget build(BuildContext context) { return StudiesMaterial( - backgroundColor: Theme.of(context).extension()!.white!, + backgroundColor: Theme.of(context).extension()!.white!, child: Padding( padding: const EdgeInsets.all(8.0), child: Column( @@ -86,7 +86,7 @@ class HeartRateCardWidgetState extends State min == null || max == null ? '-' : '${(min.toInt())} - ${(max.toInt())}', - style: heartRateNumberStyle, + style: fs28fw700, ), ), Padding( @@ -95,9 +95,9 @@ class HeartRateCardWidgetState extends State min == null || max == null ? '' : locale.translate('cards.heartrate.bpm'), - style: heartRateBPMTextStyle.copyWith( + style: fs10fw700.copyWith( fontSize: 12, - color: Theme.of(context).extension()!.grey600, + color: Theme.of(context).extension()!.grey600, ), ), ), @@ -122,9 +122,9 @@ class HeartRateCardWidgetState extends State child: currentHeartRate != null ? Text( currentHeartRate.toStringAsFixed(0), - style: heartRateNumberStyle, + style: fs28fw700, ) - : Text('-', style: heartRateNumberStyle), + : Text('-', style: fs28fw700), ), Padding( padding: const EdgeInsets.only(bottom: 14), @@ -145,8 +145,9 @@ class HeartRateCardWidgetState extends State ), Text( locale.translate('cards.heartrate.bpm'), - style: heartRateBPMTextStyle.copyWith( - color: Theme.of(context).extension()!.grey600, + style: fs10fw700.copyWith( + color: + Theme.of(context).extension()!.grey600, ), ), ], @@ -169,7 +170,7 @@ class HeartRateCardWidgetState extends State enabled: true, touchTooltipData: BarTouchTooltipData( fitInsideHorizontally: true, - // tooltipBgColor: Theme.of(context).primaryColorLight, + fitInsideVertically: true, getTooltipItem: (group, groupIndex, rod, rodIndex) { return BarTooltipItem( '', @@ -210,7 +211,7 @@ class HeartRateCardWidgetState extends State ), ), ], - heartRateNumberStyle, + fs28fw700, ); }, ), @@ -310,8 +311,8 @@ class HeartRateCardWidgetState extends State value.toInt() % meta.appliedInterval == 0 ? value.toInt().toString() : '', - style: dataCardRightTitleStyle.copyWith( - color: Theme.of(context).extension()!.grey600, + style: fs14ls1.copyWith( + color: Theme.of(context).extension()!.grey600, ), maxLines: 1, ), diff --git a/lib/ui/cards/media_card.dart b/lib/ui/cards/media_card.dart index 1fe94b1c..c69d3c0f 100644 --- a/lib/ui/cards/media_card.dart +++ b/lib/ui/cards/media_card.dart @@ -19,7 +19,7 @@ class MediaCardWidgetState extends State { } return StudiesMaterial( - backgroundColor: Theme.of(context).extension()!.white!, + backgroundColor: Theme.of(context).extension()!.white!, child: Padding( padding: const EdgeInsets.all(8.0), child: Column( @@ -34,7 +34,7 @@ class MediaCardWidgetState extends State { crossAxisAlignment: CrossAxisAlignment.start, children: [ const SizedBox(height: 5), - Text('$total MEDIA', style: dataCardTitleStyle), + Text('$total MEDIA', style: fs16fw400ls1), Column( children: widget.modelsList .asMap() @@ -47,8 +47,8 @@ class MediaCardWidgetState extends State { const SizedBox(height: 15), Text( '${entry.value.tasksDone} ${locale.translate('cards.${entry.value.taskType}.title')}', - style: dataCardTitleStyle.copyWith( - fontSize: 14), + style: + fs16fw400ls1.copyWith(fontSize: 14), ), LayoutBuilder(builder: (BuildContext context, diff --git a/lib/ui/cards/mobility_card.dart b/lib/ui/cards/mobility_card.dart index ee506136..20278945 100644 --- a/lib/ui/cards/mobility_card.dart +++ b/lib/ui/cards/mobility_card.dart @@ -30,7 +30,7 @@ class _MobilityCardState extends State { RPLocalizations locale = RPLocalizations.of(context)!; return StudiesMaterial( - backgroundColor: Theme.of(context).extension()!.white!, + backgroundColor: Theme.of(context).extension()!.white!, child: Padding( padding: const EdgeInsets.all(8.0), child: Column( @@ -39,7 +39,7 @@ class _MobilityCardState extends State { children: [ Text( '$_homestay%', - style: dataVizCardTitleNumber.copyWith( + style: fs28fw700.copyWith( color: widget.colors[0], ), ), @@ -47,8 +47,9 @@ class _MobilityCardState extends State { padding: const EdgeInsets.only(left: 4.0), child: Text( "${locale.translate('cards.mobility.homestay')} ${_getDayName(touchedIndex)}", - style: dataVizCardTitleText.copyWith( - color: Theme.of(context).extension()!.grey900!, + style: fs12fw700.copyWith( + color: + Theme.of(context).extension()!.grey900!, ), ), ), @@ -58,8 +59,8 @@ class _MobilityCardState extends State { children: [ Text( "${widget.model.currentMonth} ${widget.model.startOfWeek} - ${int.parse(widget.model.endOfWeek) < int.parse(widget.model.startOfWeek) ? widget.model.nextMonth : widget.model.currentMonth} ${widget.model.endOfWeek}, ${widget.model.currentYear}", - style: dataVizCardTitleText.copyWith( - color: Theme.of(context).extension()!.grey600, + style: fs12fw700.copyWith( + color: Theme.of(context).extension()!.grey600, ), ), Spacer(), @@ -81,7 +82,7 @@ class _MobilityCardState extends State { children: [ Text( '$_places', - style: dataVizCardBottomNumber.copyWith( + style: fs22fw700.copyWith( color: widget.colors[0], ), ), @@ -89,9 +90,9 @@ class _MobilityCardState extends State { padding: const EdgeInsets.all(4.0), child: Text( locale.translate('cards.mobility.places'), - style: dataVizCardBottomText.copyWith( + style: fs12fw700.copyWith( color: Theme.of(context) - .extension()! + .extension()! .grey800), ), ), @@ -206,8 +207,8 @@ class _MobilityCardState extends State { value.toInt() % meta.appliedInterval == 0 ? value.toInt().toString() : '', - style: dataCardRightTitleStyle.copyWith( - color: Theme.of(context).extension()!.grey600, + style: fs14ls1.copyWith( + color: Theme.of(context).extension()!.grey600, ), ), ); @@ -221,8 +222,8 @@ class _MobilityCardState extends State { value.toInt() % meta.appliedInterval == 0 ? value.toInt().toString() : '', - style: dataCardRightTitleStyle.copyWith( - color: Theme.of(context).extension()!.grey600, + style: fs14ls1.copyWith( + color: Theme.of(context).extension()!.grey600, ), ), ); diff --git a/lib/ui/cards/scoreboard_card.dart b/lib/ui/cards/scoreboard_card.dart index 7ea6e62d..bcdc706e 100644 --- a/lib/ui/cards/scoreboard_card.dart +++ b/lib/ui/cards/scoreboard_card.dart @@ -54,41 +54,41 @@ class ScoreboardPersistentHeaderDelegate List childrenDays = [ Text(model.daysInStudy.toString(), - style: scoreNumberStyle.copyWith( - fontSize: calculateScrollAwareSizing(shrinkOffset, - scoreNumberStyleSmall.fontSize!, scoreNumberStyle.fontSize!), - color: Theme.of(context).extension()!.grey900)), + style: fs36fw800.copyWith( + fontSize: calculateScrollAwareSizing( + shrinkOffset, fs20fw800.fontSize!, fs36fw800.fontSize!), + color: Theme.of(context).extension()!.grey900)), if (shrinkOffset < offsetForShrink) Text(locale.translate('cards.scoreboard.days'), - style: scoreTextStyle.copyWith( - color: Theme.of(context).extension()!.grey900)), + style: fs12fw700.copyWith( + color: Theme.of(context).extension()!.grey900)), if (shrinkOffset > offsetForShrink) Padding( padding: const EdgeInsets.only(left: 8.0), child: Text(locale.translate('cards.scoreboard.days-short'), - style: scoreTextStyle.copyWith( - color: Theme.of(context).extension()!.grey900)), + style: fs12fw700.copyWith( + color: Theme.of(context).extension()!.grey900)), ) ]; List childrenTasks = [ Text(model.taskCompleted.toString(), - style: scoreNumberStyle.copyWith( - fontSize: calculateScrollAwareSizing(shrinkOffset, - scoreNumberStyleSmall.fontSize!, scoreNumberStyle.fontSize!), - color: Theme.of(context).extension()!.primary)), + style: fs36fw800.copyWith( + fontSize: calculateScrollAwareSizing( + shrinkOffset, fs20fw800.fontSize!, fs36fw800.fontSize!), + color: Theme.of(context).extension()!.primary)), if (shrinkOffset < offsetForShrink) Text(locale.translate('cards.scoreboard.tasks'), - style: scoreTextStyle.copyWith( - color: Theme.of(context).extension()!.primary)), + style: fs12fw700.copyWith( + color: Theme.of(context).extension()!.primary)), if (shrinkOffset > offsetForShrink) Expanded( flex: 0, child: Padding( padding: const EdgeInsets.only(left: 8.0), child: Text(locale.translate('cards.scoreboard.tasks-short'), - style: scoreTextStyle.copyWith( - color: Theme.of(context).extension()!.primary)), + style: fs12fw700.copyWith( + color: Theme.of(context).extension()!.primary)), ), ) ]; @@ -96,7 +96,7 @@ class ScoreboardPersistentHeaderDelegate return Container( height: height, decoration: BoxDecoration( - color: Theme.of(context).extension()!.white, + color: Theme.of(context).extension()!.white, borderRadius: BorderRadius.circular(8), // Rounded corners ), child: StreamBuilder( diff --git a/lib/ui/cards/steps_card.dart b/lib/ui/cards/steps_card.dart index f8caef84..ffb40e14 100644 --- a/lib/ui/cards/steps_card.dart +++ b/lib/ui/cards/steps_card.dart @@ -29,7 +29,7 @@ class StepsCardWidgetState extends State { RPLocalizations locale = RPLocalizations.of(context)!; return StudiesMaterial( - backgroundColor: Theme.of(context).extension()!.white!, + backgroundColor: Theme.of(context).extension()!.white!, child: Padding( padding: const EdgeInsets.all(8.0), child: Column( @@ -37,17 +37,17 @@ class StepsCardWidgetState extends State { Row( children: [ Text( - '$_step', - style: dataVizCardTitleNumber.copyWith( - color: Theme.of(context).extension()!.grey900!, + _step > 0 ? '$_step' : '0', + style: fs28fw700.copyWith( + color: Theme.of(context).extension()!.grey900!, ), ), Padding( padding: const EdgeInsets.only(left: 4.0), child: Text( '${locale.translate('cards.steps.steps')} ${_getDayName(touchedIndex)}', - style: dataVizCardTitleText.copyWith( - color: Theme.of(context).extension()!.grey600, + style: fs12fw700.copyWith( + color: Theme.of(context).extension()!.grey600, ), ), ), @@ -57,8 +57,8 @@ class StepsCardWidgetState extends State { children: [ Text( "${widget.model.currentMonth} ${widget.model.startOfWeek} - ${int.parse(widget.model.endOfWeek) < int.parse(widget.model.startOfWeek) ? widget.model.nextMonth : widget.model.currentMonth} ${widget.model.endOfWeek}, ${widget.model.currentYear}", - style: dataVizCardTitleText.copyWith( - color: Theme.of(context).extension()!.grey600, + style: fs12fw700.copyWith( + color: Theme.of(context).extension()!.grey600, ), ), Spacer(), @@ -172,8 +172,8 @@ class StepsCardWidgetState extends State { value.toInt() % meta.appliedInterval == 0 ? value.toInt().toString() : '', - style: dataCardRightTitleStyle.copyWith( - color: Theme.of(context).extension()!.grey600, + style: fs14ls1.copyWith( + color: Theme.of(context).extension()!.grey600, ), ), ); diff --git a/lib/ui/cards/study_progress_card.dart b/lib/ui/cards/study_progress_card.dart index c74e4cf6..800b6b46 100644 --- a/lib/ui/cards/study_progress_card.dart +++ b/lib/ui/cards/study_progress_card.dart @@ -19,7 +19,7 @@ class StudyProgressCardWidgetState extends State { widget.model.updateProgress(); return StudiesMaterial( - backgroundColor: Theme.of(context).extension()!.white!, + backgroundColor: Theme.of(context).extension()!.white!, child: Padding( padding: const EdgeInsets.all(8.0), child: StreamBuilder( @@ -33,7 +33,7 @@ class StudyProgressCardWidgetState extends State { mainAxisAlignment: MainAxisAlignment.start, children: [ Text(locale.translate('cards.study_progress.title'), - style: dataCardTitleStyle), + style: fs16fw400ls1), ], ), ), diff --git a/lib/ui/cards/survey_card.dart b/lib/ui/cards/survey_card.dart index 92569b90..579b1b1f 100644 --- a/lib/ui/cards/survey_card.dart +++ b/lib/ui/cards/survey_card.dart @@ -21,7 +21,7 @@ class _SurveyCardState extends State { } return StudiesMaterial( - backgroundColor: Theme.of(context).extension()!.white!, + backgroundColor: Theme.of(context).extension()!.white!, child: Padding( padding: const EdgeInsets.all(8.0), child: Column( @@ -30,7 +30,7 @@ class _SurveyCardState extends State { Padding( padding: const EdgeInsets.only(left: 10.0), child: Text(locale.translate('cards.survey.title').toUpperCase(), - style: dataCardTitleStyle), + style: fs16fw400ls1), ), SizedBox( height: 160, @@ -57,7 +57,7 @@ class _SurveyCardState extends State { ); Widget text = Text( '${entry.value} ${locale.translate(entry.key).truncateTo(12)}', - style: legendStyle, + style: fs12fw400, ); return Row( children: [ @@ -83,9 +83,10 @@ class _SurveyCardState extends State { ), Text( '$totalSurveys', - style: surveysCardTotalTextStyle.copyWith( - color: - Theme.of(context).extension()!.grey800, + style: fs24fw700.copyWith( + color: Theme.of(context) + .extension()! + .grey800, ), ) ], diff --git a/lib/ui/carp_study_style.dart b/lib/ui/carp_study_style.dart index 3d6f935f..0ac9bfce 100644 --- a/lib/ui/carp_study_style.dart +++ b/lib/ui/carp_study_style.dart @@ -1,8 +1,8 @@ part of carp_study_app; @immutable -class CarpColors extends ThemeExtension { - const CarpColors({ +class StudyAppColors extends ThemeExtension { + const StudyAppColors({ this.primary, this.warningColor, this.backgroundGray, @@ -44,7 +44,7 @@ class CarpColors extends ThemeExtension { final Color? grey950; @override - CarpColors copyWith( + StudyAppColors copyWith( {Color? primary, Color? warningColor, Color? backgroundGray, @@ -61,7 +61,7 @@ class CarpColors extends ThemeExtension { Color? grey800, Color? grey900, Color? grey950}) { - return CarpColors( + return StudyAppColors( primary: primary ?? this.primary, warningColor: warningColor ?? this.warningColor, backgroundGray: backgroundGray ?? this.backgroundGray, @@ -82,11 +82,11 @@ class CarpColors extends ThemeExtension { } @override - CarpColors lerp(CarpColors? other, double t) { - if (other is! CarpColors) { + StudyAppColors lerp(StudyAppColors? other, double t) { + if (other is! StudyAppColors) { return this; } - return CarpColors( + return StudyAppColors( primary: Color.lerp(primary, other.primary, t), warningColor: Color.lerp(warningColor, other.warningColor, t), backgroundGray: Color.lerp(backgroundGray, other.backgroundGray, t), @@ -109,7 +109,7 @@ class CarpColors extends ThemeExtension { ThemeData carpStudyTheme = ThemeData.light().copyWith( extensions: >[ - CarpColors( + StudyAppColors( primary: const Color(0xff000000), warningColor: Colors.orange[500], backgroundGray: const Color(0xfff2f2f7), @@ -179,7 +179,7 @@ ThemeData carpStudyTheme = ThemeData.light().copyWith( ThemeData carpStudyDarkTheme = ThemeData.dark().copyWith( extensions: >[ - CarpColors( + StudyAppColors( primary: const Color(0xff24B2FF), warningColor: Colors.orange[700], backgroundGray: const Color(0xff0e0e0e), @@ -253,13 +253,13 @@ ThemeData carpStudyDarkTheme = ThemeData.dark().copyWith( // These TextStyles are now implemented in ResearchPackage -// TextStyle studyTitleStyle = +// TextStyle fs24fw600 = // const TextStyle(fontSize: 24, fontWeight: FontWeight.w600); -// TextStyle studyDetailsInfoTitle = +// TextStyle fs16fw700 = // const TextStyle(fontSize: 16, fontWeight: FontWeight.w700); -// TextStyle studyDetailsInfoMessage = +// TextStyle fs12fw700 = // const TextStyle(fontSize: 12, fontWeight: FontWeight.w700); // TextStyle readMoreStudyStyle = @@ -278,29 +278,29 @@ ThemeData carpStudyDarkTheme = ThemeData.dark().copyWith( // TextStyle scoreTextStyle = // const TextStyle(fontSize: 12, fontWeight: FontWeight.w700); -// TextStyle aboutStudyCardTitleStyle = +// TextStyle fs24fw700 = // const TextStyle(fontSize: 24, fontWeight: FontWeight.w700) // .apply(fontFamily: 'OpenSans'); -// TextStyle aboutCardTitleStyle = +// TextStyle fs20fw700 = // const TextStyle(fontSize: 20, fontWeight: FontWeight.w700) // .apply(fontFamily: 'OpenSans'); // TextStyle aboutCardInfoStyle = // const TextStyle(fontSize: 14, fontStyle: FontStyle.italic); -// TextStyle aboutCardSubtitleStyle = +// TextStyle fs16fw600 = // const TextStyle(fontSize: 16, fontWeight: FontWeight.w600); -// TextStyle aboutCardContentStyle = +// TextStyle fs16fw400 = // const TextStyle(fontSize: 16, fontWeight: FontWeight.w400) // .apply(fontFamily: 'OpenSans'); -// TextStyle aboutCardTimeAgoStyle = +// TextStyle fs10fw600 = // const TextStyle(fontSize: 10, fontWeight: FontWeight.w600) // .apply(fontFamily: 'OpenSans'); -// TextStyle sectionTitleStyle = +// TextStyle fs18fw700 = // const TextStyle(fontSize: 18, fontWeight: FontWeight.w700); // TextStyle inputFieldStyle = @@ -312,18 +312,18 @@ ThemeData carpStudyDarkTheme = ThemeData.dark().copyWith( // TextStyle studyDescriptionStyle = // const TextStyle(fontSize: 12, fontWeight: FontWeight.w300); -// TextStyle dataCardTitleStyle = const TextStyle( +// TextStyle fs16fw400ls1 = const TextStyle( // fontSize: 16, fontWeight: FontWeight.w400, letterSpacing: 1); // TextStyle dataCardRightTitleStyle = // const TextStyle(fontSize: 14, letterSpacing: 1); // TextStyle measuresStyle = // const TextStyle(fontSize: 18, fontWeight: FontWeight.w400); -// TextStyle legendStyle = +// TextStyle fs12fw400 = // const TextStyle(fontSize: 12, fontWeight: FontWeight.w400); -// TextStyle audioTitleStyle = +// TextStyle fs22fw700 = // const TextStyle(fontSize: 22, fontWeight: FontWeight.w700); -// TextStyle audioContentStyle = +// TextStyle fs16fw600 = // const TextStyle(fontSize: 16, fontWeight: FontWeight.w700); // TextStyle heartRateNumberStyle = @@ -343,27 +343,27 @@ ThemeData carpStudyDarkTheme = ThemeData.dark().copyWith( // TextStyle dataVizCardBottomText = // const TextStyle(fontSize: 12, fontWeight: FontWeight.w700); -// TextStyle deviceTitle = +// TextStyle fs16fw700 = // const TextStyle(fontSize: 16, fontWeight: FontWeight.w700); -// TextStyle deviceSubtitle = +// TextStyle fs12fw700 = // const TextStyle(fontSize: 12, fontWeight: FontWeight.w700); // TextStyle healthServiceConnectTitleStyle = // const TextStyle(fontSize: 24, fontWeight: FontWeight.w700); -// TextStyle healthServiceConnectMessageStyle = +// TextStyle fs22fw700 = // const TextStyle(fontSize: 22, fontWeight: FontWeight.w700); -// TextStyle profileSectionStyle = +// TextStyle fs12fw600 = // TextStyle(fontSize: 12, fontWeight: FontWeight.w600); -// TextStyle profileTitleStyle = +// TextStyle fs14fw600 = // TextStyle(fontSize: 14, fontWeight: FontWeight.w600); -// TextStyle profileActionStyle = +// TextStyle fs16fw600 = // TextStyle(fontSize: 16, fontWeight: FontWeight.w600); // TextStyle timerStyle = // const TextStyle(fontSize: 36, fontWeight: FontWeight.w600); -// TextStyle studyNameStyle = +// TextStyle fs30fw800 = // const TextStyle(fontSize: 30.0, fontWeight: FontWeight.w800); diff --git a/lib/ui/pages/data_visualization_page.dart b/lib/ui/pages/data_visualization_page.dart index 56db1a91..373b3ca6 100644 --- a/lib/ui/pages/data_visualization_page.dart +++ b/lib/ui/pages/data_visualization_page.dart @@ -16,7 +16,7 @@ class _DataVisualizationPageState extends State { RPLocalizations locale = RPLocalizations.of(context)!; return Scaffold( backgroundColor: - Theme.of(context).extension()!.backgroundGray, + Theme.of(context).extension()!.backgroundGray, body: SafeArea( child: Column( crossAxisAlignment: CrossAxisAlignment.center, @@ -38,9 +38,9 @@ class _DataVisualizationPageState extends State { crossAxisAlignment: CrossAxisAlignment.start, children: [ Text(locale.translate('pages.data_viz.title'), - style: aboutStudyCardTitleStyle.copyWith( + style: fs24fw700.copyWith( color: Theme.of(context) - .extension()! + .extension()! .grey900, fontWeight: FontWeight.bold, )), @@ -60,9 +60,9 @@ class _DataVisualizationPageState extends State { padding: const EdgeInsets.symmetric( horizontal: 15, vertical: 24.0), child: Text(locale.translate('pages.data_viz.thanks'), - style: aboutCardSubtitleStyle.copyWith( + style: fs16fw600.copyWith( color: Theme.of(context) - .extension()! + .extension()! .grey600, )), ), diff --git a/lib/ui/pages/device_list_page.dart b/lib/ui/pages/device_list_page.dart index d392f148..9e563688 100644 --- a/lib/ui/pages/device_list_page.dart +++ b/lib/ui/pages/device_list_page.dart @@ -49,7 +49,8 @@ class DeviceListPageState extends State { Widget build(BuildContext context) { RPLocalizations locale = RPLocalizations.of(context)!; return Scaffold( - backgroundColor: Theme.of(context).extension()!.backgroundGray, + backgroundColor: + Theme.of(context).extension()!.backgroundGray, body: SafeArea( child: Column( crossAxisAlignment: CrossAxisAlignment.center, @@ -72,9 +73,10 @@ class DeviceListPageState extends State { children: [ Text( locale.translate('pages.devices.title'), - style: aboutStudyCardTitleStyle.copyWith( - color: - Theme.of(context).extension()!.grey900, + style: fs24fw700.copyWith( + color: Theme.of(context) + .extension()! + .grey900, fontWeight: FontWeight.bold, ), ), @@ -94,9 +96,9 @@ class DeviceListPageState extends State { crossAxisAlignment: CrossAxisAlignment.start, children: [ Text(locale.translate("pages.devices.message"), - style: aboutCardSubtitleStyle.copyWith( + style: fs16fw600.copyWith( color: Theme.of(context) - .extension()! + .extension()! .grey600, )), const SizedBox(height: 15), @@ -134,7 +136,7 @@ class DeviceListPageState extends State { builder: (BuildContext context, Widget? widget) => Center( child: StudiesMaterial( backgroundColor: - Theme.of(context).extension()!.grey50!, + Theme.of(context).extension()!.grey50!, child: _cardListBuilder( leading: _smartphoneDevice[index].icon!, title: ( @@ -182,8 +184,7 @@ class DeviceListPageState extends State { child: Text( locale.translate( device.getDeviceStatusIcon as String), - style: aboutCardTitleStyle.copyWith( - color: Colors.white)), + style: fs20fw700.copyWith(color: Colors.white)), ), ), ); @@ -218,8 +219,7 @@ class DeviceListPageState extends State { child: Text( locale.translate( service.getServiceStatusIcon as String), - style: aboutCardTitleStyle.copyWith( - color: Colors.white), + style: fs20fw700.copyWith(color: Colors.white), ), ) : service.getServiceStatusIcon as Icon, @@ -255,8 +255,8 @@ class DeviceListPageState extends State { children: [ Text( title!.$1, - style: deviceTitle.copyWith( - color: Theme.of(context).extension()!.grey900, + style: fs16fw700.copyWith( + color: Theme.of(context).extension()!.grey900, ), ), SizedBox(width: 6), @@ -275,8 +275,9 @@ class DeviceListPageState extends State { alignment: Alignment.centerLeft, child: Text( subtitle, - style: deviceSubtitle.copyWith( - color: Theme.of(context).extension()!.grey700, + style: fs12fw700.copyWith( + color: + Theme.of(context).extension()!.grey700, ), ), ), @@ -300,7 +301,7 @@ class DeviceListPageState extends State { ) => Center( child: StudiesMaterial( - backgroundColor: Theme.of(context).extension()!.grey50!, + backgroundColor: Theme.of(context).extension()!.grey50!, child: StreamBuilder( stream: stream, initialData: initialData, @@ -320,7 +321,7 @@ class DeviceListPageState extends State { Navigator.push( context, MaterialPageRoute( - builder: (context) => HealthServiceConnectPage1()), + builder: (context) => HealthServiceConnectPage()), ); } else { await service.deviceManager.requestPermissions(); @@ -356,7 +357,7 @@ class DeviceListPageState extends State { if (disconnect) await device.disconnectFromDevice(); } else { final hasSeenInstructions = - LocalSettings().hasSeenConnectionInstructions; + LocalSettings().hasSeenBluetoothConnectionInstructions; Navigator.push( context, MaterialPageRoute( diff --git a/lib/ui/pages/devices_page.authorization_dialog.dart b/lib/ui/pages/devices_page.authorization_dialog.dart index ec22957e..f7a6f370 100644 --- a/lib/ui/pages/devices_page.authorization_dialog.dart +++ b/lib/ui/pages/devices_page.authorization_dialog.dart @@ -32,7 +32,7 @@ class AuthorizationDialog extends StatelessWidget { Text( locale.translate( "pages.devices.connection.bluetooth_authorization.message"), - style: aboutCardContentStyle, + style: fs16fw400, textAlign: TextAlign.justify, ), Image( diff --git a/lib/ui/pages/devices_page.bluetooth_connection_page.dart b/lib/ui/pages/devices_page.bluetooth_connection_page.dart index 9d952dfc..0d0be9e1 100644 --- a/lib/ui/pages/devices_page.bluetooth_connection_page.dart +++ b/lib/ui/pages/devices_page.bluetooth_connection_page.dart @@ -41,16 +41,21 @@ class _BluetoothConnectionPageState extends State { BluetoothDevice? selectedDevice; int selected = 40; + /// Set of normalized UUIDs (no dashes, lower-case) to filter discovered devices by + /// If empty, no UUID filtering is applied. + final Set _filterUuids = {}; + @override Widget build(BuildContext context) { RPLocalizations locale = RPLocalizations.of(context)!; return Scaffold( + backgroundColor: + Theme.of(context).extension()!.backgroundGray, body: SafeArea( child: Stack( children: [ Container( - color: Theme.of(context).colorScheme.secondary, child: Column( children: [ Padding( @@ -120,7 +125,7 @@ class _BluetoothConnectionPageState extends State { Flexible( child: Text( stepTitleMap[currentStep] ?? '', - style: healthServiceConnectMessageStyle.copyWith( + style: fs22fw700.copyWith( color: Theme.of(context).primaryColor, ), textAlign: TextAlign.center, @@ -165,7 +170,7 @@ class _BluetoothConnectionPageState extends State { _connectDevice(), selectedDevice != null, ElevatedButton.styleFrom( - backgroundColor: Theme.of(context).extension()!.primary, + backgroundColor: Theme.of(context).extension()!.primary, padding: const EdgeInsets.symmetric(horizontal: 30, vertical: 12), ), TextStyle( @@ -186,7 +191,7 @@ class _BluetoothConnectionPageState extends State { }, true, ElevatedButton.styleFrom( - backgroundColor: Theme.of(context).extension()!.primary, + backgroundColor: Theme.of(context).extension()!.primary, padding: const EdgeInsets.symmetric(horizontal: 30, vertical: 12), ), TextStyle( @@ -206,7 +211,7 @@ class _BluetoothConnectionPageState extends State { }, true, ElevatedButton.styleFrom( - backgroundColor: Theme.of(context).extension()!.primary, + backgroundColor: Theme.of(context).extension()!.primary, padding: const EdgeInsets.symmetric(horizontal: 30, vertical: 12), ), TextStyle( @@ -305,41 +310,55 @@ class _BluetoothConnectionPageState extends State { "${locale.translate("pages.devices.connection.step.scan.1")} " "${locale.translate(device.typeName)} " "${locale.translate("pages.devices.connection.step.scan.2")}", - style: healthServiceConnectMessageStyle, + style: fs22fw700, textAlign: TextAlign.justify, ), Expanded( child: StreamBuilder>( stream: FlutterBluePlus.scanResults, initialData: const [], - builder: (context, snapshot) => SingleChildScrollView( - padding: const EdgeInsets.only(top: 16), - child: Column( - children: snapshot.data! - .where( - (element) => element.device.platformName.isNotEmpty) - .toList() - .asMap() - .entries - .map( - (bluetoothDevice) => ListTile( - selected: bluetoothDevice.key == selected, - title: Text( - bluetoothDevice.value.device.platformName, - style: healthServiceConnectMessageStyle, + builder: (context, snapshot) => Scrollbar( + thumbVisibility: true, + child: SingleChildScrollView( + padding: const EdgeInsets.only(top: 16), + child: Column( + children: snapshot.data! + .where((element) => + element.device.platformName.isNotEmpty && + _matchesUuid(element, _filterUuids)) + .toList() + .asMap() + .entries + .map( + (bluetoothDevice) => StudiesMaterial( + // hasBorder: true, + backgroundColor: Theme.of(context) + .extension()! + .grey50!, + child: InkWell( + child: ListTile( + selected: bluetoothDevice.key == selected, + title: Text( + bluetoothDevice.value.device.platformName, + style: fs22fw700.copyWith( + fontSize: 20, + ), + ), + selectedTileColor: Theme.of(context) + .primaryColor + .withValues(alpha: 0.2), + ), + onTap: () { + selectedDevice = bluetoothDevice.value.device; + setState(() { + selected = bluetoothDevice.key; + }); + }, + ), ), - selectedTileColor: Theme.of(context) - .primaryColor - .withValues(alpha: 0.2), - onTap: () { - selectedDevice = bluetoothDevice.value.device; - setState(() { - selected = bluetoothDevice.key; - }); - }, - ), - ) - .toList(), + ) + .toList(), + ), ), ), ), @@ -357,7 +376,7 @@ class _BluetoothConnectionPageState extends State { text: locale .translate("pages.devices.connection.instructions"), style: TextStyle( - color: Theme.of(context).extension()!.primary, + color: Theme.of(context).extension()!.primary, decoration: TextDecoration.underline, fontWeight: FontWeight.bold, ), @@ -373,8 +392,8 @@ class _BluetoothConnectionPageState extends State { ), ], ), - style: healthServiceConnectMessageStyle.copyWith( - color: Theme.of(context).extension()!.grey900), + style: fs22fw700.copyWith( + color: Theme.of(context).extension()!.grey900), textAlign: TextAlign.center, ), ) @@ -383,6 +402,34 @@ class _BluetoothConnectionPageState extends State { ); } + /// Returns true if [scanResult] advertises any UUID present in [filterUuids]. + /// If [filterUuids] is empty, always returns true. + bool _matchesUuid(ScanResult scanResult, Set filterUuids) { + if (filterUuids.isEmpty) return true; + + // Normalize helper: remove dashes and lowercase + String normalize(String u) => u.replaceAll('-', '').toLowerCase(); + + try { + // FlutterBluePlus ScanResult contains advertisementData with serviceUuids + final adv = scanResult.advertisementData; + final serviceUuids = adv.serviceUuids; + for (var u in serviceUuids) { + final us = u.toString(); + if (filterUuids.contains(normalize(us))) return true; + } + + // Also check device id (remoteId) as fallback + final devId = scanResult.device.remoteId.str; + if (filterUuids.contains(normalize(devId))) return true; + } catch (_) { + // If structure differs, fall back to allowing the device + return true; + } + + return false; + } + Widget connectionInstructions(DeviceViewModel device, BuildContext context) { RPLocalizations locale = RPLocalizations.of(context)!; AssetImage? assetImage; @@ -420,8 +467,8 @@ class _BluetoothConnectionPageState extends State { Image connectionImage = Image( image: assetImage, - width: MediaQuery.of(context).size.height * 0.5, - height: MediaQuery.of(context).size.height * 0.5, + width: MediaQuery.of(context).size.height * 0.3, + height: MediaQuery.of(context).size.height * 0.3, ); return Column( children: [ @@ -436,7 +483,7 @@ class _BluetoothConnectionPageState extends State { padding: const EdgeInsets.only(bottom: 20.0), child: Text( locale.translate(device.connectionInstructions!), - style: aboutCardContentStyle, + style: fs16fw400, textAlign: TextAlign.justify, ), ), @@ -467,7 +514,7 @@ class _BluetoothConnectionPageState extends State { child: Text( ("${locale.translate("pages.devices.connection.step.confirm.1")} '${device?.platformName}' ${locale.translate("pages.devices.connection.step.confirm.2")}") .trim(), - style: aboutCardContentStyle, + style: fs16fw400, textAlign: TextAlign.justify, ), ), diff --git a/lib/ui/pages/devices_page.disconnection_dialog.dart b/lib/ui/pages/devices_page.disconnection_dialog.dart index a1326908..0390df0e 100644 --- a/lib/ui/pages/devices_page.disconnection_dialog.dart +++ b/lib/ui/pages/devices_page.disconnection_dialog.dart @@ -26,7 +26,7 @@ class DisconnectionDialog extends StatelessWidget { children: [ Text( "${locale.translate("pages.devices.connection.disconnect_bluetooth.message")} ${locale.translate(device.name)}?", - style: aboutCardContentStyle, + style: fs16fw400, textAlign: TextAlign.justify, ), Row( diff --git a/lib/ui/pages/devices_page.enable_bluetooth_dialog.dart b/lib/ui/pages/devices_page.enable_bluetooth_dialog.dart index 7c6d3aa6..72944dfc 100644 --- a/lib/ui/pages/devices_page.enable_bluetooth_dialog.dart +++ b/lib/ui/pages/devices_page.enable_bluetooth_dialog.dart @@ -31,7 +31,7 @@ class EnableBluetoothDialog extends StatelessWidget { Text( locale.translate( "pages.devices.connection.enable_bluetooth.message1"), - style: aboutCardContentStyle, + style: fs16fw400, textAlign: TextAlign.justify, ), Padding( @@ -40,7 +40,7 @@ class EnableBluetoothDialog extends StatelessWidget { Text( locale.translate( "pages.devices.connection.enable_bluetooth.message2"), - style: aboutCardContentStyle, + style: fs16fw400, textAlign: TextAlign.justify, ), if (Platform.isAndroid || Platform.isIOS) @@ -54,7 +54,7 @@ class EnableBluetoothDialog extends StatelessWidget { Text( locale.translate( "pages.devices.connection.enable_bluetooth.message3"), - style: aboutCardContentStyle, + style: fs16fw400, textAlign: TextAlign.justify, ), ], diff --git a/lib/ui/pages/devices_page.health_service_connect2.dart b/lib/ui/pages/devices_page.health_service_connect.dart similarity index 52% rename from lib/ui/pages/devices_page.health_service_connect2.dart rename to lib/ui/pages/devices_page.health_service_connect.dart index 9d79643d..0a35387b 100644 --- a/lib/ui/pages/devices_page.health_service_connect2.dart +++ b/lib/ui/pages/devices_page.health_service_connect.dart @@ -1,7 +1,7 @@ part of carp_study_app; -class HealthServiceConnectPage2 extends StatelessWidget { - const HealthServiceConnectPage2({super.key}); +class HealthServiceConnectPage extends StatelessWidget { + const HealthServiceConnectPage({super.key}); @override Widget build(BuildContext context) { @@ -14,15 +14,15 @@ class HealthServiceConnectPage2 extends StatelessWidget { .first; return Scaffold( + backgroundColor: Theme.of(context).extension()!.grey100, body: SafeArea( child: Container( - color: Theme.of(context).colorScheme.secondary, child: Column( children: [ Padding( padding: const EdgeInsets.symmetric(vertical: 8.0, horizontal: 18), - child: const CarpAppBar(hasProfileIcon: true), + child: const CarpAppBar(), ), Expanded( child: Padding( @@ -30,25 +30,15 @@ class HealthServiceConnectPage2 extends StatelessWidget { child: Column( mainAxisAlignment: MainAxisAlignment.center, children: [ - Container( - padding: const EdgeInsets.all(20), - decoration: BoxDecoration( - color: Colors.white, - borderRadius: BorderRadius.circular(20), - boxShadow: [ - BoxShadow( - color: Colors.black.withValues(alpha: 0.1), - blurRadius: 10, - spreadRadius: 2, - ), - ], - ), - child: Image.asset( - Platform.isAndroid - ? 'assets/instructions/google_health_connect_icon.png' - : 'assets/instructions/apple_health_icon.png', - height: 250, - width: 250, + Expanded( + child: Center( + child: Image.asset( + Platform.isAndroid + ? 'assets/instructions/google_health_connect_preview.png' + : 'assets/instructions/apple_health_preview.png', + fit: BoxFit.contain, + width: double.infinity, + ), ), ), const SizedBox(height: 20), @@ -58,36 +48,36 @@ class HealthServiceConnectPage2 extends StatelessWidget { TextSpan( text: "${locale.translate("pages.devices.type.health.instructions.page2.part1")} ", - style: healthServiceConnectMessageStyle.copyWith( + style: fs22fw700.copyWith( color: Theme.of(context) - .extension()! + .extension()! .grey900, ), ), TextSpan( text: "${Platform.isAndroid ? locale.translate("pages.devices.type.health.instructions.page2.android.allow_all") : locale.translate("pages.devices.type.health.instructions.page2.ios.turn_on_all")} ", - style: healthServiceConnectMessageStyle.copyWith( + style: fs22fw700.copyWith( color: Theme.of(context) - .extension()! + .extension()! .primary, // Change to desired color ), ), TextSpan( text: "${locale.translate("pages.devices.type.health.instructions.page2.part2")} ", - style: healthServiceConnectMessageStyle.copyWith( + style: fs22fw700.copyWith( color: Theme.of(context) - .extension()! + .extension()! .grey900, ), ), TextSpan( text: "${locale.translate("pages.devices.type.health.instructions.page2.allow")} ", - style: healthServiceConnectMessageStyle.copyWith( + style: fs22fw700.copyWith( color: Theme.of(context) - .extension()! + .extension()! .primary, // Change to desired color ), ), @@ -97,9 +87,9 @@ class HealthServiceConnectPage2 extends StatelessWidget { "pages.devices.type.health.instructions.page2.part3.android") : locale.translate( "pages.devices.type.health.instructions.page2.part3.ios"), - style: healthServiceConnectMessageStyle.copyWith( + style: fs22fw700.copyWith( color: Theme.of(context) - .extension()! + .extension()! .grey900, ), ), @@ -108,39 +98,6 @@ class HealthServiceConnectPage2 extends StatelessWidget { textAlign: TextAlign.center, ), const SizedBox(height: 30), - Row( - mainAxisAlignment: MainAxisAlignment.spaceEvenly, - children: [ - OutlinedButton( - child: const Text("Cancel"), - onPressed: () { - Navigator.pop(context); - }, - ), - ElevatedButton( - child: const Text( - "Next", - style: TextStyle( - color: Colors.white, - ), - ), - style: ElevatedButton.styleFrom( - backgroundColor: Theme.of(context) - .extension()! - .primary, - padding: const EdgeInsets.symmetric( - horizontal: 30, vertical: 12), - ), - onPressed: () async { - await healthServive.deviceManager - .requestPermissions(); - await healthServive.deviceManager.connect(); - - Navigator.pop(context); - }, - ), - ], - ), ], ), ), @@ -149,6 +106,40 @@ class HealthServiceConnectPage2 extends StatelessWidget { ), ), ), + bottomNavigationBar: Padding( + padding: const EdgeInsets.symmetric(vertical: 26), + child: Row( + mainAxisAlignment: MainAxisAlignment.spaceEvenly, + children: [ + OutlinedButton( + child: const Text("Cancel"), + onPressed: () { + Navigator.pop(context); + }, + ), + ElevatedButton( + child: const Text( + "Next", + style: TextStyle( + color: Colors.white, + ), + ), + style: ElevatedButton.styleFrom( + backgroundColor: + Theme.of(context).extension()!.primary, + padding: + const EdgeInsets.symmetric(horizontal: 30, vertical: 12), + ), + onPressed: () async { + await healthServive.deviceManager.requestPermissions(); + await healthServive.deviceManager.connect(); + + Navigator.pop(context); + }, + ), + ], + ), + ), ); } } diff --git a/lib/ui/pages/devices_page.health_service_connect1.dart b/lib/ui/pages/devices_page.health_service_connect1.dart deleted file mode 100644 index 70f358e8..00000000 --- a/lib/ui/pages/devices_page.health_service_connect1.dart +++ /dev/null @@ -1,116 +0,0 @@ -part of carp_study_app; - -class HealthServiceConnectPage1 extends StatelessWidget { - const HealthServiceConnectPage1({super.key}); - - @override - Widget build(BuildContext context) { - RPLocalizations locale = RPLocalizations.of(context)!; - return Scaffold( - body: SafeArea( - child: Container( - color: Theme.of(context).colorScheme.secondary, - child: Column( - children: [ - Padding( - padding: - const EdgeInsets.symmetric(vertical: 8.0, horizontal: 18), - child: const CarpAppBar(hasProfileIcon: true), - ), - Expanded( - child: Padding( - padding: const EdgeInsets.symmetric(horizontal: 24.0), - child: Column( - mainAxisAlignment: MainAxisAlignment.center, - children: [ - Container( - padding: const EdgeInsets.all(20), - decoration: BoxDecoration( - color: Colors.white, - borderRadius: BorderRadius.circular(20), - boxShadow: [ - BoxShadow( - color: Colors.black.withValues(alpha: 0.1), - blurRadius: 10, - spreadRadius: 2, - ), - ], - ), - child: Image.asset( - Platform.isAndroid - ? 'assets/instructions/google_health_connect_icon.png' - : 'assets/instructions/apple_health_icon.png', - height: 250, - width: 250, - ), - ), - const SizedBox(height: 20), - Text( - Platform.isAndroid - ? locale.translate( - "pages.devices.type.health.instructions.page1.android") - : locale.translate( - "pages.devices.type.health.instructions.page1.ios"), - style: healthServiceConnectTitleStyle.copyWith( - color: Theme.of(context) - .extension()! - .primary), - textAlign: TextAlign.center, - ), - const SizedBox(height: 10), - Text( - "${locale.translate("pages.devices.type.health.instructions.page1.part1")} " - "${Platform.isAndroid ? locale.translate("pages.devices.type.health.instructions.page1.android") : locale.translate("pages.devices.type.health.instructions.page1.ios")} " - "${locale.translate("pages.devices.type.health.instructions.page1.part2")}", - style: healthServiceConnectMessageStyle.copyWith( - color: Theme.of(context) - .extension()! - .grey900), - textAlign: TextAlign.center, - ), - const SizedBox(height: 30), - Row( - mainAxisAlignment: MainAxisAlignment.spaceEvenly, - children: [ - OutlinedButton( - child: const Text("Cancel"), - onPressed: () { - Navigator.pop(context); - }, - ), - ElevatedButton( - child: Text( - locale.translate("Next"), - style: TextStyle( - color: Colors.white, - ), - ), - style: ElevatedButton.styleFrom( - backgroundColor: Theme.of(context) - .extension()! - .primary, - padding: const EdgeInsets.symmetric( - horizontal: 30, vertical: 12), - ), - onPressed: () { - Navigator.pushReplacement( - context, - MaterialPageRoute( - builder: (context) => - HealthServiceConnectPage2()), - ); - }, - ), - ], - ), - ], - ), - ), - ), - ], - ), - ), - ), - ); - } -} diff --git a/lib/ui/pages/devices_page.list_title.dart b/lib/ui/pages/devices_page.list_title.dart index 339c4c7f..19f57309 100644 --- a/lib/ui/pages/devices_page.list_title.dart +++ b/lib/ui/pages/devices_page.list_title.dart @@ -23,8 +23,8 @@ class DevicesPageListTitle extends StatelessWidget { padding: const EdgeInsets.symmetric(horizontal: 24, vertical: 6), child: Text( locale.translate("pages.devices.${type.name}.title").toUpperCase(), - style: dataCardTitleStyle.copyWith( - color: Theme.of(context).extension()!.grey900, + style: fs16fw400ls1.copyWith( + color: Theme.of(context).extension()!.grey900, fontWeight: FontWeight.bold)), ), ); diff --git a/lib/ui/pages/enable_connection_dialog.dart b/lib/ui/pages/enable_connection_dialog.dart index 5ebb653d..cf5c7776 100644 --- a/lib/ui/pages/enable_connection_dialog.dart +++ b/lib/ui/pages/enable_connection_dialog.dart @@ -37,7 +37,7 @@ class EnableInternetConnectionDialog extends StatelessWidget { Text( locale.translate( "pages.login.internet_connection.enable_internet_connections.general_message"), - style: aboutCardContentStyle, + style: fs16fw400, textAlign: TextAlign.justify, ), Padding( @@ -45,7 +45,7 @@ class EnableInternetConnectionDialog extends StatelessWidget { child: Text( locale.translate( "pages.login.internet_connection.enable_internet_connections.wifi_message"), - style: aboutCardContentStyle, + style: fs16fw400, textAlign: TextAlign.justify, )), Padding( @@ -60,7 +60,7 @@ class EnableInternetConnectionDialog extends StatelessWidget { child: Text( locale.translate( "pages.login.internet_connection.enable_internet_connections.mobile_data_message"), - style: aboutCardContentStyle, + style: fs16fw400, textAlign: TextAlign.justify, ), ), @@ -111,7 +111,7 @@ class EnableInternetConnectionDialog extends StatelessWidget { Text( locale.translate( "pages.login.internet_connection.enable_internet_connections.general_message"), - style: aboutCardContentStyle, + style: fs16fw400, textAlign: TextAlign.justify, ), Padding( @@ -119,7 +119,7 @@ class EnableInternetConnectionDialog extends StatelessWidget { child: Text( locale.translate( "pages.login.internet_connection.enable_internet_connections.wifi_message"), - style: aboutCardContentStyle, + style: fs16fw400, textAlign: TextAlign.justify, )), Padding( @@ -135,7 +135,7 @@ class EnableInternetConnectionDialog extends StatelessWidget { Text( locale.translate( "pages.login.internet_connection.enable_internet_connections.mobile_data_message"), - style: aboutCardContentStyle, + style: fs16fw400, textAlign: TextAlign.justify, ), ]), diff --git a/lib/ui/pages/home_page.dart b/lib/ui/pages/home_page.dart index aa6aacc8..791a9920 100644 --- a/lib/ui/pages/home_page.dart +++ b/lib/ui/pages/home_page.dart @@ -96,19 +96,22 @@ class HomePageState extends State { AppTaskController().userTaskEvents.listen((userTask) { if (userTask.state == UserTaskState.notified) { userTask.onStart(); - if (userTask.hasWidget) context.push('/task/${userTask.id}'); + if (userTask.hasWidget) { + _rootNavigatorKey.currentContext?.push('/task/${userTask.id}'); + } } }); return Scaffold( - backgroundColor: Theme.of(context).extension()!.backgroundGray, + backgroundColor: + Theme.of(context).extension()!.backgroundGray, body: SafeArea( child: widget.child, ), bottomNavigationBar: BottomNavigationBar( - backgroundColor: Theme.of(context).extension()!.white, + backgroundColor: Theme.of(context).extension()!.white, type: BottomNavigationBarType.fixed, - selectedItemColor: Theme.of(context).extension()!.primary, + selectedItemColor: Theme.of(context).extension()!.primary, //unselectedItemColor: Theme.of(context).primaryColor.withOpacity(0.8), items: [ BottomNavigationBarItem( diff --git a/lib/ui/pages/home_page.install_health_connect_dialog.dart b/lib/ui/pages/home_page.install_health_connect_dialog.dart index 2a60a0cf..2129ece0 100644 --- a/lib/ui/pages/home_page.install_health_connect_dialog.dart +++ b/lib/ui/pages/home_page.install_health_connect_dialog.dart @@ -14,7 +14,7 @@ class InstallHealthConnectDialog extends StatelessWidget { ), content: Text( locale.translate('pages.about.install_health_connect.description'), - style: aboutCardContentStyle, + style: fs16fw400, textAlign: TextAlign.justify, ), actions: [ diff --git a/lib/ui/pages/invitation_list_page.dart b/lib/ui/pages/invitation_list_page.dart index 0180d634..d6ddbadb 100644 --- a/lib/ui/pages/invitation_list_page.dart +++ b/lib/ui/pages/invitation_list_page.dart @@ -9,7 +9,8 @@ class InvitationListPage extends StatelessWidget { Widget build(BuildContext context) { RPLocalizations locale = RPLocalizations.of(context)!; return Scaffold( - backgroundColor: Theme.of(context).extension()!.backgroundGray, + backgroundColor: + Theme.of(context).extension()!.backgroundGray, body: FutureBuilder>( future: bloc.backend.getInvitations(), builder: (context, snapshot) { @@ -38,7 +39,7 @@ class InvitationListPage extends StatelessWidget { slivers: [ SliverAppBar( backgroundColor: - Theme.of(context).extension()!.backgroundGray, + Theme.of(context).extension()!.backgroundGray, title: const CarpAppBar(), centerTitle: true, pinned: true, @@ -121,7 +122,7 @@ class InvitationMaterial extends StatelessWidget { Widget build(BuildContext context) { RPLocalizations locale = RPLocalizations.of(context)!; return StudiesMaterial( - backgroundColor: Theme.of(context).extension()!.white!, + backgroundColor: Theme.of(context).extension()!.white!, shape: RoundedRectangleBorder( borderRadius: BorderRadius.circular(12.0), ), @@ -138,7 +139,7 @@ class InvitationMaterial extends StatelessWidget { Text( invitation.invitation.name, maxLines: 1, - style: studyTitleStyle.copyWith( + style: fs24fw600.copyWith( color: CACHET.TASK_COMPLETED_BLUE, overflow: TextOverflow.ellipsis), ), @@ -148,15 +149,17 @@ class InvitationMaterial extends StatelessWidget { TextSpan( text: locale.translate( 'invitation_list.roles_in_the_study.description'), - style: studyDetailsInfoTitle.copyWith( - color: Theme.of(context).extension()!.grey600, + style: fs16fw700.copyWith( + color: + Theme.of(context).extension()!.grey600, fontSize: 12, ), ), TextSpan( text: invitation.participantRoleName, - style: studyDetailsInfoTitle.copyWith( - color: Theme.of(context).extension()!.grey600, + style: fs16fw700.copyWith( + color: + Theme.of(context).extension()!.grey600, fontSize: 12, ), ), @@ -166,8 +169,8 @@ class InvitationMaterial extends StatelessWidget { Text( invitation.invitation.description ?? '', maxLines: 2, - style: studyDetailsInfoTitle.copyWith( - color: Theme.of(context).extension()!.grey900, + style: fs16fw700.copyWith( + color: Theme.of(context).extension()!.grey900, overflow: TextOverflow.ellipsis, ), ), diff --git a/lib/ui/pages/invitation_page.dart b/lib/ui/pages/invitation_page.dart index 76199656..c7084b18 100644 --- a/lib/ui/pages/invitation_page.dart +++ b/lib/ui/pages/invitation_page.dart @@ -17,7 +17,8 @@ class InvitationDetailsPage extends StatelessWidget { var invitation = model.getInvitation(invitationId); return Scaffold( - backgroundColor: Theme.of(context).extension()!.backgroundGray, + backgroundColor: + Theme.of(context).extension()!.backgroundGray, body: Padding( padding: const EdgeInsets.symmetric(vertical: 16.0), child: SafeArea( @@ -59,7 +60,7 @@ class InvitationDetailsPage extends StatelessWidget { padding: const EdgeInsets.only(top: 16.0), child: StudiesMaterial( backgroundColor: - Theme.of(context).extension()!.white!, + Theme.of(context).extension()!.white!, shape: RoundedRectangleBorder( borderRadius: BorderRadius.circular(12.0), ), @@ -93,7 +94,7 @@ class InvitationDetailsPage extends StatelessWidget { padding: const EdgeInsets.only(top: 16.0), child: StudiesMaterial( backgroundColor: - Theme.of(context).extension()!.white!, + Theme.of(context).extension()!.white!, shape: RoundedRectangleBorder( borderRadius: BorderRadius.circular(12.0), ), @@ -118,7 +119,7 @@ class InvitationDetailsPage extends StatelessWidget { fontWeight: FontWeight.bold, fontSize: 22.0, color: Theme.of(context) - .extension()! + .extension()! .primary, ), ), @@ -133,7 +134,7 @@ class InvitationDetailsPage extends StatelessWidget { fontWeight: FontWeight.bold, fontSize: 14, color: Theme.of(context) - .extension()! + .extension()! .grey600, ), maxLines: 1, diff --git a/lib/ui/pages/message_details_page.dart b/lib/ui/pages/message_details_page.dart index 93817864..757cf560 100644 --- a/lib/ui/pages/message_details_page.dart +++ b/lib/ui/pages/message_details_page.dart @@ -42,7 +42,7 @@ class MessageDetailsPage extends StatelessWidget { left: 26, right: 10, top: 16, bottom: 16), icon: Icon( Icons.arrow_back_ios, - color: Theme.of(context).extension()!.grey600, + color: Theme.of(context).extension()!.grey600, ), onPressed: () { if (context.canPop()) { @@ -52,19 +52,31 @@ class MessageDetailsPage extends StatelessWidget { } }, ), - Material( - color: CACHET.DEPLOYMENT_DEPLOYING, - borderRadius: BorderRadius.circular(100.0), - child: Padding( - padding: const EdgeInsets.all(12.0), - child: Text( - locale.translate(message.type - .toString() - .split('.') - .last - .toLowerCase()), - style: aboutCardSubtitleStyle.copyWith( - color: Colors.white)), + Padding( + padding: const EdgeInsets.symmetric(vertical: 10.0), + child: Text(locale.translate(message.title!), + style: fs20fw700.copyWith( + color: Theme.of(context) + .extension()! + .grey900)), + ), + Spacer(), + Padding( + padding: const EdgeInsets.only(right: 24), + child: Material( + color: CACHET.DEPLOYMENT_DEPLOYING, + borderRadius: BorderRadius.circular(100.0), + child: Padding( + padding: const EdgeInsets.symmetric( + horizontal: 12.0, vertical: 6.0), + child: Text( + locale.translate(message.type + .toString() + .split('.') + .last + .toLowerCase()), + style: fs16fw600.copyWith(color: Colors.white)), + ), ), ), ], @@ -74,22 +86,14 @@ class MessageDetailsPage extends StatelessWidget { padding: const EdgeInsets.symmetric(horizontal: 24, vertical: 16), children: [ - Padding( - padding: const EdgeInsets.symmetric(vertical: 10.0), - child: Text(locale.translate(message.title!), - style: aboutCardTitleStyle.copyWith( - color: Theme.of(context) - .extension()! - .grey900)), - ), message.subTitle != null ? Padding( padding: const EdgeInsets.symmetric( horizontal: 10.0, vertical: 6.0), child: Text(locale.translate(message.subTitle!), - style: aboutCardContentStyle.copyWith( + style: fs16fw400.copyWith( color: Theme.of(context) - .extension()! + .extension()! .grey700)), ) : const SizedBox.shrink(), @@ -118,9 +122,9 @@ class MessageDetailsPage extends StatelessWidget { if (message.message != null) Text( locale.translate(message.message!), - style: aboutCardContentStyle.copyWith( + style: fs16fw400.copyWith( color: Theme.of(context) - .extension()! + .extension()! .grey900), textAlign: TextAlign.justify, ) diff --git a/lib/ui/pages/process_message_page.dart b/lib/ui/pages/process_message_page.dart index df00b325..d9b4b131 100644 --- a/lib/ui/pages/process_message_page.dart +++ b/lib/ui/pages/process_message_page.dart @@ -70,11 +70,9 @@ class ProcessMessagePage extends StatelessWidget { const SizedBox(height: 40), messageImage(), const SizedBox(height: 20), - Center( - child: - Text(locale.translate(title), style: audioTitleStyle)), + Center(child: Text(locale.translate(title), style: fs22fw700)), const SizedBox(height: 10), - Text(locale.translate(description), style: audioContentStyle), + Text(locale.translate(description), style: fs16fw600), ]), ), bottomSheet: Row( diff --git a/lib/ui/pages/profile_page.dart b/lib/ui/pages/profile_page.dart index 14e53592..4b390de4 100644 --- a/lib/ui/pages/profile_page.dart +++ b/lib/ui/pages/profile_page.dart @@ -26,7 +26,7 @@ class ProfilePageState extends State { RPLocalizations locale = RPLocalizations.of(context)!; return Scaffold( - backgroundColor: Theme.of(context).extension()!.grey100, + backgroundColor: Theme.of(context).extension()!.grey100, body: Column( crossAxisAlignment: CrossAxisAlignment.start, mainAxisAlignment: MainAxisAlignment.start, @@ -43,7 +43,7 @@ class ProfilePageState extends State { icon: Icon(Icons.account_circle, color: Theme.of(context).primaryColor, size: 30), label: Text(locale.translate("pages.profile.title"), - style: aboutCardTitleStyle.copyWith( + style: fs20fw700.copyWith( color: Theme.of(context).primaryColor)), ), IconButton( @@ -215,7 +215,7 @@ class ProfilePageState extends State { Widget _buildSectionCard(BuildContext context, List children) { return Card( - color: Theme.of(context).extension()!.grey50, + color: Theme.of(context).extension()!.grey50, shape: RoundedRectangleBorder( borderRadius: BorderRadius.circular(8.0), ), @@ -225,7 +225,7 @@ class ProfilePageState extends State { children: ListTile.divideTiles( context: context, tiles: children, - color: Theme.of(context).extension()!.grey400, + color: Theme.of(context).extension()!.grey400, ).toList(), ), ), @@ -234,14 +234,13 @@ class ProfilePageState extends State { Widget _buildListTile(String title, String subtitle) { return ListTile( - title: Text(title, - style: profileSectionStyle.copyWith(color: CACHET.GREY_6)), + title: Text(title, style: fs12fw600.copyWith(color: CACHET.GREY_6)), subtitle: FittedBox( fit: BoxFit.scaleDown, alignment: Alignment.centerLeft, child: Text( subtitle, - style: profileTitleStyle, + style: fs14fw600, maxLines: 1, ), ), @@ -258,8 +257,8 @@ class ProfilePageState extends State { return ListTile( leading: leading, title: Text(title, - style: profileActionStyle.copyWith( - color: Theme.of(context).extension()!.grey900)), + style: fs16fw600.copyWith( + color: Theme.of(context).extension()!.grey900)), trailing: trailing, onTap: onTap, contentPadding: EdgeInsets.symmetric(vertical: 4, horizontal: 16), diff --git a/lib/ui/pages/study_details_page.dart b/lib/ui/pages/study_details_page.dart index b4a6102b..6f1673fc 100644 --- a/lib/ui/pages/study_details_page.dart +++ b/lib/ui/pages/study_details_page.dart @@ -10,10 +10,11 @@ class StudyDetailsPage extends StatelessWidget { RPLocalizations locale = RPLocalizations.of(context)!; return Scaffold( - backgroundColor: Theme.of(context).extension()!.backgroundGray, + backgroundColor: + Theme.of(context).extension()!.backgroundGray, body: SafeArea( child: Container( - color: Theme.of(context).extension()!.backgroundGray, + color: Theme.of(context).extension()!.backgroundGray, child: Column( children: [ Padding( @@ -28,7 +29,7 @@ class StudyDetailsPage extends StatelessWidget { left: 26, right: 10, top: 16, bottom: 16), icon: Icon( Icons.arrow_back_ios, - color: Theme.of(context).extension()!.grey600, + color: Theme.of(context).extension()!.grey600, ), onPressed: () { if (context.canPop()) { @@ -41,9 +42,9 @@ class StudyDetailsPage extends StatelessWidget { Padding( padding: const EdgeInsets.symmetric(vertical: 10.0), child: Text(locale.translate(model.title), - style: aboutCardTitleStyle.copyWith( + style: fs20fw700.copyWith( color: Theme.of(context) - .extension()! + .extension()! .primary)), ), ], @@ -76,7 +77,7 @@ class StudyDetailsPage extends StatelessWidget { context: context, leading: Icon(Icons.mail, color: Theme.of(context) - .extension()! + .extension()! .primary), trailing: const Icon(Icons.arrow_forward_ios, color: CACHET.GREY_6), @@ -92,7 +93,7 @@ class StudyDetailsPage extends StatelessWidget { context: context, leading: Icon(Icons.policy, color: Theme.of(context) - .extension()! + .extension()! .primary), trailing: const Icon(Icons.arrow_forward_ios, color: CACHET.GREY_6), @@ -111,7 +112,7 @@ class StudyDetailsPage extends StatelessWidget { context: context, leading: Icon(Icons.public, color: Theme.of(context) - .extension()! + .extension()! .primary), trailing: const Icon(Icons.arrow_forward_ios, color: CACHET.GREY_6), @@ -136,53 +137,53 @@ class StudyDetailsPage extends StatelessWidget { children: [ Text( locale.translate('widgets.study_card.responsible'), - style: studyDetailsInfoTitle.copyWith( + style: fs16fw700.copyWith( color: Theme.of(context) - .extension()! + .extension()! .grey900), ), Padding( padding: const EdgeInsets.only(top: 4.0, bottom: 8), child: Text( locale.translate(model.responsibleName), - style: studyDetailsInfoMessage.copyWith( + style: fs12fw700.copyWith( color: Theme.of(context) - .extension()! + .extension()! .grey700), ), ), Text( locale.translate( 'widgets.study_card.participant_role'), - style: studyDetailsInfoTitle.copyWith( + style: fs16fw700.copyWith( color: Theme.of(context) - .extension()! + .extension()! .grey900), ), Padding( padding: const EdgeInsets.only(top: 4.0, bottom: 8), child: Text( locale.translate(model.participantRole), - style: studyDetailsInfoMessage.copyWith( + style: fs12fw700.copyWith( color: Theme.of(context) - .extension()! + .extension()! .grey700), ), ), Text( locale.translate('widgets.study_card.device_role'), - style: studyDetailsInfoTitle.copyWith( + style: fs16fw700.copyWith( color: Theme.of(context) - .extension()! + .extension()! .grey900), ), Padding( padding: const EdgeInsets.only(top: 4.0, bottom: 8), child: Text( locale.translate(model.deviceRole), - style: studyDetailsInfoMessage.copyWith( + style: fs12fw700.copyWith( color: Theme.of(context) - .extension()! + .extension()! .grey700), ), ), @@ -190,7 +191,7 @@ class StudyDetailsPage extends StatelessWidget { ), ), Divider( - color: Theme.of(context).extension()!.grey300, + color: Theme.of(context).extension()!.grey300, ), Padding( padding: const EdgeInsets.only(top: 16.0), @@ -201,36 +202,36 @@ class StudyDetailsPage extends StatelessWidget { Text( locale.translate( 'widgets.study_card.study_description'), - style: studyDetailsInfoTitle.copyWith( + style: fs16fw700.copyWith( color: Theme.of(context) - .extension()! + .extension()! .grey900), ), Padding( padding: const EdgeInsets.only(top: 4.0, bottom: 8), child: Text( locale.translate(model.description), - style: studyDetailsInfoMessage.copyWith( + style: fs12fw700.copyWith( color: Theme.of(context) - .extension()! + .extension()! .grey700), ), ), Text( locale .translate('widgets.study_card.study_purpose'), - style: studyDetailsInfoTitle.copyWith( + style: fs16fw700.copyWith( color: Theme.of(context) - .extension()! + .extension()! .grey900), ), Padding( padding: const EdgeInsets.only(top: 4.0, bottom: 8), child: Text( locale.translate(model.purpose), - style: studyDetailsInfoMessage.copyWith( + style: fs12fw700.copyWith( color: Theme.of(context) - .extension()! + .extension()! .grey700), ), ), @@ -249,7 +250,8 @@ class StudyDetailsPage extends StatelessWidget { Widget _buildSectionCard(BuildContext context, List children) { return Card( - color: Theme.of(context).extension()!.white, + margin: EdgeInsets.zero, + color: Theme.of(context).extension()!.white, shape: RoundedRectangleBorder( borderRadius: BorderRadius.circular(8.0), ), @@ -259,7 +261,7 @@ class StudyDetailsPage extends StatelessWidget { children: ListTile.divideTiles( context: context, tiles: children, - color: Theme.of(context).extension()!.grey300, + color: Theme.of(context).extension()!.grey300, ).toList(), ), ), @@ -277,8 +279,8 @@ class StudyDetailsPage extends StatelessWidget { return ListTile( leading: leading, title: Text(title, - style: profileActionStyle.copyWith( - color: Theme.of(context).extension()!.grey900)), + style: fs16fw600.copyWith( + color: Theme.of(context).extension()!.grey900)), trailing: trailing, onTap: onTap, contentPadding: EdgeInsets.symmetric(vertical: 4, horizontal: 16), diff --git a/lib/ui/pages/study_page.dart b/lib/ui/pages/study_page.dart index f96e3a42..6b3352b9 100644 --- a/lib/ui/pages/study_page.dart +++ b/lib/ui/pages/study_page.dart @@ -13,7 +13,8 @@ class StudyPageState extends State { @override Widget build(BuildContext context) { return Scaffold( - backgroundColor: Theme.of(context).extension()!.backgroundGray, + backgroundColor: + Theme.of(context).extension()!.backgroundGray, body: SafeArea( child: Column( crossAxisAlignment: CrossAxisAlignment.center, @@ -68,9 +69,12 @@ class StudyPageState extends State { if (LocalSettings().isAnonymous) { items.add(AnonymousCard()); } - if (bloc.messages.isNotEmpty) { + if (widget.model.messages.isNotEmpty) { items.add(_buildAnnouncementsTitle(context)); - items.addAll(bloc.messages.map((message) { + // Show newest announcements first: sort by timestamp descending + final messages = List.from(widget.model.messages) + ..sort((a, b) => b.timestamp.compareTo(a.timestamp)); + items.addAll(messages.map((message) { return _announcementCard(context, message); }).toList()); } @@ -84,7 +88,8 @@ class StudyPageState extends State { builder: (context, snapshot) { if (snapshot.data == true) { return StudiesMaterial( - backgroundColor: Theme.of(context).extension()!.grey50!, + backgroundColor: + Theme.of(context).extension()!.grey50!, elevation: 8, child: Padding( padding: const EdgeInsets.only(left: 16.0), @@ -95,9 +100,9 @@ class StudyPageState extends State { padding: const EdgeInsets.all(8.0), child: Text( locale.translate('pages.about.app_update'), - style: aboutCardSubtitleStyle.copyWith( + style: fs16fw600.copyWith( color: Theme.of(context) - .extension()! + .extension()! .grey900, ), ), @@ -146,7 +151,7 @@ class StudyPageState extends State { timeago.setLocaleMessages('es', timeago.EsMessages()); return StudiesMaterial( - backgroundColor: Theme.of(context).extension()!.grey50!, + backgroundColor: Theme.of(context).extension()!.grey50!, child: InkWell( onTap: () { if (onTap != null) { @@ -172,9 +177,10 @@ class StudyPageState extends State { Padding( padding: const EdgeInsets.symmetric(vertical: 8.0), child: Text(locale.translate(message.title!), - style: aboutStudyCardTitleStyle.copyWith( - color: - Theme.of(context).extension()!.primary)), + style: fs24fw700.copyWith( + color: Theme.of(context) + .extension()! + .primary)), ), if (message.subTitle != null && message.subTitle!.isNotEmpty) Row( @@ -182,9 +188,10 @@ class StudyPageState extends State { Expanded( child: Text( locale.translate(message.subTitle!), - style: aboutCardContentStyle.copyWith( - color: - Theme.of(context).extension()!.grey700, + style: fs16fw400.copyWith( + color: Theme.of(context) + .extension()! + .grey700, ), ), ), @@ -195,9 +202,9 @@ class StudyPageState extends State { Expanded( child: Text( "${locale.translate(message.message!).substring(0, (message.message!.length > 150) ? 150 : null)}...", - style: aboutCardContentStyle.copyWith( + style: fs16fw400.copyWith( color: - Theme.of(context).extension()!.grey900), + Theme.of(context).extension()!.grey900), textAlign: TextAlign.start, )), ]), @@ -215,15 +222,27 @@ class StudyPageState extends State { future: bloc.studyDeploymentStatus, builder: (context, snapshot) { if (snapshot.connectionState == ConnectionState.waiting) { - return Container(); + return StudiesMaterial( + child: Padding( + padding: const EdgeInsets.symmetric(vertical: 28), + child: Center( + child: CircularProgressIndicator(), + ), + ), + ); } else if (snapshot.hasError) { - return Padding( - padding: const EdgeInsets.symmetric(horizontal: 16, vertical: 22), - child: Text('Error: ${snapshot.error}'), + return StudiesMaterial( + child: Padding( + padding: const EdgeInsets.symmetric(vertical: 28), + child: Text( + 'Error: ${snapshot.error}', + textAlign: TextAlign.center, + ), + ), ); // Show an error message if the future fails } else if (!snapshot.hasData || snapshot.data == null) { return Padding( - padding: const EdgeInsets.symmetric(horizontal: 16, vertical: 22), + padding: const EdgeInsets.symmetric(horizontal: 16, vertical: 28), child: Center( child: CircularProgressIndicator(), ), @@ -234,7 +253,7 @@ class StudyPageState extends State { return StudiesMaterial( margin: const EdgeInsets.all(16.0), - backgroundColor: Theme.of(context).extension()!.grey50!, + backgroundColor: Theme.of(context).extension()!.grey50!, shape: RoundedRectangleBorder( borderRadius: BorderRadius.circular(8), ), @@ -275,7 +294,7 @@ class StudyPageState extends State { .split('.') .last, maxLines: 2, - style: aboutCardSubtitleStyle.copyWith( + style: fs16fw600.copyWith( color: studyStatusColors[deploymentStatus]), ), ), @@ -286,9 +305,9 @@ class StudyPageState extends State { padding: const EdgeInsets.only(left: 16.0), child: Text( getStatusText(locale, deploymentStatus, snapshot), - style: aboutCardSubtitleStyle.copyWith( + style: fs16fw600.copyWith( color: Theme.of(context) - .extension()! + .extension()! .grey900, fontSize: 14, ), @@ -320,8 +339,8 @@ class StudyPageState extends State { crossAxisAlignment: CrossAxisAlignment.start, children: [ Text(locale.translate('Announcements'), - style: aboutStudyCardTitleStyle.copyWith( - color: Theme.of(context).extension()!.grey900, + style: fs24fw700.copyWith( + color: Theme.of(context).extension()!.grey900, fontWeight: FontWeight.bold, )), ], @@ -344,7 +363,7 @@ class StudyPageState extends State { return Container( child: StudiesMaterial( - backgroundColor: Theme.of(context).extension()!.grey50!, + backgroundColor: Theme.of(context).extension()!.grey50!, child: InkWell( onTap: () { if (onTap != null) { @@ -368,9 +387,9 @@ class StudyPageState extends State { child: Text( locale.translate(message.title!), overflow: TextOverflow.ellipsis, - style: aboutCardTitleStyle.copyWith( + style: fs20fw700.copyWith( color: Theme.of(context) - .extension()! + .extension()! .grey900, ), ), @@ -380,15 +399,8 @@ class StudyPageState extends State { color: CACHET.DEPLOYMENT_DEPLOYING, borderRadius: BorderRadius.circular(100.0), child: Padding( - padding: const EdgeInsets.all(8.0), - child: Text( - locale.translate(message.type - .toString() - .split('.') - .last - .toLowerCase()), - style: aboutCardSubtitleStyle.copyWith( - color: Colors.white)), + padding: const EdgeInsets.all(4.0), + child: messageTypeIcon[message.type], ), ), ], @@ -402,9 +414,9 @@ class StudyPageState extends State { Expanded( child: Text( locale.translate(message.subTitle!), - style: aboutCardContentStyle.copyWith( + style: fs16fw400.copyWith( color: Theme.of(context) - .extension()! + .extension()! .grey700, ), ), @@ -412,9 +424,10 @@ class StudyPageState extends State { Spacer(), Text( timeago.format(message.timestamp.toLocal()), - style: aboutCardTimeAgoStyle.copyWith( - color: - Theme.of(context).extension()!.grey600, + style: fs10fw600.copyWith( + color: Theme.of(context) + .extension()! + .grey600, ), ) ], @@ -428,7 +441,7 @@ class StudyPageState extends State { locale.translate(message.message!).length > 150 ? '${locale.translate(message.message!).substring(0, 150)}...' : locale.translate(message.message!), - style: aboutCardContentStyle, + style: fs16fw400, textAlign: TextAlign.start, )), ], @@ -489,6 +502,12 @@ class StudyPageState extends State { StudyDeploymentStatusTypes.Running: 'pages.about.status.running.message', StudyDeploymentStatusTypes.Stopped: 'pages.about.status.stopped.message', }; + + static Map messageTypeIcon = { + MessageType.announcement: Icon(Icons.campaign, color: Colors.white), + MessageType.news: Icon(Icons.newspaper, color: Colors.white), + MessageType.article: Icon(Icons.article, color: Colors.white), + }; } extension CopyWithAdditional on DateTime { diff --git a/lib/ui/pages/task_list_page.dart b/lib/ui/pages/task_list_page.dart index 1aec37ac..5abea3c3 100644 --- a/lib/ui/pages/task_list_page.dart +++ b/lib/ui/pages/task_list_page.dart @@ -29,7 +29,7 @@ class _SliverAppBarDelegate extends SliverPersistentHeaderDelegate { padding: const EdgeInsets.symmetric(vertical: 4), decoration: BoxDecoration( borderRadius: BorderRadius.circular(8), - color: Theme.of(context).extension()!.grey200, + color: Theme.of(context).extension()!.grey200, ), child: _tabBar, ); @@ -45,7 +45,7 @@ class TaskListPageState extends State with TickerProviderStateMixin { late TabController _tabController; - bool? showParticipantDataCard = false; + bool showParticipantDataCard = false; @override void initState() { @@ -69,7 +69,7 @@ class TaskListPageState extends State length: 2, child: Scaffold( backgroundColor: - Theme.of(context).extension()!.backgroundGray, + Theme.of(context).extension()!.backgroundGray, body: SafeArea( child: Column( crossAxisAlignment: CrossAxisAlignment.center, @@ -97,9 +97,9 @@ class TaskListPageState extends State alignment: Alignment.centerLeft, child: Text( locale.translate('pages.task_list.title'), - style: aboutStudyCardTitleStyle.copyWith( + style: fs24fw700.copyWith( color: Theme.of(context) - .extension()! + .extension()! .grey900, fontWeight: FontWeight.bold, ), @@ -125,10 +125,10 @@ class TaskListPageState extends State labelPadding: const EdgeInsets.only( top: 4, bottom: 4, left: 4, right: 4), labelColor: Theme.of(context) - .extension()! + .extension()! .grey900, unselectedLabelColor: Theme.of(context) - .extension()! + .extension()! .grey900, dividerColor: Colors.transparent, indicator: ShapeDecoration( @@ -136,7 +136,7 @@ class TaskListPageState extends State borderRadius: BorderRadius.circular(8), ), color: Theme.of(context) - .extension()! + .extension()! .white, ), tabs: [ @@ -159,7 +159,7 @@ class TaskListPageState extends State ), ), ), - if (showParticipantDataCard!) + if (showParticipantDataCard) SliverToBoxAdapter( child: _buildParticipantDataCard(), ), @@ -208,7 +208,7 @@ class TaskListPageState extends State right: Radius.circular(8.0), ), ), - backgroundColor: Theme.of(context).extension()!.grey50!, + backgroundColor: Theme.of(context).extension()!.grey50!, child: Padding( padding: const EdgeInsets.symmetric(vertical: 16), child: IntrinsicHeight( @@ -291,7 +291,7 @@ class TaskListPageState extends State backgroundColor: userTask.expiresIn != null && userTask.expiresIn!.inHours < 24 ? CACHET.TASK_TO_EXPIRE_BACKGROUND - : Theme.of(context).extension()!.grey50!, + : Theme.of(context).extension()!.grey50!, child: Padding( padding: const EdgeInsets.symmetric(vertical: 16), child: IntrinsicHeight( @@ -328,7 +328,7 @@ class TaskListPageState extends State color: userTask.expiresIn != null && userTask.expiresIn!.inHours < 24 ? Theme.of(context) - .extension()! + .extension()! .warningColor : Colors.grey, ), @@ -341,7 +341,7 @@ class TaskListPageState extends State color: userTask.expiresIn != null && userTask.expiresIn!.inHours < 24 ? Theme.of(context) - .extension()! + .extension()! .warningColor : Colors.grey, fontSize: 12.0, @@ -411,7 +411,7 @@ class TaskListPageState extends State userTask.onDone(); ScaffoldMessenger.of(context).showSnackBar(SnackBar( backgroundColor: - Theme.of(context).extension()!.grey700, + Theme.of(context).extension()!.grey700, content: Text(locale.translate('Done!')), shape: RoundedRectangleBorder( borderRadius: BorderRadius.circular(4), @@ -453,7 +453,7 @@ class TaskListPageState extends State return Icon(originalIcon.icon, color: CACHET.TASK_COMPLETED_BLUE); } else { return Icon(originalIcon.icon, - color: Theme.of(context).extension()!.grey600); + color: Theme.of(context).extension()!.grey600); } }, ); @@ -493,7 +493,7 @@ class TaskListPageState extends State return Center( child: GestureDetector( child: StudiesMaterial( - backgroundColor: Theme.of(context).extension()!.grey50!, + backgroundColor: Theme.of(context).extension()!.grey50!, hasBorder: true, shape: RoundedRectangleBorder( borderRadius: BorderRadius.horizontal( @@ -541,7 +541,7 @@ class TaskListPageState extends State color: userTask.expiresIn != null && userTask.expiresIn!.inHours < 24 ? Theme.of(context) - .extension()! + .extension()! .warningColor : Colors.grey, fontSize: 12.0, @@ -600,7 +600,7 @@ class TaskListPageState extends State padding: const EdgeInsets.symmetric(horizontal: 10, vertical: 5), child: Text( locale.translate("pages.task_list.no_tasks"), - style: aboutCardSubtitleStyle, + style: fs16fw600, textAlign: TextAlign.center, )) ], diff --git a/lib/ui/tasks/audio_page.dart b/lib/ui/tasks/audio_page.dart index 74f9da9a..f236941e 100644 --- a/lib/ui/tasks/audio_page.dart +++ b/lib/ui/tasks/audio_page.dart @@ -37,7 +37,7 @@ class AudioPageState extends State { Spacer(), IconButton( color: Theme.of(context) - .extension()! + .extension()! .grey900!, onPressed: () { _showCancelConfirmationDialog(); @@ -66,16 +66,16 @@ class AudioPageState extends State { locale.translate( widget.audioUserTask!.title, ), - style: audioTitleStyle.copyWith( + style: fs22fw700.copyWith( color: Theme.of(context) - .extension()! + .extension()! .primary, ), ), ), StudiesMaterial( backgroundColor: Theme.of(context) - .extension()! + .extension()! .white!, child: Scrollbar( child: SingleChildScrollView( @@ -89,7 +89,7 @@ class AudioPageState extends State { widget.audioUserTask! .instructions, ), - style: audioContentStyle, + style: fs16fw600, ), ), ), @@ -99,7 +99,7 @@ class AudioPageState extends State { CircleAvatar( radius: 30, backgroundColor: Theme.of(context) - .extension()! + .extension()! .primary, child: IconButton( onPressed: () => widget.audioUserTask! @@ -118,7 +118,7 @@ class AudioPageState extends State { child: Text( locale.translate( "pages.audio_task.play"), - style: audioContentStyle, + style: fs16fw600, ), ), ], @@ -135,16 +135,16 @@ class AudioPageState extends State { locale.translate( widget.audioUserTask!.title, ), - style: audioTitleStyle.copyWith( + style: fs22fw700.copyWith( color: Theme.of(context) - .extension()! + .extension()! .primary, ), ), ), StudiesMaterial( backgroundColor: Theme.of(context) - .extension()! + .extension()! .white!, child: Scrollbar( child: SingleChildScrollView( @@ -157,7 +157,7 @@ class AudioPageState extends State { locale.translate(widget .audioUserTask! .instructions), - style: audioContentStyle, + style: fs16fw600, ), ), ), @@ -193,7 +193,7 @@ class AudioPageState extends State { child: Text( locale.translate( "pages.audio_task.recording"), - style: audioTitleStyle, + style: fs22fw700, ), ), ], @@ -209,9 +209,9 @@ class AudioPageState extends State { child: Text( locale.translate( 'pages.audio_task.done'), - style: audioTitleStyle.copyWith( + style: fs22fw700.copyWith( color: Theme.of(context) - .extension()! + .extension()! .primary, ), ), @@ -222,7 +222,7 @@ class AudioPageState extends State { child: Text( locale.translate( 'pages.audio_task.recording_completed'), - style: audioContentStyle), + style: fs16fw600), ), Spacer(), Padding( @@ -245,7 +245,7 @@ class AudioPageState extends State { icon: Icon( Icons.replay, color: Theme.of(context) - .extension()! + .extension()! .grey700, size: 30, ), diff --git a/lib/ui/tasks/audio_task_page.dart b/lib/ui/tasks/audio_task_page.dart index aa589ef8..46518caa 100644 --- a/lib/ui/tasks/audio_task_page.dart +++ b/lib/ui/tasks/audio_task_page.dart @@ -33,8 +33,9 @@ class AudioTaskPageState extends State { ), Spacer(), IconButton( - color: - Theme.of(context).extension()!.grey900!, + color: Theme.of(context) + .extension()! + .grey900!, onPressed: () { _showCancelConfirmationDialog(); }, @@ -55,7 +56,7 @@ class AudioTaskPageState extends State { Padding( padding: const EdgeInsets.symmetric(vertical: 12), child: Text(locale.translate(widget.audioUserTask!.title), - style: audioTitleStyle), + style: fs22fw700), ), Padding( padding: const EdgeInsets.symmetric( @@ -63,7 +64,7 @@ class AudioTaskPageState extends State { child: Text( '${locale.translate(widget.audioUserTask!.description)}\n\n' '${locale.translate('pages.audio_task.play')}', - style: audioContentStyle, + style: fs16fw600, ), ), Padding( @@ -89,7 +90,7 @@ class AudioTaskPageState extends State { ), style: ElevatedButton.styleFrom( backgroundColor: Theme.of(context) - .extension()! + .extension()! .primary, padding: const EdgeInsets.symmetric( horizontal: 30, diff --git a/lib/ui/tasks/camera_page.dart b/lib/ui/tasks/camera_page.dart index 07ecc94a..eaef6e53 100644 --- a/lib/ui/tasks/camera_page.dart +++ b/lib/ui/tasks/camera_page.dart @@ -101,7 +101,7 @@ class CameraPageState extends State { } } - void stopRecording(details) async { + void stopRecording(dynamic details) async { try { var video = await _cameraController.stopVideoRecording(); diff --git a/lib/ui/tasks/camera_task_page.dart b/lib/ui/tasks/camera_task_page.dart index 251d36e9..6d827520 100644 --- a/lib/ui/tasks/camera_task_page.dart +++ b/lib/ui/tasks/camera_task_page.dart @@ -45,7 +45,7 @@ class CameraTaskPageState extends State { Spacer(), IconButton( color: Theme.of(context) - .extension()! + .extension()! .grey900!, onPressed: () { _showCancelConfirmationDialog(); @@ -74,7 +74,7 @@ class CameraTaskPageState extends State { child: Text( locale.translate( widget.mediaUserTask.title), - style: audioTitleStyle, + style: fs22fw700, ), ), Padding( @@ -83,7 +83,7 @@ class CameraTaskPageState extends State { child: Text( locale.translate( widget.mediaUserTask.description), - style: audioContentStyle, + style: fs16fw600, ), ), Padding( @@ -112,7 +112,7 @@ class CameraTaskPageState extends State { ), style: ElevatedButton.styleFrom( backgroundColor: Theme.of(context) - .extension()! + .extension()! .primary, padding: const EdgeInsets.symmetric( horizontal: 30, diff --git a/lib/ui/tasks/display_picture_page.dart b/lib/ui/tasks/display_picture_page.dart index bd7df449..29cff952 100644 --- a/lib/ui/tasks/display_picture_page.dart +++ b/lib/ui/tasks/display_picture_page.dart @@ -60,7 +60,7 @@ class DisplayPicturePageState extends State { ), Spacer(), IconButton( - color: Theme.of(context).extension()!.grey900!, + color: Theme.of(context).extension()!.grey900!, onPressed: () { _showCancelConfirmationDialog(); }, @@ -97,14 +97,14 @@ class DisplayPicturePageState extends State { Padding( padding: const EdgeInsets.symmetric(horizontal: 10), child: Text(locale.translate('pages.audio_task.done'), - style: audioTitleStyle), + style: fs22fw700), ), const SizedBox(height: 40), Padding( padding: const EdgeInsets.symmetric(horizontal: 10), child: Text( locale.translate('pages.audio_task.recording_completed'), - style: audioContentStyle, + style: fs16fw600, ), ), const SizedBox(height: 20), diff --git a/lib/ui/tasks/participant_data_page.dart b/lib/ui/tasks/participant_data_page.dart index c3397326..23c1320f 100644 --- a/lib/ui/tasks/participant_data_page.dart +++ b/lib/ui/tasks/participant_data_page.dart @@ -266,7 +266,8 @@ class ParticipantDataPageState extends State { Widget build(BuildContext context) { RPLocalizations locale = RPLocalizations.of(context)!; return Scaffold( - backgroundColor: Theme.of(context).extension()!.backgroundGray!, + backgroundColor: + Theme.of(context).extension()!.backgroundGray!, body: SafeArea( child: Container( padding: const EdgeInsets.all(16.0), @@ -283,7 +284,7 @@ class ParticipantDataPageState extends State { ), Spacer(), IconButton( - color: Theme.of(context).extension()!.grey900!, + color: Theme.of(context).extension()!.grey900!, onPressed: () { _showCancelConfirmationDialog(); }, @@ -357,7 +358,7 @@ class ParticipantDataPageState extends State { Flexible( child: Text( stepTitleMap[currentStep] ?? '', - style: healthServiceConnectMessageStyle.copyWith( + style: fs22fw700.copyWith( color: Theme.of(context).primaryColor, ), textAlign: TextAlign.center, @@ -548,7 +549,8 @@ class ParticipantDataPageState extends State { child: Container( decoration: BoxDecoration( border: Border.all( - color: Theme.of(context).extension()!.grey600!, + color: + Theme.of(context).extension()!.grey600!, width: 1.0, ), borderRadius: BorderRadius.circular(16.0), @@ -564,8 +566,9 @@ class ParticipantDataPageState extends State { showCountryOnly: true, showOnlyCountryWhenClosed: true, alignLeft: false, - textStyle: audioContentStyle.copyWith( - color: Theme.of(context).extension()!.grey900!, + textStyle: fs16fw600.copyWith( + color: + Theme.of(context).extension()!.grey900!, ), ), ), @@ -681,7 +684,7 @@ class ParticipantDataPageState extends State { _nextEnabled, ElevatedButton.styleFrom( backgroundColor: - Theme.of(context).extension()!.primary, + Theme.of(context).extension()!.primary, padding: const EdgeInsets.symmetric(horizontal: 30, vertical: 12), ), @@ -702,7 +705,7 @@ class ParticipantDataPageState extends State { currentStep == ParticipantStep.presentTypes ? true : _nextEnabled, ElevatedButton.styleFrom( backgroundColor: - Theme.of(context).extension()!.primary, + Theme.of(context).extension()!.primary, padding: const EdgeInsets.symmetric(horizontal: 30, vertical: 12), ), @@ -774,7 +777,6 @@ class ParticipantDataPageState extends State { participantData, bloc.study!.participantRoleName, ); - LocalSettings().hasSeenConnectionInstructions = true; } Future _showCancelConfirmationDialog() { diff --git a/lib/ui/widgets/charts_legend.dart b/lib/ui/widgets/charts_legend.dart index 1c17583f..12f0a434 100644 --- a/lib/ui/widgets/charts_legend.dart +++ b/lib/ui/widgets/charts_legend.dart @@ -26,7 +26,7 @@ class ChartsLegend extends StatelessWidget { child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ - Text(title.toUpperCase(), style: dataCardTitleStyle), + Text(title.toUpperCase(), style: fs16fw400ls1), Padding( padding: const EdgeInsets.symmetric(vertical: 8.0), child: Row( @@ -39,7 +39,7 @@ class ChartsLegend extends StatelessWidget { children: [ Icon(Icons.circle, color: colors[entry.key], size: 12.0), - Text(' ${entry.value} ', style: legendStyle), + Text(' ${entry.value} ', style: fs12fw400), ], ), ) diff --git a/lib/ui/widgets/details_banner.dart b/lib/ui/widgets/details_banner.dart index d0f4c06b..cc070eb2 100644 --- a/lib/ui/widgets/details_banner.dart +++ b/lib/ui/widgets/details_banner.dart @@ -29,7 +29,7 @@ class DetailsBanner extends StatelessWidget { children: [ Text( locale.translate(title), - style: studyNameStyle.copyWith( + style: fs30fw800.copyWith( fontSize: 30, color: Theme.of(context).primaryColor), ), ], diff --git a/lib/ui/widgets/dialog_title.dart b/lib/ui/widgets/dialog_title.dart index 884f2155..51ed72ac 100644 --- a/lib/ui/widgets/dialog_title.dart +++ b/lib/ui/widgets/dialog_title.dart @@ -48,7 +48,7 @@ class DialogTitle extends StatelessWidget { (titleEnd != null ? ' ${locale.translate(titleEnd!)}' : ""), - style: sectionTitleStyle.copyWith( + style: fs18fw700.copyWith( color: Theme.of(context).primaryColor, ), textAlign: TextAlign.center, diff --git a/lib/ui/widgets/horizontal_bar.dart b/lib/ui/widgets/horizontal_bar.dart index 89e696b4..bc3b3aa6 100644 --- a/lib/ui/widgets/horizontal_bar.dart +++ b/lib/ui/widgets/horizontal_bar.dart @@ -158,7 +158,7 @@ class MyAssetsBar extends StatelessWidget { children: [ Icon(Icons.circle, color: entry.value.color, size: 12.0), Text(' ${entry.value.name!} ${entry.value.size}', - style: legendStyle, textAlign: TextAlign.right), + style: fs12fw400, textAlign: TextAlign.right), ], )), ) @@ -187,10 +187,10 @@ class MyAssetsBar extends StatelessWidget { children: [ Icon(Icons.circle, color: entry.value.color, size: 12.0), Text(' ${entry.value.size}', - style: legendStyle, textAlign: TextAlign.left), + style: fs12fw400, textAlign: TextAlign.left), Expanded( child: Text(' ${entry.value.name!}', - style: legendStyle, + style: fs12fw400, textAlign: TextAlign.left, overflow: TextOverflow.ellipsis)), ], diff --git a/lib/ui/widgets/location_permission_page.dart b/lib/ui/widgets/location_permission_page.dart index 5732b9f8..c4fce61a 100644 --- a/lib/ui/widgets/location_permission_page.dart +++ b/lib/ui/widgets/location_permission_page.dart @@ -5,7 +5,8 @@ class LocationPermissionPage { RPLocalizations locale = RPLocalizations.of(context)!; return Scaffold( - backgroundColor: Theme.of(context).extension()!.backgroundGray, + backgroundColor: + Theme.of(context).extension()!.backgroundGray, body: Padding( padding: const EdgeInsets.symmetric(vertical: 16.0), child: SafeArea( @@ -27,7 +28,7 @@ class LocationPermissionPage { padding: const EdgeInsets.only(top: 16.0), child: StudiesMaterial( backgroundColor: - Theme.of(context).extension()!.white!, + Theme.of(context).extension()!.white!, shape: RoundedRectangleBorder( borderRadius: BorderRadius.circular(12.0), ), @@ -55,7 +56,7 @@ class LocationPermissionPage { fontWeight: FontWeight.bold, fontSize: 22.0, color: Theme.of(context) - .extension()! + .extension()! .primary, ), ), @@ -67,14 +68,14 @@ class LocationPermissionPage { child: Icon( Icons.location_on, color: Theme.of(context) - .extension()! + .extension()! .primary, size: 48, ), ), Text( locale.translate(message), - style: aboutCardContentStyle.copyWith( + style: fs16fw400.copyWith( fontWeight: FontWeight.bold, ), textAlign: TextAlign.justify, diff --git a/lib/ui/widgets/location_usage_dialog.dart b/lib/ui/widgets/location_usage_dialog.dart index 35642004..33f5599a 100644 --- a/lib/ui/widgets/location_usage_dialog.dart +++ b/lib/ui/widgets/location_usage_dialog.dart @@ -16,7 +16,7 @@ class LocationUsageDialog { height: MediaQuery.of(context).size.height * 0.15, ), Text(locale.translate("dialog.location.permission"), - style: aboutCardTitleStyle), + style: fs20fw700), ], ), contentPadding: const EdgeInsets.all(15), @@ -28,7 +28,7 @@ class LocationUsageDialog { children: [ Text( locale.translate(message), - style: aboutCardContentStyle, + style: fs16fw400, textAlign: TextAlign.justify, ), ], diff --git a/lib/view_models/tasklist_page_model.dart b/lib/view_models/tasklist_page_model.dart index 1a03b570..258d5727 100644 --- a/lib/view_models/tasklist_page_model.dart +++ b/lib/view_models/tasklist_page_model.dart @@ -34,8 +34,14 @@ class TaskListPageViewModel extends ViewModel { Stream get userTaskEvents => AppTaskController().userTaskEvents; /// The number of days the user has been part of this study. - int get daysInStudy => (bloc.studyStartTimestamp != null) - ? DateTime.now().difference(bloc.studyStartTimestamp!).inDays + 1 + /// + /// This is calculated from the study deployment status creation date from the + /// [StudyDeploymentStatus]. + /// Returns 0 if the study deployment status is not available. + int get daysInStudy => (Sensing().studyDeploymentStatus != null) + ? DateTime.now() + .difference(Sensing().studyDeploymentStatus!.createdOn) + .inDays : 0; /// The number of tasks completed so far. diff --git a/lib/view_models/view_model.dart b/lib/view_models/view_model.dart index 447535f5..9585bb84 100644 --- a/lib/view_models/view_model.dart +++ b/lib/view_models/view_model.dart @@ -15,11 +15,12 @@ abstract class ViewModel extends ChangeNotifier { _controller = ctrl; } - /// Called when this view model is to clear its state (e.g., cached data). + /// Clear this view model, i.e. delete all data incl. cached data. @mustCallSuper void clear() {} - /// Called when this view model is disposed and no longer used. + /// Called when this view model is disposed. Typically on app exit, incl. when + /// closed by the OS. @override @mustCallSuper void dispose() { @@ -92,7 +93,7 @@ abstract class SerializableViewModel extends ViewModel { _filename = null; _persistenceTimer?.cancel(); _persistenceTimer = null; - save(); + delete(); } @override @@ -127,7 +128,7 @@ abstract class SerializableViewModel extends ViewModel { return success; } - /// Permanently delete the [model]. + /// Permanently delete the cached [model]. /// Returns true if successful, false otherwise. bool delete() { bool success = true; diff --git a/pubspec.lock b/pubspec.lock index 4598dacb..fcaa4258 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -149,10 +149,10 @@ packages: dependency: transitive description: name: build_daemon - sha256: "8e928697a82be082206edb0b9c99c5a4ad6bc31c9e9b8b2f291ae65cd4a25daa" + sha256: bf05f6e12cfea92d3c09308d7bcdab1906cd8a179b023269eed00c071004b957 url: "https://pub.dev" source: hosted - version: "4.0.4" + version: "4.1.1" build_resolvers: dependency: transitive description: @@ -197,34 +197,34 @@ packages: dependency: "direct main" description: name: camera - sha256: d6ec2cbdbe2fa8f5e0d07d8c06368fe4effa985a4a5ddade9cc58a8cd849557d + sha256: eefad89f262a873f38d21e5eec853461737ea074d7c9ede39f3ceb135d201cab url: "https://pub.dev" source: hosted - version: "0.11.2" + version: "0.11.3" camera_android_camerax: dependency: "direct main" description: name: camera_android_camerax - sha256: d04649fab70a5d586a7b26d5ac26f700656b6aab26a16bfd5a29302589b7a973 + sha256: d5256612833f9169c1698599a87370490622a188c5a7fb601169bb7b2f41f22b url: "https://pub.dev" source: hosted - version: "0.6.23" + version: "0.6.24+1" camera_avfoundation: dependency: transitive description: name: camera_avfoundation - sha256: "397f44f8a63c8c0a474668d500f9739d4f2bc45ac2b21801194b7d29260f03ee" + sha256: "34bcd5db30e52414f1f0783c5e3f566909fab14141a21b3b576c78bd35382bf6" url: "https://pub.dev" source: hosted - version: "0.9.22+1" + version: "0.9.22+4" camera_platform_interface: dependency: transitive description: name: camera_platform_interface - sha256: ea1ef6ba79cdbed93df2d3eeef11542a90dec24dbcd9cde574926b86d7a09a10 + sha256: "98cfc9357e04bad617671b4c1f78a597f25f08003089dd94050709ae54effc63" url: "https://pub.dev" source: hosted - version: "2.11.0" + version: "2.12.0" camera_web: dependency: transitive description: @@ -293,10 +293,10 @@ packages: dependency: "direct main" description: name: carp_movesense_package - sha256: ecf454337a4ef6ce2ce71516bb7544fb659c2fb64562b6f4ce3e303d1cc07f0c + sha256: e17094a42fae084d26c7759459493389016d9efc9f1555c7a5044eec1469d87d url: "https://pub.dev" source: hosted - version: "1.7.5" + version: "1.7.6" carp_polar_package: dependency: "direct main" description: @@ -321,6 +321,14 @@ packages: url: "https://pub.dev" source: hosted version: "1.9.1" + carp_themes_package: + dependency: "direct main" + description: + name: carp_themes_package + sha256: "48e747c82392db406531289828b4143275b28736354fb9e7bc62cfe1a189d675" + url: "https://pub.dev" + source: hosted + version: "0.0.3" carp_webservices: dependency: "direct main" description: @@ -429,10 +437,10 @@ packages: dependency: "direct main" description: name: country_code_picker - sha256: c9e8c012472c8060f5a705dabef223677801cd9eb49e684aecee705edeceacc8 + sha256: f0411f4833b6f98e8b7215f4fa3813bcc88e50f13925f70a170dbd36e3e447f5 url: "https://pub.dev" source: hosted - version: "3.4.0" + version: "3.4.1" coverage: dependency: transitive description: @@ -453,18 +461,18 @@ packages: dependency: transitive description: name: cross_file - sha256: "7caf6a750a0c04effbb52a676dce9a4a592e10ad35c34d6d2d0e4811160d5670" + sha256: "942a4791cd385a68ccb3b32c71c427aba508a1bb949b86dff2adbe4049f16239" url: "https://pub.dev" source: hosted - version: "0.3.4+2" + version: "0.3.5" crypto: dependency: transitive description: name: crypto - sha256: "1e445881f28f22d6140f181e07737b22f1e099a5e1ff94b0af2f9e4a463f4855" + sha256: c8ea0233063ba03258fbcf2ca4d6dadfefe14f02fab57702265467a19f27fadf url: "https://pub.dev" source: hosted - version: "3.0.6" + version: "3.0.7" crypto_keys_plus: dependency: transitive description: @@ -565,10 +573,10 @@ packages: dependency: transitive description: name: exception_templates - sha256: "517f7c770da690073663f867ee2057ae2f4ffb28edae9da9faa624aa29ac76eb" + sha256: "57adef649aa2a99a5b324a921355ee9214472a007ca257cbec2f3abae005c93e" url: "https://pub.dev" source: hosted - version: "0.3.1" + version: "0.3.2" expandable: dependency: "direct main" description: @@ -706,10 +714,10 @@ packages: dependency: transitive description: name: flutter_local_notifications - sha256: "7ed76be64e8a7d01dfdf250b8434618e2a028c9dfa2a3c41dc9b531d4b3fc8a5" + sha256: "19ffb0a8bb7407875555e5e98d7343a633bb73707bae6c6a5f37c90014077875" url: "https://pub.dev" source: hosted - version: "19.4.2" + version: "19.5.0" flutter_local_notifications_linux: dependency: transitive description: @@ -743,10 +751,10 @@ packages: dependency: "direct main" description: name: flutter_plugin_android_lifecycle - sha256: b0694b7fb1689b0e6cc193b3f1fcac6423c4f93c74fb20b806c6b6f196db0c31 + sha256: "306f0596590e077338312f38837f595c04f28d6cdeeac392d3d74df2f0003687" url: "https://pub.dev" source: hosted - version: "2.0.30" + version: "2.0.32" flutter_secure_storage: dependency: transitive description: @@ -823,10 +831,10 @@ packages: dependency: "direct main" description: name: flutter_svg - sha256: b9c2ad5872518a27507ab432d1fb97e8813b05f0fc693f9d40fad06d073e0678 + sha256: "055de8921be7b8e8b98a233c7a5ef84b3a6fcc32f46f1ebf5b9bb3576d108355" url: "https://pub.dev" source: hosted - version: "2.2.1" + version: "2.2.2" flutter_test: dependency: "direct dev" description: flutter @@ -1057,10 +1065,10 @@ packages: dependency: transitive description: name: lazy_memo - sha256: dcb30b4184a6d767e1d779d74ce784d752d38313b8fb4bad6b659ae7af4bb34d + sha256: f3f4afe9c4ccf0f29082213c5319a3711041446fc41cd325a9bf91724d4ea9c8 url: "https://pub.dev" source: hosted - version: "0.2.3" + version: "0.2.5" leak_tracker: dependency: transitive description: @@ -1105,10 +1113,10 @@ packages: dependency: transitive description: name: list_operators - sha256: "795b1a2b3fe689008907e92ddab0e965434dd1f02e7321cd65858d553c0740bf" + sha256: "480e6726f44c9fc5dd0dbcdec192bfcaad24d4edef366abea572fbbaf6f96575" url: "https://pub.dev" source: hosted - version: "0.5.0" + version: "0.5.1" location: dependency: transitive description: @@ -1433,18 +1441,18 @@ packages: dependency: transitive description: name: path_provider_android - sha256: "993381400e94d18469750e5b9dcb8206f15bc09f9da86b9e44a9b0092a0066db" + sha256: e122c5ea805bb6773bb12ce667611265980940145be920cd09a4b0ec0285cb16 url: "https://pub.dev" source: hosted - version: "2.2.18" + version: "2.2.20" path_provider_foundation: dependency: transitive description: name: path_provider_foundation - sha256: "16eef174aacb07e09c351502740fa6254c165757638eba1e9116b0a781201bbd" + sha256: efaec349ddfc181528345c56f8eda9d6cccd71c177511b132c6a0ddaefaa2738 url: "https://pub.dev" source: hosted - version: "2.4.2" + version: "2.4.3" path_provider_linux: dependency: transitive description: @@ -1609,10 +1617,10 @@ packages: dependency: "direct main" description: name: qr_code_scanner_plus - sha256: a0f1ac8e13299b3db2646635f252fe2ec67222b848b24ed34d11052faf080bfa + sha256: b764e5004251c58d9dee0c295e6006e05bd8d249e78ac3383abdb5afe0a996cd url: "https://pub.dev" source: hosted - version: "2.0.12" + version: "2.0.14" recase: dependency: transitive description: @@ -1657,10 +1665,10 @@ packages: dependency: transitive description: name: sample_statistics - sha256: "115b076b61bd680975d620c02b47a3b56fa779d31eaac5d2b8896279d45f25a8" + sha256: ba47e4a81f57fc1968472daf392c22ffc5142c42e93a2e9b899e569c3843168a url: "https://pub.dev" source: hosted - version: "0.2.0" + version: "0.2.2" screen_state: dependency: transitive description: @@ -1697,18 +1705,18 @@ packages: dependency: transitive description: name: shared_preferences_android - sha256: "0b0f98d535319cb5cdd4f65783c2a54ee6d417a2f093dbb18be3e36e4c3d181f" + sha256: "34266009473bf71d748912da4bf62d439185226c03e01e2d9687bc65bbfcb713" url: "https://pub.dev" source: hosted - version: "2.4.14" + version: "2.4.15" shared_preferences_foundation: dependency: transitive description: name: shared_preferences_foundation - sha256: "6a52cfcdaeac77cad8c97b539ff688ccfc458c007b4db12be584fbe5c0e49e03" + sha256: "1c33a907142607c40a7542768ec9badfd16293bac51da3a4482623d15845f88b" url: "https://pub.dev" source: hosted - version: "2.5.4" + version: "2.5.5" shared_preferences_linux: dependency: transitive description: @@ -1789,14 +1797,6 @@ packages: url: "https://pub.dev" source: hosted version: "0.3.0" - simulated_annealing: - dependency: transitive - description: - name: simulated_annealing - sha256: "5fac4326f446780a01fe0703a6be2d98dfca4a93d71e49c782f5574da22755c9" - url: "https://pub.dev" - source: hosted - version: "0.4.0" sky_engine: dependency: transitive description: flutter @@ -1842,14 +1842,6 @@ packages: url: "https://pub.dev" source: hosted version: "1.10.1" - sprintf: - dependency: transitive - description: - name: sprintf - sha256: "1fc9ffe69d4df602376b52949af107d8f5703b77cda567c4d7d86a0693120f23" - url: "https://pub.dev" - source: hosted - version: "7.0.0" sqflite: dependency: transitive description: @@ -2054,18 +2046,18 @@ packages: dependency: transitive description: name: url_launcher_android - sha256: c0fb544b9ac7efa10254efaf00a951615c362d1ea1877472f8f6c0fa00fcf15b + sha256: "5c8b6c2d89a78f5a1cca70a73d9d5f86c701b36b42f9c9dac7bad592113c28e9" url: "https://pub.dev" source: hosted - version: "6.3.23" + version: "6.3.24" url_launcher_ios: dependency: transitive description: name: url_launcher_ios - sha256: d80b3f567a617cb923546034cc94bfe44eb15f989fe670b37f26abdb9d939cb7 + sha256: "6b63f1441e4f653ae799166a72b50b1767321ecc263a57aadf825a7a2a5477d9" url: "https://pub.dev" source: hosted - version: "6.3.4" + version: "6.3.5" url_launcher_linux: dependency: transitive description: @@ -2078,10 +2070,10 @@ packages: dependency: transitive description: name: url_launcher_macos - sha256: c043a77d6600ac9c38300567f33ef12b0ef4f4783a2c1f00231d2b1941fea13f + sha256: "8262208506252a3ed4ff5c0dc1e973d2c0e0ef337d0a074d35634da5d44397c9" url: "https://pub.dev" source: hosted - version: "3.2.3" + version: "3.2.4" url_launcher_platform_interface: dependency: transitive description: @@ -2110,10 +2102,10 @@ packages: dependency: transitive description: name: uuid - sha256: a5be9ef6618a7ac1e964353ef476418026db906c4facdedaa299b7a2e71690ff + sha256: a11b666489b1954e01d992f3d601b1804a33937b5a8fe677bd26b8a9f96f96e8 url: "https://pub.dev" source: hosted - version: "4.5.1" + version: "4.5.2" vector_graphics: dependency: transitive description: @@ -2158,26 +2150,26 @@ packages: dependency: transitive description: name: video_player_android - sha256: "6cfe0b1e102522eda1e139b82bf00602181c5844fd2885340f595fb213d74842" + sha256: cf768d02924b91e333e2bc1ff928528f57d686445874f383bafab12d0bdfc340 url: "https://pub.dev" source: hosted - version: "2.8.14" + version: "2.8.17" video_player_avfoundation: dependency: transitive description: name: video_player_avfoundation - sha256: f9a780aac57802b2892f93787e5ea53b5f43cc57dc107bee9436458365be71cd + sha256: "19ed1162a7a5520e7d7791e0b7b73ba03161b6a69428b82e4689e435b325432d" url: "https://pub.dev" source: hosted - version: "2.8.4" + version: "2.8.5" video_player_platform_interface: dependency: transitive description: name: video_player_platform_interface - sha256: cf2a1d29a284db648fd66cbd18aacc157f9862d77d2cc790f6f9678a46c1db5a + sha256: "57c5d73173f76d801129d0531c2774052c5a7c11ccb962f1830630decd9f24ec" url: "https://pub.dev" source: hosted - version: "6.4.0" + version: "6.6.0" video_player_web: dependency: transitive description: diff --git a/pubspec.yaml b/pubspec.yaml index 28c79c5e..1d0fd20f 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -1,7 +1,7 @@ name: carp_study_app description: The generic CARP study app. publish_to: "none" -version: 4.1.1+87 +version: 4.2.0+89 environment: sdk: ">=3.2.0 <4.0.0" @@ -21,6 +21,7 @@ dependencies: carp_polar_package: ^1.6.1 carp_health_package: ^3.2.0 carp_movesense_package: ^1.7.2 + carp_themes_package: ^0.0.1 carp_webservices: ^3.8.0 carp_backend: ^1.9.2 @@ -69,7 +70,7 @@ dependency_overrides: # carp_core: # path: ../carp/carp.sensing-flutter/carp_core/ # carp_mobile_sensing: - # path: ../carp/carp.sensing-flutter/carp_mobile_sensing/ + # path: ../carp.sensing-flutter/carp_mobile_sensing/ # carp_context_package: # path: ../carp/carp.sensing-flutter/packages/carp_context_package/ # carp_connectivity_package: