Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Testing Rhevan+Alex #121

Merged
merged 27 commits into from
Sep 29, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
27 commits
Select commit Hold shift + click to select a range
cf5d5eb
Navbar test for Home Page working.
JimmyBee1 Sep 28, 2024
e2976ce
Home page Widget Working on Navbar Test.
JimmyBee1 Sep 28, 2024
f82b288
testing_rhevan: camera page widget tests
RhevanKruger Sep 29, 2024
394ab78
testing_rhevan: auth service unit testing
RhevanKruger Sep 29, 2024
f4569fe
testing_rhevan: log in page unit testing
RhevanKruger Sep 29, 2024
0c7d029
testing_rhevan: added SQL database testing
GerritPotgieter Sep 29, 2024
aafd79b
Merge remote-tracking branch 'origin/testing_rhevan' into testing_rhevan
GerritPotgieter Sep 29, 2024
6c2c567
Audio Integration
PineCone85 Sep 29, 2024
63a2633
testing_rhevan: added pubspec yaml dependancy for the database tests
GerritPotgieter Sep 29, 2024
331a4ff
testing_rhevan: sing up unit testing
RhevanKruger Sep 29, 2024
889756a
Merge remote-tracking branch 'origin/testing_rhevan' into testing_rhevan
RhevanKruger Sep 29, 2024
f7ca4b0
Navbar test for Home Page working.
JimmyBee1 Sep 28, 2024
c9dfe1c
Home page Widget Working on Navbar Test.
JimmyBee1 Sep 28, 2024
6edd44a
testing_rhevan: camera page widget tests
RhevanKruger Sep 29, 2024
ed8684e
testing_rhevan: auth service unit testing
RhevanKruger Sep 29, 2024
c4be430
testing_rhevan: log in page unit testing
RhevanKruger Sep 29, 2024
0511f30
testing_rhevan: sing up unit testing
RhevanKruger Sep 29, 2024
a2b8360
testing_rhevan: added SQL database testing
GerritPotgieter Sep 29, 2024
83810d4
Audio Integration
PineCone85 Sep 29, 2024
a27167a
testing_rhevan: added pubspec yaml dependancy for the database tests
GerritPotgieter Sep 29, 2024
4f2ba8e
Merge remote-tracking branch 'origin/testing_rhevan' into testing_rhevan
RhevanKruger Sep 29, 2024
14d65f6
testing_rhevan: non static spotify auth for testing
RhevanKruger Sep 29, 2024
553753c
testing_rhevan: user profile unit testing
RhevanKruger Sep 29, 2024
d179fca
testing_rhevan: user playlist testing
RhevanKruger Sep 29, 2024
7093ed7
Audio Integration
PineCone85 Sep 29, 2024
caeea9f
Audio Integration
PineCone85 Sep 29, 2024
105ae9d
Audio Integration
PineCone85 Sep 29, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
232 changes: 29 additions & 203 deletions frontend/lib/auth/auth_service.dart
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@

import 'dart:convert';
import 'dart:core';
import 'package:flutter/material.dart';
Expand All @@ -11,65 +10,16 @@ import 'dart:math';
import '/database/database.dart';
import 'package:intl/intl.dart';



class AuthService {
final FirebaseAuth _auth = FirebaseAuth.instance;
final GoogleSignIn googleSignIn = GoogleSignIn(
clientId:
'717450671046-s8e21c4eu14ebejnnc3varjpues2g2s2.apps.googleusercontent.com',
);

Future<Map<String, dynamic>?> getSpotifyUserDetails() async {
final String endpoint =
'https://api.spotify.com/v1/me'; // Replace with your backend endpoint
try {
final response = await http.get(Uri.parse(endpoint));
if (response.statusCode == 200) {
return jsonDecode(response.body);
} else {
print('Failed to load user details');
return null;
}
} catch (e) {
print('Error: $e');
return null;
}
}

Future<List<Map<String, dynamic>>?> getSpotifyPlaylists() async {
final String endpoint =
'http://localhost:5002/spotify-playlists'; // Replace with your backend endpoint

try {
final response = await http.get(Uri.parse(endpoint));
if (response.statusCode == 200) {
Map<String, dynamic> jsonResponse = jsonDecode(response.body);
List<dynamic> playlists = jsonResponse['items'];
List<Map<String, dynamic>> formattedPlaylists = playlists
.map((playlist) => {
'id': playlist['id'],
'name': playlist['name'],
'description': playlist['description'],
'image': playlist['images'].isNotEmpty
? playlist['images'][0]['url']
: null,
'owner': playlist['owner']['display_name'],
'tracks': playlist['tracks']['total'],
'public': playlist['public'],
'href': playlist['external_urls']['spotify'],
})
.toList();
return formattedPlaylists;
} else {
print('Failed to load Spotify playlists: ${response.statusCode}');
return null;
}
} catch (e) {
print('Error: $e');
return null;
}
}
final FirebaseAuth _auth;
final GoogleSignIn _googleSignIn;

// Constructor for dependency injection
AuthService({FirebaseAuth? auth, GoogleSignIn? googleSignIn})
: _auth = auth ?? FirebaseAuth.instance,
_googleSignIn = googleSignIn ?? GoogleSignIn(
clientId: '717450671046-s8e21c4eu14ebejnnc3varjpues2g2s2.apps.googleusercontent.com',
);

Future<String?> registration({
required String email,
Expand All @@ -78,50 +28,17 @@ class AuthService {
}) async {
try {
UserCredential userCredential =
await _auth.createUserWithEmailAndPassword(
email: email,
password: password,
);

await userCredential.user?.updateProfile(displayName: username);
await userCredential.user?.reload();
await _auth.createUserWithEmailAndPassword(email: email, password: password);

await _updateProfile(userCredential.user, username);
return 'Success';
} on FirebaseAuthException catch (e) {
if (e.code == 'weak-password') {
return 'The password provided is too weak.';
} else if (e.code == 'email-already-in-use') {
return 'The account already exists for that email.';
} else {
return e.message;
}
return _handleAuthException(e);
} catch (e) {
return e.toString();
}
}

Future<String?> signInWithGoogle() async {
try {
final GoogleSignInAccount? googleSignInAccount =
await googleSignIn.signIn();
if (googleSignInAccount != null) {
// final GoogleSignInAuthentication googleSignInAuthentication =
await googleSignInAccount.authentication;

// final AuthCredential credential = GoogleAuthProvider.credential(
// accessToken: googleSignInAuthentication.accessToken,
// idToken: googleSignInAuthentication.idToken,
// );

return 'Success';
} else {
// User cancelled Google sign-in
return 'Google sign-in cancelled.';
}
} catch (error) {
return error.toString();
}
}

Future<String?> login({
required String email,
Expand Down Expand Up @@ -170,40 +87,29 @@ class AuthService {
}
}

Future<void> authenticateWithSpotify(BuildContext context) async {
final url =
'https://accounts.spotify.com/authorize?client_id=4a35390dc3c74e85abfd35698529a7f8&response_type=code&redirect_uri=http://localhost:5001/callback&scope=user-read-email';

final result = await FlutterWebAuth.authenticate(
url: url,
callbackUrlScheme: 'myapp',
);

final code = Uri.parse(result).queryParameters['code'];

if (code != null) {
await _linkSpotifyAccountToFirebase(code);
ScaffoldMessenger.of(context).showSnackBar(SnackBar(
content: Text('Spotify account linked successfully!'),
));
} else {
ScaffoldMessenger.of(context).showSnackBar(SnackBar(
content: Text('Failed to link Spotify account.'),
));
Future<void> _updateProfile(User? user, String username) async {
if (user != null) {
await user.updateProfile(displayName: username);
await user.reload();
}
}

Future<void> _linkSpotifyAccountToFirebase(String code) async {
final User? user = FirebaseAuth.instance.currentUser;
final OAuthCredential credential = OAuthProvider('spotify.com').credential(
accessToken: code,
);
await user?.linkWithCredential(credential);
String? _handleAuthException(FirebaseAuthException e) {
switch (e.code) {
case 'weak-password':
return 'The password provided is too weak.';
case 'email-already-in-use':
return 'The account already exists for that email.';
case 'user-not-found':
return 'No user found for that email.';
case 'wrong-password':
return 'Wrong password provided for that user.';
default:
return e.message;
}
}
}



class SpotifyUser {
final String id;
final String displayName;
Expand Down Expand Up @@ -696,86 +602,6 @@ class SpotifyAuth {

}


//My Idea for PlaylistGeneration is to get a Users most listened to Artists and add their songs to the playlist
//then also add the spotify Recommendations

//Fetches Top Tracks of Artists from a Specific Genre
// static Future<List<String>> fetchTopTracks() async{
// if (_accessToken == null) {
// print('Access token is not available');
// return [];
// }
//
// List<String> trackIds = [];
//
// final String topArtistsEndpoint = 'https://api.spotify.com/v1/me/top/artists';
//
// try {
// final topArtistsResponse = await http.get(
// Uri.parse(topArtistsEndpoint),
// headers: {'Authorization': 'Bearer $_accessToken'},
// );
//
// if (topArtistsResponse.statusCode == 200) {
// // Parse the top artists
// final Map<String, dynamic> artistsData = jsonDecode(topArtistsResponse.body);
//
// //If Users does not listen to that Genre
// // bool flag = false;
//
// // Finding your most listened to artists of that genre
// List<String> artistC = [];
// int i = 0;
// final Map<String, dynamic> chosenArtist = {};
// if(selectedGenres != ''){
// for(Map<String, dynamic> g in artistsData['items']){
// if(g['genres'].contains(selectedGenres.toLowerCase())){
// chosenArtist.addAll(g);
// artistC[i] = g['id'];
// i++;
// // flag = true;
// }
// }
// }
//
// //Pulling Multiple Artists Top Tracks and adding it to the List
// for(int j = 0; j < i; j++){
//
// String artistID = artistC[j];
// final String artistsTopEndpoint = "https://api.spotify.com/v1/artists/$artistID/top-tracks";
//
// final topTracksResponse = await http.get(
// Uri.parse(artistsTopEndpoint),
// headers: {'Authorization': 'Bearer $_accessToken'},
// );
//
// if (topTracksResponse.statusCode == 200) {
// // Parse the top tracks
// final Map<String, dynamic> tracksData = jsonDecode(topTracksResponse.body);
// for (var track in tracksData['tracks']) {
// trackIds.add(track['id']);
// }
//
// // Return the combined object
// return trackIds;
// } else {
// print('Failed to fetch top tracks for artist');
// return [];
// }
// }
//
// } else {
// print('Failed to fetch top artists');
// return [];
// }
// } catch (e) {
// print('Error occurred: $e');
// return [];
// }
// return trackIds;
// }

//Filter the Top Artists Tracks based on the mood
static Future<List<String>> moodOfTrackIDs({
required List<String> tracks,
Expand Down
5 changes: 3 additions & 2 deletions frontend/lib/main.dart
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import 'package:frontend/pages/user_profile.dart';
import 'package:frontend/pages/link_spotify.dart';
import 'package:frontend/theme/theme_provider.dart';
import 'package:provider/provider.dart';
import 'auth/auth_service.dart';
import 'firebase_options.dart';
import 'package:frontend/pages/log_in.dart';
import 'package:frontend/pages/sing_up.dart';
Expand Down Expand Up @@ -61,8 +62,8 @@ class MyApp extends StatelessWidget {
initialRoute: '/',
routes: {
'/': (context) => const Welcome(),
'/signup': (context) => const SignUp(),
'/login': (context) => const LogIn(),
'/signup': (context) => SignUp(authService: AuthService(),),
'/login': (context) => LogIn(authService: AuthService(),),
'/userprofile': (context) => const UserProfile(),
'/linkspotify': (context) => const LinkSpotify(),
'/userplaylist': (context) => const PlaylistPage(),
Expand Down
2 changes: 2 additions & 0 deletions frontend/lib/pages/camera.dart
Original file line number Diff line number Diff line change
Expand Up @@ -360,6 +360,7 @@ class _CameraPageState extends State<CameraPage> {
),
),
IconButton(
key: Key('flipCamButton'),
icon: Icon(Icons.switch_camera_outlined),
color: Colors.white,
onPressed: _switchCamera,
Expand Down Expand Up @@ -388,6 +389,7 @@ class _CameraPageState extends State<CameraPage> {
),
),
IconButton(
key: Key('drawerButton'),
icon: Icon(Icons.tune_rounded),
color: Colors.white,
onPressed: () => Scaffold.of(context).openDrawer(), // Open the drawer
Expand Down
Loading
Loading