From 7334e7ab9bf1afbde37a90cd73486d53a4a1b397 Mon Sep 17 00:00:00 2001 From: Ida631 <52692119+Ida631@users.noreply.github.com> Date: Thu, 21 Nov 2024 11:37:58 +1300 Subject: [PATCH] Lulin/task/apple signin (#55) --- ios/Podfile.lock | 46 ++++----- ios/Runner/Runner.entitlements | 5 +- .../settings/viewModels/login_view_model.dart | 66 +++++++++++++ .../viewModels/settings_view_model.dart | 41 ++++---- .../viewModels/user_profile_view_model.dart | 33 +++++-- .../settings/views/login_page.dart | 89 +++++++++-------- .../settings/views/settings_page.dart | 1 - .../settings/views/user_profile_page.dart | 2 +- pubspec.lock | 96 ++++++++++++------- pubspec.yaml | 12 +-- 10 files changed, 243 insertions(+), 148 deletions(-) diff --git a/ios/Podfile.lock b/ios/Podfile.lock index cccddf3..eb0c10e 100644 --- a/ios/Podfile.lock +++ b/ios/Podfile.lock @@ -7,14 +7,11 @@ PODS: - AppAuth/Core (1.7.5) - AppAuth/ExternalUserAgent (1.7.5): - AppAuth/Core - - device_info (0.0.1): + - device_info_plus (0.0.1): - Flutter - Flutter (1.0.0) - flutter_secure_storage (6.0.0): - Flutter - - fluttertoast (0.0.2): - - Flutter - - Toast - google_sign_in_ios (0.0.1): - AppAuth (>= 1.7.4) - Flutter @@ -35,35 +32,33 @@ PODS: - GTMSessionFetcher/Core - in_app_review (0.2.0): - Flutter - - launch_review (0.0.1): - - Flutter - package_info_plus (0.4.5): - Flutter - path_provider_foundation (0.0.1): - Flutter - FlutterMacOS - - share (0.0.1): + - share_plus (0.0.1): - Flutter - shared_preferences_foundation (0.0.1): - Flutter - FlutterMacOS - - Toast (4.1.0) + - sign_in_with_apple (0.0.1): + - Flutter - url_launcher_ios (0.0.1): - Flutter DEPENDENCIES: - app_tracking_transparency (from `.symlinks/plugins/app_tracking_transparency/ios`) - - device_info (from `.symlinks/plugins/device_info/ios`) + - device_info_plus (from `.symlinks/plugins/device_info_plus/ios`) - Flutter (from `Flutter`) - flutter_secure_storage (from `.symlinks/plugins/flutter_secure_storage/ios`) - - fluttertoast (from `.symlinks/plugins/fluttertoast/ios`) - google_sign_in_ios (from `.symlinks/plugins/google_sign_in_ios/darwin`) - in_app_review (from `.symlinks/plugins/in_app_review/ios`) - - launch_review (from `.symlinks/plugins/launch_review/ios`) - package_info_plus (from `.symlinks/plugins/package_info_plus/ios`) - path_provider_foundation (from `.symlinks/plugins/path_provider_foundation/darwin`) - - share (from `.symlinks/plugins/share/ios`) + - share_plus (from `.symlinks/plugins/share_plus/ios`) - shared_preferences_foundation (from `.symlinks/plugins/shared_preferences_foundation/darwin`) + - sign_in_with_apple (from `.symlinks/plugins/sign_in_with_apple/ios`) - url_launcher_ios (from `.symlinks/plugins/url_launcher_ios/ios`) SPEC REPOS: @@ -72,56 +67,51 @@ SPEC REPOS: - GoogleSignIn - GTMAppAuth - GTMSessionFetcher - - Toast EXTERNAL SOURCES: app_tracking_transparency: :path: ".symlinks/plugins/app_tracking_transparency/ios" - device_info: - :path: ".symlinks/plugins/device_info/ios" + device_info_plus: + :path: ".symlinks/plugins/device_info_plus/ios" Flutter: :path: Flutter flutter_secure_storage: :path: ".symlinks/plugins/flutter_secure_storage/ios" - fluttertoast: - :path: ".symlinks/plugins/fluttertoast/ios" google_sign_in_ios: :path: ".symlinks/plugins/google_sign_in_ios/darwin" in_app_review: :path: ".symlinks/plugins/in_app_review/ios" - launch_review: - :path: ".symlinks/plugins/launch_review/ios" package_info_plus: :path: ".symlinks/plugins/package_info_plus/ios" path_provider_foundation: :path: ".symlinks/plugins/path_provider_foundation/darwin" - share: - :path: ".symlinks/plugins/share/ios" + share_plus: + :path: ".symlinks/plugins/share_plus/ios" shared_preferences_foundation: :path: ".symlinks/plugins/shared_preferences_foundation/darwin" + sign_in_with_apple: + :path: ".symlinks/plugins/sign_in_with_apple/ios" url_launcher_ios: :path: ".symlinks/plugins/url_launcher_ios/ios" SPEC CHECKSUMS: app_tracking_transparency: e169b653478da7bb15a6c61209015378ca73e375 AppAuth: 501c04eda8a8d11f179dbe8637b7a91bb7e5d2fa - device_info: d7d233b645a32c40dfdc212de5cf646ca482f175 + device_info_plus: c6fb39579d0f423935b0c9ce7ee2f44b71b9fce6 Flutter: e0871f40cf51350855a761d2e70bf5af5b9b5de7 flutter_secure_storage: d33dac7ae2ea08509be337e775f6b59f1ff45f12 - fluttertoast: e9a18c7be5413da53898f660530c56f35edfba9c google_sign_in_ios: 07375bfbf2620bc93a602c0e27160d6afc6ead38 GoogleSignIn: d4281ab6cf21542b1cfaff85c191f230b399d2db GTMAppAuth: f69bd07d68cd3b766125f7e072c45d7340dea0de GTMSessionFetcher: 5aea5ba6bd522a239e236100971f10cb71b96ab6 in_app_review: 318597b3a06c22bb46dc454d56828c85f444f99d - launch_review: 75d5a956ba8eaa493e9c9d4bf4c05e505e8d5ed0 - package_info_plus: 58f0028419748fad15bf008b270aaa8e54380b1c + package_info_plus: 115f4ad11e0698c8c1c5d8a689390df880f47e85 path_provider_foundation: 2b6b4c569c0fb62ec74538f866245ac84301af46 - share: 0b2c3e82132f5888bccca3351c504d0003b3b410 + share_plus: c3fef564749587fc939ef86ffb283ceac0baf9f5 shared_preferences_foundation: fcdcbc04712aee1108ac7fda236f363274528f78 - Toast: ec33c32b8688982cecc6348adeae667c1b9938da + sign_in_with_apple: f3bf75217ea4c2c8b91823f225d70230119b8440 url_launcher_ios: 5334b05cef931de560670eeae103fd3e431ac3fe PODFILE CHECKSUM: 4e8f8b2be68aeea4c0d5beb6ff1e79fface1d048 -COCOAPODS: 1.15.2 +COCOAPODS: 1.16.2 diff --git a/ios/Runner/Runner.entitlements b/ios/Runner/Runner.entitlements index 3a64624..a812db5 100644 --- a/ios/Runner/Runner.entitlements +++ b/ios/Runner/Runner.entitlements @@ -2,10 +2,9 @@ - com.apple.developer.associated-domains + com.apple.developer.applesignin - applinks:compositesai.com - webcredentials:compositesai.com + Default diff --git a/lib/presentation/settings/viewModels/login_view_model.dart b/lib/presentation/settings/viewModels/login_view_model.dart index 8865687..7c41df9 100644 --- a/lib/presentation/settings/viewModels/login_view_model.dart +++ b/lib/presentation/settings/viewModels/login_view_model.dart @@ -1,11 +1,15 @@ // lib/presentation/viewmodels/login_view_model.dart +import 'dart:convert'; + import 'package:flutter/foundation.dart'; import 'dart:io'; import 'package:flutter/material.dart'; import 'package:domain/usecases/auth_usecase.dart'; import 'package:flutter_dotenv/flutter_dotenv.dart'; import 'package:google_sign_in/google_sign_in.dart'; +import 'package:sign_in_with_apple/sign_in_with_apple.dart'; +import 'package:http/http.dart' as http; class LoginViewModel extends ChangeNotifier { final AuthUseCase authUseCase; @@ -109,4 +113,66 @@ class LoginViewModel extends ChangeNotifier { final accessToken = await authUseCase.syncUser(displayName, email, photoUrl); return accessToken; } + + Future signInWithApple() async { + try { + // Request credentials from Apple + final credential = await SignInWithApple.getAppleIDCredential( + scopes: [ + AppleIDAuthorizationScopes.email, + AppleIDAuthorizationScopes.fullName, + ], + webAuthenticationOptions: WebAuthenticationOptions( + clientId: 'com.example.swiftcompsignin', + redirectUri: kIsWeb //This is where Apple sends the user back after they sign in. + ? Uri.parse('https://compositesai.com/') + : Uri.parse( + 'https://flutter-sign-in-with-apple-example.glitch.me/callbacks/sign_in_with_apple', + ), + ), + ); + + final identityToken = credential.identityToken; + + if (identityToken == null) { + throw Exception('Identity token not available in Apple credentials'); + } + // Send token to backend for validation + // This is where app sends token to backend to check if the the "identityToken" is real and safe to use. + final validateTokenEndpoint = Uri.parse('http://localhost:8080/api/auth/sign_in_with_apple'); + final validationResponse = await http.Client().post( + validateTokenEndpoint, + headers: { + 'Content-Type': 'application/json', + }, + body: jsonEncode({ + 'identityToken': identityToken, + }), + ); + + if (validationResponse.statusCode != 200) { + print('Token validation failed: ${validationResponse.body}'); + throw Exception('Failed to validate token with backend'); + } + print('Token validated successfully: ${validationResponse.body}'); + + // Extract user information + final String? email = credential.email; + final String? givenName = credential.givenName; + + if (email == null) { + throw Exception('Email not available in Apple credentials'); + } + + // Sync user with backend (you may modify syncUser based on backend response if needed) + await syncUser(givenName, email, null); + + // Notify listeners for UI update + notifyListeners(); + } catch (e) { + print('Sign in with Apple failed: $e'); + rethrow; // Optionally rethrow for higher-level error handling + } + } + } diff --git a/lib/presentation/settings/viewModels/settings_view_model.dart b/lib/presentation/settings/viewModels/settings_view_model.dart index b74f381..f6196f4 100644 --- a/lib/presentation/settings/viewModels/settings_view_model.dart +++ b/lib/presentation/settings/viewModels/settings_view_model.dart @@ -1,19 +1,17 @@ // lib/presentation/viewmodels/settings_view_model.dart import 'dart:io'; -import 'package:device_info/device_info.dart'; +import 'package:device_info_plus/device_info_plus.dart'; import 'package:domain/entities/user.dart'; import 'package:domain/usecases/auth_usecase.dart'; import 'package:domain/usecases/user_usercase.dart'; import 'package:flutter/foundation.dart'; import 'package:flutter/material.dart'; -import 'package:fluttertoast/fluttertoast.dart'; import 'package:package_info_plus/package_info_plus.dart'; +import 'package:share_plus/share_plus.dart'; import 'package:swiftcomp/presentation/settings/providers/feature_flag_provider.dart'; import 'package:url_launcher/url_launcher.dart'; import 'package:url_launcher/url_launcher_string.dart'; -import 'package:launch_review/launch_review.dart'; -import 'package:share/share.dart'; class SettingsViewModel extends ChangeNotifier { @@ -84,13 +82,14 @@ class SettingsViewModel extends ChangeNotifier { Future newLogout(BuildContext context) async { try { await authUseCase.logout(); - Fluttertoast.showToast( - msg: "Logged out", - toastLength: Toast.LENGTH_SHORT, - gravity: ToastGravity.CENTER, - backgroundColor: Colors.black, - textColor: Colors.white, - fontSize: 16.0, + + // Display Snackbar for success message + ScaffoldMessenger.of(context).showSnackBar( + SnackBar( + content: Text("Logged out"), + duration: Duration(seconds: 2), + backgroundColor: Colors.black, + ), ); isLoggedIn = false; notifyListeners(); @@ -98,9 +97,18 @@ class SettingsViewModel extends ChangeNotifier { if (kDebugMode) { print(e); } + // Display Snackbar for error message + ScaffoldMessenger.of(context).showSnackBar( + SnackBar( + content: Text("Failed to log out. Please try again."), + duration: Duration(seconds: 2), + backgroundColor: Colors.red, + ), + ); } } + Future openFeedback() async { final DeviceInfoPlugin deviceInfo = DeviceInfoPlugin(); String device; @@ -158,16 +166,7 @@ class SettingsViewModel extends ChangeNotifier { } void rateApp() async { - try { - await LaunchReview.launch( - androidAppId: "com.banghuazhao.swiftcomp", - iOSAppId: "1297825946", - writeReview: true, - ); - } catch (e) { - // Use fallback to open the app store directly if `LaunchReview` fails - openAppStore(); - } + openAppStore(); } Future shareApp(BuildContext context) async { diff --git a/lib/presentation/settings/viewModels/user_profile_view_model.dart b/lib/presentation/settings/viewModels/user_profile_view_model.dart index d18e12d..725806f 100644 --- a/lib/presentation/settings/viewModels/user_profile_view_model.dart +++ b/lib/presentation/settings/viewModels/user_profile_view_model.dart @@ -3,7 +3,7 @@ import 'package:domain/usecases/user_usercase.dart'; import 'package:flutter/foundation.dart'; import 'package:flutter/material.dart'; import 'package:domain/usecases/auth_usecase.dart'; -import 'package:fluttertoast/fluttertoast.dart'; // Assuming your use cases are here +// Assuming your use cases are here class UserProfileViewModel extends ChangeNotifier { final AuthUseCase authUseCase; @@ -48,27 +48,40 @@ class UserProfileViewModel extends ChangeNotifier { } } - Future logoutUser() async { + Future logoutUser(BuildContext context) async { setLoading(true); try { await authUseCase.logout(); - Fluttertoast.showToast( - msg: "Logged out", - toastLength: Toast.LENGTH_SHORT, - gravity: ToastGravity.CENTER, - backgroundColor: Colors.black, - textColor: Colors.white, - fontSize: 16.0, + + // Display a success Snackbar + ScaffoldMessenger.of(context).showSnackBar( + SnackBar( + content: Text("Logged out"), + duration: Duration(seconds: 2), + backgroundColor: Colors.black, + ), ); + + // Update state isLoggedIn = false; // Explicitly set isLoggedIn to false user = null; // Clear user data notifyListeners(); } catch (e) { + // Log the error and display an error Snackbar print("Logout failed: $e"); + ScaffoldMessenger.of(context).showSnackBar( + SnackBar( + content: Text("Logout failed. Please try again."), + duration: Duration(seconds: 2), + backgroundColor: Colors.red, + ), + ); + } finally { + setLoading(false); // Ensure loading state is cleared } - setLoading(false); } + Future deleteUser() async { setLoading(true); try { diff --git a/lib/presentation/settings/views/login_page.dart b/lib/presentation/settings/views/login_page.dart index 87d996e..696f428 100644 --- a/lib/presentation/settings/views/login_page.dart +++ b/lib/presentation/settings/views/login_page.dart @@ -1,7 +1,7 @@ import 'package:flutter/material.dart'; import 'package:provider/provider.dart'; import 'package:swiftcomp/presentation/settings/views/sigup_page.dart'; -import 'package:fluttertoast/fluttertoast.dart'; + import '../../../app/injection_container.dart'; import '../viewModels/login_view_model.dart'; @@ -41,12 +41,11 @@ class _LoginPageState extends State { }); } - void _login(LoginViewModel viewModel) async { + void _login(LoginViewModel viewModel, BuildContext context) async { if (!_formKey.currentState!.validate()) return; try { // Call login from viewModel and pass the credentials - final accessToken = await viewModel.login( _emailController.text, _passwordController.text, @@ -54,72 +53,70 @@ class _LoginPageState extends State { if (accessToken != null) { // Login successful - Fluttertoast.showToast( - msg: "Logged in", - toastLength: Toast.LENGTH_SHORT, - gravity: ToastGravity.CENTER, - timeInSecForIosWeb: 2, - backgroundColor: Colors.black, - textColor: Colors.white, - fontSize: 16.0, + ScaffoldMessenger.of(context).showSnackBar( + SnackBar( + content: Text("Logged in"), + duration: Duration(seconds: 2), + backgroundColor: Colors.black, + ), ); Navigator.pop(context, "Log in Success"); } else { // Login failed - error handled within viewModel and errorMessage will be populated if (viewModel.errorMessage != null) { - Fluttertoast.showToast( - msg: viewModel.errorMessage!, - toastLength: Toast.LENGTH_SHORT, - gravity: ToastGravity.CENTER, - timeInSecForIosWeb: 2, - backgroundColor: Colors.red, - textColor: Colors.white, - fontSize: 16.0, + ScaffoldMessenger.of(context).showSnackBar( + SnackBar( + content: Text(viewModel.errorMessage!), + duration: Duration(seconds: 2), + backgroundColor: Colors.red, + ), ); } } } catch (e) { // General error handling, if something unexpected happens - Fluttertoast.showToast( - msg: 'An unexpected error occurred: ${e.toString()}', - toastLength: Toast.LENGTH_SHORT, - gravity: ToastGravity.CENTER, - timeInSecForIosWeb: 2, - backgroundColor: Colors.red, - textColor: Colors.white, - fontSize: 16.0, + ScaffoldMessenger.of(context).showSnackBar( + SnackBar( + content: Text('An unexpected error occurred: ${e.toString()}'), + duration: Duration(seconds: 2), + backgroundColor: Colors.red, + ), ); } } - void _googleSignIn(LoginViewModel viewModel) async { + void _googleSignIn(LoginViewModel viewModel, BuildContext context) async { await viewModel.signInWithGoogle(); + if (viewModel.user != null) { - Fluttertoast.showToast( - msg: "Logged in with Google", - toastLength: Toast.LENGTH_SHORT, - gravity: ToastGravity.CENTER, - timeInSecForIosWeb: 2, - backgroundColor: Colors.black, - textColor: Colors.white, - fontSize: 16.0, + // Display success Snackbar + ScaffoldMessenger.of(context).showSnackBar( + SnackBar( + content: Text("Logged in with Google"), + duration: Duration(seconds: 2), + backgroundColor: Colors.black, + ), ); + // Navigate to the next screen Navigator.pop(context, "Log in Success"); } else { - Fluttertoast.showToast( - msg: "Google Sign-In failed", - toastLength: Toast.LENGTH_SHORT, - gravity: ToastGravity.CENTER, - timeInSecForIosWeb: 2, - backgroundColor: Colors.red, - textColor: Colors.white, - fontSize: 16.0, + // Display failure Snackbar + ScaffoldMessenger.of(context).showSnackBar( + SnackBar( + content: Text("Google Sign-In failed"), + duration: Duration(seconds: 2), + backgroundColor: Colors.red, + ), ); } } + + + + @override void dispose() { _emailController.dispose(); @@ -222,7 +219,7 @@ class _LoginPageState extends State { shape: RoundedRectangleBorder( borderRadius: BorderRadius.circular(6), ), - onPressed: isButtonEnabled ? () => _login(viewModel) : null, + onPressed: isButtonEnabled ? () => _login(viewModel, context) : null, child: Text( 'Login', style: TextStyle(color: Colors.white, fontSize: 16), @@ -240,7 +237,7 @@ class _LoginPageState extends State { Row( mainAxisAlignment: MainAxisAlignment.center, children: [ - _buildSocialButton('images/google_logo.png', () => _googleSignIn(viewModel)), + _buildSocialButton('images/google_logo.png', () => _googleSignIn(viewModel, context)), //_buildSocialButton('images/apple_logo.png', () => _googleSignIn(viewModel)), ], ), diff --git a/lib/presentation/settings/views/settings_page.dart b/lib/presentation/settings/views/settings_page.dart index 577fcec..c520bb0 100644 --- a/lib/presentation/settings/views/settings_page.dart +++ b/lib/presentation/settings/views/settings_page.dart @@ -5,7 +5,6 @@ import 'package:provider/provider.dart'; import 'package:flutter_progress_hud/flutter_progress_hud.dart'; import 'package:swiftcomp/presentation/settings/views/qa_settings_page.dart'; import 'package:swiftcomp/presentation/settings/views/user_profile_page.dart'; -import 'package:launch_review/launch_review.dart'; import '../viewModels/settings_view_model.dart'; import 'login_page.dart'; import 'tool_setting_page.dart'; diff --git a/lib/presentation/settings/views/user_profile_page.dart b/lib/presentation/settings/views/user_profile_page.dart index 43dbd84..b373f9d 100644 --- a/lib/presentation/settings/views/user_profile_page.dart +++ b/lib/presentation/settings/views/user_profile_page.dart @@ -131,7 +131,7 @@ class UserProfilePage extends StatelessWidget { ElevatedButton( onPressed: () async { - await viewModel.logoutUser(); + await viewModel.logoutUser(context); Navigator.of(context).pop("refresh"); }, style: ElevatedButton.styleFrom( diff --git a/pubspec.lock b/pubspec.lock index 2801f0d..dcab4f2 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -129,6 +129,14 @@ packages: url: "https://pub.dev" source: hosted version: "3.1.1" + cross_file: + dependency: transitive + description: + name: cross_file + sha256: "7caf6a750a0c04effbb52a676dce9a4a592e10ad35c34d6d2d0e4811160d5670" + url: "https://pub.dev" + source: hosted + version: "0.3.4+2" crypto: dependency: transitive description: @@ -160,22 +168,22 @@ packages: relative: true source: path version: "0.0.1" - device_info: + device_info_plus: dependency: "direct main" description: - name: device_info - sha256: f4a8156cb7b7480d969cb734907d18b333c8f0bc0b1ad0b342cdcecf30d62c48 + name: device_info_plus + sha256: "77f757b789ff68e4eaf9c56d1752309bd9f7ad557cb105b938a7f8eb89e59110" url: "https://pub.dev" source: hosted - version: "2.0.3" - device_info_platform_interface: + version: "9.1.2" + device_info_plus_platform_interface: dependency: transitive description: - name: device_info_platform_interface - sha256: b148e0bf9640145d09a4f8dea96614076f889e7f7f8b5ecab1c7e5c2dbc73c1b + name: device_info_plus_platform_interface + sha256: "282d3cf731045a2feb66abfe61bbc40870ae50a3ed10a4d3d217556c35c8c2ba" url: "https://pub.dev" source: hosted - version: "2.0.1" + version: "7.0.1" domain: dependency: "direct main" description: @@ -355,14 +363,6 @@ packages: description: flutter source: sdk version: "0.0.0" - fluttertoast: - dependency: "direct main" - description: - name: fluttertoast - sha256: "95f349437aeebe524ef7d6c9bde3e6b4772717cf46a0eb6a3ceaddc740b297cc" - url: "https://pub.dev" - source: hosted - version: "8.2.8" get_it: dependency: "direct main" description: @@ -447,10 +447,10 @@ packages: dependency: "direct main" description: name: in_app_review - sha256: "99869244d09adc76af16bf8fd731dd13cef58ecafd5917847589c49f378cbb30" + sha256: "36a06771b88fb0e79985b15e7f2ac0f1142e903fe72517f3c055d78bc3bc1819" url: "https://pub.dev" source: hosted - version: "2.0.9" + version: "2.0.10" in_app_review_platform_interface: dependency: transitive description: @@ -475,14 +475,6 @@ packages: url: "https://pub.dev" source: hosted version: "0.6.7" - launch_review: - dependency: "direct main" - description: - name: launch_review - sha256: "04cdaf752033cefd53bc0fa9c22105801ef53791a93d8b6cdd00fcb3c1c1604b" - url: "https://pub.dev" - source: hosted - version: "3.0.1" leak_tracker: dependency: transitive description: @@ -599,10 +591,10 @@ packages: dependency: "direct main" description: name: package_info_plus - sha256: cb44f49b6e690fa766f023d5b22cac6b9affe741dd792b6ac7ad4fabe0d7b097 + sha256: "7e76fad405b3e4016cd39d08f455a4eb5199723cf594cd1b8916d47140d93017" url: "https://pub.dev" source: hosted - version: "6.0.0" + version: "4.2.0" package_info_plus_platform_interface: dependency: transitive description: @@ -715,14 +707,22 @@ packages: url: "https://pub.dev" source: hosted version: "2.1.4" - share: + share_plus: dependency: "direct main" description: - name: share - sha256: "97e6403f564ed1051a01534c2fc919cb6e40ea55e60a18ec23cee6e0ce19f4be" + name: share_plus + sha256: "3ef39599b00059db0990ca2e30fca0a29d8b37aae924d60063f8e0184cf20900" + url: "https://pub.dev" + source: hosted + version: "7.2.2" + share_plus_platform_interface: + dependency: transitive + description: + name: share_plus_platform_interface + sha256: "251eb156a8b5fa9ce033747d73535bf53911071f8d3b6f4f0b578505ce0d4496" url: "https://pub.dev" source: hosted - version: "2.0.4" + version: "3.4.0" shared_preferences: dependency: "direct main" description: @@ -779,6 +779,30 @@ packages: url: "https://pub.dev" source: hosted version: "2.4.1" + sign_in_with_apple: + dependency: "direct main" + description: + name: sign_in_with_apple + sha256: "602f1374c9c4c33889c969b53ebf7cc8417c22cc7e25ea771581330173bc6603" + url: "https://pub.dev" + source: hosted + version: "6.1.3" + sign_in_with_apple_platform_interface: + dependency: transitive + description: + name: sign_in_with_apple_platform_interface + sha256: c2ef2ce6273fce0c61acd7e9ff5be7181e33d7aa2b66508b39418b786cca2119 + url: "https://pub.dev" + source: hosted + version: "1.1.0" + sign_in_with_apple_web: + dependency: transitive + description: + name: sign_in_with_apple_web + sha256: c009e9beeb6c376e86aaa154fcc8b4e075d4bad90c56286b9668a51cdb6129ea + url: "https://pub.dev" + source: hosted + version: "2.1.0" sky_engine: dependency: transitive description: flutter @@ -1000,6 +1024,14 @@ packages: url: "https://pub.dev" source: hosted version: "5.5.0" + win32_registry: + dependency: transitive + description: + name: win32_registry + sha256: "10589e0d7f4e053f2c61023a31c9ce01146656a70b7b7f0828c0b46d7da2a9bb" + url: "https://pub.dev" + source: hosted + version: "1.1.3" xdg_directories: dependency: transitive description: diff --git a/pubspec.yaml b/pubspec.yaml index bb99f20..819d8c5 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -30,17 +30,15 @@ dependencies: app_tracking_transparency: ^2.0.6 flutter_math_fork: ^0.7.2 flutter_staggered_grid_view: ^0.4.1 - device_info: ^2.0.3 - package_info_plus: ^6.0.0 + device_info_plus: ^9.1.2 + package_info_plus: ^4.2.0 url_launcher: ^6.0.20 - launch_review: ^3.0.1 - share: ^2.0.4 + share_plus: ^7.2.2 linalg: ^0.4.0 - in_app_review: ^2.0.9 + in_app_review: ^2.0.10 shared_preferences: ^2.2.3 intl: ^0.18.1 auto_size_text: ^3.0.0 - fluttertoast: ^8.2.8 provider: ^6.0.2 flutter_progress_hud: ^2.0.2 file: ^6.1.4 @@ -49,6 +47,8 @@ dependencies: flutter_dotenv: ^5.0.2 flutter_secure_storage: ^9.2.2 google_sign_in: ^6.2.2 + sign_in_with_apple: ^6.1.3 + dev_dependencies: