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: