diff --git a/devtools_options.yaml b/devtools_options.yaml new file mode 100644 index 00000000..7e7e7f67 --- /dev/null +++ b/devtools_options.yaml @@ -0,0 +1 @@ +extensions: diff --git a/ios/Podfile.lock b/ios/Podfile.lock index 9ec8e7cd..86a67f31 100644 --- a/ios/Podfile.lock +++ b/ios/Podfile.lock @@ -68,8 +68,8 @@ PODS: - Flutter - polar (0.0.1): - Flutter - - PolarBleSdk (~> 5.4.0) - - PolarBleSdk (5.4.0): + - PolarBleSdk (~> 5.5.0) + - PolarBleSdk (5.5.0): - RxSwift (~> 6.5.0) - SwiftProtobuf (~> 1.0) - ReachabilitySwift (5.0.0) @@ -84,7 +84,7 @@ PODS: - sqflite (0.0.3): - Flutter - FMDB (>= 2.7.5) - - SwiftProtobuf (1.25.1) + - SwiftProtobuf (1.25.2) - url_launcher_ios (0.0.1): - Flutter - video_player_avfoundation (0.0.1): @@ -213,7 +213,7 @@ SPEC CHECKSUMS: audiofileplayer: 4aaff759a721ec3a850a682e0d9ec554e5f9e86f battery_plus: 091633b7f01cb33dfc4aeedb450816f4d33818fa camera_avfoundation: 3125e8cd1a4387f6f31c6c63abb8a55892a9eeeb - connectivity_plus: 07c49e96d7fc92bc9920617b83238c4d178b446a + connectivity_plus: bf0076dd84a130856aa636df1c71ccaff908fa1d device_info_plus: c6fb39579d0f423935b0c9ce7ee2f44b71b9fce6 ESense: cbe103ad16c435424f2fd6f8b274f2468af84173 esense_flutter: 8bfadfdefe7b51d6f78366e43b2b64ec9b6144b6 @@ -236,17 +236,17 @@ SPEC CHECKSUMS: path_provider_foundation: 29f094ae23ebbca9d3d0cec13889cd9060c0e943 pedometer: 381969883680ade42559782cc41a3bbd453d8234 permission_handler_apple: e76247795d700c14ea09e3a2d8855d41ee80a2e6 - polar: 3df98f4edaae7ff57d39fa6af2bd01b5b857e79d - PolarBleSdk: 980933f58cb2856c3627f40a54c91b9351a07736 + polar: 8efdf64c1b4e0034e8fa3b1d12b64e5b27a877f1 + PolarBleSdk: 2551160f3dcba0207723fc466a275e2d3aeda01f ReachabilitySwift: 985039c6f7b23a1da463388634119492ff86c825 RxSwift: 5710a9e6b17f3c3d6e40d6e559b9fa1e813b2ef8 screen_state: a7ae251997e97f3f001839df09b57313b0ddef18 sensors_plus: 4ee32bc7d61a055f27f88d3215ad6b6fb96a2b8e shared_preferences_foundation: 5b919d13b803cadd15ed2dc053125c68730e5126 sqflite: 31f7eba61e3074736dff8807a9b41581e4f7f15a - SwiftProtobuf: 69f02cd54fb03201c5e6bf8b76f687c5ef7541a3 - url_launcher_ios: 68d46cc9766d0c41dbdc884310529557e3cd7a86 - video_player_avfoundation: 8563f13d8fc8b2c29dc2d09e60b660e4e8128837 + SwiftProtobuf: 407a385e97fd206c4fbe880cc84123989167e0d1 + url_launcher_ios: bf5ce03e0e2088bad9cc378ea97fa0ed5b49673b + video_player_avfoundation: e9e6f9cae7d7a6d9b43519b0aab382bca60fcfd1 PODFILE CHECKSUM: cf73571b196c8b5799c2f2111e13846fa4ef168b diff --git a/lib/blocs/app_bloc.dart b/lib/blocs/app_bloc.dart index 123eb742..5c458487 100644 --- a/lib/blocs/app_bloc.dart +++ b/lib/blocs/app_bloc.dart @@ -24,9 +24,7 @@ class StudyAppBLoC { get stateStream => _stateStream; - List _invitations = []; - set invitations(value) => _invitations = value; - get invitations => _invitations; + List invitations = []; List _messages = []; final StreamController _messageStreamController = @@ -219,8 +217,8 @@ class StudyAppBLoC { /// * shown to the user /// * accepted by the user /// * successfully uploaded to CARP - set setHasInformedConsentBeenAccepted(bool accepted) => - LocalSettings().setHasInformedConsentBeenAccepted = accepted; + set hasInformedConsentBeenAccepted(bool accepted) => + LocalSettings().hasInformedConsentBeenAccepted = accepted; /// Refresh the list of messages (news, announcements, articles) to be shown in /// the Study Page of the app. @@ -336,7 +334,7 @@ class StudyAppBLoC { /// available. Future leaveStudy() async { _state = StudyAppState.initialized; - setHasInformedConsentBeenAccepted = false; + hasInformedConsentBeenAccepted = false; await LocalSettings().eraseStudyIds(); await Sensing().removeStudy(); } diff --git a/lib/carp_study_app.dart b/lib/carp_study_app.dart index 0404fa9b..c1b49d21 100644 --- a/lib/carp_study_app.dart +++ b/lib/carp_study_app.dart @@ -2,6 +2,7 @@ part of carp_study_app; final _rootNavigatorKey = GlobalKey(); final _shellNavigatorKey = GlobalKey(); +const String firstRoute = '/about'; class CarpStudyApp extends StatefulWidget { const CarpStudyApp({super.key}); @@ -38,7 +39,9 @@ class CarpStudyAppState extends State { parentNavigatorKey: _shellNavigatorKey, redirect: (context, state) => !CarpService().authenticated ? '/login' - : (bloc.hasInformedConsentBeenAccepted ? '/tasks' : '/consent'), + : (bloc.hasInformedConsentBeenAccepted + ? firstRoute + : '/consent'), ), GoRoute( path: '/tasks', @@ -105,7 +108,7 @@ class CarpStudyAppState extends State { path: '/consent', parentNavigatorKey: _rootNavigatorKey, redirect: (context, state) => bloc.hasInformedConsentBeenAccepted - ? '/tasks' + ? firstRoute : (bloc.studyId == null ? '/invitations' : null), builder: (context, state) => InformedConsentPage( bloc.data.informedConsentViewModel, diff --git a/lib/data/carp_backend.dart b/lib/data/carp_backend.dart index 16463e0a..0feea2f2 100644 --- a/lib/data/carp_backend.dart +++ b/lib/data/carp_backend.dart @@ -29,9 +29,6 @@ class CarpBackend { /// Has the user been authenticated? bool get isAuthenticated => CarpService().authenticated; - /// The authenticated user - CarpUser? get user => CarpService().currentUser; - /// The URI of the CANS server - depending on deployment mode. Uri get uri => Uri( scheme: 'https', @@ -44,11 +41,11 @@ class CarpBackend { ], ); - OAuthToken? get oauthToken => LocalSettings().oauthToken; - set oauthToken(OAuthToken? token) => LocalSettings().oauthToken = token; + CarpUser? get user => LocalSettings().user; + set user(CarpUser? user) => LocalSettings().user = user; - String? get username => LocalSettings().username; - set username(String? username) => LocalSettings().username = username; + String? get username => user?.username; + OAuthToken? get oauthToken => user?.token; String? get studyId => bloc.studyId; set studyId(String? id) { @@ -73,7 +70,7 @@ class CarpBackend { name: "CAWS @ DTU", uri: uri.replace(pathSegments: [uris[bloc.deploymentMode]!]), authURL: uri, - clientId: 'carp-webservices-dart', + clientId: 'studies-app', redirectURI: Uri.parse('carp-studies-auth://auth'), discoveryURL: uri.replace(pathSegments: [ ...uri.pathSegments, @@ -85,20 +82,39 @@ class CarpBackend { ); CarpService().configure(app!); + if (user != null) { + CarpService().currentUser = user; + if (oauthToken!.hasExpired) { + try { + await refresh(); + } catch (error) { + CarpService().currentUser = null; + warning('Failed to refresh access token - $error'); + } + } + } + + CarpParticipationService().configureFrom(CarpService()); info('$runtimeType initialized - app: $app'); } Future authenticate() async { - var response = await CarpService().authenticate(); + bloc.stateStream.sink.add(StudiesAppState.authenticating); + user = await CarpService().authenticate(); - username = response.username; - oauthToken = response.token; bloc.stateStream.sink.add(StudiesAppState.accessTokenRetrieved); - CarpParticipationService().configureFrom(CarpService()); + return user as CarpUser; + } + + Future refresh() async { + bloc.stateStream.sink.add(StudiesAppState.authenticating); + user = await CarpService().refresh(); + + bloc.stateStream.sink.add(StudiesAppState.accessTokenRetrieved); - return response; + return user as CarpUser; } Future uploadInformedConsent( @@ -113,9 +129,9 @@ class CarpBackend { document = await CarpService().createConsentDocument(informedConsent); info( 'Informed consent document uploaded successfully - id: ${document.id}'); - bloc.setHasInformedConsentBeenAccepted = true; + bloc.hasInformedConsentBeenAccepted = true; } on Exception { - bloc.setHasInformedConsentBeenAccepted = false; + bloc.hasInformedConsentBeenAccepted = false; warning('Informed consent upload failed for username: $username'); } diff --git a/lib/data/local_settings.dart b/lib/data/local_settings.dart index 04e9d0ef..79a6d132 100644 --- a/lib/data/local_settings.dart +++ b/lib/data/local_settings.dart @@ -7,63 +7,33 @@ class LocalSettings { static const String studyIdKey = 'study_id'; static const String studyDeploymentIdKey = 'study_deployment_id'; static const String deviceRolenameKey = 'role_name'; - static const String oauthTokenKey = 'token'; - static const String accessTokenKey = 'access_token'; - static const String usernameKey = 'username'; - static const informedConsentAcceptedKey = 'informed_consent_accepted'; + static const String userKey = 'user'; + static const String informedConsentAcceptedKey = 'informed_consent_accepted'; static final LocalSettings _instance = LocalSettings._(); factory LocalSettings() => _instance; LocalSettings._() : super(); - OAuthToken? _oauthToken; - String? _accessToken; String? _studyId; String? _studyDeploymentId; String? _deviceRolename; bool? _hasInformedConsentBeenAccepted; - String? _username; + CarpUser? _user; - String? get accessToken { - if (_accessToken == null) { - String? accessTokenString = - Settings().preferences!.getString(accessTokenKey); + CarpUser? get user { + if (_user == null) { + String? userString = Settings().preferences!.getString(userKey); - _accessToken = (accessTokenString != null) ? accessTokenString : null; - } - return _accessToken; - } - - set accessToken(String? value) { - _accessToken = value; - Settings().preferences!.setString(accessTokenKey, value!); - } - - OAuthToken? get oauthToken { - if (_oauthToken == null) { - String? ouathTokenString = - Settings().preferences!.getString(oauthTokenKey); - - _oauthToken = (ouathTokenString != null) - ? OAuthToken.fromJson(jsonDecode(ouathTokenString)) + _user = (userString != null) + ? CarpUser.fromJson(jsonDecode(userString)) : null; } - return _oauthToken; + return _user; } - set oauthToken(OAuthToken? token) { - _oauthToken = token; - Settings() - .preferences! - .setString(oauthTokenKey, jsonEncode(token?.toJson())); - } - - String? get username => - (_username ??= Settings().preferences!.getString(usernameKey)); - - set username(String? username) { - _username = username; - Settings().preferences!.setString(usernameKey, username!); + set user(CarpUser? user) { + _user = user; + Settings().preferences!.setString(userKey, jsonEncode(user!.toJson())); } String? get studyId => @@ -124,12 +94,15 @@ class LocalSettings { : await Settings().getCacheBasePath(studyDeploymentId!); /// Has the informed consent been shown to, and accepted by the user? + /// Is `true` if there is no informed consent. bool get hasInformedConsentBeenAccepted => _hasInformedConsentBeenAccepted ??= Settings().preferences!.getBool(informedConsentAcceptedKey) ?? false; /// Specify if the informed consent has been handled. - set setHasInformedConsentBeenAccepted(bool accepted) => - Settings().preferences!.setBool(informedConsentAcceptedKey, accepted); + set hasInformedConsentBeenAccepted(bool accepted) { + _hasInformedConsentBeenAccepted = accepted; + Settings().preferences!.setBool(informedConsentAcceptedKey, accepted); + } Future eraseStudyIds() async { _studyId = null; @@ -141,9 +114,7 @@ class LocalSettings { } Future eraseAuthCredentials() async { - _username = null; - _oauthToken = null; - await Settings().preferences!.remove(usernameKey); - await Settings().preferences!.remove(oauthTokenKey); + _user = null; + await Settings().preferences!.remove(userKey); } } diff --git a/lib/ui/pages/audio_task_page.dart b/lib/ui/pages/audio_task_page.dart index 14e3c8d9..425626f7 100644 --- a/lib/ui/pages/audio_task_page.dart +++ b/lib/ui/pages/audio_task_page.dart @@ -347,7 +347,7 @@ class AudioTaskPageState extends State { TextButton( child: Text(locale.translate("YES")), onPressed: () { - context.pushReplacement('/tasks'); + context.pushReplacement('/'); }, ) ], diff --git a/lib/ui/pages/informed_consent_page.dart b/lib/ui/pages/informed_consent_page.dart index 55944329..82ce289e 100644 --- a/lib/ui/pages/informed_consent_page.dart +++ b/lib/ui/pages/informed_consent_page.dart @@ -15,7 +15,7 @@ class InformedConsentState extends State { void resultCallback(RPTaskResult result) async { await widget.model.informedConsentHasBeenAccepted(result); if (context.mounted) { - context.go('/tasks'); + context.go('/'); } } @@ -29,7 +29,8 @@ class InformedConsentState extends State { future: widget.model.getInformedConsent(localization.locale).then( (value) { if (value == null) { - context.go('/tasks'); + bloc.hasInformedConsentBeenAccepted = true; + context.go('/'); } return value; }, diff --git a/lib/ui/pages/study_details_page.dart b/lib/ui/pages/study_details_page.dart index ff1342a0..c37983e6 100644 --- a/lib/ui/pages/study_details_page.dart +++ b/lib/ui/pages/study_details_page.dart @@ -29,9 +29,8 @@ class StudyDetailsPage extends StatelessWidget { children: [ Row(mainAxisAlignment: MainAxisAlignment.end, children: [ IconButton( - onPressed: () => context.canPop() - ? context.pop() - : context.replace('/tasks'), + onPressed: () => + context.canPop() ? context.pop() : context.replace('/'), icon: const Icon(Icons.close)) ]), Flexible( diff --git a/lib/ui/pages/task_list_page.dart b/lib/ui/pages/task_list_page.dart index 08dedf15..cec1ddeb 100644 --- a/lib/ui/pages/task_list_page.dart +++ b/lib/ui/pages/task_list_page.dart @@ -18,8 +18,6 @@ class TaskListPageState extends State { @override Widget build(BuildContext context) { RPLocalizations locale = RPLocalizations.of(context)!; - bloc.configurePermissions(context); - return Scaffold( backgroundColor: Theme.of(context).colorScheme.secondary, body: SafeArea( diff --git a/lib/view_models/informed_consent_page_model.dart b/lib/view_models/informed_consent_page_model.dart index a4cfc18b..a87c4672 100644 --- a/lib/view_models/informed_consent_page_model.dart +++ b/lib/view_models/informed_consent_page_model.dart @@ -29,7 +29,7 @@ class InformedConsentViewModel extends ViewModel { RPTaskResult informedConsentResult, ) async { info('Informed consent has been accepted by user.'); - bloc.setHasInformedConsentBeenAccepted = true; + bloc.hasInformedConsentBeenAccepted = true; await bloc.backend.uploadInformedConsent(informedConsentResult); } } diff --git a/lib/view_models/invitations_list_model.dart b/lib/view_models/invitations_list_model.dart index 03eceea5..9d209ec1 100644 --- a/lib/view_models/invitations_list_model.dart +++ b/lib/view_models/invitations_list_model.dart @@ -2,8 +2,22 @@ part of carp_study_app; class InvitationsListViewModel extends ViewModel { Future> get invitations async { + CarpParticipationService().configureFrom(CarpService()); + bloc.invitations = await CarpParticipationService().getActiveParticipationInvitations(); + + /// Filter the invitations to only include those that + /// have a smartphone as a device in [ActiveParticipationInvitation.assignedDevices] list + /// (i.e. the invitation is for a smartphone). + /// This is done to avoid showing invitations for other devices (e.g. [WebBrowser]). + bloc.invitations = bloc.invitations + .where((invitation) => + invitation.assignedDevices + ?.any((device) => device.device is Smartphone) ?? + false) + .toList(); + return bloc.invitations; } diff --git a/pubspec.lock b/pubspec.lock index 28a26c96..7ae0544f 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -5,10 +5,10 @@ packages: dependency: transitive description: name: _fe_analyzer_shared - sha256: ae92f5d747aee634b87f89d9946000c2de774be1d6ac3e58268224348cd0101a + sha256: eb376e9acf6938204f90eb3b1f00b578640d3188b4c8a8ec054f9f479af8d051 url: "https://pub.dev" source: hosted - version: "61.0.0" + version: "64.0.0" air_quality: dependency: transitive description: @@ -21,10 +21,10 @@ packages: dependency: transitive description: name: analyzer - sha256: ea3d8652bda62982addfd92fdc2d0214e5f82e43325104990d4f4c4a2a313562 + sha256: "69f54f967773f6c26c7dcb13e93d7ccee8b17a641689da39e878d5cf13b06893" url: "https://pub.dev" source: hosted - version: "5.13.0" + version: "6.2.0" app_settings: dependency: "direct main" description: @@ -61,10 +61,10 @@ packages: dependency: transitive description: name: audio_session - sha256: "8a2bc5e30520e18f3fb0e366793d78057fb64cd5287862c76af0c8771f2a52ad" + sha256: "6fdf255ed3af86535c96452c33ecff1245990bb25a605bfb1958661ccc3d467f" url: "https://pub.dev" source: hosted - version: "0.1.16" + version: "0.1.18" audio_streamer: dependency: transitive description: @@ -133,10 +133,10 @@ packages: dependency: transitive description: name: build_daemon - sha256: "5f02d73eb2ba16483e693f80bee4f088563a820e47d1027d4cdfe62b5bb43e65" + sha256: "0343061a33da9c5810b2d6cee51945127d8f4c060b7fbdd9d54917f0a3feaaa1" url: "https://pub.dev" source: hosted - version: "4.0.0" + version: "4.0.1" build_resolvers: dependency: transitive description: @@ -149,10 +149,10 @@ packages: dependency: "direct dev" description: name: build_runner - sha256: "10c6bcdbf9d049a0b666702cf1cee4ddfdc38f02a19d35ae392863b47519848b" + sha256: "67d591d602906ef9201caf93452495ad1812bea2074f04e25dbd7c133785821b" url: "https://pub.dev" source: hosted - version: "2.4.6" + version: "2.4.7" build_runner_core: dependency: transitive description: @@ -173,10 +173,10 @@ packages: dependency: transitive description: name: built_value - sha256: "723b4021e903217dfc445ec4cf5b42e27975aece1fc4ebbc1ca6329c2d9fb54e" + sha256: "69acb7007eb2a31dc901512bfe0f7b767168be34cb734835d54c070bfa74c1b2" url: "https://pub.dev" source: hosted - version: "8.7.0" + version: "8.8.0" camera: dependency: "direct main" description: @@ -189,10 +189,10 @@ packages: dependency: transitive description: name: camera_android - sha256: "58463140f1b39591b8e2155861b436abad4ceb48160058be8374164ff0309ef3" + sha256: b63304d553dde613ca68fb40aaa76bbbcdbd051683bdbf2019671ec8d9645ce7 url: "https://pub.dev" source: hosted - version: "0.10.8+13" + version: "0.10.8+14" camera_avfoundation: dependency: transitive description: @@ -221,98 +221,98 @@ packages: dependency: "direct main" description: name: carp_audio_package - sha256: "5cadf32ab31a022a7c4c92c6279e0ee6fbdea385098df4f37a4f7832e9dc70a3" + sha256: "8a73f31ea26a8b209df5e5b07fe7fa5eedeb0b4310d29045521d97e40b8ed4b3" url: "https://pub.dev" source: hosted - version: "1.3.0" + version: "1.4.0" carp_backend: dependency: "direct main" description: name: carp_backend - sha256: fe000165067bbc49c0dbb1745459e245f593cbd2c04ffa3cc424b74e35591863 + sha256: "28f2f1fa1d961f9ec3ba540daddd4fb3827bde17d643b785deee2b28a76d901b" url: "https://pub.dev" source: hosted - version: "1.3.0" + version: "1.3.2" carp_connectivity_package: dependency: "direct main" description: name: carp_connectivity_package - sha256: ea29e7a8ea02b488f4791d3611012132a056f5596329a4628263a913e4b9a51f + sha256: db0ad6375e1a0a57c09ece799f1bff39b95c2ab65f19b6a45fa81dd27f5253ea url: "https://pub.dev" source: hosted - version: "1.3.1" + version: "1.4.0" carp_context_package: dependency: "direct main" description: name: carp_context_package - sha256: "7ee2f78d501a6517b44315daa43212029fee3cfdef17df8ad6970dc39b3a6a6b" + sha256: "7e166609e89921a26ae2898af198929d5cb7e3a3d69799de05dff6cf877c9279" url: "https://pub.dev" source: hosted - version: "1.3.2" + version: "1.4.0" carp_core: dependency: "direct main" description: name: carp_core - sha256: faa4b15cdb76dfc8a01324223e23ea85d83068dc6fe60d1e148f1bf5a7441edc + sha256: ee1d2925efbdcc33fd959871a87dfd5c7d2d45376728344ac11d9b3099a2e08b url: "https://pub.dev" source: hosted - version: "1.3.1" + version: "1.4.0" carp_esense_package: dependency: "direct main" description: name: carp_esense_package - sha256: ea493fd4ec4024f931f1974b9dd920ce476dc339e7b68d0b572edcf203f68804 + sha256: adc274206efa3ddb77ee087969decfcdb6023ccf48d2928e68ba04abf37b0854 url: "https://pub.dev" source: hosted - version: "1.3.1" + version: "1.4.0" carp_health_package: dependency: "direct main" description: name: carp_health_package - sha256: "0dc120f8eb0b403d94b560d29e771f124ec58b0caa9e9b5859f35083701217cf" + sha256: "3e5ef40227b18b7840b58634a3f4612f8c343dd13cc08dc393d0f82bd45792e6" url: "https://pub.dev" source: hosted - version: "2.7.0" + version: "2.8.0" carp_mobile_sensing: dependency: "direct main" description: name: carp_mobile_sensing - sha256: "17f8bb6c18ba3c6c4e67bcc91e23424d03569c6b6e6f9a1121bc4e1c83869089" + sha256: "10f5dfd54dd897464a564149452e14b52d087ebfdded567e7be05d15d701ca0d" url: "https://pub.dev" source: hosted - version: "1.3.4" + version: "1.4.0+1" carp_polar_package: dependency: "direct main" description: name: carp_polar_package - sha256: "5f7965e6a7366194dff54c7a14b2adc0823031a9297b5caa43816420b1cbbd8b" + sha256: "6956a7a5bc0144ae406bfc476d1c6e87dd5ce47153541fc9d0dddd148a977dee" url: "https://pub.dev" source: hosted - version: "1.3.0" + version: "1.4.0" carp_serializable: dependency: "direct main" description: name: carp_serializable - sha256: "537f611539b6d183900a704e2b9b7821f9eaccf2f17d8936bdd01341514952cb" + sha256: "9d3faf463e27831a36f01265ea937b75194690494954b6c0926a55c89a6a2f7a" url: "https://pub.dev" source: hosted - version: "1.1.0" + version: "1.1.1" carp_survey_package: dependency: "direct main" description: name: carp_survey_package - sha256: "2979f4c581bbb3504648d6fb2dd50610959cf21e20aaaa577c2ed81d462e7a64" + sha256: be9da57d0e247897ea5318f4d724f37959d3799500c7ea2d89e78e50613e113f url: "https://pub.dev" source: hosted - version: "1.3.0" + version: "1.4.0" carp_webservices: dependency: "direct main" description: name: carp_webservices - sha256: ba45c9b6eac9fbc72f961fac1262b3d162a33205709f3464a76043efb2ac0e82 + sha256: "44670736cd7e131c4d04c9ad7398df52dac63e168ed0772107e67200e641f773" url: "https://pub.dev" source: hosted - version: "2.0.0" + version: "2.0.1" characters: dependency: transitive description: @@ -349,10 +349,10 @@ packages: dependency: transitive description: name: code_builder - sha256: "1be9be30396d7e4c0db42c35ea6ccd7cc6a1e19916b5dc64d6ac216b5544d677" + sha256: b2151ce26a06171005b379ecff6e08d34c470180ffe16b8e14b6d52be292b55f url: "https://pub.dev" source: hosted - version: "4.7.0" + version: "4.8.0" cognition_package: dependency: "direct main" description: @@ -373,10 +373,10 @@ packages: dependency: transitive description: name: connectivity_plus - sha256: "77a180d6938f78ca7d2382d2240eb626c0f6a735d0bfdce227d8ffb80f95c48b" + sha256: "224a77051d52a11fbad53dd57827594d3bd24f945af28bd70bab376d68d437f0" url: "https://pub.dev" source: hosted - version: "4.0.2" + version: "5.0.2" connectivity_plus_platform_interface: dependency: transitive description: @@ -397,10 +397,10 @@ packages: dependency: transitive description: name: coverage - sha256: "595a29b55ce82d53398e1bcc2cba525d7bd7c59faeb2d2540e9d42c390cfeeeb" + sha256: ac86d3abab0f165e4b8f561280ff4e066bceaac83c424dd19f1ae2c2fcd12ca9 url: "https://pub.dev" source: hosted - version: "1.6.4" + version: "1.7.1" cron: dependency: transitive description: @@ -413,10 +413,10 @@ packages: dependency: transitive description: name: cross_file - sha256: "445db18de832dba8d851e287aff8ccf169bed30d2e94243cb54c7d2f1ed2142c" + sha256: "2f9d2cbccb76127ba28528cb3ae2c2326a122446a83de5a056aaa3880d3882c5" url: "https://pub.dev" source: hosted - version: "0.3.3+6" + version: "0.3.3+7" crypto: dependency: transitive description: @@ -437,34 +437,34 @@ packages: dependency: transitive description: name: dart_style - sha256: "1efa911ca7086affd35f463ca2fc1799584fb6aa89883cf0af8e3664d6a02d55" + sha256: "40ae61a5d43feea6d24bd22c0537a6629db858963b99b4bc1c3db80676f32368" url: "https://pub.dev" source: hosted - version: "2.3.2" + version: "2.3.4" data_serializer: dependency: transitive description: name: data_serializer - sha256: "4f5fe72aab892bb4853dedfb974fc606a2791e37c4913236a57bc10defb9137b" + sha256: e13386c6780d5ab808af1331b241521d0d5045080a25920bfc9151fb7d701f57 url: "https://pub.dev" source: hosted - version: "1.0.7" + version: "1.0.12" dbus: dependency: transitive description: name: dbus - sha256: "6f07cba3f7b3448d42d015bfd3d53fe12e5b36da2423f23838efc1d5fb31a263" + sha256: "365c771ac3b0e58845f39ec6deebc76e3276aa9922b0cc60840712094d9047ac" url: "https://pub.dev" source: hosted - version: "0.7.8" + version: "0.7.10" device_info_plus: dependency: transitive description: name: device_info_plus - sha256: "7035152271ff67b072a211152846e9f1259cf1be41e34cd3e0b5463d2d6b8419" + sha256: "0042cb3b2a76413ea5f8a2b40cec2a33e01d0c937e91f0f7c211fde4f7739ba6" url: "https://pub.dev" source: hosted - version: "9.1.0" + version: "9.1.1" device_info_plus_platform_interface: dependency: transitive description: @@ -541,10 +541,10 @@ packages: dependency: "direct main" description: name: fl_chart - sha256: c1e26c7e48496be85104c16c040950b0436674cdf0737f3f6e95511b2529b592 + sha256: "5a74434cc83bf64346efb562f1a06eefaf1bcb530dc3d96a104f631a1eff8d79" url: "https://pub.dev" source: hosted - version: "0.63.0" + version: "0.65.0" flutter: dependency: "direct main" description: flutter @@ -578,10 +578,10 @@ packages: dependency: "direct main" description: name: flutter_blue_plus - sha256: "1223f9a493ad57407c52a01cf5de6dc4d9e0e6f557189bc66a29e96dfefbca07" + sha256: b099abd98db419dbd46981ccb6c751e00420a28d2c65a50fb6e3e2018b8a319c url: "https://pub.dev" source: hosted - version: "1.27.0" + version: "1.29.8" flutter_launcher_icons: dependency: "direct main" description: @@ -602,10 +602,10 @@ packages: dependency: transitive description: name: flutter_local_notifications - sha256: "501ed9d54f1c8c0535b7991bade36f9e7e3b45a2346401f03775c1ec7a3c06ae" + sha256: bb5cd63ff7c91d6efe452e41d0d0ae6348925c82eafd10ce170ef585ea04776e url: "https://pub.dev" source: hosted - version: "15.1.2" + version: "16.2.0" flutter_local_notifications_linux: dependency: transitive description: @@ -729,10 +729,10 @@ packages: dependency: "direct main" description: name: go_router - sha256: "2ccd74480706e0a70a0e0dfa9543dede41bc11d0fe3b146a6ad7b7686f6b4407" + sha256: c247a4f76071c3b97bb5ae8912968870d5565644801c5e09f3bc961b4d874895 url: "https://pub.dev" source: hosted - version: "11.1.4" + version: "12.1.1" google_fonts: dependency: "direct main" description: @@ -753,10 +753,10 @@ packages: dependency: transitive description: name: health - sha256: b2eea6fbae995800d2c6831359618525deb9ec148e2b638a133bf87c3ef1d5cf + sha256: cd486352d97ffbf77fc43814360389619c040714cd59bf29a559f4da5cfec75d url: "https://pub.dev" source: hosted - version: "8.0.0" + version: "8.1.0" html: dependency: transitive description: @@ -777,10 +777,10 @@ packages: dependency: transitive description: name: http - sha256: "759d1a329847dd0f39226c688d3e06a6b8679668e350e2891a6474f8b4bb8525" + sha256: d4872660c46d929f6b8a9ef4e7a7eff7e49bbf0c4ec3f385ee32df5119175139 url: "https://pub.dev" source: hosted - version: "1.1.0" + version: "1.1.2" http_multi_server: dependency: transitive description: @@ -857,26 +857,26 @@ packages: dependency: transitive description: name: just_audio - sha256: "5ed0cd723e17dfd8cd4b0253726221e67f6546841ea4553635cf895061fc335b" + sha256: b607cd1a43bac03d85c3aaee00448ff4a589ef2a77104e3d409889ff079bf823 url: "https://pub.dev" source: hosted - version: "0.9.35" + version: "0.9.36" just_audio_platform_interface: dependency: transitive description: name: just_audio_platform_interface - sha256: d8409da198bbc59426cd45d4c92fca522a2ec269b576ce29459d6d6fcaeb44df + sha256: c3dee0014248c97c91fe6299edb73dc4d6c6930a2f4f713579cd692d9e47f4a1 url: "https://pub.dev" source: hosted - version: "4.2.1" + version: "4.2.2" just_audio_web: dependency: transitive description: name: just_audio_web - sha256: ff62f733f437b25a0ff590f0e295fa5441dcb465f1edbdb33b3dea264705bc13 + sha256: "134356b0fe3d898293102b33b5fd618831ffdc72bb7a1b726140abdf22772b70" url: "https://pub.dev" source: hosted - version: "0.4.8" + version: "0.4.9" jwt_decoder: dependency: transitive description: @@ -1009,10 +1009,10 @@ packages: dependency: "direct dev" description: name: mockito - sha256: "7d5b53bcd556c1bc7ffbe4e4d5a19c3e112b7e925e9e172dd7c6ad0630812616" + sha256: "4b693867cee1853c9d1d7ecc1871f27f39b2ef2c13c0d8d8507dfe5bebd8aaf1" url: "https://pub.dev" source: hosted - version: "5.4.2" + version: "5.4.3" nested: dependency: transitive description: @@ -1089,10 +1089,10 @@ packages: dependency: transitive description: name: package_info_plus - sha256: "7e76fad405b3e4016cd39d08f455a4eb5199723cf594cd1b8916d47140d93017" + sha256: "88bc797f44a94814f2213db1c9bd5badebafdfb8290ca9f78d4b9ee2a3db4d79" url: "https://pub.dev" source: hosted - version: "4.2.0" + version: "5.0.1" package_info_plus_platform_interface: dependency: transitive description: @@ -1177,50 +1177,58 @@ packages: dependency: "direct main" description: name: permission_handler - sha256: "284a66179cabdf942f838543e10413246f06424d960c92ba95c84439154fcac8" + sha256: "860c6b871c94c78e202dc69546d4d8fd84bd59faeb36f8fb9888668a53ff4f78" url: "https://pub.dev" source: hosted - version: "11.0.1" + version: "11.1.0" permission_handler_android: dependency: transitive description: name: permission_handler_android - sha256: f9fddd3b46109bd69ff3f9efa5006d2d309b7aec0f3c1c5637a60a2d5659e76e + sha256: "2f1bec180ee2f5665c22faada971a8f024761f632e93ddc23310487df52dcfa6" url: "https://pub.dev" source: hosted - version: "11.1.0" + version: "12.0.1" permission_handler_apple: dependency: transitive description: name: permission_handler_apple - sha256: "99e220bce3f8877c78e4ace901082fb29fa1b4ebde529ad0932d8d664b34f3f5" + sha256: "1a816084338ada8d574b1cb48390e6e8b19305d5120fe3a37c98825bacc78306" url: "https://pub.dev" source: hosted - version: "9.1.4" + version: "9.2.0" + permission_handler_html: + dependency: transitive + description: + name: permission_handler_html + sha256: d96ff56a757b7f04fa825c469d296c5aebc55f743e87bd639fef91a466a24da8 + url: "https://pub.dev" + source: hosted + version: "0.1.0+1" permission_handler_platform_interface: dependency: transitive description: name: permission_handler_platform_interface - sha256: "6760eb5ef34589224771010805bea6054ad28453906936f843a8cc4d3a55c4a4" + sha256: d87349312f7eaf6ce0adaf668daf700ac5b06af84338bd8b8574dfbd93ffe1a1 url: "https://pub.dev" source: hosted - version: "3.12.0" + version: "4.0.2" permission_handler_windows: dependency: transitive description: name: permission_handler_windows - sha256: cc074aace208760f1eee6aa4fae766b45d947df85bc831cde77009cdb4720098 + sha256: "1e8640c1e39121128da6b816d236e714d2cf17fac5a105dd6acdd3403a628004" url: "https://pub.dev" source: hosted - version: "0.1.3" + version: "0.2.0" petitparser: dependency: transitive description: name: petitparser - sha256: cb3798bef7fc021ac45b308f4b51208a152792445cce0448c9a4ba5879dd8750 + sha256: c15605cd28af66339f8eb6fbe0e541bfe2d1b72d5825efc6598f3e0a31b9ad27 url: "https://pub.dev" source: hosted - version: "5.4.0" + version: "6.0.2" platform: dependency: transitive description: @@ -1233,10 +1241,10 @@ packages: dependency: transitive description: name: plugin_platform_interface - sha256: da3fdfeccc4d4ff2da8f8c556704c08f912542c5fb3cf2233ed75372384a034d + sha256: f4f88d4a900933e7267e2b353594774fc0d07fb072b47eedcd5b54e1ea3269f8 url: "https://pub.dev" source: hosted - version: "2.1.6" + version: "2.1.7" pointycastle: dependency: transitive description: @@ -1249,10 +1257,10 @@ packages: dependency: transitive description: name: polar - sha256: "43d091a9169790023f9e4708a4cd7e9bc6438781d4ea273298894d69a76b9a09" + sha256: "25dfa3a66a6abcbf2c07c8efa60525c6508dcfb5f5bf567ab797136d5121ff47" url: "https://pub.dev" source: hosted - version: "6.2.0" + version: "7.0.0" pool: dependency: transitive description: @@ -1265,10 +1273,10 @@ packages: dependency: transitive description: name: provider - sha256: cdbe7530b12ecd9eb455bdaa2fcb8d4dad22e80b8afb4798b41479d5ce26847f + sha256: "9a96a0a19b594dbc5bf0f1f27d2bc67d5f95957359b461cd9feb44ed6ae75096" url: "https://pub.dev" source: hosted - version: "6.0.5" + version: "6.1.1" pub_semver: dependency: transitive description: @@ -1361,10 +1369,10 @@ packages: dependency: transitive description: name: sensors_plus_platform_interface - sha256: "95f0cc08791b8bf0c41c5fa99c84be2a7d5bf60a811ddc17e1438b1e68caf0d3" + sha256: bc472d6cfd622acb4f020e726433ee31788b038056691ba433fec80e448a094f url: "https://pub.dev" source: hosted - version: "1.1.3" + version: "1.2.0" shared_preferences: dependency: transitive description: @@ -1409,10 +1417,10 @@ packages: dependency: transitive description: name: shared_preferences_web - sha256: d762709c2bbe80626ecc819143013cc820fa49ca5e363620ee20a8b15a3e3daf + sha256: "7b15ffb9387ea3e237bb7a66b8a23d2147663d391cafc5c8f37b2e7b4bde5d21" url: "https://pub.dev" source: hosted - version: "2.2.1" + version: "2.2.2" shared_preferences_windows: dependency: transitive description: @@ -1457,10 +1465,10 @@ packages: dependency: transitive description: name: signature - sha256: d95143b8e310b395ea0be59a46bb69fa24106cb6ec79815fc56fd320268e24e6 + sha256: d072a766e9a40496296b7593c0d9dee2abded0bdcfb306d9962d0320a9763395 url: "https://pub.dev" source: hosted - version: "5.4.0" + version: "5.4.1" simple_cluster: dependency: transitive description: @@ -1530,14 +1538,6 @@ packages: url: "https://pub.dev" source: hosted version: "1.10.0" - sprintf: - dependency: transitive - description: - name: sprintf - sha256: "1fc9ffe69d4df602376b52949af107d8f5703b77cda567c4d7d86a0693120f23" - url: "https://pub.dev" - source: hosted - version: "7.0.0" sqflite: dependency: transitive description: @@ -1550,10 +1550,10 @@ packages: dependency: transitive description: name: sqflite_common - sha256: "8ed044102f3135add97be8653662052838859f5400075ef227f8ad72ae320803" + sha256: bb4738f15b23352822f4c42a531677e5c6f522e079461fd240ead29d8d8a54a6 url: "https://pub.dev" source: hosted - version: "2.5.0+1" + version: "2.5.0+2" stack_trace: dependency: transitive description: @@ -1710,10 +1710,10 @@ packages: dependency: transitive description: name: url_launcher_ios - sha256: "4ac97281cf60e2e8c5cc703b2b28528f9b50c8f7cebc71df6bdf0845f647268a" + sha256: bba3373219b7abb6b5e0d071b0fe66dfbe005d07517a68e38d4fc3638f35c6d3 url: "https://pub.dev" source: hosted - version: "6.2.0" + version: "6.2.1" url_launcher_linux: dependency: transitive description: @@ -1742,10 +1742,10 @@ packages: dependency: transitive description: name: url_launcher_web - sha256: "7fd2f55fe86cea2897b963e864dc01a7eb0719ecc65fcef4c1cc3d686d718bb2" + sha256: "138bd45b3a456dcfafc46d1a146787424f8d2edfbf2809c9324361e58f851cf7" url: "https://pub.dev" source: hosted - version: "2.2.0" + version: "2.2.1" url_launcher_windows: dependency: transitive description: @@ -1755,13 +1755,13 @@ packages: source: hosted version: "3.1.0" uuid: - dependency: "direct overridden" + dependency: transitive description: name: uuid - sha256: b715b8d3858b6fa9f68f87d20d98830283628014750c2b09b6f516c1da4af2a7 + sha256: "648e103079f7c64a36dc7d39369cabb358d377078a051d6ae2ad3aa539519313" url: "https://pub.dev" source: hosted - version: "4.1.0" + version: "3.0.7" vector_graphics: dependency: transitive description: @@ -1814,10 +1814,10 @@ packages: dependency: transitive description: name: video_player_avfoundation - sha256: fe73d636f82286a3739f5e644f95f09442cacdc436ebbe5436521dc915f3ecac + sha256: bc923884640d6dc403050586eb40713cdb8d1d84e6886d8aca50ab04c59124c2 url: "https://pub.dev" source: hosted - version: "2.5.1" + version: "2.5.2" video_player_platform_interface: dependency: transitive description: @@ -1838,10 +1838,10 @@ packages: dependency: transitive description: name: vm_service - sha256: c538be99af830f478718b51630ec1b6bee5e74e52c8a802d328d9e71d35d2583 + sha256: b3d56ff4341b8f182b96aceb2fa20e3dcb336b9f867bc0eafc0de10f1048e957 url: "https://pub.dev" source: hosted - version: "11.10.0" + version: "13.0.0" watcher: dependency: transitive description: @@ -1886,10 +1886,10 @@ packages: dependency: transitive description: name: win32 - sha256: "350a11abd2d1d97e0cc7a28a81b781c08002aa2864d9e3f192ca0ffa18b06ed3" + sha256: "7c99c0e1e2fa190b48d25c81ca5e42036d5cac81430ef249027d97b0935c553f" url: "https://pub.dev" source: hosted - version: "5.0.9" + version: "5.1.0" win32_registry: dependency: transitive description: @@ -1910,10 +1910,10 @@ packages: dependency: transitive description: name: xml - sha256: "5bc72e1e45e941d825fd7468b9b4cc3b9327942649aeb6fc5cdbf135f0a86e84" + sha256: af5e77e9b83f2f4adc5d3f0a4ece1c7f45a2467b695c2540381bac793e34e556 url: "https://pub.dev" source: hosted - version: "6.3.0" + version: "6.4.2" yaml: dependency: transitive description: @@ -1923,5 +1923,5 @@ packages: source: hosted version: "3.1.2" sdks: - dart: ">=3.2.0-194.0.dev <4.0.0" - flutter: ">=3.13.0" + dart: ">=3.2.0 <4.0.0" + flutter: ">=3.16.0" diff --git a/pubspec.yaml b/pubspec.yaml index e0d44a24..614fdab2 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -22,7 +22,7 @@ dependencies: carp_polar_package: ^1.3.0 carp_health_package: ^2.7.0 carp_backend: ^1.3.0 - carp_webservices: ^2.0.0 + carp_webservices: ^2.0.1 research_package: ^1.3.0 cognition_package: ^1.4.0 @@ -41,18 +41,14 @@ dependencies: flutter_localizations: sdk: flutter - fl_chart: ^0.63.0 + fl_chart: ^0.65.0 google_fonts: ^6.1.0 - go_router: ^11.0.0 + go_router: ^12.1.1 flutter_svg: ^2.0.4 flutter_blue_plus: ^1.15.5 intl: ^0.18.1 permission_handler: ^11.0.1 -dependency_overrides: - uuid: 4.1.0 - carp_webservices: 2.0.0 - dev_dependencies: # flutter_test: # sdk: flutter