diff --git a/ios/Podfile.lock b/ios/Podfile.lock index 64ec0de..6bf5a3f 100644 --- a/ios/Podfile.lock +++ b/ios/Podfile.lock @@ -1,11 +1,32 @@ PODS: + - AppAuth (1.7.5): + - AppAuth/Core (= 1.7.5) + - AppAuth/ExternalUserAgent (= 1.7.5) + - AppAuth/Core (1.7.5) + - AppAuth/ExternalUserAgent (1.7.5): + - AppAuth/Core - audioplayers_darwin (0.0.1): - Flutter + - Firebase/Auth (10.24.0): + - Firebase/CoreOnly + - FirebaseAuth (~> 10.24.0) - Firebase/CoreOnly (10.24.0): - FirebaseCore (= 10.24.0) + - firebase_auth (4.19.4): + - Firebase/Auth (= 10.24.0) + - firebase_core + - Flutter - firebase_core (2.30.1): - Firebase/CoreOnly (= 10.24.0) - Flutter + - FirebaseAppCheckInterop (10.25.0) + - FirebaseAuth (10.24.0): + - FirebaseAppCheckInterop (~> 10.17) + - FirebaseCore (~> 10.0) + - GoogleUtilities/AppDelegateSwizzler (~> 7.8) + - GoogleUtilities/Environment (~> 7.8) + - GTMSessionFetcher/Core (< 4.0, >= 2.1) + - RecaptchaInterop (~> 100.0) - FirebaseCore (10.24.0): - FirebaseCoreInternal (~> 10.0) - GoogleUtilities/Environment (~> 7.12) @@ -13,60 +34,114 @@ PODS: - FirebaseCoreInternal (10.25.0): - "GoogleUtilities/NSData+zlib (~> 7.8)" - Flutter (1.0.0) + - google_sign_in_ios (0.0.1): + - AppAuth (>= 1.7.4) + - Flutter + - FlutterMacOS + - GoogleSignIn (~> 7.1) + - GTMSessionFetcher (>= 3.4.0) + - GoogleSignIn (7.1.0): + - AppAuth (< 2.0, >= 1.7.3) + - GTMAppAuth (< 5.0, >= 4.1.1) + - GTMSessionFetcher/Core (~> 3.3) + - GoogleUtilities/AppDelegateSwizzler (7.13.2): + - GoogleUtilities/Environment + - GoogleUtilities/Logger + - GoogleUtilities/Network + - GoogleUtilities/Privacy - GoogleUtilities/Environment (7.13.2): - GoogleUtilities/Privacy - PromisesObjC (< 3.0, >= 1.2) - GoogleUtilities/Logger (7.13.2): - GoogleUtilities/Environment - GoogleUtilities/Privacy + - GoogleUtilities/Network (7.13.2): + - GoogleUtilities/Logger + - "GoogleUtilities/NSData+zlib" + - GoogleUtilities/Privacy + - GoogleUtilities/Reachability - "GoogleUtilities/NSData+zlib (7.13.2)": - GoogleUtilities/Privacy - GoogleUtilities/Privacy (7.13.2) + - GoogleUtilities/Reachability (7.13.2): + - GoogleUtilities/Logger + - GoogleUtilities/Privacy + - GTMAppAuth (4.1.1): + - AppAuth/Core (~> 1.7) + - GTMSessionFetcher/Core (< 4.0, >= 3.3) + - GTMSessionFetcher (3.4.1): + - GTMSessionFetcher/Full (= 3.4.1) + - GTMSessionFetcher/Core (3.4.1) + - GTMSessionFetcher/Full (3.4.1): + - GTMSessionFetcher/Core - path_provider_foundation (0.0.1): - Flutter - FlutterMacOS - PromisesObjC (2.4.0) + - RecaptchaInterop (100.0.0) - sqflite (0.0.3): - Flutter - FlutterMacOS DEPENDENCIES: - audioplayers_darwin (from `.symlinks/plugins/audioplayers_darwin/ios`) + - firebase_auth (from `.symlinks/plugins/firebase_auth/ios`) - firebase_core (from `.symlinks/plugins/firebase_core/ios`) - Flutter (from `Flutter`) + - google_sign_in_ios (from `.symlinks/plugins/google_sign_in_ios/darwin`) - path_provider_foundation (from `.symlinks/plugins/path_provider_foundation/darwin`) - sqflite (from `.symlinks/plugins/sqflite/darwin`) SPEC REPOS: trunk: + - AppAuth - Firebase + - FirebaseAppCheckInterop + - FirebaseAuth - FirebaseCore - FirebaseCoreInternal + - GoogleSignIn - GoogleUtilities + - GTMAppAuth + - GTMSessionFetcher - PromisesObjC + - RecaptchaInterop EXTERNAL SOURCES: audioplayers_darwin: :path: ".symlinks/plugins/audioplayers_darwin/ios" + firebase_auth: + :path: ".symlinks/plugins/firebase_auth/ios" firebase_core: :path: ".symlinks/plugins/firebase_core/ios" Flutter: :path: Flutter + google_sign_in_ios: + :path: ".symlinks/plugins/google_sign_in_ios/darwin" path_provider_foundation: :path: ".symlinks/plugins/path_provider_foundation/darwin" sqflite: :path: ".symlinks/plugins/sqflite/darwin" SPEC CHECKSUMS: + AppAuth: 501c04eda8a8d11f179dbe8637b7a91bb7e5d2fa audioplayers_darwin: 877d9a4d06331c5c374595e46e16453ac7eafa40 Firebase: 91fefd38712feb9186ea8996af6cbdef41473442 + firebase_auth: b782567cafd5cfd64debf54638a9f29b63abd7bf firebase_core: 7f1e1156934d0da3be260174812842df9420e4ab + FirebaseAppCheckInterop: 5da5ce93e8797a215e3f677fb0654b74e736c8b8 + FirebaseAuth: 711d01cccefaf10035b3090a92956d0dd4f99088 FirebaseCore: 11dc8a16dfb7c5e3c3f45ba0e191a33ac4f50894 FirebaseCoreInternal: 910a81992c33715fec9263ca7381d59ab3a750b7 Flutter: e0871f40cf51350855a761d2e70bf5af5b9b5de7 + google_sign_in_ios: 07375bfbf2620bc93a602c0e27160d6afc6ead38 + GoogleSignIn: d4281ab6cf21542b1cfaff85c191f230b399d2db GoogleUtilities: c56430aef51a1aa57b25da78c3f8397e522c67b7 + GTMAppAuth: f69bd07d68cd3b766125f7e072c45d7340dea0de + GTMSessionFetcher: 8000756fc1c19d2e5697b90311f7832d2e33f6cd path_provider_foundation: 3784922295ac71e43754bd15e0653ccfd36a147c PromisesObjC: f5707f49cb48b9636751c5b2e7d227e43fba9f47 + RecaptchaInterop: 7d1a4a01a6b2cb1610a47ef3f85f0c411434cb21 sqflite: 673a0e54cc04b7d6dba8d24fb8095b31c3a99eec PODFILE CHECKSUM: 819463e6a0290f5a72f145ba7cde16e8b6ef0796 diff --git a/ios/Runner.xcodeproj/project.pbxproj b/ios/Runner.xcodeproj/project.pbxproj index 8c1582d..e7bc656 100644 --- a/ios/Runner.xcodeproj/project.pbxproj +++ b/ios/Runner.xcodeproj/project.pbxproj @@ -202,6 +202,7 @@ 9705A1C41CF9048500538489 /* Embed Frameworks */, 3B06AD1E1E4923F5004D2608 /* Thin Binary */, AD391FFF678BDCD13589FD5A /* [CP] Embed Pods Frameworks */, + 3B92086DEF000E17E9046345 /* [CP] Copy Pods Resources */, ); buildRules = ( ); @@ -290,6 +291,23 @@ shellPath = /bin/sh; shellScript = "/bin/sh \"$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh\" embed_and_thin"; }; + 3B92086DEF000E17E9046345 /* [CP] Copy Pods Resources */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputFileListPaths = ( + "${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-resources-${CONFIGURATION}-input-files.xcfilelist", + ); + name = "[CP] Copy Pods Resources"; + outputFileListPaths = ( + "${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-resources-${CONFIGURATION}-output-files.xcfilelist", + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-resources.sh\"\n"; + showEnvVarsInLog = 0; + }; 8A4C96B6F750C210D430AEBA /* [CP] Check Pods Manifest.lock */ = { isa = PBXShellScriptBuildPhase; buildActionMask = 2147483647; diff --git a/ios/Runner/GoogleService-Info.plist b/ios/Runner/GoogleService-Info.plist index d086b87..59f85b7 100644 --- a/ios/Runner/GoogleService-Info.plist +++ b/ios/Runner/GoogleService-Info.plist @@ -2,6 +2,10 @@ + CLIENT_ID + 716247414791-di6i0kdd77u99bdl43sbdmc0h9pa9923.apps.googleusercontent.com + REVERSED_CLIENT_ID + com.googleusercontent.apps.716247414791-di6i0kdd77u99bdl43sbdmc0h9pa9923 API_KEY AIzaSyClhib10AmhoVtldDkGZHOZG66fVGh_ODQ GCM_SENDER_ID diff --git a/ios/Runner/Info.plist b/ios/Runner/Info.plist index 9e7657a..b92b626 100644 --- a/ios/Runner/Info.plist +++ b/ios/Runner/Info.plist @@ -4,6 +4,8 @@ FlutterDeepLinkingEnabled +GIDClientID +716247414791-di6i0kdd77u99bdl43sbdmc0h9pa9923.apps.googleusercontent.com CFBundleURLTypes @@ -13,6 +15,7 @@ 192.168.100.243 CFBundleURLSchemes + com.googleusercontent.apps.716247414791-di6i0kdd77u99bdl43sbdmc0h9pa9923 appscheme diff --git a/lib/config/route.dart b/lib/config/route.dart index 1aa92b8..1e310bb 100644 --- a/lib/config/route.dart +++ b/lib/config/route.dart @@ -2,6 +2,7 @@ import 'package:flutter/material.dart'; import 'package:go_router/go_router.dart'; import 'package:spotify_clone/screens/category_detail/category_detail.dart'; import 'package:spotify_clone/screens/common/splash_screen.dart'; +import 'package:spotify_clone/screens/login/login_screen.dart'; import 'package:spotify_clone/screens/lyric/full_lyric_screen.dart'; import 'package:spotify_clone/screens/home/home_screen.dart'; import 'package:spotify_clone/screens/common/main_screen.dart'; @@ -130,6 +131,13 @@ class AppRouter { ); }, ), + GoRoute( + path: LoginScreen.routeName, + pageBuilder: (context, state) { + return const MaterialPage( + child: LoginScreen(), + ); + }), ], ); diff --git a/lib/main.dart b/lib/main.dart index a9cef09..c5800b9 100644 --- a/lib/main.dart +++ b/lib/main.dart @@ -37,7 +37,6 @@ class MyApp extends StatelessWidget { ChangeNotifierProvider(create: (context) => MusicPlayerProvider()), ChangeNotifierProvider(create: (context) => CategoryProvider()), ChangeNotifierProvider(create: (context) => PlaylistProvider()), - Provider(create: (context) => SpotifyService()), ], child: MaterialApp.router( routerDelegate: AppRouter.router.routerDelegate, diff --git a/lib/screens/login/login_screen.dart b/lib/screens/login/login_screen.dart new file mode 100644 index 0000000..9f2df0b --- /dev/null +++ b/lib/screens/login/login_screen.dart @@ -0,0 +1,29 @@ +import 'package:flutter/material.dart'; +import 'package:go_router/go_router.dart'; +import 'package:spotify_clone/screens/home/home_screen.dart'; +import 'package:spotify_clone/services/auth_service.dart'; + +class LoginScreen extends StatefulWidget { + static const routeName = '/login'; + const LoginScreen({super.key}); + + @override + State createState() => _LoginScreenState(); +} + +class _LoginScreenState extends State { + @override + Widget build(BuildContext context) { + return Scaffold( + body: Center( + child: ElevatedButton( + onPressed: () async { + final user = await AuthService.logInWithGoogle(); + if (user.user != null) { + context.go(MyHomePage.routeName); + } + }, + child: Text('Login with google')), + )); + } +} diff --git a/lib/screens/search/widget/search_appbar.dart b/lib/screens/search/widget/search_appbar.dart index 281400f..2c5322d 100644 --- a/lib/screens/search/widget/search_appbar.dart +++ b/lib/screens/search/widget/search_appbar.dart @@ -1,18 +1,29 @@ +import 'package:firebase_auth/firebase_auth.dart'; import 'package:flutter/material.dart'; +import 'package:go_router/go_router.dart'; +import 'package:spotify_clone/screens/login/login_screen.dart'; AppBar searchAppBar(BuildContext context) { + final user = FirebaseAuth.instance.currentUser; + return AppBar( - automaticallyImplyLeading: false, - title: const Text( - 'Search', - style: TextStyle( - fontWeight: FontWeight.bold, + automaticallyImplyLeading: false, + title: const Text( + 'Search', + style: TextStyle( + fontWeight: FontWeight.bold, + ), ), - ), - centerTitle: false, - leading: const IconButton( - icon: Icon(Icons.person), - onPressed: null, - ), - ); + centerTitle: false, + leading: CircleAvatar( + radius: 10, + child: user?.photoURL != null + ? ClipOval( + child: Image.network( + user!.photoURL!, + fit: BoxFit.cover, + ), + ) + : const Icon(Icons.person), + )); } diff --git a/lib/services/auth_service.dart b/lib/services/auth_service.dart new file mode 100644 index 0000000..36d8c12 --- /dev/null +++ b/lib/services/auth_service.dart @@ -0,0 +1,30 @@ +import 'package:firebase_auth/firebase_auth.dart'; +import 'package:google_sign_in/google_sign_in.dart'; + +const List scopes = [ + 'email', + 'https://www.googleapis.com/auth/contacts.readonly', +]; + +class AuthService { + static Future logInWithGoogle() async { + final GoogleSignIn googleSignIn = GoogleSignIn( + scopes: scopes, + ); + // Trigger the authentication flow + final GoogleSignInAccount? googleUser = await googleSignIn.signIn(); + + // Obtain the auth details from the request + final GoogleSignInAuthentication? googleAuth = + await googleUser?.authentication; + + // Create a new credential + final credential = GoogleAuthProvider.credential( + accessToken: googleAuth?.accessToken, + idToken: googleAuth?.idToken, + ); + + // Once signed in, return the UserCredential + return await FirebaseAuth.instance.signInWithCredential(credential); + } +} diff --git a/pubspec.lock b/pubspec.lock index 3a7b0a9..3a8bc73 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -1,6 +1,14 @@ # Generated by pub # See https://dart.dev/tools/pub/glossary#lockfile packages: + _flutterfire_internals: + dependency: transitive + description: + name: _flutterfire_internals + sha256: "3dee3db3468c5f4640a4e8aa9c1e22561c298976d8c39ed2fdd456a9a3db26e1" + url: "https://pub.dev" + source: hosted + version: "1.3.32" archive: dependency: transitive description: @@ -217,6 +225,30 @@ packages: url: "https://pub.dev" source: hosted version: "7.0.0" + firebase_auth: + dependency: "direct main" + description: + name: firebase_auth + sha256: "63b4401c95ddb00fb272872c451147e33509e80eed43937369910ef6c34c00b7" + url: "https://pub.dev" + source: hosted + version: "4.19.4" + firebase_auth_platform_interface: + dependency: transitive + description: + name: firebase_auth_platform_interface + sha256: "4e204f9ef43d83ac9e7a324a9317e4dd2a1ddda2aa72b67bc6cc364f0b8492dc" + url: "https://pub.dev" + source: hosted + version: "7.2.5" + firebase_auth_web: + dependency: transitive + description: + name: firebase_auth_web + sha256: "809a2eb444d1a07c0a680b205b86d713bc7171a4b2627fd6c01cf05f2b6f93cd" + url: "https://pub.dev" + source: hosted + version: "5.11.4" firebase_core: dependency: "direct main" description: @@ -302,14 +334,6 @@ packages: url: "https://pub.dev" source: hosted version: "0.6.5" - flutter_sticky_widgets: - dependency: "direct main" - description: - name: flutter_sticky_widgets - sha256: d0624d3aec3f6acc25993515073c82233efcd658fa5a94818a212da97ee02c6f - url: "https://pub.dev" - source: hosted - version: "0.0.3" flutter_test: dependency: "direct dev" description: flutter @@ -344,6 +368,54 @@ packages: url: "https://pub.dev" source: hosted version: "13.2.1" + google_identity_services_web: + dependency: transitive + description: + name: google_identity_services_web + sha256: "9482364c9f8b7bd36902572ebc3a7c2b5c8ee57a9c93e6eb5099c1a9ec5265d8" + url: "https://pub.dev" + source: hosted + version: "0.3.1+1" + google_sign_in: + dependency: "direct main" + description: + name: google_sign_in + sha256: "0b8787cb9c1a68ad398e8010e8c8766bfa33556d2ab97c439fb4137756d7308f" + url: "https://pub.dev" + source: hosted + version: "6.2.1" + google_sign_in_android: + dependency: transitive + description: + name: google_sign_in_android + sha256: "7647893c65e6720973f0e579051c8f84b877b486614d9f70a404259c41a4632e" + url: "https://pub.dev" + source: hosted + version: "6.1.23" + google_sign_in_ios: + dependency: transitive + description: + name: google_sign_in_ios + sha256: a058c9880be456f21e2e8571c1126eaacd570bdc5b6c6d9d15aea4bdf22ca9fe + url: "https://pub.dev" + source: hosted + version: "5.7.6" + google_sign_in_platform_interface: + dependency: transitive + description: + name: google_sign_in_platform_interface + sha256: "1f6e5787d7a120cc0359ddf315c92309069171306242e181c09472d1b00a2971" + url: "https://pub.dev" + source: hosted + version: "2.4.5" + google_sign_in_web: + dependency: transitive + description: + name: google_sign_in_web + sha256: fc0f14ed45ea616a6cfb4d1c7534c2221b7092cc4f29a709f0c3053cc3e821bd + url: "https://pub.dev" + source: hosted + version: "0.12.4" html: dependency: transitive description: diff --git a/pubspec.yaml b/pubspec.yaml index ab94e87..f376740 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -53,8 +53,11 @@ dependencies: cached_network_image: ^3.3.1 loading_animation_widget: ^1.2.1 font_awesome_flutter: ^10.7.0 - flutter_sticky_widgets: ^0.0.3 firebase_core: ^2.30.1 + google_sign_in: ^6.2.1 + firebase_auth: ^4.19.4 + + dev_dependencies: flutter_launcher_icons: ^0.13.1