From 2c11b6f44aeac13174f8a6f5a214132271014e07 Mon Sep 17 00:00:00 2001 From: dadalmeida1 Date: Sat, 29 Jul 2023 18:07:38 +0200 Subject: [PATCH 1/8] startin working on auth flow --- .../android/app/google-services.json | 46 + .../ios/Runner/GoogleService-Info.plist | 34 + .../justMUSIC/ios/firebase_app_id_file.json | 7 + .../lib/components/login_button.dart | 6 +- Sources/justMUSIC/lib/firebase_options.dart | 76 ++ Sources/justMUSIC/lib/main.dart | 13 +- Sources/justMUSIC/lib/model/User.dart | 4 +- .../lib/model/mapper/UserMapper.dart | 36 + .../justMUSIC/lib/screens/login_screen.dart | 958 ++++++------------ .../lib/screens/registration_screen.dart | 6 +- .../justMUSIC/lib/service/AuthService.dart | 57 ++ .../justMUSIC/lib/service/UserService.dart | 15 + .../lib/view_model/UserViewModel.dart | 48 +- Sources/justMUSIC/pubspec.lock | 114 ++- Sources/justMUSIC/pubspec.yaml | 3 + 15 files changed, 744 insertions(+), 679 deletions(-) create mode 100644 Sources/justMUSIC/android/app/google-services.json create mode 100644 Sources/justMUSIC/ios/Runner/GoogleService-Info.plist create mode 100644 Sources/justMUSIC/ios/firebase_app_id_file.json create mode 100644 Sources/justMUSIC/lib/firebase_options.dart create mode 100644 Sources/justMUSIC/lib/model/mapper/UserMapper.dart create mode 100644 Sources/justMUSIC/lib/service/AuthService.dart create mode 100644 Sources/justMUSIC/lib/service/UserService.dart diff --git a/Sources/justMUSIC/android/app/google-services.json b/Sources/justMUSIC/android/app/google-services.json new file mode 100644 index 0000000..9fb09e0 --- /dev/null +++ b/Sources/justMUSIC/android/app/google-services.json @@ -0,0 +1,46 @@ +{ + "project_info": { + "project_number": "994903990520", + "project_id": "justmusic-435d5", + "storage_bucket": "justmusic-435d5.appspot.com" + }, + "client": [ + { + "client_info": { + "mobilesdk_app_id": "1:994903990520:android:02a445b6561bf2820a9b0d", + "android_client_info": { + "package_name": "com.example.justmusic" + } + }, + "oauth_client": [ + { + "client_id": "994903990520-rdk6ldrmbi71ddqt84qfhtuficm7ngon.apps.googleusercontent.com", + "client_type": 3 + } + ], + "api_key": [ + { + "current_key": "AIzaSyCjkofl0nvfzQqRZPv_-H99WoyYa7O660g" + } + ], + "services": { + "appinvite_service": { + "other_platform_oauth_client": [ + { + "client_id": "994903990520-9jsnq9ipdn7smk7tlbdd20i7j6sl3jcd.apps.googleusercontent.com", + "client_type": 3 + }, + { + "client_id": "994903990520-n6jd98ena56kb1tvtrd67tvb5et3nfbf.apps.googleusercontent.com", + "client_type": 2, + "ios_info": { + "bundle_id": "com.example.justmusic" + } + } + ] + } + } + } + ], + "configuration_version": "1" +} \ No newline at end of file diff --git a/Sources/justMUSIC/ios/Runner/GoogleService-Info.plist b/Sources/justMUSIC/ios/Runner/GoogleService-Info.plist new file mode 100644 index 0000000..cdb37d7 --- /dev/null +++ b/Sources/justMUSIC/ios/Runner/GoogleService-Info.plist @@ -0,0 +1,34 @@ + + + + + CLIENT_ID + 994903990520-n6jd98ena56kb1tvtrd67tvb5et3nfbf.apps.googleusercontent.com + REVERSED_CLIENT_ID + com.googleusercontent.apps.994903990520-n6jd98ena56kb1tvtrd67tvb5et3nfbf + API_KEY + AIzaSyBbYqsR6t7JTi8_XFNEHd43IRuKlYGeI3U + GCM_SENDER_ID + 994903990520 + PLIST_VERSION + 1 + BUNDLE_ID + com.example.justmusic + PROJECT_ID + justmusic-435d5 + STORAGE_BUCKET + justmusic-435d5.appspot.com + IS_ADS_ENABLED + + IS_ANALYTICS_ENABLED + + IS_APPINVITE_ENABLED + + IS_GCM_ENABLED + + IS_SIGNIN_ENABLED + + GOOGLE_APP_ID + 1:994903990520:ios:93188f32e320babe0a9b0d + + \ No newline at end of file diff --git a/Sources/justMUSIC/ios/firebase_app_id_file.json b/Sources/justMUSIC/ios/firebase_app_id_file.json new file mode 100644 index 0000000..ef1bedc --- /dev/null +++ b/Sources/justMUSIC/ios/firebase_app_id_file.json @@ -0,0 +1,7 @@ +{ + "file_generated_by": "FlutterFire CLI", + "purpose": "FirebaseAppID & ProjectID for this Firebase app in this directory", + "GOOGLE_APP_ID": "1:994903990520:ios:93188f32e320babe0a9b0d", + "FIREBASE_PROJECT_ID": "justmusic-435d5", + "GCM_SENDER_ID": "994903990520" +} \ No newline at end of file diff --git a/Sources/justMUSIC/lib/components/login_button.dart b/Sources/justMUSIC/lib/components/login_button.dart index 3e41e8e..1d794dd 100644 --- a/Sources/justMUSIC/lib/components/login_button.dart +++ b/Sources/justMUSIC/lib/components/login_button.dart @@ -3,7 +3,9 @@ import 'package:flutter/material.dart'; import 'package:flutter_screenutil/flutter_screenutil.dart'; class LoginButton extends StatefulWidget { - const LoginButton({Key? key}) : super(key: key); + final Function callback; + + const LoginButton({Key? key, required this.callback}) : super(key: key); @override State createState() => _LoginButtonState(); @@ -14,7 +16,7 @@ class _LoginButtonState extends State { Widget build(BuildContext context) { return ElevatedButton( onPressed: () { - Navigator.pushNamed(context, '/explanation'); + widget.callback(); }, style: ButtonStyle( backgroundColor: MaterialStateProperty.all(Color(0xFF1C1C1C)), diff --git a/Sources/justMUSIC/lib/firebase_options.dart b/Sources/justMUSIC/lib/firebase_options.dart new file mode 100644 index 0000000..bfc6ec0 --- /dev/null +++ b/Sources/justMUSIC/lib/firebase_options.dart @@ -0,0 +1,76 @@ +// File generated by FlutterFire CLI. +// ignore_for_file: lines_longer_than_80_chars, avoid_classes_with_only_static_members +import 'package:firebase_core/firebase_core.dart' show FirebaseOptions; +import 'package:flutter/foundation.dart' + show defaultTargetPlatform, kIsWeb, TargetPlatform; + +/// Default [FirebaseOptions] for use with your Firebase apps. +/// +/// Example: +/// ```dart +/// import 'firebase_options.dart'; +/// // ... +/// await Firebase.initializeApp( +/// options: DefaultFirebaseOptions.currentPlatform, +/// ); +/// ``` +class DefaultFirebaseOptions { + static FirebaseOptions get currentPlatform { + if (kIsWeb) { + return web; + } + switch (defaultTargetPlatform) { + case TargetPlatform.android: + return android; + case TargetPlatform.iOS: + return ios; + case TargetPlatform.macOS: + throw UnsupportedError( + 'DefaultFirebaseOptions have not been configured for macos - ' + 'you can reconfigure this by running the FlutterFire CLI again.', + ); + case TargetPlatform.windows: + throw UnsupportedError( + 'DefaultFirebaseOptions have not been configured for windows - ' + 'you can reconfigure this by running the FlutterFire CLI again.', + ); + case TargetPlatform.linux: + throw UnsupportedError( + 'DefaultFirebaseOptions have not been configured for linux - ' + 'you can reconfigure this by running the FlutterFire CLI again.', + ); + default: + throw UnsupportedError( + 'DefaultFirebaseOptions are not supported for this platform.', + ); + } + } + + static const FirebaseOptions web = FirebaseOptions( + apiKey: 'AIzaSyBv-Sba07nFFhctn6c3ARyvi9RfYwEKoNA', + appId: '1:994903990520:web:724c75003432ddbc0a9b0d', + messagingSenderId: '994903990520', + projectId: 'justmusic-435d5', + authDomain: 'justmusic-435d5.firebaseapp.com', + storageBucket: 'justmusic-435d5.appspot.com', + measurementId: 'G-D4YRLXK9TQ', + ); + + static const FirebaseOptions android = FirebaseOptions( + apiKey: 'AIzaSyCjkofl0nvfzQqRZPv_-H99WoyYa7O660g', + appId: '1:994903990520:android:02a445b6561bf2820a9b0d', + messagingSenderId: '994903990520', + projectId: 'justmusic-435d5', + storageBucket: 'justmusic-435d5.appspot.com', + ); + + static const FirebaseOptions ios = FirebaseOptions( + apiKey: 'AIzaSyBbYqsR6t7JTi8_XFNEHd43IRuKlYGeI3U', + appId: '1:994903990520:ios:93188f32e320babe0a9b0d', + messagingSenderId: '994903990520', + projectId: 'justmusic-435d5', + storageBucket: 'justmusic-435d5.appspot.com', + iosClientId: '994903990520-n6jd98ena56kb1tvtrd67tvb5et3nfbf.apps.googleusercontent.com', + iosBundleId: 'com.example.justmusic', + ); +} diff --git a/Sources/justMUSIC/lib/main.dart b/Sources/justMUSIC/lib/main.dart index 1203f32..283502a 100644 --- a/Sources/justMUSIC/lib/main.dart +++ b/Sources/justMUSIC/lib/main.dart @@ -1,3 +1,4 @@ +import 'package:cloud_firestore/cloud_firestore.dart'; import 'package:flutter/material.dart'; import 'package:flutter/services.dart'; import 'package:flutter_screenutil/flutter_screenutil.dart'; @@ -10,12 +11,20 @@ import 'package:justmusic/screens/registration_screen.dart'; import 'package:justmusic/screens/welcome_screen.dart'; import 'package:justmusic/view_model/MusicViewModel.dart'; import 'package:justmusic/view_model/UserViewModel.dart'; +import 'package:firebase_core/firebase_core.dart'; +import 'firebase_options.dart'; -void main() { +Future main() async { + WidgetsFlutterBinding.ensureInitialized(); + await Firebase.initializeApp( + options: DefaultFirebaseOptions.currentPlatform, + ); runApp(const MyApp()); } class MyApp extends StatelessWidget { + // ugly as fuck + static FirebaseFirestore db = FirebaseFirestore.instance; static UserViewModel userViewModel = UserViewModel(); static MusicViewModel musicViewModel = MusicViewModel(); @@ -51,7 +60,7 @@ class MyApp extends StatelessWidget { // is not restarted. primarySwatch: Colors.blue, ), - home: WellcomeScreen()); + home: LoginScreen()); }, designSize: Size(390, 844), ); diff --git a/Sources/justMUSIC/lib/model/User.dart b/Sources/justMUSIC/lib/model/User.dart index f601867..f53996b 100644 --- a/Sources/justMUSIC/lib/model/User.dart +++ b/Sources/justMUSIC/lib/model/User.dart @@ -1,5 +1,5 @@ class User { - final int _id; + final String _id; String _pseudo; String _country; String _mail; @@ -14,7 +14,7 @@ class User { this._followers, this._capsules, this._followed, this.friends); //Getters and setters - int get id => _id; + String get id => _id; String get pseudo => _pseudo; diff --git a/Sources/justMUSIC/lib/model/mapper/UserMapper.dart b/Sources/justMUSIC/lib/model/mapper/UserMapper.dart new file mode 100644 index 0000000..25a8900 --- /dev/null +++ b/Sources/justMUSIC/lib/model/mapper/UserMapper.dart @@ -0,0 +1,36 @@ +import 'package:cloud_firestore/cloud_firestore.dart'; +import 'package:justmusic/model/User.dart'; +import 'package:firebase_auth/firebase_auth.dart' as firebase_auth; +import '../../main.dart'; + +class UserMapper { + static User? toModel(DocumentSnapshot>? snapshot, + SnapshotOptions? options) { + if (snapshot == null) { + return null; + } + final data = snapshot.data(); + return User( + data?["uid"], + data?["pseudo"], + data?["country"], + data?["mail"], + data?["profilePicture"], + data?["followers"] as int, + data?["nbCapsules"] as int, + data?["followed"] as int, + data?['friends'] is Iterable ? List.from(data?['friends']) : []); + } +/* + static Map toFirebase(User user) { + return { + if (user.pseudo != null) "name": u, + if (user.country != null) "state": state, + if (user.mail != null) "country": country, + if (user.pp != null) "capital": capital, + if (user.followers != null) "population": population, + if (user.capsules != null) "regions": regions, + if () + }; + }*/ +} diff --git a/Sources/justMUSIC/lib/screens/login_screen.dart b/Sources/justMUSIC/lib/screens/login_screen.dart index 778d76d..58b52f4 100644 --- a/Sources/justMUSIC/lib/screens/login_screen.dart +++ b/Sources/justMUSIC/lib/screens/login_screen.dart @@ -1,9 +1,11 @@ import 'package:flutter/cupertino.dart'; import 'package:flutter/material.dart'; +import 'package:flutter/services.dart'; import 'package:flutter_screenutil/flutter_screenutil.dart'; import 'package:flutter_signin_button/button_list.dart'; import 'package:flutter_signin_button/button_view.dart'; import 'package:google_fonts/google_fonts.dart'; +import 'package:justmusic/main.dart'; import 'package:justmusic/values/constants.dart'; import '../components/login_button.dart'; @@ -18,6 +20,32 @@ class LoginScreen extends StatefulWidget { class _LoginScreenState extends State { bool passenable = true; final _formKey = GlobalKey(); + final _userMailTextField = TextEditingController(); + final _passwordTextField = TextEditingController(); + + handleLogin() async { + if (_formKey.currentState!.validate()) { + try { + await MyApp.userViewModel + .login(_userMailTextField.text, _passwordTextField.text); + Navigator.pushNamed(context, '/explanation'); + } catch (e) { + print(e); + ScaffoldMessenger.of(context).showSnackBar( + SnackBar( + content: Text( + e.toString(), + style: GoogleFonts.plusJakartaSans( + color: Colors.white, + fontWeight: FontWeight.w400, + fontSize: 20.h), + ), + backgroundColor: Colors.red, + ), + ); + } + } + } @override Widget build(BuildContext context) { @@ -26,684 +54,312 @@ class _LoginScreenState extends State { child: Scaffold( resizeToAvoidBottomInset: false, backgroundColor: bgColor, - body: LayoutBuilder( - builder: (context, constraints) { - if (constraints.maxHeight >= 740) { - return Align( - child: SizedBox( - height: double.infinity, - width: 600, - child: Column( - mainAxisAlignment: MainAxisAlignment.center, - children: [ - Expanded( - child: Padding( - padding: - EdgeInsets.only(left: 40, right: 40), - child: Form( - key: _formKey, + body: Align( + child: SizedBox( + height: double.infinity, + width: 600, + child: Column( + mainAxisAlignment: MainAxisAlignment.center, + children: [ + Expanded( + child: Padding( + padding: EdgeInsets.only(left: 40, right: 40), + child: Form( + key: _formKey, + child: Column( + crossAxisAlignment: + CrossAxisAlignment.center, + children: [ + Flexible( + flex: 5, + child: Padding( + padding: EdgeInsets.only(bottom: 60), + child: Column( + mainAxisAlignment: + MainAxisAlignment.end, + children: [ + Text( + "Te revoilà!", + style: + GoogleFonts.plusJakartaSans( + color: Colors.white, + fontWeight: + FontWeight.w600, + fontSize: 38.h), + ), + SizedBox( + height: 10, + ), + SizedBox( + width: 230.w, + child: Text( + "Bon retour parmis nous tu nous as manqué!", + style: GoogleFonts + .plusJakartaSans( + color: Colors.white, + fontWeight: + FontWeight.w400, + fontSize: 20.h), + textAlign: TextAlign.center, + ), + ), + ], + ), + ), + ), + Expanded( + flex: 4, child: Column( crossAxisAlignment: - CrossAxisAlignment.center, + CrossAxisAlignment.end, children: [ - Flexible( - flex: 5, - child: Padding( - padding: - EdgeInsets.only(bottom: 60), - child: Column( - mainAxisAlignment: - MainAxisAlignment.end, - children: [ - Text( - "Te revoilà!", - style: GoogleFonts - .plusJakartaSans( - color: - Colors.white, - fontWeight: - FontWeight - .w600, - fontSize: 38.h), - ), - SizedBox( - height: 10, - ), - SizedBox( - width: 230.w, - child: Text( - "Bon retour parmis nous tu nous as manqué!", - style: GoogleFonts - .plusJakartaSans( - color: Colors - .white, - fontWeight: - FontWeight - .w400, - fontSize: 20.h), - textAlign: - TextAlign.center, - ), - ), - ], - ), - ), + TextFormField( + controller: _userMailTextField, + keyboardAppearance: + Brightness.dark, + validator: (value) { + if (value == null || + value.isEmpty) { + return 'entrez un email valide'; + } + return null; + }, + cursorColor: primaryColor, + keyboardType: + TextInputType.emailAddress, + style: + GoogleFonts.plusJakartaSans( + color: primaryColor), + decoration: InputDecoration( + focusedBorder: OutlineInputBorder( + borderSide: BorderSide( + width: 1, + color: + strokeTextField), + borderRadius: BorderRadius.all( + Radius.circular(10))), + contentPadding: + EdgeInsets.only( + top: 0, + bottom: 0, + left: defaultPadding), + fillColor: bgTextField, + filled: true, + focusColor: Color.fromRGBO( + 255, 255, 255, 0.30), + enabledBorder: OutlineInputBorder( + borderSide: BorderSide( + width: 1, + color: + strokeTextField), + borderRadius: BorderRadius.all( + Radius.circular(10))), + hintText: 'Email', + hintStyle: + GoogleFonts.plusJakartaSans(color: strokeTextField)), ), - Expanded( - flex: 4, - child: Column( - crossAxisAlignment: - CrossAxisAlignment.end, - children: [ - TextFormField( - keyboardAppearance: - Brightness.dark, - validator: (value) { - if (value == null || - value.isEmpty) { - return 'TODO'; - } - return null; - }, - cursorColor: primaryColor, - keyboardType: - TextInputType - .emailAddress, - style: GoogleFonts - .plusJakartaSans( - color: - primaryColor), - decoration: InputDecoration( - focusedBorder: OutlineInputBorder( - borderSide: BorderSide( - width: 1, - color: - strokeTextField), - borderRadius: - BorderRadius.all( - Radius.circular( - 10))), - contentPadding: - EdgeInsets.only( - top: 0, - bottom: 0, - left: - defaultPadding), - fillColor: - bgTextField, - filled: true, - focusColor: Color.fromRGBO( - 255, 255, 255, 0.30), - enabledBorder: OutlineInputBorder( - borderSide: BorderSide( - width: 1, - color: - strokeTextField), - borderRadius: - BorderRadius.all(Radius.circular(10))), - hintText: 'Email', - hintStyle: GoogleFonts.plusJakartaSans(color: strokeTextField)), - ), - SizedBox( - height: 18, - ), - TextFormField( - keyboardAppearance: - Brightness.dark, - obscureText: passenable, - validator: (value) { - if (value == null || - value.isEmpty) { - return 'TODO'; - } - return null; + SizedBox( + height: 18, + ), + TextFormField( + controller: _passwordTextField, + keyboardAppearance: + Brightness.dark, + obscureText: passenable, + validator: (value) { + if (value == null || + value.isEmpty) { + return 'entrez un mot de passe valide'; + } + return null; + }, + cursorColor: primaryColor, + keyboardType: + TextInputType.emailAddress, + style: + GoogleFonts.plusJakartaSans( + color: primaryColor), + decoration: InputDecoration( + focusedBorder: + OutlineInputBorder( + borderSide: BorderSide( + width: 1, + color: + strokeTextField), + borderRadius: + BorderRadius.all( + Radius.circular( + 10))), + contentPadding: EdgeInsets.only( + top: 0, + bottom: 0, + left: defaultPadding), + fillColor: bgTextField, + filled: true, + focusColor: Color.fromRGBO( + 255, 255, 255, 0.30), + enabledBorder: + OutlineInputBorder( + borderSide: BorderSide( + width: 1, + color: + strokeTextField), + borderRadius: + BorderRadius.all( + Radius.circular( + 10))), + hintText: 'Mot de passe', + hintStyle: + GoogleFonts.plusJakartaSans( + color: strokeTextField), + suffixIcon: Container( + padding: EdgeInsets.only( + right: 10), + margin: EdgeInsets.all(5), + height: 3, + child: InkWell( + onTap: () { + setState(() { + if (passenable) { + passenable = false; + } else { + passenable = true; + } + }); }, - cursorColor: primaryColor, - keyboardType: - TextInputType - .emailAddress, - style: GoogleFonts - .plusJakartaSans( - color: - primaryColor), - decoration: - InputDecoration( - focusedBorder: OutlineInputBorder( - borderSide: BorderSide( - width: 1, - color: - strokeTextField), - borderRadius: - BorderRadius - .all(Radius - .circular( - 10))), - contentPadding: - EdgeInsets.only( - top: 0, - bottom: 0, - left: - defaultPadding), - fillColor: bgTextField, - filled: true, - focusColor: - Color.fromRGBO(255, - 255, 255, 0.30), - enabledBorder: OutlineInputBorder( - borderSide: BorderSide( - width: 1, - color: - strokeTextField), - borderRadius: - BorderRadius - .all(Radius - .circular( - 10))), - hintText: - 'Mot de passe', - hintStyle: GoogleFonts - .plusJakartaSans( - color: - strokeTextField), - suffixIcon: Container( - padding: - EdgeInsets.only( - right: 10), - margin: - EdgeInsets.all( - 5), - height: 3, - child: InkWell( - onTap: () { - setState(() { - if (passenable) { - passenable = - false; - } else { - passenable = - true; - } - }); - }, // Image tapped - splashColor: Colors - .white10, // Splash color over image - child: Image( - image: passenable - ? AssetImage( - "assets/images/show_icon.png") - : AssetImage( - "assets/images/hide_icon.png"), - height: 2, - ), - )), + // Image tapped + splashColor: + Colors.white10, + // Splash color over image + child: Image( + image: passenable + ? AssetImage( + "assets/images/show_icon.png") + : AssetImage( + "assets/images/hide_icon.png"), + height: 2, ), - ), - Padding( - padding: EdgeInsets.only( - top: 10), - child: Text( - "Mot de passe oublié?", - style: GoogleFonts - .plusJakartaSans( - color: Colors - .white), - ), - ), - SizedBox( - height: defaultPadding, - ), - SizedBox( - width: 600, - child: LoginButton()), - ], + )), + ), + ), + Padding( + padding: EdgeInsets.only(top: 10), + child: Text( + "Mot de passe oublié?", + style: + GoogleFonts.plusJakartaSans( + color: Colors.white), + ), + ), + SizedBox( + height: defaultPadding, + ), + SizedBox( + width: 600, + child: LoginButton( + callback: handleLogin, )), - Expanded( - flex: 3, - child: Padding( - padding: - EdgeInsets.only(top: 20), - child: Column( + ], + ), + ), + Expanded( + flex: 3, + child: Padding( + padding: EdgeInsets.only(top: 20), + child: Column( + mainAxisAlignment: + MainAxisAlignment.start, + crossAxisAlignment: + CrossAxisAlignment.center, + children: [ + ConstrainedBox( + constraints: BoxConstraints( + maxWidth: 600), + child: Row( mainAxisAlignment: - MainAxisAlignment.start, - crossAxisAlignment: - CrossAxisAlignment - .center, + MainAxisAlignment + .spaceEvenly, children: [ - ConstrainedBox( - constraints: - BoxConstraints( - maxWidth: 600), - child: Row( - mainAxisAlignment: - MainAxisAlignment - .spaceEvenly, - children: [ - Expanded( - child: Container( - color: Color( - 0xFF3D3D3D), - height: 1, - ), - ), - Padding( - padding: const EdgeInsets - .only( - left: - defaultPadding, - right: - defaultPadding), - child: Text( - 'Ou', - style: GoogleFonts.plusJakartaSans( - color: Colors - .white, - fontWeight: - FontWeight - .bold), - ), - ), - Expanded( - child: - Container( - height: 1, - color: Color( - 0xFF3D3D3D), - )), - ], + Expanded( + child: Container( + color: + Color(0xFF3D3D3D), + height: 1, ), ), - SizedBox( - height: - defaultPadding), - SignInButton( - Buttons.Google, - text: - "Login with Google", - onPressed: () {}, - ), Padding( - padding: - EdgeInsets.only( - top: 20), - child: RichText( - textAlign: - TextAlign.center, - text: TextSpan( - text: - 'Pas encore inscrit?', - style: GoogleFonts - .plusJakartaSans( - color: Colors - .white, - fontWeight: - FontWeight - .w400, - fontSize: - 13), - children: < - TextSpan>[ - TextSpan( - text: - " S’inscire", - style: GoogleFonts.plusJakartaSans( - fontSize: - 13, - fontWeight: - FontWeight - .w400, - color: - primaryColor)), - ], - ), + padding: const EdgeInsets + .only( + left: + defaultPadding, + right: + defaultPadding), + child: Text( + 'Ou', + style: GoogleFonts + .plusJakartaSans( + color: Colors + .white, + fontWeight: + FontWeight + .bold), ), - ) + ), + Expanded( + child: Container( + height: 1, + color: + Color(0xFF3D3D3D), + )), ], ), - )) - ], - )))) - ], - )), - ); - } else { - return Align( - child: SizedBox( - height: double.infinity, - width: 600, - child: Column( - mainAxisAlignment: MainAxisAlignment.center, - children: [ - Expanded( - child: Padding( - padding: - EdgeInsets.only(left: 40, right: 40), - child: Form( - key: _formKey, - child: Column( - crossAxisAlignment: - CrossAxisAlignment.center, - children: [ - Flexible( - flex: 2, - child: Padding( - padding: - EdgeInsets.only(bottom: 30), - child: Column( - mainAxisAlignment: - MainAxisAlignment.end, - children: [ - Text( - "Te revoilà!", + ), + SizedBox( + height: defaultPadding), + SignInButton( + Buttons.Google, + text: "Login with Google", + onPressed: () {}, + ), + Padding( + padding: + EdgeInsets.only(top: 20), + child: RichText( + textAlign: TextAlign.center, + text: TextSpan( + text: + 'Pas encore inscrit?', style: GoogleFonts .plusJakartaSans( color: Colors.white, fontWeight: FontWeight - .w600, - fontSize: 38.h), - ), - SizedBox( - height: 10, - ), - SizedBox( - width: 230, - child: Text( - "Bon retour parmis nous tu nous as manqué!", - style: GoogleFonts - .plusJakartaSans( - color: Colors - .white, - fontWeight: - FontWeight - .w400, - fontSize: 20.h), - textAlign: - TextAlign.center, - ), - ), - ], - ), - ), - ), - Expanded( - flex: 4, - child: Column( - crossAxisAlignment: - CrossAxisAlignment.end, - children: [ - TextFormField( - keyboardAppearance: - Brightness.dark, - validator: (value) { - if (value == null || - value.isEmpty) { - return 'TODO'; - } - return null; - }, - cursorColor: primaryColor, - keyboardType: - TextInputType - .emailAddress, - style: GoogleFonts - .plusJakartaSans( - color: - primaryColor), - decoration: InputDecoration( - focusedBorder: OutlineInputBorder( - borderSide: BorderSide( - width: 1, - color: - strokeTextField), - borderRadius: - BorderRadius.all( - Radius.circular( - 10))), - contentPadding: - EdgeInsets.only( - top: 0, - bottom: 0, - left: - defaultPadding), - fillColor: - bgTextField, - filled: true, - focusColor: Color.fromRGBO( - 255, 255, 255, 0.30), - enabledBorder: OutlineInputBorder( - borderSide: BorderSide( - width: 1, - color: - strokeTextField), - borderRadius: - BorderRadius.all(Radius.circular(10))), - hintText: 'Email', - hintStyle: GoogleFonts.plusJakartaSans(color: strokeTextField, fontSize: 15)), - ), - SizedBox( - height: 18, - ), - TextFormField( - keyboardAppearance: - Brightness.dark, - obscureText: passenable, - validator: (value) { - if (value == null || - value.isEmpty) { - return 'TODO'; - } - return null; - }, - cursorColor: primaryColor, - keyboardType: - TextInputType - .emailAddress, - style: GoogleFonts - .plusJakartaSans( - color: - primaryColor), - decoration: - InputDecoration( - focusedBorder: OutlineInputBorder( - borderSide: BorderSide( - width: 1, - color: - strokeTextField), - borderRadius: - BorderRadius - .all(Radius - .circular( - 10))), - contentPadding: - EdgeInsets.only( - top: 0, - bottom: 0, - left: - defaultPadding), - fillColor: bgTextField, - filled: true, - focusColor: - Color.fromRGBO(255, - 255, 255, 0.30), - enabledBorder: OutlineInputBorder( - borderSide: BorderSide( - width: 1, - color: - strokeTextField), - borderRadius: - BorderRadius - .all(Radius - .circular( - 10))), - hintText: - 'Mot de passe', - hintStyle: GoogleFonts - .plusJakartaSans( - color: - strokeTextField), - suffixIcon: Container( - padding: - EdgeInsets.only( - right: 10), - margin: - EdgeInsets.all( - 5), - height: 3, - child: InkWell( - onTap: () { - setState(() { - if (passenable) { - passenable = - false; - } else { - passenable = - true; - } - }); - }, // Image tapped - splashColor: Colors - .white10, // Splash color over image - child: Image( - image: passenable - ? AssetImage( - "assets/images/show_icon.png") - : AssetImage( - "assets/images/hide_icon.png"), - height: 2, - ), - )), - ), - ), - Padding( - padding: EdgeInsets.only( - top: 10.h), - child: Text( - "Mot de passe oublié?", - style: GoogleFonts - .plusJakartaSans( - color: Colors - .white), - ), - ), - SizedBox( - height: defaultPadding, - ), - SizedBox( - width: 600, - child: LoginButton()), - ], - )), - Expanded( - flex: 3, - child: Padding( - padding: - EdgeInsets.only(top: 20), - child: Column( - mainAxisAlignment: - MainAxisAlignment.start, - crossAxisAlignment: - CrossAxisAlignment - .center, - children: [ - ConstrainedBox( - constraints: - BoxConstraints( - maxWidth: 600), - child: Row( - mainAxisAlignment: - MainAxisAlignment - .spaceEvenly, - children: [ - Expanded( - child: Container( - color: Color( - 0xFF3D3D3D), - height: 1, - ), - ), - Padding( - padding: const EdgeInsets - .only( - left: - defaultPadding, - right: - defaultPadding), - child: Text( - 'Ou', - style: GoogleFonts.plusJakartaSans( - color: Colors - .white, - fontWeight: - FontWeight - .bold), - ), - ), - Expanded( - child: - Container( - height: 1, - color: Color( - 0xFF3D3D3D), - )), - ], - ), - ), - SizedBox( - height: - defaultPadding), - SignInButton( - Buttons.Google, - text: - "Login with Google", - onPressed: () {}, - ), - Padding( - padding: - EdgeInsets.only( - top: 20), - child: RichText( - textAlign: - TextAlign.center, - text: TextSpan( - text: - 'Pas encore inscrit?', + .w400, + fontSize: 13), + children: [ + TextSpan( + text: " S’inscire", style: GoogleFonts .plusJakartaSans( - color: Colors - .white, + fontSize: + 13, fontWeight: FontWeight .w400, - fontSize: - 13), - children: < - TextSpan>[ - TextSpan( - text: - " S’inscire", - style: GoogleFonts.plusJakartaSans( - fontSize: - 13, - fontWeight: - FontWeight - .w400, - color: - primaryColor)), - ], - ), - ), - ) - ], + color: + primaryColor)), + ], + ), ), - )) - ], - )))) - ], - )), - ); - } - }, + ) + ], + ), + )) + ], + )))) + ], + )), ))); } } diff --git a/Sources/justMUSIC/lib/screens/registration_screen.dart b/Sources/justMUSIC/lib/screens/registration_screen.dart index 679fd11..ff62533 100644 --- a/Sources/justMUSIC/lib/screens/registration_screen.dart +++ b/Sources/justMUSIC/lib/screens/registration_screen.dart @@ -286,7 +286,11 @@ class _RegistrationScreenState extends State { Padding( padding: EdgeInsets.symmetric(horizontal: defaultPadding), - child: SizedBox(width: 600, child: LoginButton()), + child: SizedBox( + width: 600, + child: LoginButton( + callback: () {}, + )), ), ], )), diff --git a/Sources/justMUSIC/lib/service/AuthService.dart b/Sources/justMUSIC/lib/service/AuthService.dart new file mode 100644 index 0000000..0baefe0 --- /dev/null +++ b/Sources/justMUSIC/lib/service/AuthService.dart @@ -0,0 +1,57 @@ +import 'package:cloud_firestore/cloud_firestore.dart'; + +import '../model/User.dart'; +import 'package:firebase_auth/firebase_auth.dart'; +import '../main.dart'; + +class AuthService { + register(String pseudo, String email, String password) async { + try { + final data = await FirebaseAuth.instance.createUserWithEmailAndPassword( + email: email, + password: password, + ); + + final user = { + "mail": email, + "pseudo": pseudo, + "phone_number": "", + "picture": + "https://media.licdn.com/dms/image/D4E03AQHvc_b89ogFtQ/profile-displayphoto-shrink_400_400/0/1665060931103?e=1695859200&v=beta&t=wVLbxqeokYiPJ13nJ3SMq97iZvcm3ra0ufWFZCSzhjg", + "friends": [] + }; + + MyApp.db + .collection("users") + .doc(data.user?.uid) + .set(user) + .then((value) => print("User Added")) + .catchError((error) => print("Failed to add user: $error")); + } on FirebaseAuthException catch (e) { + if (e.code == 'weak-password') { + throw ('The password provided is too weak.'); + } else if (e.code == 'email-already-in-use') { + throw ('The account already exists for that email.'); + } + } catch (e) { + throw (e); + } + } + + login(String email, String password) async { + try { + await FirebaseAuth.instance + .signInWithEmailAndPassword(email: email, password: password); + } on FirebaseAuthException catch (e) { + if (e.code == 'user-not-found') { + throw ('No user found for that email.'); + } else if (e.code == 'wrong-password') { + throw ('Wrong password provided for that user.'); + } + } + } + + void signOut() async { + await FirebaseAuth.instance.signOut(); + } +} diff --git a/Sources/justMUSIC/lib/service/UserService.dart b/Sources/justMUSIC/lib/service/UserService.dart new file mode 100644 index 0000000..b60cd92 --- /dev/null +++ b/Sources/justMUSIC/lib/service/UserService.dart @@ -0,0 +1,15 @@ +import 'package:cloud_firestore/cloud_firestore.dart'; + +import '../model/User.dart'; +import '../main.dart'; + +class UserService { + acceptFriend(User user, String idFriend) { + MyApp.db.collection("users").doc(user.id).update({ + "friends": FieldValue.arrayUnion([idFriend]) + }); + MyApp.db.collection("users").doc(idFriend).update({ + "friends": FieldValue.arrayUnion([user.id]) + }); + } +} diff --git a/Sources/justMUSIC/lib/view_model/UserViewModel.dart b/Sources/justMUSIC/lib/view_model/UserViewModel.dart index 2aaa1fb..d4bbfa7 100644 --- a/Sources/justMUSIC/lib/view_model/UserViewModel.dart +++ b/Sources/justMUSIC/lib/view_model/UserViewModel.dart @@ -1,8 +1,14 @@ +import 'package:cloud_firestore/cloud_firestore.dart'; +import 'package:firebase_auth/firebase_auth.dart' as firebase_auth; +import 'package:justmusic/service/AuthService.dart'; + import '../model/User.dart'; +import '../model/mapper/UserMapper.dart'; +import '../main.dart'; class UserViewModel { - User _userCurrent = User( - 1, "MelinaShow", "France", "test@gmail.com", "zezrzrzr", 5, 12, 114, []); + late User _userCurrent; + final AuthService _authService = AuthService(); User get userCurrent => _userCurrent; @@ -13,7 +19,41 @@ class UserViewModel { UserViewModel(); // Methods - User getUser(int id) { - throw new Error(); + Future getUser(String id) async { + final user = await MyApp.db.collection("users").doc(id).get(); + return UserMapper.toModel(user, null); + } + + login(String pseudo, String password) async { + await _authService.login(pseudo, password); + if (firebase_auth.FirebaseAuth.instance.currentUser == null) { + throw Exception("User login failed"); + } + final user = await MyApp.db + .collection("users") + .doc(firebase_auth.FirebaseAuth.instance.currentUser?.uid) + .get(); + User? data = UserMapper.toModel(user, null); + if (data == null) { + throw Exception("User login failed"); + } + _userCurrent = data; + } + + register(String pseudo, String password, String email) async { + _authService.register(pseudo, email, password); + final user = await MyApp.db + .collection("users") + .doc(firebase_auth.FirebaseAuth.instance.currentUser?.uid) + .get(); + User? data = UserMapper.toModel(user, null); + if (data == null) { + throw Exception("User register failed"); + } + _userCurrent = data; + } + + logout() { + _authService.signOut(); } } diff --git a/Sources/justMUSIC/pubspec.lock b/Sources/justMUSIC/pubspec.lock index 685a4a9..979c119 100644 --- a/Sources/justMUSIC/pubspec.lock +++ b/Sources/justMUSIC/pubspec.lock @@ -1,14 +1,22 @@ # Generated by pub # See https://dart.dev/tools/pub/glossary#lockfile packages: + _flutterfire_internals: + dependency: transitive + description: + name: _flutterfire_internals + sha256: "5dce45a06d386358334eb1689108db6455d90ceb0d75848d5f4819283d4ee2b8" + url: "https://pub.dev" + source: hosted + version: "1.3.4" async: dependency: transitive description: name: async - sha256: bfe67ef28df125b7dddcea62755991f807aa39a2492a23e1550161692950bbe0 + sha256: "947bfcf187f74dbc5e146c9eb9c0f10c9f8b30743e341481c1e2ed3ecc18c20c" url: "https://pub.dev" source: hosted - version: "2.10.0" + version: "2.11.0" audioplayers: dependency: "direct main" description: @@ -85,10 +93,10 @@ packages: dependency: transitive description: name: characters - sha256: e6a326c8af69605aec75ed6c187d06b349707a27fbff8222ca9cc2cff167975c + sha256: "04a925763edad70e8443c99234dc3328f442e811f1d8fd1a72f1c8ad0f69a605" url: "https://pub.dev" source: hosted - version: "1.2.1" + version: "1.3.0" circular_reveal_animation: dependency: "direct main" description: @@ -105,14 +113,38 @@ packages: url: "https://pub.dev" source: hosted version: "1.1.1" + cloud_firestore: + dependency: "direct main" + description: + name: cloud_firestore + sha256: f1a06ad4499ed9ab73703560d44893e6b9e66ce3923c9121f4ef3981c972057f + url: "https://pub.dev" + source: hosted + version: "4.8.4" + cloud_firestore_platform_interface: + dependency: transitive + description: + name: cloud_firestore_platform_interface + sha256: "86bd1865abbeb09a7d09da3e70364a09f894937270651fc611a1c6d6a9f7b02c" + url: "https://pub.dev" + source: hosted + version: "5.15.3" + cloud_firestore_web: + dependency: transitive + description: + name: cloud_firestore_web + sha256: ac2eeb2a7ab1928c3aacc30eed750fa839d6f620e112a5459e321df217be2f47 + url: "https://pub.dev" + source: hosted + version: "3.6.3" collection: dependency: transitive description: name: collection - sha256: cfc915e6923fe5ce6e153b0723c753045de46de1b4d63771530504004a45fae0 + sha256: "4a07be6cb69c84d677a6c3096fcf960cc3285a8330b4603e0d463d15d9bd934c" url: "https://pub.dev" source: hosted - version: "1.17.0" + version: "1.17.1" crypto: dependency: transitive description: @@ -161,6 +193,54 @@ packages: url: "https://pub.dev" source: hosted version: "6.1.4" + firebase_auth: + dependency: "direct main" + description: + name: firebase_auth + sha256: "49fd35ce06f2530dd460e5dc123235731cb61dd7c76b0af4b6e190404880d04d" + url: "https://pub.dev" + source: hosted + version: "4.7.2" + firebase_auth_platform_interface: + dependency: transitive + description: + name: firebase_auth_platform_interface + sha256: "817f3ceb84ef5e9adaaf50cf7a19255f6ffcdd12c6f9e9aa4cf00fc7f2eb3cfb" + url: "https://pub.dev" + source: hosted + version: "6.16.1" + firebase_auth_web: + dependency: transitive + description: + name: firebase_auth_web + sha256: e9044778287f1ff8f9f4cee7e247b03ec87bb8977e0e65ad27dc337e196132e8 + url: "https://pub.dev" + source: hosted + version: "5.6.2" + firebase_core: + dependency: "direct main" + description: + name: firebase_core + sha256: "2e9324f719e90200dc7d3c4f5d2abc26052f9f2b995d3b6626c47a0dfe1c8192" + url: "https://pub.dev" + source: hosted + version: "2.15.0" + firebase_core_platform_interface: + dependency: transitive + description: + name: firebase_core_platform_interface + sha256: b63e3be6c96ef5c33bdec1aab23c91eb00696f6452f0519401d640938c94cba2 + url: "https://pub.dev" + source: hosted + version: "4.8.0" + firebase_core_web: + dependency: transitive + description: + name: firebase_core_web + sha256: "0fd5c4b228de29b55fac38aed0d9e42514b3d3bd47675de52bf7f8fccaf922fa" + url: "https://pub.dev" + source: hosted + version: "2.6.0" flutter: dependency: "direct main" description: flutter @@ -268,10 +348,10 @@ packages: dependency: transitive description: name: js - sha256: "5528c2f391ededb7775ec1daa69e65a2d61276f7552de2b5f7b8d34ee9fd4ab7" + sha256: f2c445dce49627136094980615a031419f7f3eb393237e4ecd97ac15dea343f3 url: "https://pub.dev" source: hosted - version: "0.6.5" + version: "0.6.7" lints: dependency: transitive description: @@ -284,10 +364,10 @@ packages: dependency: transitive description: name: matcher - sha256: "16db949ceee371e9b99d22f88fa3a73c4e59fd0afed0bd25fc336eb76c198b72" + sha256: "6501fbd55da300384b768785b83e5ce66991266cec21af89ab9ae7f5ce1c4cbb" url: "https://pub.dev" source: hosted - version: "0.12.13" + version: "0.12.15" material_color_utilities: dependency: transitive description: @@ -300,10 +380,10 @@ packages: dependency: transitive description: name: meta - sha256: "6c268b42ed578a53088d834796959e4a1814b5e9e164f147f580a386e5decf42" + sha256: "3c74dbf8763d36539f114c799d8a2d87343b5067e9d796ca22b5eb8437090ee3" url: "https://pub.dev" source: hosted - version: "1.8.0" + version: "1.9.1" modal_bottom_sheet: dependency: "direct main" description: @@ -316,10 +396,10 @@ packages: dependency: transitive description: name: path - sha256: db9d4f58c908a4ba5953fcee2ae317c94889433e5024c27ce74a37f94267945b + sha256: "8829d8a55c13fc0e37127c29fedf290c102f4e40ae94ada574091fe0ff96c917" url: "https://pub.dev" source: hosted - version: "1.8.2" + version: "1.8.3" path_provider: dependency: transitive description: @@ -449,10 +529,10 @@ packages: dependency: transitive description: name: test_api - sha256: ad540f65f92caa91bf21dfc8ffb8c589d6e4dc0c2267818b4cc2792857706206 + sha256: eb6ac1540b26de412b3403a163d919ba86f6a973fe6cc50ae3541b80092fdcfb url: "https://pub.dev" source: hosted - version: "0.4.16" + version: "0.5.1" text_scroll: dependency: "direct main" description: @@ -518,5 +598,5 @@ packages: source: hosted version: "1.1.0" sdks: - dart: ">=2.18.2 <3.0.0" + dart: ">=3.0.0-0 <4.0.0" flutter: ">=3.3.0" diff --git a/Sources/justMUSIC/pubspec.yaml b/Sources/justMUSIC/pubspec.yaml index 1a52f91..9913d71 100644 --- a/Sources/justMUSIC/pubspec.yaml +++ b/Sources/justMUSIC/pubspec.yaml @@ -53,6 +53,9 @@ dependencies: audioplayers: ^4.1.0 ionicons: ^0.2.2 top_snackbar_flutter: ^3.1.0 + firebase_core: ^2.15.0 + firebase_auth: ^4.7.2 + cloud_firestore: ^4.8.4 dev_dependencies: flutter_test: -- 2.36.3 From 75c71394429d9770a321a838fd42851c000348d1 Mon Sep 17 00:00:00 2001 From: Lucas Delanier Date: Sat, 29 Jul 2023 19:39:48 +0200 Subject: [PATCH 2/8] new branch --- Sources/justMUSIC/lib/main.dart | 2 +- .../lib/model/mapper/UserMapper.dart | 7 +- .../justMUSIC/lib/screens/login_screen.dart | 117 ++++++++++-------- .../lib/screens/registration_screen.dart | 28 +++++ .../justMUSIC/lib/screens/welcome_screen.dart | 20 ++- .../lib/view_model/UserViewModel.dart | 26 ++-- 6 files changed, 116 insertions(+), 84 deletions(-) diff --git a/Sources/justMUSIC/lib/main.dart b/Sources/justMUSIC/lib/main.dart index 283502a..4b5ce53 100644 --- a/Sources/justMUSIC/lib/main.dart +++ b/Sources/justMUSIC/lib/main.dart @@ -60,7 +60,7 @@ class MyApp extends StatelessWidget { // is not restarted. primarySwatch: Colors.blue, ), - home: LoginScreen()); + home: WellcomeScreen()); }, designSize: Size(390, 844), ); diff --git a/Sources/justMUSIC/lib/model/mapper/UserMapper.dart b/Sources/justMUSIC/lib/model/mapper/UserMapper.dart index 25a8900..baca8fe 100644 --- a/Sources/justMUSIC/lib/model/mapper/UserMapper.dart +++ b/Sources/justMUSIC/lib/model/mapper/UserMapper.dart @@ -1,14 +1,9 @@ import 'package:cloud_firestore/cloud_firestore.dart'; import 'package:justmusic/model/User.dart'; -import 'package:firebase_auth/firebase_auth.dart' as firebase_auth; -import '../../main.dart'; class UserMapper { - static User? toModel(DocumentSnapshot>? snapshot, + static User toModel(DocumentSnapshot> snapshot, SnapshotOptions? options) { - if (snapshot == null) { - return null; - } final data = snapshot.data(); return User( data?["uid"], diff --git a/Sources/justMUSIC/lib/screens/login_screen.dart b/Sources/justMUSIC/lib/screens/login_screen.dart index 58b52f4..16dd4d2 100644 --- a/Sources/justMUSIC/lib/screens/login_screen.dart +++ b/Sources/justMUSIC/lib/screens/login_screen.dart @@ -30,11 +30,10 @@ class _LoginScreenState extends State { .login(_userMailTextField.text, _passwordTextField.text); Navigator.pushNamed(context, '/explanation'); } catch (e) { - print(e); ScaffoldMessenger.of(context).showSnackBar( SnackBar( content: Text( - e.toString(), + "Erreur: Email ou mot de passe incorrect", style: GoogleFonts.plusJakartaSans( color: Colors.white, fontWeight: FontWeight.w400, @@ -71,7 +70,7 @@ class _LoginScreenState extends State { CrossAxisAlignment.center, children: [ Flexible( - flex: 5, + flex: 4, child: Padding( padding: EdgeInsets.only(bottom: 60), child: Column( @@ -108,10 +107,12 @@ class _LoginScreenState extends State { ), ), Expanded( - flex: 4, + flex: 5, child: Column( crossAxisAlignment: CrossAxisAlignment.end, + mainAxisAlignment: + MainAxisAlignment.center, children: [ TextFormField( controller: _userMailTextField, @@ -138,25 +139,24 @@ class _LoginScreenState extends State { strokeTextField), borderRadius: BorderRadius.all( Radius.circular(10))), - contentPadding: - EdgeInsets.only( - top: 0, - bottom: 0, - left: defaultPadding), + prefix: const Padding( + padding: EdgeInsets.only( + left: 20.0)), + suffix: const Padding( + padding: EdgeInsets.only( + left: 20.0)), fillColor: bgTextField, filled: true, + errorStyle: TextStyle( + fontSize: 9, height: 0.3), focusColor: Color.fromRGBO( 255, 255, 255, 0.30), enabledBorder: OutlineInputBorder( - borderSide: BorderSide( - width: 1, - color: - strokeTextField), - borderRadius: BorderRadius.all( - Radius.circular(10))), + borderSide: + BorderSide(width: 1, color: strokeTextField), + borderRadius: BorderRadius.all(Radius.circular(10))), hintText: 'Email', - hintStyle: - GoogleFonts.plusJakartaSans(color: strokeTextField)), + hintStyle: GoogleFonts.plusJakartaSans(color: strokeTextField)), ), SizedBox( height: 18, @@ -174,8 +174,6 @@ class _LoginScreenState extends State { return null; }, cursorColor: primaryColor, - keyboardType: - TextInputType.emailAddress, style: GoogleFonts.plusJakartaSans( color: primaryColor), @@ -190,10 +188,6 @@ class _LoginScreenState extends State { BorderRadius.all( Radius.circular( 10))), - contentPadding: EdgeInsets.only( - top: 0, - bottom: 0, - left: defaultPadding), fillColor: bgTextField, filled: true, focusColor: Color.fromRGBO( @@ -212,6 +206,9 @@ class _LoginScreenState extends State { hintStyle: GoogleFonts.plusJakartaSans( color: strokeTextField), + prefix: const Padding( + padding: EdgeInsets.only( + left: 20.0)), suffixIcon: Container( padding: EdgeInsets.only( right: 10), @@ -240,6 +237,8 @@ class _LoginScreenState extends State { height: 2, ), )), + errorStyle: TextStyle( + fontSize: 9, height: 0.3), ), ), Padding( @@ -259,6 +258,46 @@ class _LoginScreenState extends State { child: LoginButton( callback: handleLogin, )), + Align( + child: GestureDetector( + onTap: () { + Navigator.pushNamed( + context, '/register'); + }, + child: Padding( + padding: + EdgeInsets.only(top: 20), + child: RichText( + textAlign: TextAlign.center, + text: TextSpan( + text: + 'Pas encore inscrit?', + style: GoogleFonts + .plusJakartaSans( + color: + Colors.white, + fontWeight: + FontWeight + .w400, + fontSize: 15), + children: [ + TextSpan( + text: " S’inscire", + style: GoogleFonts + .plusJakartaSans( + fontSize: + 15, + fontWeight: + FontWeight + .w400, + color: + primaryColor)), + ], + ), + ), + ), + ), + ), ], ), ), @@ -321,38 +360,6 @@ class _LoginScreenState extends State { text: "Login with Google", onPressed: () {}, ), - Padding( - padding: - EdgeInsets.only(top: 20), - child: RichText( - textAlign: TextAlign.center, - text: TextSpan( - text: - 'Pas encore inscrit?', - style: GoogleFonts - .plusJakartaSans( - color: - Colors.white, - fontWeight: - FontWeight - .w400, - fontSize: 13), - children: [ - TextSpan( - text: " S’inscire", - style: GoogleFonts - .plusJakartaSans( - fontSize: - 13, - fontWeight: - FontWeight - .w400, - color: - primaryColor)), - ], - ), - ), - ) ], ), )) diff --git a/Sources/justMUSIC/lib/screens/registration_screen.dart b/Sources/justMUSIC/lib/screens/registration_screen.dart index ff62533..ece7456 100644 --- a/Sources/justMUSIC/lib/screens/registration_screen.dart +++ b/Sources/justMUSIC/lib/screens/registration_screen.dart @@ -292,6 +292,34 @@ class _RegistrationScreenState extends State { callback: () {}, )), ), + Align( + child: GestureDetector( + onTap: () { + Navigator.pushNamed(context, '/login'); + }, + child: Padding( + padding: EdgeInsets.only(top: 20), + child: RichText( + textAlign: TextAlign.center, + text: TextSpan( + text: 'Tu as déjà un compte?', + style: GoogleFonts.plusJakartaSans( + color: Colors.white, + fontWeight: FontWeight.w400, + fontSize: 15), + children: [ + TextSpan( + text: " Connexion", + style: GoogleFonts.plusJakartaSans( + fontSize: 15, + fontWeight: FontWeight.w400, + color: primaryColor)), + ], + ), + ), + ), + ), + ), ], )), SizedBox(height: 50.h), diff --git a/Sources/justMUSIC/lib/screens/welcome_screen.dart b/Sources/justMUSIC/lib/screens/welcome_screen.dart index 5ba91e5..1d61dbc 100644 --- a/Sources/justMUSIC/lib/screens/welcome_screen.dart +++ b/Sources/justMUSIC/lib/screens/welcome_screen.dart @@ -71,12 +71,20 @@ class WellcomeScreen extends StatelessWidget { SizedBox( height: defaultPadding, ), - Text( - "Tu as déja un compte? Connexion", - style: GoogleFonts.plusJakartaSans( - color: Colors.white, - fontWeight: FontWeight.w400, - fontSize: 15), + GestureDetector( + onTap: () { + Navigator.pushNamed(context, '/login'); + }, + child: Padding( + padding: const EdgeInsets.all(3.0), + child: Text( + "Tu as déja un compte? Connexion", + style: GoogleFonts.plusJakartaSans( + color: Colors.white, + fontWeight: FontWeight.w400, + fontSize: 15), + ), + ), ), ], ), diff --git a/Sources/justMUSIC/lib/view_model/UserViewModel.dart b/Sources/justMUSIC/lib/view_model/UserViewModel.dart index d4bbfa7..881dda3 100644 --- a/Sources/justMUSIC/lib/view_model/UserViewModel.dart +++ b/Sources/justMUSIC/lib/view_model/UserViewModel.dart @@ -1,4 +1,3 @@ -import 'package:cloud_firestore/cloud_firestore.dart'; import 'package:firebase_auth/firebase_auth.dart' as firebase_auth; import 'package:justmusic/service/AuthService.dart'; @@ -25,19 +24,17 @@ class UserViewModel { } login(String pseudo, String password) async { - await _authService.login(pseudo, password); - if (firebase_auth.FirebaseAuth.instance.currentUser == null) { - throw Exception("User login failed"); + try { + await _authService.login(pseudo, password); + final user = await MyApp.db + .collection("users") + .doc(firebase_auth.FirebaseAuth.instance.currentUser?.uid) + .get(); + User data = UserMapper.toModel(user, null); + _userCurrent = data; + } catch (e) { + throw Exception("Erreur: Email ou mot de passe incorrect"); } - final user = await MyApp.db - .collection("users") - .doc(firebase_auth.FirebaseAuth.instance.currentUser?.uid) - .get(); - User? data = UserMapper.toModel(user, null); - if (data == null) { - throw Exception("User login failed"); - } - _userCurrent = data; } register(String pseudo, String password, String email) async { @@ -47,9 +44,6 @@ class UserViewModel { .doc(firebase_auth.FirebaseAuth.instance.currentUser?.uid) .get(); User? data = UserMapper.toModel(user, null); - if (data == null) { - throw Exception("User register failed"); - } _userCurrent = data; } -- 2.36.3 From 20b2f487a9f2519436a6dc6847f9ebfddb858343 Mon Sep 17 00:00:00 2001 From: Lucas Delanier Date: Sat, 29 Jul 2023 20:12:30 +0200 Subject: [PATCH 3/8] connexion --- .../justMUSIC/lib/model/mapper/UserMapper.dart | 18 +++++++++--------- .../justMUSIC/lib/screens/login_screen.dart | 5 +++-- Sources/justMUSIC/lib/service/AuthService.dart | 11 ++--------- .../lib/view_model/UserViewModel.dart | 2 +- 4 files changed, 15 insertions(+), 21 deletions(-) diff --git a/Sources/justMUSIC/lib/model/mapper/UserMapper.dart b/Sources/justMUSIC/lib/model/mapper/UserMapper.dart index baca8fe..a7d3a24 100644 --- a/Sources/justMUSIC/lib/model/mapper/UserMapper.dart +++ b/Sources/justMUSIC/lib/model/mapper/UserMapper.dart @@ -6,15 +6,15 @@ class UserMapper { SnapshotOptions? options) { final data = snapshot.data(); return User( - data?["uid"], - data?["pseudo"], - data?["country"], - data?["mail"], - data?["profilePicture"], - data?["followers"] as int, - data?["nbCapsules"] as int, - data?["followed"] as int, - data?['friends'] is Iterable ? List.from(data?['friends']) : []); + data?["uid"] ?? "", + data?["pseudo"] ?? "", + data?["country"] ?? "", + data?["mail"] ?? "", + data?["profilePicture"] ?? "", + data?["followers"] ?? 0, + data?["nbCapsules"] ?? 0, + data?["followed"] ?? 0, + data?['friends'] is List ? List.from(data?['friends']) : []); } /* static Map toFirebase(User user) { diff --git a/Sources/justMUSIC/lib/screens/login_screen.dart b/Sources/justMUSIC/lib/screens/login_screen.dart index 16dd4d2..1924761 100644 --- a/Sources/justMUSIC/lib/screens/login_screen.dart +++ b/Sources/justMUSIC/lib/screens/login_screen.dart @@ -1,3 +1,4 @@ +import 'package:firebase_auth/firebase_auth.dart'; import 'package:flutter/cupertino.dart'; import 'package:flutter/material.dart'; import 'package:flutter/services.dart'; @@ -29,11 +30,11 @@ class _LoginScreenState extends State { await MyApp.userViewModel .login(_userMailTextField.text, _passwordTextField.text); Navigator.pushNamed(context, '/explanation'); - } catch (e) { + } on FirebaseAuthException catch (e) { ScaffoldMessenger.of(context).showSnackBar( SnackBar( content: Text( - "Erreur: Email ou mot de passe incorrect", + e.message ?? "", style: GoogleFonts.plusJakartaSans( color: Colors.white, fontWeight: FontWeight.w400, diff --git a/Sources/justMUSIC/lib/service/AuthService.dart b/Sources/justMUSIC/lib/service/AuthService.dart index 0baefe0..707a9c5 100644 --- a/Sources/justMUSIC/lib/service/AuthService.dart +++ b/Sources/justMUSIC/lib/service/AuthService.dart @@ -1,6 +1,3 @@ -import 'package:cloud_firestore/cloud_firestore.dart'; - -import '../model/User.dart'; import 'package:firebase_auth/firebase_auth.dart'; import '../main.dart'; @@ -42,12 +39,8 @@ class AuthService { try { await FirebaseAuth.instance .signInWithEmailAndPassword(email: email, password: password); - } on FirebaseAuthException catch (e) { - if (e.code == 'user-not-found') { - throw ('No user found for that email.'); - } else if (e.code == 'wrong-password') { - throw ('Wrong password provided for that user.'); - } + } on FirebaseAuthException { + rethrow; } } diff --git a/Sources/justMUSIC/lib/view_model/UserViewModel.dart b/Sources/justMUSIC/lib/view_model/UserViewModel.dart index 881dda3..29200d2 100644 --- a/Sources/justMUSIC/lib/view_model/UserViewModel.dart +++ b/Sources/justMUSIC/lib/view_model/UserViewModel.dart @@ -33,7 +33,7 @@ class UserViewModel { User data = UserMapper.toModel(user, null); _userCurrent = data; } catch (e) { - throw Exception("Erreur: Email ou mot de passe incorrect"); + rethrow; } } -- 2.36.3 From 80fb1c0794ea941057fb1f2d5d2f06466d8e7fd1 Mon Sep 17 00:00:00 2001 From: Lucas Delanier Date: Sat, 29 Jul 2023 21:58:56 +0200 Subject: [PATCH 4/8] manage multiple song playing --- Sources/justMUSIC/.metadata | 25 ++++--------------- Sources/justMUSIC/android/app/build.gradle | 11 ++++++-- .../android/app/src/debug/AndroidManifest.xml | 3 +-- .../android/app/src/main/AndroidManifest.xml | 5 ++-- .../app/FlutterMultiDexApplication.java | 25 +++++++++++++++++++ .../app/src/profile/AndroidManifest.xml | 3 +-- Sources/justMUSIC/android/build.gradle | 12 ++++++--- .../gradle/wrapper/gradle-wrapper.properties | 2 +- 8 files changed, 53 insertions(+), 33 deletions(-) create mode 100644 Sources/justMUSIC/android/app/src/main/java/io/flutter/app/FlutterMultiDexApplication.java diff --git a/Sources/justMUSIC/.metadata b/Sources/justMUSIC/.metadata index e1179a6..732ba6d 100644 --- a/Sources/justMUSIC/.metadata +++ b/Sources/justMUSIC/.metadata @@ -4,7 +4,7 @@ # This file should be version controlled. version: - revision: 18a827f3933c19f51862dde3fa472197683249d6 + revision: f468f3366c26a5092eb964a230ce7892fda8f2f8 channel: stable project_type: app @@ -13,26 +13,11 @@ project_type: app migration: platforms: - platform: root - create_revision: 18a827f3933c19f51862dde3fa472197683249d6 - base_revision: 18a827f3933c19f51862dde3fa472197683249d6 + create_revision: f468f3366c26a5092eb964a230ce7892fda8f2f8 + base_revision: f468f3366c26a5092eb964a230ce7892fda8f2f8 - platform: android - create_revision: 18a827f3933c19f51862dde3fa472197683249d6 - base_revision: 18a827f3933c19f51862dde3fa472197683249d6 - - platform: ios - create_revision: 18a827f3933c19f51862dde3fa472197683249d6 - base_revision: 18a827f3933c19f51862dde3fa472197683249d6 - - platform: linux - create_revision: 18a827f3933c19f51862dde3fa472197683249d6 - base_revision: 18a827f3933c19f51862dde3fa472197683249d6 - - platform: macos - create_revision: 18a827f3933c19f51862dde3fa472197683249d6 - base_revision: 18a827f3933c19f51862dde3fa472197683249d6 - - platform: web - create_revision: 18a827f3933c19f51862dde3fa472197683249d6 - base_revision: 18a827f3933c19f51862dde3fa472197683249d6 - - platform: windows - create_revision: 18a827f3933c19f51862dde3fa472197683249d6 - base_revision: 18a827f3933c19f51862dde3fa472197683249d6 + create_revision: f468f3366c26a5092eb964a230ce7892fda8f2f8 + base_revision: f468f3366c26a5092eb964a230ce7892fda8f2f8 # User provided section diff --git a/Sources/justMUSIC/android/app/build.gradle b/Sources/justMUSIC/android/app/build.gradle index 2c71df3..44f9732 100644 --- a/Sources/justMUSIC/android/app/build.gradle +++ b/Sources/justMUSIC/android/app/build.gradle @@ -1,4 +1,5 @@ def localProperties = new Properties() + def localPropertiesFile = rootProject.file('local.properties') if (localPropertiesFile.exists()) { localPropertiesFile.withReader('UTF-8') { reader -> @@ -26,9 +27,11 @@ apply plugin: 'kotlin-android' apply from: "$flutterRoot/packages/flutter_tools/gradle/flutter.gradle" android { + namespace "com.example.justmusic" compileSdkVersion 33 ndkVersion flutter.ndkVersion + compileOptions { sourceCompatibility JavaVersion.VERSION_1_8 targetCompatibility JavaVersion.VERSION_1_8 @@ -46,8 +49,8 @@ android { // TODO: Specify your own unique Application ID (https://developer.android.com/studio/build/application-id.html). applicationId "com.example.justmusic" // You can update the following values to match your application needs. - // For more information, see: https://docs.flutter.dev/deployment/android#reviewing-the-build-configuration. - minSdkVersion flutter.minSdkVersion + // For more information, see: https://docs.flutter.dev/deployment/android#reviewing-the-gradle-build-configuration. + minSdkVersion 19 targetSdkVersion flutter.targetSdkVersion versionCode flutterVersionCode.toInteger() versionName flutterVersionName @@ -66,6 +69,10 @@ flutter { source '../..' } + dependencies { implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version" + implementation(platform("com.google.firebase:firebase-bom:32.2.0")) + implementation 'com.google.firebase:firebase-analytics-ktx' } +apply plugin: 'com.google.gms.google-services' diff --git a/Sources/justMUSIC/android/app/src/debug/AndroidManifest.xml b/Sources/justMUSIC/android/app/src/debug/AndroidManifest.xml index 44a649b..399f698 100644 --- a/Sources/justMUSIC/android/app/src/debug/AndroidManifest.xml +++ b/Sources/justMUSIC/android/app/src/debug/AndroidManifest.xml @@ -1,5 +1,4 @@ - + - - + + + + diff --git a/Sources/justMUSIC/android/app/src/main/AndroidManifest.xml b/Sources/justMUSIC/android/app/src/main/AndroidManifest.xml index 266fa7e..e855118 100644 --- a/Sources/justMUSIC/android/app/src/main/AndroidManifest.xml +++ b/Sources/justMUSIC/android/app/src/main/AndroidManifest.xml @@ -1,33 +1,33 @@ - - - - - - - - - - - - - - + + + + + + + + + + + + + + diff --git a/Sources/justMUSIC/android/app/src/main/java/io/flutter/app/FlutterMultiDexApplication.java b/Sources/justMUSIC/android/app/src/main/java/io/flutter/app/FlutterMultiDexApplication.java index 752fc18..7ab3f6d 100644 --- a/Sources/justMUSIC/android/app/src/main/java/io/flutter/app/FlutterMultiDexApplication.java +++ b/Sources/justMUSIC/android/app/src/main/java/io/flutter/app/FlutterMultiDexApplication.java @@ -1,25 +1,25 @@ -// Generated file. -// -// If you wish to remove Flutter's multidex support, delete this entire file. -// -// Modifications to this file should be done in a copy under a different name -// as this file may be regenerated. - -package io.flutter.app; - -import android.app.Application; -import android.content.Context; -import androidx.annotation.CallSuper; -import androidx.multidex.MultiDex; - -/** - * Extension of {@link android.app.Application}, adding multidex support. - */ -public class FlutterMultiDexApplication extends Application { - @Override - @CallSuper - protected void attachBaseContext(Context base) { - super.attachBaseContext(base); - MultiDex.install(this); - } -} +// Generated file. +// +// If you wish to remove Flutter's multidex support, delete this entire file. +// +// Modifications to this file should be done in a copy under a different name +// as this file may be regenerated. + +package io.flutter.app; + +import android.app.Application; +import android.content.Context; +import androidx.annotation.CallSuper; +import androidx.multidex.MultiDex; + +/** + * Extension of {@link android.app.Application}, adding multidex support. + */ +public class FlutterMultiDexApplication extends Application { + @Override + @CallSuper + protected void attachBaseContext(Context base) { + super.attachBaseContext(base); + MultiDex.install(this); + } +} diff --git a/Sources/justMUSIC/android/app/src/profile/AndroidManifest.xml b/Sources/justMUSIC/android/app/src/profile/AndroidManifest.xml index 399f698..8ffe024 100644 --- a/Sources/justMUSIC/android/app/src/profile/AndroidManifest.xml +++ b/Sources/justMUSIC/android/app/src/profile/AndroidManifest.xml @@ -1,7 +1,7 @@ - - - - + + + + diff --git a/Sources/justMUSIC/android/build.gradle b/Sources/justMUSIC/android/build.gradle index 094ae21..791e37b 100644 --- a/Sources/justMUSIC/android/build.gradle +++ b/Sources/justMUSIC/android/build.gradle @@ -1,37 +1,37 @@ -buildscript { - ext.kotlin_version = '1.7.10' - repositories { - google() - mavenCentral() - } - - dependencies { - classpath 'com.android.tools.build:gradle:7.3.0' - classpath 'com.google.gms:google-services:4.3.15' - classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version" - } - - - - -} - -allprojects { - repositories { - google() - mavenCentral() - } -} - -rootProject.buildDir = '../build' -subprojects { - project.buildDir = "${rootProject.buildDir}/${project.name}" -} -subprojects { - project.evaluationDependsOn(':app') -} - -tasks.register("clean", Delete) { - delete rootProject.buildDir -} - +buildscript { + ext.kotlin_version = '1.7.10' + repositories { + google() + mavenCentral() + } + + dependencies { + classpath 'com.android.tools.build:gradle:7.3.0' + classpath 'com.google.gms:google-services:4.3.15' + classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version" + } + + + + +} + +allprojects { + repositories { + google() + mavenCentral() + } +} + +rootProject.buildDir = '../build' +subprojects { + project.buildDir = "${rootProject.buildDir}/${project.name}" +} +subprojects { + project.evaluationDependsOn(':app') +} + +tasks.register("clean", Delete) { + delete rootProject.buildDir +} + diff --git a/Sources/justMUSIC/android/gradle/wrapper/gradle-wrapper.properties b/Sources/justMUSIC/android/gradle/wrapper/gradle-wrapper.properties index 3c472b9..eabb85f 100644 --- a/Sources/justMUSIC/android/gradle/wrapper/gradle-wrapper.properties +++ b/Sources/justMUSIC/android/gradle/wrapper/gradle-wrapper.properties @@ -1,5 +1,5 @@ -distributionBase=GRADLE_USER_HOME -distributionPath=wrapper/dists -zipStoreBase=GRADLE_USER_HOME -zipStorePath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-7.5-all.zip +distributionBase=GRADLE_USER_HOME +distributionPath=wrapper/dists +zipStoreBase=GRADLE_USER_HOME +zipStorePath=wrapper/dists +distributionUrl=https\://services.gradle.org/distributions/gradle-7.5-all.zip diff --git a/Sources/justMUSIC/ios/Runner/GoogleService-Info.plist b/Sources/justMUSIC/ios/Runner/GoogleService-Info.plist index cdb37d7..d67674a 100644 --- a/Sources/justMUSIC/ios/Runner/GoogleService-Info.plist +++ b/Sources/justMUSIC/ios/Runner/GoogleService-Info.plist @@ -1,34 +1,34 @@ - - - - - CLIENT_ID - 994903990520-n6jd98ena56kb1tvtrd67tvb5et3nfbf.apps.googleusercontent.com - REVERSED_CLIENT_ID - com.googleusercontent.apps.994903990520-n6jd98ena56kb1tvtrd67tvb5et3nfbf - API_KEY - AIzaSyBbYqsR6t7JTi8_XFNEHd43IRuKlYGeI3U - GCM_SENDER_ID - 994903990520 - PLIST_VERSION - 1 - BUNDLE_ID - com.example.justmusic - PROJECT_ID - justmusic-435d5 - STORAGE_BUCKET - justmusic-435d5.appspot.com - IS_ADS_ENABLED - - IS_ANALYTICS_ENABLED - - IS_APPINVITE_ENABLED - - IS_GCM_ENABLED - - IS_SIGNIN_ENABLED - - GOOGLE_APP_ID - 1:994903990520:ios:93188f32e320babe0a9b0d - + + + + + CLIENT_ID + 994903990520-n6jd98ena56kb1tvtrd67tvb5et3nfbf.apps.googleusercontent.com + REVERSED_CLIENT_ID + com.googleusercontent.apps.994903990520-n6jd98ena56kb1tvtrd67tvb5et3nfbf + API_KEY + AIzaSyBbYqsR6t7JTi8_XFNEHd43IRuKlYGeI3U + GCM_SENDER_ID + 994903990520 + PLIST_VERSION + 1 + BUNDLE_ID + com.example.justmusic + PROJECT_ID + justmusic-435d5 + STORAGE_BUCKET + justmusic-435d5.appspot.com + IS_ADS_ENABLED + + IS_ANALYTICS_ENABLED + + IS_APPINVITE_ENABLED + + IS_GCM_ENABLED + + IS_SIGNIN_ENABLED + + GOOGLE_APP_ID + 1:994903990520:ios:93188f32e320babe0a9b0d + \ No newline at end of file diff --git a/Sources/justMUSIC/ios/firebase_app_id_file.json b/Sources/justMUSIC/ios/firebase_app_id_file.json index ef1bedc..dd5eb02 100644 --- a/Sources/justMUSIC/ios/firebase_app_id_file.json +++ b/Sources/justMUSIC/ios/firebase_app_id_file.json @@ -1,7 +1,7 @@ -{ - "file_generated_by": "FlutterFire CLI", - "purpose": "FirebaseAppID & ProjectID for this Firebase app in this directory", - "GOOGLE_APP_ID": "1:994903990520:ios:93188f32e320babe0a9b0d", - "FIREBASE_PROJECT_ID": "justmusic-435d5", - "GCM_SENDER_ID": "994903990520" +{ + "file_generated_by": "FlutterFire CLI", + "purpose": "FirebaseAppID & ProjectID for this Firebase app in this directory", + "GOOGLE_APP_ID": "1:994903990520:ios:93188f32e320babe0a9b0d", + "FIREBASE_PROJECT_ID": "justmusic-435d5", + "GCM_SENDER_ID": "994903990520" } \ No newline at end of file diff --git a/Sources/justMUSIC/lib/components/login_button.dart b/Sources/justMUSIC/lib/components/login_button.dart index 1d794dd..6a41d9c 100644 --- a/Sources/justMUSIC/lib/components/login_button.dart +++ b/Sources/justMUSIC/lib/components/login_button.dart @@ -1,68 +1,68 @@ -import 'package:flutter/cupertino.dart'; -import 'package:flutter/material.dart'; -import 'package:flutter_screenutil/flutter_screenutil.dart'; - -class LoginButton extends StatefulWidget { - final Function callback; - - const LoginButton({Key? key, required this.callback}) : super(key: key); - - @override - State createState() => _LoginButtonState(); -} - -class _LoginButtonState extends State { - @override - Widget build(BuildContext context) { - return ElevatedButton( - onPressed: () { - widget.callback(); - }, - style: ButtonStyle( - backgroundColor: MaterialStateProperty.all(Color(0xFF1C1C1C)), - overlayColor: - MaterialStateProperty.all(Color(0xffD3C2FF).withOpacity(0.2)), - shape: MaterialStateProperty.all(RoundedRectangleBorder( - borderRadius: BorderRadius.circular(18), - )), - padding: MaterialStateProperty.all(EdgeInsets.all(0.0)), - ), - child: Ink( - decoration: BoxDecoration( - gradient: RadialGradient( - center: Alignment(0, 3), - focalRadius: 10, - radius: 2.5, - stops: [0.4, 1.0], - colors: [Color(0xff9E78FF), Color(0xff633AF4)], - ), - borderRadius: BorderRadius.circular(18.0), - border: Border.all( - color: Color(0xff1C1C1C), - width: 5, - ), - ), - child: Container( - padding: EdgeInsets.only(top: 20.h, bottom: 20.h), - constraints: BoxConstraints(maxWidth: 600, minHeight: 50), - decoration: BoxDecoration( - boxShadow: [ - BoxShadow( - color: Color(0xff7E56F9).withOpacity(0.23), - spreadRadius: 4, - blurRadius: 40, - offset: Offset(0, 3), // changes position of shadow - ), - ], - ), - alignment: Alignment.center, - child: Text( - "Se connecter", - textAlign: TextAlign.center, - style: TextStyle(color: Colors.white, fontSize: 18), - ), - ), - ), - ); - } -} +import 'package:flutter/cupertino.dart'; +import 'package:flutter/material.dart'; +import 'package:flutter_screenutil/flutter_screenutil.dart'; + +class LoginButton extends StatefulWidget { + final Function callback; + + const LoginButton({Key? key, required this.callback}) : super(key: key); + + @override + State createState() => _LoginButtonState(); +} + +class _LoginButtonState extends State { + @override + Widget build(BuildContext context) { + return ElevatedButton( + onPressed: () { + widget.callback(); + }, + style: ButtonStyle( + backgroundColor: MaterialStateProperty.all(Color(0xFF1C1C1C)), + overlayColor: + MaterialStateProperty.all(Color(0xffD3C2FF).withOpacity(0.2)), + shape: MaterialStateProperty.all(RoundedRectangleBorder( + borderRadius: BorderRadius.circular(18), + )), + padding: MaterialStateProperty.all(EdgeInsets.all(0.0)), + ), + child: Ink( + decoration: BoxDecoration( + gradient: RadialGradient( + center: Alignment(0, 3), + focalRadius: 10, + radius: 2.5, + stops: [0.4, 1.0], + colors: [Color(0xff9E78FF), Color(0xff633AF4)], + ), + borderRadius: BorderRadius.circular(18.0), + border: Border.all( + color: Color(0xff1C1C1C), + width: 5, + ), + ), + child: Container( + padding: EdgeInsets.only(top: 20.h, bottom: 20.h), + constraints: BoxConstraints(maxWidth: 600, minHeight: 50), + decoration: BoxDecoration( + boxShadow: [ + BoxShadow( + color: Color(0xff7E56F9).withOpacity(0.23), + spreadRadius: 4, + blurRadius: 40, + offset: Offset(0, 3), // changes position of shadow + ), + ], + ), + alignment: Alignment.center, + child: Text( + "Se connecter", + textAlign: TextAlign.center, + style: TextStyle(color: Colors.white, fontSize: 18), + ), + ), + ), + ); + } +} diff --git a/Sources/justMUSIC/lib/components/music_list_component.dart b/Sources/justMUSIC/lib/components/music_list_component.dart index c92bba1..4d8976d 100644 --- a/Sources/justMUSIC/lib/components/music_list_component.dart +++ b/Sources/justMUSIC/lib/components/music_list_component.dart @@ -1,100 +1,100 @@ -import 'package:flutter/Material.dart'; -import 'package:google_fonts/google_fonts.dart'; -import 'package:justmusic/components/play_button_component.dart'; -import 'package:text_scroll/text_scroll.dart'; -import '../model/Music.dart'; - -class MusicListComponent extends StatelessWidget { - final Music music; - const MusicListComponent({ - Key? key, - required this.music, - }) : super(key: key); - - @override - Widget build(BuildContext context) { - return Container( - padding: const EdgeInsets.only(bottom: 14), - child: Row( - children: [ - LayoutBuilder( - builder: (BuildContext context, BoxConstraints constraints) { - if (music.cover != null) { - return ClipRRect( - borderRadius: BorderRadius.all(Radius.circular(5)), - child: music.cover != null - ? FadeInImage.assetNetwork( - height: 60, - width: 60, - fit: BoxFit.cover, - placeholder: "assets/images/loadingPlaceholder.gif", - image: music.cover!) - : Container( - height: 60, - width: 60, - color: Colors.grey, - ), - ); - } else { - return Image( - image: AssetImage("assets/images/exemple_cover.png"), - height: 60, - width: 60, - ); - } - }), - const SizedBox( - width: 10, - ), - Expanded( - flex: 10, - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - mainAxisAlignment: MainAxisAlignment.center, - children: [ - Row( - children: [ - Flexible( - flex: 8, - child: ScrollConfiguration( - behavior: - ScrollBehavior().copyWith(scrollbars: false), - child: TextScroll( - music.title ?? "Unknown", - style: GoogleFonts.plusJakartaSans( - fontSize: 16, - color: Colors.white, - fontWeight: FontWeight.w700), - mode: TextScrollMode.endless, - pauseBetween: Duration(milliseconds: 2500), - velocity: Velocity(pixelsPerSecond: Offset(30, 0)), - intervalSpaces: 10, - ), - )), - Icon( - Icons.explicit, - color: Colors.grey.withOpacity(0.7), - size: 17, - ), - ], - ), - ScrollConfiguration( - behavior: ScrollBehavior().copyWith(scrollbars: false), - child: Text( - music.artists.first.name ?? "Unknown", - overflow: TextOverflow.ellipsis, - style: GoogleFonts.plusJakartaSans( - color: Colors.grey, fontWeight: FontWeight.w400), - )) - ], - ), - ), - Spacer(), - PlayButtonComponent( - urlPreview: music.previewUrl, - ) - ], - ), - ); - } -} +import 'package:flutter/Material.dart'; +import 'package:google_fonts/google_fonts.dart'; +import 'package:justmusic/components/play_button_component.dart'; +import 'package:text_scroll/text_scroll.dart'; +import '../model/Music.dart'; + +class MusicListComponent extends StatelessWidget { + final Music music; + const MusicListComponent({ + Key? key, + required this.music, + }) : super(key: key); + + @override + Widget build(BuildContext context) { + return Container( + padding: const EdgeInsets.only(bottom: 14), + child: Row( + children: [ + LayoutBuilder( + builder: (BuildContext context, BoxConstraints constraints) { + if (music.cover != null) { + return ClipRRect( + borderRadius: BorderRadius.all(Radius.circular(5)), + child: music.cover != null + ? FadeInImage.assetNetwork( + height: 60, + width: 60, + fit: BoxFit.cover, + placeholder: "assets/images/loadingPlaceholder.gif", + image: music.cover!) + : Container( + height: 60, + width: 60, + color: Colors.grey, + ), + ); + } else { + return Image( + image: AssetImage("assets/images/exemple_cover.png"), + height: 60, + width: 60, + ); + } + }), + const SizedBox( + width: 10, + ), + Expanded( + flex: 10, + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + mainAxisAlignment: MainAxisAlignment.center, + children: [ + Row( + children: [ + Flexible( + flex: 8, + child: ScrollConfiguration( + behavior: + ScrollBehavior().copyWith(scrollbars: false), + child: TextScroll( + music.title ?? "Unknown", + style: GoogleFonts.plusJakartaSans( + fontSize: 16, + color: Colors.white, + fontWeight: FontWeight.w700), + mode: TextScrollMode.endless, + pauseBetween: Duration(milliseconds: 2500), + velocity: Velocity(pixelsPerSecond: Offset(30, 0)), + intervalSpaces: 10, + ), + )), + Icon( + Icons.explicit, + color: Colors.grey.withOpacity(0.7), + size: 17, + ), + ], + ), + ScrollConfiguration( + behavior: ScrollBehavior().copyWith(scrollbars: false), + child: Text( + music.artists.first.name ?? "Unknown", + overflow: TextOverflow.ellipsis, + style: GoogleFonts.plusJakartaSans( + color: Colors.grey, fontWeight: FontWeight.w400), + )) + ], + ), + ), + Spacer(), + PlayButtonComponent( + urlPreview: music.previewUrl, + ) + ], + ), + ); + } +} diff --git a/Sources/justMUSIC/lib/components/play_button_component.dart b/Sources/justMUSIC/lib/components/play_button_component.dart index 5c3c2e2..52f764e 100644 --- a/Sources/justMUSIC/lib/components/play_button_component.dart +++ b/Sources/justMUSIC/lib/components/play_button_component.dart @@ -1,72 +1,72 @@ -import 'package:audioplayers/audioplayers.dart'; -import 'package:flutter/Material.dart'; -import 'package:flutter_animated_play_button/flutter_animated_play_button.dart'; -import 'package:ionicons/ionicons.dart'; - -class PlayButtonComponent extends StatefulWidget { - final String? urlPreview; - const PlayButtonComponent({Key? key, required this.urlPreview}) - : super(key: key); - - @override - State createState() => _PlayButtonComponentState(); -} - -class _PlayButtonComponentState extends State { - bool isPlaying = true; - final player = AudioPlayer(); - void switchStatePlaying() { - setState(() { - isPlaying = !isPlaying; - }); - stopSong(); - } - - @override - void initState() { - player.onPlayerComplete.listen((event) { - switchStatePlaying(); - }); - super.initState(); - } - - @override - Widget build(BuildContext context) { - if (!isPlaying) { - playSong(); - } else {} - return isPlaying - ? GestureDetector( - onTap: switchStatePlaying, - child: Container( - width: 30, - height: 30, - child: Icon( - Ionicons.play_circle_outline, - color: Colors.grey.withOpacity(0.3), - size: 30, - )), - ) - : GestureDetector( - onTap: switchStatePlaying, - child: Container( - width: 30, - height: 30, - child: AnimatedPlayButton( - stopped: false, - color: Colors.grey.withOpacity(0.3), - onPressed: () {}, - ), - )); - } - - Future playSong() async { - if (widget.urlPreview != null) { - await player.play(UrlSource(widget.urlPreview ?? "")); - } - } - - Future stopSong() async { - await player.stop(); - } -} +import 'package:audioplayers/audioplayers.dart'; +import 'package:flutter/Material.dart'; +import 'package:flutter_animated_play_button/flutter_animated_play_button.dart'; +import 'package:ionicons/ionicons.dart'; + +class PlayButtonComponent extends StatefulWidget { + final String? urlPreview; + const PlayButtonComponent({Key? key, required this.urlPreview}) + : super(key: key); + + @override + State createState() => _PlayButtonComponentState(); +} + +class _PlayButtonComponentState extends State { + bool isPlaying = true; + final player = AudioPlayer(); + void switchStatePlaying() { + setState(() { + isPlaying = !isPlaying; + }); + stopSong(); + } + + @override + void initState() { + player.onPlayerComplete.listen((event) { + switchStatePlaying(); + }); + super.initState(); + } + + @override + Widget build(BuildContext context) { + if (!isPlaying) { + playSong(); + } else {} + return isPlaying + ? GestureDetector( + onTap: switchStatePlaying, + child: Container( + width: 30, + height: 30, + child: Icon( + Ionicons.play_circle_outline, + color: Colors.grey.withOpacity(0.3), + size: 30, + )), + ) + : GestureDetector( + onTap: switchStatePlaying, + child: Container( + width: 30, + height: 30, + child: AnimatedPlayButton( + stopped: false, + color: Colors.grey.withOpacity(0.3), + onPressed: () {}, + ), + )); + } + + Future playSong() async { + if (widget.urlPreview != null) { + await player.play(UrlSource(widget.urlPreview ?? "")); + } + } + + Future stopSong() async { + await player.stop(); + } +} diff --git a/Sources/justMUSIC/lib/firebase_options.dart b/Sources/justMUSIC/lib/firebase_options.dart index bfc6ec0..7155c8e 100644 --- a/Sources/justMUSIC/lib/firebase_options.dart +++ b/Sources/justMUSIC/lib/firebase_options.dart @@ -1,76 +1,76 @@ -// File generated by FlutterFire CLI. -// ignore_for_file: lines_longer_than_80_chars, avoid_classes_with_only_static_members -import 'package:firebase_core/firebase_core.dart' show FirebaseOptions; -import 'package:flutter/foundation.dart' - show defaultTargetPlatform, kIsWeb, TargetPlatform; - -/// Default [FirebaseOptions] for use with your Firebase apps. -/// -/// Example: -/// ```dart -/// import 'firebase_options.dart'; -/// // ... -/// await Firebase.initializeApp( -/// options: DefaultFirebaseOptions.currentPlatform, -/// ); -/// ``` -class DefaultFirebaseOptions { - static FirebaseOptions get currentPlatform { - if (kIsWeb) { - return web; - } - switch (defaultTargetPlatform) { - case TargetPlatform.android: - return android; - case TargetPlatform.iOS: - return ios; - case TargetPlatform.macOS: - throw UnsupportedError( - 'DefaultFirebaseOptions have not been configured for macos - ' - 'you can reconfigure this by running the FlutterFire CLI again.', - ); - case TargetPlatform.windows: - throw UnsupportedError( - 'DefaultFirebaseOptions have not been configured for windows - ' - 'you can reconfigure this by running the FlutterFire CLI again.', - ); - case TargetPlatform.linux: - throw UnsupportedError( - 'DefaultFirebaseOptions have not been configured for linux - ' - 'you can reconfigure this by running the FlutterFire CLI again.', - ); - default: - throw UnsupportedError( - 'DefaultFirebaseOptions are not supported for this platform.', - ); - } - } - - static const FirebaseOptions web = FirebaseOptions( - apiKey: 'AIzaSyBv-Sba07nFFhctn6c3ARyvi9RfYwEKoNA', - appId: '1:994903990520:web:724c75003432ddbc0a9b0d', - messagingSenderId: '994903990520', - projectId: 'justmusic-435d5', - authDomain: 'justmusic-435d5.firebaseapp.com', - storageBucket: 'justmusic-435d5.appspot.com', - measurementId: 'G-D4YRLXK9TQ', - ); - - static const FirebaseOptions android = FirebaseOptions( - apiKey: 'AIzaSyCjkofl0nvfzQqRZPv_-H99WoyYa7O660g', - appId: '1:994903990520:android:02a445b6561bf2820a9b0d', - messagingSenderId: '994903990520', - projectId: 'justmusic-435d5', - storageBucket: 'justmusic-435d5.appspot.com', - ); - - static const FirebaseOptions ios = FirebaseOptions( - apiKey: 'AIzaSyBbYqsR6t7JTi8_XFNEHd43IRuKlYGeI3U', - appId: '1:994903990520:ios:93188f32e320babe0a9b0d', - messagingSenderId: '994903990520', - projectId: 'justmusic-435d5', - storageBucket: 'justmusic-435d5.appspot.com', - iosClientId: '994903990520-n6jd98ena56kb1tvtrd67tvb5et3nfbf.apps.googleusercontent.com', - iosBundleId: 'com.example.justmusic', - ); -} +// File generated by FlutterFire CLI. +// ignore_for_file: lines_longer_than_80_chars, avoid_classes_with_only_static_members +import 'package:firebase_core/firebase_core.dart' show FirebaseOptions; +import 'package:flutter/foundation.dart' + show defaultTargetPlatform, kIsWeb, TargetPlatform; + +/// Default [FirebaseOptions] for use with your Firebase apps. +/// +/// Example: +/// ```dart +/// import 'firebase_options.dart'; +/// // ... +/// await Firebase.initializeApp( +/// options: DefaultFirebaseOptions.currentPlatform, +/// ); +/// ``` +class DefaultFirebaseOptions { + static FirebaseOptions get currentPlatform { + if (kIsWeb) { + return web; + } + switch (defaultTargetPlatform) { + case TargetPlatform.android: + return android; + case TargetPlatform.iOS: + return ios; + case TargetPlatform.macOS: + throw UnsupportedError( + 'DefaultFirebaseOptions have not been configured for macos - ' + 'you can reconfigure this by running the FlutterFire CLI again.', + ); + case TargetPlatform.windows: + throw UnsupportedError( + 'DefaultFirebaseOptions have not been configured for windows - ' + 'you can reconfigure this by running the FlutterFire CLI again.', + ); + case TargetPlatform.linux: + throw UnsupportedError( + 'DefaultFirebaseOptions have not been configured for linux - ' + 'you can reconfigure this by running the FlutterFire CLI again.', + ); + default: + throw UnsupportedError( + 'DefaultFirebaseOptions are not supported for this platform.', + ); + } + } + + static const FirebaseOptions web = FirebaseOptions( + apiKey: 'AIzaSyBv-Sba07nFFhctn6c3ARyvi9RfYwEKoNA', + appId: '1:994903990520:web:724c75003432ddbc0a9b0d', + messagingSenderId: '994903990520', + projectId: 'justmusic-435d5', + authDomain: 'justmusic-435d5.firebaseapp.com', + storageBucket: 'justmusic-435d5.appspot.com', + measurementId: 'G-D4YRLXK9TQ', + ); + + static const FirebaseOptions android = FirebaseOptions( + apiKey: 'AIzaSyCjkofl0nvfzQqRZPv_-H99WoyYa7O660g', + appId: '1:994903990520:android:02a445b6561bf2820a9b0d', + messagingSenderId: '994903990520', + projectId: 'justmusic-435d5', + storageBucket: 'justmusic-435d5.appspot.com', + ); + + static const FirebaseOptions ios = FirebaseOptions( + apiKey: 'AIzaSyBbYqsR6t7JTi8_XFNEHd43IRuKlYGeI3U', + appId: '1:994903990520:ios:93188f32e320babe0a9b0d', + messagingSenderId: '994903990520', + projectId: 'justmusic-435d5', + storageBucket: 'justmusic-435d5.appspot.com', + iosClientId: '994903990520-n6jd98ena56kb1tvtrd67tvb5et3nfbf.apps.googleusercontent.com', + iosBundleId: 'com.example.justmusic', + ); +} diff --git a/Sources/justMUSIC/lib/main.dart b/Sources/justMUSIC/lib/main.dart index 4b5ce53..191ec0d 100644 --- a/Sources/justMUSIC/lib/main.dart +++ b/Sources/justMUSIC/lib/main.dart @@ -1,68 +1,68 @@ -import 'package:cloud_firestore/cloud_firestore.dart'; -import 'package:flutter/material.dart'; -import 'package:flutter/services.dart'; -import 'package:flutter_screenutil/flutter_screenutil.dart'; -import 'package:justmusic/screens/explanations_screen.dart'; -import 'package:justmusic/screens/feed_screen.dart'; -import 'package:justmusic/screens/login_screen.dart'; -import 'package:justmusic/screens/post_screen.dart'; -import 'package:justmusic/screens/profile_screen.dart'; -import 'package:justmusic/screens/registration_screen.dart'; -import 'package:justmusic/screens/welcome_screen.dart'; -import 'package:justmusic/view_model/MusicViewModel.dart'; -import 'package:justmusic/view_model/UserViewModel.dart'; -import 'package:firebase_core/firebase_core.dart'; -import 'firebase_options.dart'; - -Future main() async { - WidgetsFlutterBinding.ensureInitialized(); - await Firebase.initializeApp( - options: DefaultFirebaseOptions.currentPlatform, - ); - runApp(const MyApp()); -} - -class MyApp extends StatelessWidget { - // ugly as fuck - static FirebaseFirestore db = FirebaseFirestore.instance; - static UserViewModel userViewModel = UserViewModel(); - static MusicViewModel musicViewModel = MusicViewModel(); - - const MyApp({super.key}); - - // This widget is the root of your application. - @override - Widget build(BuildContext context) { - SystemChrome.setEnabledSystemUIMode(SystemUiMode.immersiveSticky); - Paint.enableDithering = true; - return ScreenUtilInit( - builder: (context, child) { - return MaterialApp( - routes: { - '/welcome': (context) => WellcomeScreen(), - '/feed': (context) => FeedScreen(), - '/login': (context) => LoginScreen(), - '/register': (context) => RegistrationScreen(), - '/post': (context) => PostScreen(), - '/profile': (context) => ProfileScreen(), - '/explanation': (context) => ExplanationsScreen(), - }, - debugShowCheckedModeBanner: false, - theme: ThemeData( - // This is the theme of your application. - // - // Try running your application with "flutter run". You'll see the - // application has a blue toolbar. Then, without quitting the app, try - // changing the primarySwatch below to Colors.green and then invoke - // "hot reload" (press "r" in the console where you ran "flutter run", - // or simply save your changes to "hot reload" in a Flutter IDE). - // Notice that the counter didn't reset back to zero; the application - // is not restarted. - primarySwatch: Colors.blue, - ), - home: WellcomeScreen()); - }, - designSize: Size(390, 844), - ); - } -} +import 'package:cloud_firestore/cloud_firestore.dart'; +import 'package:flutter/material.dart'; +import 'package:flutter/services.dart'; +import 'package:flutter_screenutil/flutter_screenutil.dart'; +import 'package:justmusic/screens/explanations_screen.dart'; +import 'package:justmusic/screens/feed_screen.dart'; +import 'package:justmusic/screens/login_screen.dart'; +import 'package:justmusic/screens/post_screen.dart'; +import 'package:justmusic/screens/profile_screen.dart'; +import 'package:justmusic/screens/registration_screen.dart'; +import 'package:justmusic/screens/welcome_screen.dart'; +import 'package:justmusic/view_model/MusicViewModel.dart'; +import 'package:justmusic/view_model/UserViewModel.dart'; +import 'package:firebase_core/firebase_core.dart'; +import 'firebase_options.dart'; + +Future main() async { + WidgetsFlutterBinding.ensureInitialized(); + await Firebase.initializeApp( + options: DefaultFirebaseOptions.currentPlatform, + ); + runApp(const MyApp()); +} + +class MyApp extends StatelessWidget { + // ugly as fuck + static FirebaseFirestore db = FirebaseFirestore.instance; + static UserViewModel userViewModel = UserViewModel(); + static MusicViewModel musicViewModel = MusicViewModel(); + + const MyApp({super.key}); + + // This widget is the root of your application. + @override + Widget build(BuildContext context) { + SystemChrome.setEnabledSystemUIMode(SystemUiMode.immersiveSticky); + Paint.enableDithering = true; + return ScreenUtilInit( + builder: (context, child) { + return MaterialApp( + routes: { + '/welcome': (context) => WellcomeScreen(), + '/feed': (context) => FeedScreen(), + '/login': (context) => LoginScreen(), + '/register': (context) => RegistrationScreen(), + '/post': (context) => PostScreen(), + '/profile': (context) => ProfileScreen(), + '/explanation': (context) => ExplanationsScreen(), + }, + debugShowCheckedModeBanner: false, + theme: ThemeData( + // This is the theme of your application. + // + // Try running your application with "flutter run". You'll see the + // application has a blue toolbar. Then, without quitting the app, try + // changing the primarySwatch below to Colors.green and then invoke + // "hot reload" (press "r" in the console where you ran "flutter run", + // or simply save your changes to "hot reload" in a Flutter IDE). + // Notice that the counter didn't reset back to zero; the application + // is not restarted. + primarySwatch: Colors.blue, + ), + home: WellcomeScreen()); + }, + designSize: Size(390, 844), + ); + } +} diff --git a/Sources/justMUSIC/lib/model/Music.dart b/Sources/justMUSIC/lib/model/Music.dart index 367d6a6..26103d4 100644 --- a/Sources/justMUSIC/lib/model/Music.dart +++ b/Sources/justMUSIC/lib/model/Music.dart @@ -1,61 +1,61 @@ -import 'Artist.dart'; - -class Music { - final String _id; - String? _title; - String? _cover; - String? _previewUrl; - DateTime? _date; - double? _duration; - bool _explicit = false; - List _artists; - - // Constructor - Music(this._id, this._title, this._cover, this._previewUrl, this._date, - this._duration, this._explicit, this._artists); - - //Getters and setters - String? get id => _id; - - String? get title => _title; - - set title(String? value) { - _title = value; - } - - String? get cover => _cover; - - set cover(String? value) { - _cover = value; - } - - String? get previewUrl => _previewUrl; - - set previewUrl(String? value) { - _previewUrl = value; - } - - DateTime? get date => _date; - - set date(DateTime? value) { - _date = value; - } - - double? get duration => _duration; - - set duration(double? value) { - _duration = value; - } - - bool get explicit => _explicit; - - set explicit(bool value) { - _explicit = value; - } - - List get artists => _artists; - - set artists(List value) { - _artists = value; - } -} +import 'Artist.dart'; + +class Music { + final String _id; + String? _title; + String? _cover; + String? _previewUrl; + DateTime? _date; + double? _duration; + bool _explicit = false; + List _artists; + + // Constructor + Music(this._id, this._title, this._cover, this._previewUrl, this._date, + this._duration, this._explicit, this._artists); + + //Getters and setters + String? get id => _id; + + String? get title => _title; + + set title(String? value) { + _title = value; + } + + String? get cover => _cover; + + set cover(String? value) { + _cover = value; + } + + String? get previewUrl => _previewUrl; + + set previewUrl(String? value) { + _previewUrl = value; + } + + DateTime? get date => _date; + + set date(DateTime? value) { + _date = value; + } + + double? get duration => _duration; + + set duration(double? value) { + _duration = value; + } + + bool get explicit => _explicit; + + set explicit(bool value) { + _explicit = value; + } + + List get artists => _artists; + + set artists(List value) { + _artists = value; + } +} diff --git a/Sources/justMUSIC/lib/model/User.dart b/Sources/justMUSIC/lib/model/User.dart index f53996b..0f0bb79 100644 --- a/Sources/justMUSIC/lib/model/User.dart +++ b/Sources/justMUSIC/lib/model/User.dart @@ -1,60 +1,60 @@ -class User { - final String _id; - String _pseudo; - String _country; - String _mail; - String _pp; - int _followers; - int _capsules; - int _followed; - List friends = []; - - // Constructor - User(this._id, this._pseudo, this._country, this._mail, this._pp, - this._followers, this._capsules, this._followed, this.friends); - - //Getters and setters - String get id => _id; - - String get pseudo => _pseudo; - - set pseudo(String value) { - _pseudo = value; - } - - String get country => _country; - - set country(String value) { - _country = value; - } - - String get mail => _mail; - - set mail(String value) { - _mail = value; - } - - String get pp => _pp; - - set pp(String value) { - _pp = value; - } - - int get capsules => _capsules; - - set capsules(int value) { - _capsules = value; - } - - int get followed => _followed; - - set followed(int value) { - _followed = value; - } - - int get followers => _followers; - - set followers(int value) { - _followers = value; - } -} +class User { + final String _id; + String _pseudo; + String _country; + String _mail; + String _pp; + int _followers; + int _capsules; + int _followed; + List friends = []; + + // Constructor + User(this._id, this._pseudo, this._country, this._mail, this._pp, + this._followers, this._capsules, this._followed, this.friends); + + //Getters and setters + String get id => _id; + + String get pseudo => _pseudo; + + set pseudo(String value) { + _pseudo = value; + } + + String get country => _country; + + set country(String value) { + _country = value; + } + + String get mail => _mail; + + set mail(String value) { + _mail = value; + } + + String get pp => _pp; + + set pp(String value) { + _pp = value; + } + + int get capsules => _capsules; + + set capsules(int value) { + _capsules = value; + } + + int get followed => _followed; + + set followed(int value) { + _followed = value; + } + + int get followers => _followers; + + set followers(int value) { + _followers = value; + } +} diff --git a/Sources/justMUSIC/lib/model/mapper/UserMapper.dart b/Sources/justMUSIC/lib/model/mapper/UserMapper.dart index a7d3a24..58a3f15 100644 --- a/Sources/justMUSIC/lib/model/mapper/UserMapper.dart +++ b/Sources/justMUSIC/lib/model/mapper/UserMapper.dart @@ -1,31 +1,31 @@ -import 'package:cloud_firestore/cloud_firestore.dart'; -import 'package:justmusic/model/User.dart'; - -class UserMapper { - static User toModel(DocumentSnapshot> snapshot, - SnapshotOptions? options) { - final data = snapshot.data(); - return User( - data?["uid"] ?? "", - data?["pseudo"] ?? "", - data?["country"] ?? "", - data?["mail"] ?? "", - data?["profilePicture"] ?? "", - data?["followers"] ?? 0, - data?["nbCapsules"] ?? 0, - data?["followed"] ?? 0, - data?['friends'] is List ? List.from(data?['friends']) : []); - } -/* - static Map toFirebase(User user) { - return { - if (user.pseudo != null) "name": u, - if (user.country != null) "state": state, - if (user.mail != null) "country": country, - if (user.pp != null) "capital": capital, - if (user.followers != null) "population": population, - if (user.capsules != null) "regions": regions, - if () - }; - }*/ -} +import 'package:cloud_firestore/cloud_firestore.dart'; +import 'package:justmusic/model/User.dart'; + +class UserMapper { + static User toModel(DocumentSnapshot> snapshot, + SnapshotOptions? options) { + final data = snapshot.data(); + return User( + data?["uid"] ?? "", + data?["pseudo"] ?? "", + data?["country"] ?? "", + data?["mail"] ?? "", + data?["profilePicture"] ?? "", + data?["followers"] ?? 0, + data?["nbCapsules"] ?? 0, + data?["followed"] ?? 0, + data?['friends'] is List ? List.from(data?['friends']) : []); + } +/* + static Map toFirebase(User user) { + return { + if (user.pseudo != null) "name": u, + if (user.country != null) "state": state, + if (user.mail != null) "country": country, + if (user.pp != null) "capital": capital, + if (user.followers != null) "population": population, + if (user.capsules != null) "regions": regions, + if () + }; + }*/ +} diff --git a/Sources/justMUSIC/lib/screens/feed_screen.dart b/Sources/justMUSIC/lib/screens/feed_screen.dart index 3e2c6ea..95b696a 100644 --- a/Sources/justMUSIC/lib/screens/feed_screen.dart +++ b/Sources/justMUSIC/lib/screens/feed_screen.dart @@ -1,297 +1,297 @@ -import 'package:circular_reveal_animation/circular_reveal_animation.dart'; -import 'package:flutter/cupertino.dart'; -import 'package:flutter/material.dart'; -import 'package:flutter/services.dart'; -import 'package:flutter_screenutil/flutter_screenutil.dart'; -import 'package:google_fonts/google_fonts.dart'; -import '../components/comment_component.dart'; -import '../components/post_component.dart'; -import '../components/top_nav_bar_component.dart'; -import '../values/constants.dart'; - -class FeedScreen extends StatefulWidget { - const FeedScreen({Key? key}) : super(key: key); - - @override - State createState() => _FeedScreenState(); -} - -class _FeedScreenState extends State - with SingleTickerProviderStateMixin { - late AnimationController animationController; - late Animation animation; - late List friendFeed; - late List discoveryFeed; - late List displayFeed; - - @override - void initState() { - super.initState(); - friendFeed = [ - PostComponent( - callback: openDetailPost, - ), - PostComponent( - callback: openDetailPost, - ), - PostComponent( - callback: openDetailPost, - ), - ]; - discoveryFeed = [ - PostComponent(callback: openDetailPost), - ]; - displayFeed = friendFeed; - animationController = AnimationController( - vsync: this, - duration: Duration(milliseconds: 400), - ); - animation = CurvedAnimation( - parent: animationController, - curve: Curves.easeInOutSine, - ); - animationController.forward(); - } - - Future resetFullScreen() async { - await SystemChannels.platform.invokeMethod( - 'SystemChrome.restoreSystemUIOverlays', - ); - } - - void changeFeed(bool choice) { - // Mettez ici le code pour l'action que vous souhaitez effectuer avec le paramètre - if (choice) { - setState(() { - animationController.reset(); - displayFeed = friendFeed; - animationController.forward(); - }); - } else { - setState(() { - animationController.reset(); - displayFeed = discoveryFeed; - animationController.forward(); - }); - } - } - - void openDetailPost() { - showModalBottomSheet( - backgroundColor: bgModal, - elevation: 1, - constraints: const BoxConstraints( - maxWidth: 600, - ), - isScrollControlled: true, - context: context, - shape: const RoundedRectangleBorder( - borderRadius: BorderRadius.only( - topLeft: Radius.circular(20), topRight: Radius.circular(20))), - builder: ((context) { - return GestureDetector( - onTap: () { - FocusScopeNode currentFocus = FocusScope.of(context); - if (!currentFocus.hasPrimaryFocus) { - currentFocus.unfocus(); - resetFullScreen(); - } - }, - child: Container( - height: 720.h, - margin: const EdgeInsets.only(top: 10), - child: Column( - children: [ - Align( - child: Container( - width: 60, - height: 5, - decoration: BoxDecoration( - color: Colors.white.withOpacity(0.3), - borderRadius: BorderRadius.circular(20))), - ), - const SizedBox( - height: 20, - ), - Expanded( - child: ClipRRect( - borderRadius: BorderRadius.only( - topRight: Radius.circular(15), - topLeft: Radius.circular(15)), - child: Padding( - padding: EdgeInsets.only( - left: defaultPadding, right: defaultPadding), - child: SingleChildScrollView( - child: Wrap( - // to apply margin in the main axis of the wrap - runSpacing: 10, - children: [ - PostComponent( - callback: null, - ), - Container(height: 10), - Align( - child: RichText( - text: TextSpan( - text: "3", - style: GoogleFonts.plusJakartaSans( - color: Colors.white, - fontWeight: FontWeight.w600), - children: [ - TextSpan( - text: " commentaires", - style: GoogleFonts.plusJakartaSans( - color: Colors.white, - fontWeight: FontWeight.w300), - ) - ])), - ), - SizedBox(height: 20), - CommentComponent(), - CommentComponent(), - CommentComponent(), - Container(height: 10), - ], - ), - ), - ), - ), - ), - Padding( - padding: EdgeInsets.only( - bottom: MediaQuery.of(context).viewInsets.bottom), - child: Container( - height: 70, - width: double.infinity, - decoration: BoxDecoration( - border: Border( - top: BorderSide(color: grayColor, width: 2)), - color: textFieldMessage), - child: Center( - child: Padding( - padding: const EdgeInsets.symmetric(horizontal: 20), - child: Row( - children: [ - ClipOval( - child: SizedBox.fromSize( - // Image radius - child: const Image( - image: AssetImage( - "assets/images/exemple_profile.png"), - width: 45, - ), - ), - ), - SizedBox( - width: 10, - ), - Expanded( - child: TextField( - keyboardAppearance: Brightness.dark, - cursorColor: primaryColor, - keyboardType: TextInputType.emailAddress, - style: GoogleFonts.plusJakartaSans( - color: Colors.white), - decoration: InputDecoration( - suffixIcon: Icon( - Icons.send, - color: grayText, - size: 20, - ), - focusedBorder: OutlineInputBorder( - borderSide: BorderSide( - width: 1, color: grayText), - borderRadius: BorderRadius.all( - Radius.circular(100))), - contentPadding: EdgeInsets.only( - top: 0, - bottom: 0, - left: 20, - right: 20), - fillColor: bgModal, - filled: true, - focusColor: - Color.fromRGBO(255, 255, 255, 0.30), - enabledBorder: OutlineInputBorder( - borderSide: BorderSide( - width: 1, color: grayText), - borderRadius: BorderRadius.all( - Radius.circular(100))), - hintText: 'Ajoutez une réponse...', - hintStyle: GoogleFonts.plusJakartaSans( - color: grayText)), - ), - ) - ], - ), - ), - )), - ), - ], - ), - ), - ); - }), - ); - } - - @override - Widget build(BuildContext context) { - return Scaffold( - resizeToAvoidBottomInset: true, - backgroundColor: bgColor, - body: Stack( - children: [ - CircularRevealAnimation( - animation: animation, - centerOffset: Offset(30.w, -100), - child: SingleChildScrollView( - child: SizedBox( - width: double.infinity, - child: Align( - child: ConstrainedBox( - constraints: BoxConstraints(maxWidth: 600), - child: Padding( - padding: const EdgeInsets.symmetric( - horizontal: defaultPadding), - child: Container( - width: double.infinity, - child: Padding( - padding: EdgeInsets.only(top: 100.h), - child: SingleChildScrollView( - child: Wrap( - runSpacing: 60, - children: displayFeed, - ), - )), - ), - ), - ), - )), - ), - ), - IgnorePointer( - child: Container( - height: 240.h, - decoration: BoxDecoration( - gradient: LinearGradient(begin: Alignment.topRight, stops: [ - 0.3, - 1 - ], colors: [ - bgColor.withOpacity(0.9), - bgColor.withOpacity(0) - ])), - ), - ), - Align( - alignment: Alignment.topCenter, - child: ConstrainedBox( - constraints: BoxConstraints(maxWidth: 800), - child: TopNavBarComponent(callback: changeFeed), - ), - ), - ], - ), - ); - } -} +import 'package:circular_reveal_animation/circular_reveal_animation.dart'; +import 'package:flutter/cupertino.dart'; +import 'package:flutter/material.dart'; +import 'package:flutter/services.dart'; +import 'package:flutter_screenutil/flutter_screenutil.dart'; +import 'package:google_fonts/google_fonts.dart'; +import '../components/comment_component.dart'; +import '../components/post_component.dart'; +import '../components/top_nav_bar_component.dart'; +import '../values/constants.dart'; + +class FeedScreen extends StatefulWidget { + const FeedScreen({Key? key}) : super(key: key); + + @override + State createState() => _FeedScreenState(); +} + +class _FeedScreenState extends State + with SingleTickerProviderStateMixin { + late AnimationController animationController; + late Animation animation; + late List friendFeed; + late List discoveryFeed; + late List displayFeed; + + @override + void initState() { + super.initState(); + friendFeed = [ + PostComponent( + callback: openDetailPost, + ), + PostComponent( + callback: openDetailPost, + ), + PostComponent( + callback: openDetailPost, + ), + ]; + discoveryFeed = [ + PostComponent(callback: openDetailPost), + ]; + displayFeed = friendFeed; + animationController = AnimationController( + vsync: this, + duration: Duration(milliseconds: 400), + ); + animation = CurvedAnimation( + parent: animationController, + curve: Curves.easeInOutSine, + ); + animationController.forward(); + } + + Future resetFullScreen() async { + await SystemChannels.platform.invokeMethod( + 'SystemChrome.restoreSystemUIOverlays', + ); + } + + void changeFeed(bool choice) { + // Mettez ici le code pour l'action que vous souhaitez effectuer avec le paramètre + if (choice) { + setState(() { + animationController.reset(); + displayFeed = friendFeed; + animationController.forward(); + }); + } else { + setState(() { + animationController.reset(); + displayFeed = discoveryFeed; + animationController.forward(); + }); + } + } + + void openDetailPost() { + showModalBottomSheet( + backgroundColor: bgModal, + elevation: 1, + constraints: const BoxConstraints( + maxWidth: 600, + ), + isScrollControlled: true, + context: context, + shape: const RoundedRectangleBorder( + borderRadius: BorderRadius.only( + topLeft: Radius.circular(20), topRight: Radius.circular(20))), + builder: ((context) { + return GestureDetector( + onTap: () { + FocusScopeNode currentFocus = FocusScope.of(context); + if (!currentFocus.hasPrimaryFocus) { + currentFocus.unfocus(); + resetFullScreen(); + } + }, + child: Container( + height: 720.h, + margin: const EdgeInsets.only(top: 10), + child: Column( + children: [ + Align( + child: Container( + width: 60, + height: 5, + decoration: BoxDecoration( + color: Colors.white.withOpacity(0.3), + borderRadius: BorderRadius.circular(20))), + ), + const SizedBox( + height: 20, + ), + Expanded( + child: ClipRRect( + borderRadius: BorderRadius.only( + topRight: Radius.circular(15), + topLeft: Radius.circular(15)), + child: Padding( + padding: EdgeInsets.only( + left: defaultPadding, right: defaultPadding), + child: SingleChildScrollView( + child: Wrap( + // to apply margin in the main axis of the wrap + runSpacing: 10, + children: [ + PostComponent( + callback: null, + ), + Container(height: 10), + Align( + child: RichText( + text: TextSpan( + text: "3", + style: GoogleFonts.plusJakartaSans( + color: Colors.white, + fontWeight: FontWeight.w600), + children: [ + TextSpan( + text: " commentaires", + style: GoogleFonts.plusJakartaSans( + color: Colors.white, + fontWeight: FontWeight.w300), + ) + ])), + ), + SizedBox(height: 20), + CommentComponent(), + CommentComponent(), + CommentComponent(), + Container(height: 10), + ], + ), + ), + ), + ), + ), + Padding( + padding: EdgeInsets.only( + bottom: MediaQuery.of(context).viewInsets.bottom), + child: Container( + height: 70, + width: double.infinity, + decoration: BoxDecoration( + border: Border( + top: BorderSide(color: grayColor, width: 2)), + color: textFieldMessage), + child: Center( + child: Padding( + padding: const EdgeInsets.symmetric(horizontal: 20), + child: Row( + children: [ + ClipOval( + child: SizedBox.fromSize( + // Image radius + child: const Image( + image: AssetImage( + "assets/images/exemple_profile.png"), + width: 45, + ), + ), + ), + SizedBox( + width: 10, + ), + Expanded( + child: TextField( + keyboardAppearance: Brightness.dark, + cursorColor: primaryColor, + keyboardType: TextInputType.emailAddress, + style: GoogleFonts.plusJakartaSans( + color: Colors.white), + decoration: InputDecoration( + suffixIcon: Icon( + Icons.send, + color: grayText, + size: 20, + ), + focusedBorder: OutlineInputBorder( + borderSide: BorderSide( + width: 1, color: grayText), + borderRadius: BorderRadius.all( + Radius.circular(100))), + contentPadding: EdgeInsets.only( + top: 0, + bottom: 0, + left: 20, + right: 20), + fillColor: bgModal, + filled: true, + focusColor: + Color.fromRGBO(255, 255, 255, 0.30), + enabledBorder: OutlineInputBorder( + borderSide: BorderSide( + width: 1, color: grayText), + borderRadius: BorderRadius.all( + Radius.circular(100))), + hintText: 'Ajoutez une réponse...', + hintStyle: GoogleFonts.plusJakartaSans( + color: grayText)), + ), + ) + ], + ), + ), + )), + ), + ], + ), + ), + ); + }), + ); + } + + @override + Widget build(BuildContext context) { + return Scaffold( + resizeToAvoidBottomInset: true, + backgroundColor: bgColor, + body: Stack( + children: [ + CircularRevealAnimation( + animation: animation, + centerOffset: Offset(30.w, -100), + child: SingleChildScrollView( + child: SizedBox( + width: double.infinity, + child: Align( + child: ConstrainedBox( + constraints: BoxConstraints(maxWidth: 600), + child: Padding( + padding: const EdgeInsets.symmetric( + horizontal: defaultPadding), + child: Container( + width: double.infinity, + child: Padding( + padding: EdgeInsets.only(top: 100.h), + child: SingleChildScrollView( + child: Wrap( + runSpacing: 60, + children: displayFeed, + ), + )), + ), + ), + ), + )), + ), + ), + IgnorePointer( + child: Container( + height: 240.h, + decoration: BoxDecoration( + gradient: LinearGradient(begin: Alignment.topRight, stops: [ + 0.3, + 1 + ], colors: [ + bgColor.withOpacity(0.9), + bgColor.withOpacity(0) + ])), + ), + ), + Align( + alignment: Alignment.topCenter, + child: ConstrainedBox( + constraints: BoxConstraints(maxWidth: 800), + child: TopNavBarComponent(callback: changeFeed), + ), + ), + ], + ), + ); + } +} diff --git a/Sources/justMUSIC/lib/screens/login_screen.dart b/Sources/justMUSIC/lib/screens/login_screen.dart index 578ec8b..2ca2f03 100644 --- a/Sources/justMUSIC/lib/screens/login_screen.dart +++ b/Sources/justMUSIC/lib/screens/login_screen.dart @@ -1,373 +1,373 @@ -import 'package:firebase_auth/firebase_auth.dart'; -import 'package:flutter/cupertino.dart'; -import 'package:flutter/material.dart'; -import 'package:flutter/services.dart'; -import 'package:flutter_screenutil/flutter_screenutil.dart'; -import 'package:flutter_signin_button/button_list.dart'; -import 'package:flutter_signin_button/button_view.dart'; -import 'package:google_fonts/google_fonts.dart'; -import 'package:justmusic/main.dart'; -import 'package:justmusic/values/constants.dart'; - -import '../components/login_button.dart'; - -class LoginScreen extends StatefulWidget { - const LoginScreen({Key? key}) : super(key: key); - - @override - State createState() => _LoginScreenState(); -} - -class _LoginScreenState extends State { - bool passenable = true; - final _formKey = GlobalKey(); - final _userMailTextField = TextEditingController(); - final _passwordTextField = TextEditingController(); - - handleLogin() async { - if (_formKey.currentState!.validate()) { - try { - await MyApp.userViewModel - .login(_userMailTextField.text, _passwordTextField.text); - Navigator.pushNamed(context, '/explanation'); - } catch (e) { - ScaffoldMessenger.of(context).showSnackBar( - SnackBar( - content: Text( - e.toString() ?? "", - style: GoogleFonts.plusJakartaSans( - color: Colors.white, - fontWeight: FontWeight.w400, - fontSize: 20.h), - ), - backgroundColor: Colors.red, - ), - ); - } - } - } - - @override - Widget build(BuildContext context) { - return GestureDetector( - onTap: () => FocusManager.instance.primaryFocus?.unfocus(), - child: Scaffold( - resizeToAvoidBottomInset: false, - backgroundColor: bgColor, - body: Align( - child: SizedBox( - height: double.infinity, - width: 600, - child: Column( - mainAxisAlignment: MainAxisAlignment.center, - children: [ - Expanded( - child: Padding( - padding: EdgeInsets.only(left: 40, right: 40), - child: Form( - key: _formKey, - child: Column( - crossAxisAlignment: - CrossAxisAlignment.center, - children: [ - Flexible( - flex: 4, - child: Padding( - padding: EdgeInsets.only(bottom: 60), - child: Column( - mainAxisAlignment: - MainAxisAlignment.end, - children: [ - Text( - "Te revoilà!", - style: - GoogleFonts.plusJakartaSans( - color: Colors.white, - fontWeight: - FontWeight.w600, - fontSize: 38.h), - ), - SizedBox( - height: 10, - ), - SizedBox( - width: 230.w, - child: Text( - "Bon retour parmis nous tu nous as manqué!", - style: GoogleFonts - .plusJakartaSans( - color: Colors.white, - fontWeight: - FontWeight.w400, - fontSize: 20.h), - textAlign: TextAlign.center, - ), - ), - ], - ), - ), - ), - Expanded( - flex: 5, - child: Column( - crossAxisAlignment: - CrossAxisAlignment.end, - mainAxisAlignment: - MainAxisAlignment.center, - children: [ - TextFormField( - controller: _userMailTextField, - keyboardAppearance: - Brightness.dark, - validator: (value) { - if (value == null || - value.isEmpty) { - return 'entrez un email valide'; - } - return null; - }, - cursorColor: primaryColor, - keyboardType: - TextInputType.emailAddress, - style: - GoogleFonts.plusJakartaSans( - color: primaryColor), - decoration: InputDecoration( - focusedBorder: OutlineInputBorder( - borderSide: BorderSide( - width: 1, - color: - strokeTextField), - borderRadius: BorderRadius.all( - Radius.circular(10))), - prefix: const Padding( - padding: EdgeInsets.only( - left: 20.0)), - suffix: const Padding( - padding: EdgeInsets.only( - left: 20.0)), - fillColor: bgTextField, - filled: true, - errorStyle: TextStyle( - fontSize: 9, height: 0.3), - focusColor: Color.fromRGBO( - 255, 255, 255, 0.30), - enabledBorder: OutlineInputBorder( - borderSide: - BorderSide(width: 1, color: strokeTextField), - borderRadius: BorderRadius.all(Radius.circular(10))), - hintText: 'Email', - hintStyle: GoogleFonts.plusJakartaSans(color: strokeTextField)), - ), - SizedBox( - height: 18, - ), - TextFormField( - controller: _passwordTextField, - keyboardAppearance: - Brightness.dark, - obscureText: passenable, - validator: (value) { - if (value == null || - value.isEmpty) { - return 'entrez un mot de passe valide'; - } - return null; - }, - cursorColor: primaryColor, - style: - GoogleFonts.plusJakartaSans( - color: primaryColor), - decoration: InputDecoration( - focusedBorder: - OutlineInputBorder( - borderSide: BorderSide( - width: 1, - color: - strokeTextField), - borderRadius: - BorderRadius.all( - Radius.circular( - 10))), - fillColor: bgTextField, - filled: true, - focusColor: Color.fromRGBO( - 255, 255, 255, 0.30), - enabledBorder: - OutlineInputBorder( - borderSide: BorderSide( - width: 1, - color: - strokeTextField), - borderRadius: - BorderRadius.all( - Radius.circular( - 10))), - hintText: 'Mot de passe', - hintStyle: - GoogleFonts.plusJakartaSans( - color: strokeTextField), - prefix: const Padding( - padding: EdgeInsets.only( - left: 20.0)), - suffixIcon: Container( - padding: EdgeInsets.only( - right: 10), - margin: EdgeInsets.all(5), - height: 3, - child: InkWell( - onTap: () { - setState(() { - if (passenable) { - passenable = false; - } else { - passenable = true; - } - }); - }, - // Image tapped - splashColor: - Colors.white10, - // Splash color over image - child: Image( - image: passenable - ? AssetImage( - "assets/images/show_icon.png") - : AssetImage( - "assets/images/hide_icon.png"), - height: 2, - ), - )), - errorStyle: TextStyle( - fontSize: 9, height: 0.3), - ), - ), - Padding( - padding: EdgeInsets.only(top: 10), - child: Text( - "Mot de passe oublié?", - style: - GoogleFonts.plusJakartaSans( - color: Colors.white), - ), - ), - SizedBox( - height: defaultPadding, - ), - SizedBox( - width: 600, - child: LoginButton( - callback: handleLogin, - )), - Align( - child: GestureDetector( - onTap: () { - Navigator.pushNamed( - context, '/register'); - }, - child: Padding( - padding: - EdgeInsets.only(top: 20), - child: RichText( - textAlign: TextAlign.center, - text: TextSpan( - text: - 'Pas encore inscrit?', - style: GoogleFonts - .plusJakartaSans( - color: - Colors.white, - fontWeight: - FontWeight - .w400, - fontSize: 15), - children: [ - TextSpan( - text: " S’inscire", - style: GoogleFonts - .plusJakartaSans( - fontSize: - 15, - fontWeight: - FontWeight - .w400, - color: - primaryColor)), - ], - ), - ), - ), - ), - ), - ], - ), - ), - Expanded( - flex: 3, - child: Padding( - padding: EdgeInsets.only(top: 20), - child: Column( - mainAxisAlignment: - MainAxisAlignment.start, - crossAxisAlignment: - CrossAxisAlignment.center, - children: [ - ConstrainedBox( - constraints: BoxConstraints( - maxWidth: 600), - child: Row( - mainAxisAlignment: - MainAxisAlignment - .spaceEvenly, - children: [ - Expanded( - child: Container( - color: - Color(0xFF3D3D3D), - height: 1, - ), - ), - Padding( - padding: const EdgeInsets - .only( - left: - defaultPadding, - right: - defaultPadding), - child: Text( - 'Ou', - style: GoogleFonts - .plusJakartaSans( - color: Colors - .white, - fontWeight: - FontWeight - .bold), - ), - ), - Expanded( - child: Container( - height: 1, - color: - Color(0xFF3D3D3D), - )), - ], - ), - ), - SizedBox( - height: defaultPadding), - SignInButton( - Buttons.Google, - text: "Login with Google", - onPressed: () {}, - ), - ], - ), - )) - ], - )))) - ], - )), - ))); - } -} +import 'package:firebase_auth/firebase_auth.dart'; +import 'package:flutter/cupertino.dart'; +import 'package:flutter/material.dart'; +import 'package:flutter/services.dart'; +import 'package:flutter_screenutil/flutter_screenutil.dart'; +import 'package:flutter_signin_button/button_list.dart'; +import 'package:flutter_signin_button/button_view.dart'; +import 'package:google_fonts/google_fonts.dart'; +import 'package:justmusic/main.dart'; +import 'package:justmusic/values/constants.dart'; + +import '../components/login_button.dart'; + +class LoginScreen extends StatefulWidget { + const LoginScreen({Key? key}) : super(key: key); + + @override + State createState() => _LoginScreenState(); +} + +class _LoginScreenState extends State { + bool passenable = true; + final _formKey = GlobalKey(); + final _userMailTextField = TextEditingController(); + final _passwordTextField = TextEditingController(); + + handleLogin() async { + if (_formKey.currentState!.validate()) { + try { + await MyApp.userViewModel + .login(_userMailTextField.text, _passwordTextField.text); + Navigator.pushNamed(context, '/feed'); + } catch (e) { + ScaffoldMessenger.of(context).showSnackBar( + SnackBar( + content: Text( + e.toString() ?? "", + style: GoogleFonts.plusJakartaSans( + color: Colors.white, + fontWeight: FontWeight.w400, + fontSize: 20.h), + ), + backgroundColor: Colors.red, + ), + ); + } + } + } + + @override + Widget build(BuildContext context) { + return GestureDetector( + onTap: () => FocusManager.instance.primaryFocus?.unfocus(), + child: Scaffold( + resizeToAvoidBottomInset: false, + backgroundColor: bgColor, + body: Align( + child: SizedBox( + height: double.infinity, + width: 600, + child: Column( + mainAxisAlignment: MainAxisAlignment.center, + children: [ + Expanded( + child: Padding( + padding: EdgeInsets.only(left: 40, right: 40), + child: Form( + key: _formKey, + child: Column( + crossAxisAlignment: + CrossAxisAlignment.center, + children: [ + Flexible( + flex: 4, + child: Padding( + padding: EdgeInsets.only(bottom: 60), + child: Column( + mainAxisAlignment: + MainAxisAlignment.end, + children: [ + Text( + "Te revoilà!", + style: + GoogleFonts.plusJakartaSans( + color: Colors.white, + fontWeight: + FontWeight.w600, + fontSize: 38.h), + ), + SizedBox( + height: 10, + ), + SizedBox( + width: 230.w, + child: Text( + "Bon retour parmis nous tu nous as manqué!", + style: GoogleFonts + .plusJakartaSans( + color: Colors.white, + fontWeight: + FontWeight.w400, + fontSize: 20.h), + textAlign: TextAlign.center, + ), + ), + ], + ), + ), + ), + Expanded( + flex: 5, + child: Column( + crossAxisAlignment: + CrossAxisAlignment.end, + mainAxisAlignment: + MainAxisAlignment.center, + children: [ + TextFormField( + controller: _userMailTextField, + keyboardAppearance: + Brightness.dark, + validator: (value) { + if (value == null || + value.isEmpty) { + return 'entrez un email valide'; + } + return null; + }, + cursorColor: primaryColor, + keyboardType: + TextInputType.emailAddress, + style: + GoogleFonts.plusJakartaSans( + color: primaryColor), + decoration: InputDecoration( + focusedBorder: OutlineInputBorder( + borderSide: BorderSide( + width: 1, + color: + strokeTextField), + borderRadius: BorderRadius.all( + Radius.circular(10))), + prefix: const Padding( + padding: EdgeInsets.only( + left: 20.0)), + suffix: const Padding( + padding: EdgeInsets.only( + left: 20.0)), + fillColor: bgTextField, + filled: true, + errorStyle: TextStyle( + fontSize: 9, height: 0.3), + focusColor: Color.fromRGBO( + 255, 255, 255, 0.30), + enabledBorder: OutlineInputBorder( + borderSide: + BorderSide(width: 1, color: strokeTextField), + borderRadius: BorderRadius.all(Radius.circular(10))), + hintText: 'Email', + hintStyle: GoogleFonts.plusJakartaSans(color: strokeTextField)), + ), + SizedBox( + height: 18, + ), + TextFormField( + controller: _passwordTextField, + keyboardAppearance: + Brightness.dark, + obscureText: passenable, + validator: (value) { + if (value == null || + value.isEmpty) { + return 'entrez un mot de passe valide'; + } + return null; + }, + cursorColor: primaryColor, + style: + GoogleFonts.plusJakartaSans( + color: primaryColor), + decoration: InputDecoration( + focusedBorder: + OutlineInputBorder( + borderSide: BorderSide( + width: 1, + color: + strokeTextField), + borderRadius: + BorderRadius.all( + Radius.circular( + 10))), + fillColor: bgTextField, + filled: true, + focusColor: Color.fromRGBO( + 255, 255, 255, 0.30), + enabledBorder: + OutlineInputBorder( + borderSide: BorderSide( + width: 1, + color: + strokeTextField), + borderRadius: + BorderRadius.all( + Radius.circular( + 10))), + hintText: 'Mot de passe', + hintStyle: + GoogleFonts.plusJakartaSans( + color: strokeTextField), + prefix: const Padding( + padding: EdgeInsets.only( + left: 20.0)), + suffixIcon: Container( + padding: EdgeInsets.only( + right: 10), + margin: EdgeInsets.all(5), + height: 3, + child: InkWell( + onTap: () { + setState(() { + if (passenable) { + passenable = false; + } else { + passenable = true; + } + }); + }, + // Image tapped + splashColor: + Colors.white10, + // Splash color over image + child: Image( + image: passenable + ? AssetImage( + "assets/images/show_icon.png") + : AssetImage( + "assets/images/hide_icon.png"), + height: 2, + ), + )), + errorStyle: TextStyle( + fontSize: 9, height: 0.3), + ), + ), + Padding( + padding: EdgeInsets.only(top: 10), + child: Text( + "Mot de passe oublié?", + style: + GoogleFonts.plusJakartaSans( + color: Colors.white), + ), + ), + SizedBox( + height: defaultPadding, + ), + SizedBox( + width: 600, + child: LoginButton( + callback: handleLogin, + )), + Align( + child: GestureDetector( + onTap: () { + Navigator.pushNamed( + context, '/register'); + }, + child: Padding( + padding: + EdgeInsets.only(top: 20), + child: RichText( + textAlign: TextAlign.center, + text: TextSpan( + text: + 'Pas encore inscrit?', + style: GoogleFonts + .plusJakartaSans( + color: + Colors.white, + fontWeight: + FontWeight + .w400, + fontSize: 15), + children: [ + TextSpan( + text: " S’inscire", + style: GoogleFonts + .plusJakartaSans( + fontSize: + 15, + fontWeight: + FontWeight + .w400, + color: + primaryColor)), + ], + ), + ), + ), + ), + ), + ], + ), + ), + Expanded( + flex: 3, + child: Padding( + padding: EdgeInsets.only(top: 20), + child: Column( + mainAxisAlignment: + MainAxisAlignment.start, + crossAxisAlignment: + CrossAxisAlignment.center, + children: [ + ConstrainedBox( + constraints: BoxConstraints( + maxWidth: 600), + child: Row( + mainAxisAlignment: + MainAxisAlignment + .spaceEvenly, + children: [ + Expanded( + child: Container( + color: + Color(0xFF3D3D3D), + height: 1, + ), + ), + Padding( + padding: const EdgeInsets + .only( + left: + defaultPadding, + right: + defaultPadding), + child: Text( + 'Ou', + style: GoogleFonts + .plusJakartaSans( + color: Colors + .white, + fontWeight: + FontWeight + .bold), + ), + ), + Expanded( + child: Container( + height: 1, + color: + Color(0xFF3D3D3D), + )), + ], + ), + ), + SizedBox( + height: defaultPadding), + SignInButton( + Buttons.Google, + text: "Login with Google", + onPressed: () {}, + ), + ], + ), + )) + ], + )))) + ], + )), + ))); + } +} diff --git a/Sources/justMUSIC/lib/screens/registration_screen.dart b/Sources/justMUSIC/lib/screens/registration_screen.dart index ece7456..e7d9ecc 100644 --- a/Sources/justMUSIC/lib/screens/registration_screen.dart +++ b/Sources/justMUSIC/lib/screens/registration_screen.dart @@ -1,408 +1,458 @@ -import 'dart:ui'; - -import 'package:auto_size_text/auto_size_text.dart'; -import 'package:flutter/cupertino.dart'; -import 'package:flutter/material.dart'; -import 'package:flutter_screenutil/flutter_screenutil.dart'; -import 'package:flutter_signin_button/button_list.dart'; -import 'package:flutter_signin_button/button_view.dart'; -import 'package:google_fonts/google_fonts.dart'; -import 'package:justmusic/values/constants.dart'; - -import '../components/login_button.dart'; - -class RegistrationScreen extends StatefulWidget { - const RegistrationScreen({Key? key}) : super(key: key); - - @override - State createState() => _RegistrationScreenState(); -} - -class _RegistrationScreenState extends State { - bool passenable = true; - - @override - Widget build(BuildContext context) { - return Scaffold( - backgroundColor: bgColor, - body: Stack( - children: [ - SingleChildScrollView( - child: SizedBox( - width: double.infinity, - child: Column( - children: [ - Padding( - padding: EdgeInsets.only(top: 100.h), - child: AutoSizeText( - "On a besoin de ça!", - style: GoogleFonts.plusJakartaSans( - color: Colors.white, - fontWeight: FontWeight.w600, - fontSize: 30.w), - maxLines: 1, - maxFontSize: 50, - overflow: TextOverflow.fade, - ), - ), - ConstrainedBox( - constraints: BoxConstraints(maxWidth: 600), - child: Column( - mainAxisAlignment: MainAxisAlignment.start, - children: [ - Padding( - padding: - EdgeInsets.symmetric(horizontal: defaultPadding), - child: Padding( - padding: EdgeInsets.only(bottom: 50.h), - child: Column( - mainAxisAlignment: MainAxisAlignment.end, - children: [ - SizedBox( - height: 15.h, - ), - SizedBox( - width: 230.h, - child: AutoSizeText( - "Promis c’est rapide.", - style: GoogleFonts.plusJakartaSans( - color: Colors.white, - fontWeight: FontWeight.w400, - fontSize: 17.w), - maxFontSize: 20, - textAlign: TextAlign.center, - ), - ), - ], - ), - ), - ), - Padding( - padding: EdgeInsets.only( - bottom: 16.h, - left: defaultPadding, - right: defaultPadding), - child: TextFormField( - keyboardAppearance: Brightness.dark, - validator: (value) { - if (value == null || value.isEmpty) { - return 'TODO'; - } - return null; - }, - cursorColor: primaryColor, - keyboardType: TextInputType.emailAddress, - style: GoogleFonts.plusJakartaSans( - color: primaryColor, fontSize: 15), - decoration: InputDecoration( - focusedBorder: OutlineInputBorder( - borderSide: BorderSide( - width: 1.sp, color: strokeTextField), - borderRadius: const BorderRadius.all( - Radius.circular(10))), - contentPadding: const EdgeInsets.only( - top: 0, bottom: 0, left: defaultPadding), - fillColor: bgTextField, - filled: true, - focusColor: - const Color.fromRGBO(255, 255, 255, 0.30), - enabledBorder: const OutlineInputBorder( - borderSide: BorderSide( - width: 1, color: strokeTextField), - borderRadius: BorderRadius.all( - Radius.circular(10))), - hintText: 'Pseudo', - hintStyle: GoogleFonts.plusJakartaSans( - color: strokeTextField)), - )), - Padding( - padding: EdgeInsets.only( - bottom: 16.h, - left: defaultPadding, - right: defaultPadding), - child: TextFormField( - keyboardAppearance: Brightness.dark, - validator: (value) { - if (value == null || value.isEmpty) { - return 'TODO'; - } - return null; - }, - cursorColor: primaryColor, - keyboardType: TextInputType.emailAddress, - style: GoogleFonts.plusJakartaSans( - color: primaryColor), - decoration: InputDecoration( - focusedBorder: OutlineInputBorder( - borderSide: BorderSide( - width: 1, color: strokeTextField), - borderRadius: BorderRadius.all( - Radius.circular(10))), - contentPadding: EdgeInsets.only( - top: 0, bottom: 0, left: defaultPadding), - fillColor: bgTextField, - filled: true, - focusColor: - Color.fromRGBO(255, 255, 255, 0.30), - enabledBorder: OutlineInputBorder( - borderSide: BorderSide( - width: 1, color: strokeTextField), - borderRadius: BorderRadius.all( - Radius.circular(10))), - hintText: 'Email', - hintStyle: GoogleFonts.plusJakartaSans( - color: strokeTextField)), - )), - Padding( - padding: EdgeInsets.only( - bottom: 16.h, - left: defaultPadding, - right: defaultPadding), - child: TextFormField( - keyboardAppearance: Brightness.dark, - obscureText: passenable, - validator: (value) { - if (value == null || value.isEmpty) { - return 'TODO'; - } - return null; - }, - cursorColor: primaryColor, - keyboardType: TextInputType.emailAddress, - style: GoogleFonts.plusJakartaSans( - color: primaryColor), - decoration: InputDecoration( - focusedBorder: OutlineInputBorder( - borderSide: BorderSide( - width: 1, color: strokeTextField), - borderRadius: - BorderRadius.all(Radius.circular(10))), - contentPadding: EdgeInsets.only( - top: 0, bottom: 0, left: defaultPadding), - fillColor: bgTextField, - filled: true, - focusColor: Color.fromRGBO(255, 255, 255, 0.30), - enabledBorder: OutlineInputBorder( - borderSide: BorderSide( - width: 1, color: strokeTextField), - borderRadius: - BorderRadius.all(Radius.circular(10))), - hintText: 'Mot de passe', - hintStyle: GoogleFonts.plusJakartaSans( - color: strokeTextField), - suffixIcon: Container( - padding: EdgeInsets.only(right: 10), - margin: EdgeInsets.all(5), - height: 3, - child: InkWell( - onTap: () { - setState(() { - if (passenable) { - passenable = false; - } else { - passenable = true; - } - }); - }, // Image tapped - splashColor: Colors - .white10, // Splash color over image - child: Image( - image: passenable - ? AssetImage( - "assets/images/show_icon.png") - : AssetImage( - "assets/images/hide_icon.png"), - height: 2, - ), - )), - ), - ), - ), - Padding( - padding: EdgeInsets.only( - bottom: 16.h, - left: defaultPadding, - right: defaultPadding), - child: TextFormField( - keyboardAppearance: Brightness.dark, - obscureText: passenable, - validator: (value) { - if (value == null || value.isEmpty) { - return 'TODO'; - } - return null; - }, - cursorColor: primaryColor, - keyboardType: TextInputType.emailAddress, - style: GoogleFonts.plusJakartaSans( - color: primaryColor), - decoration: InputDecoration( - focusedBorder: OutlineInputBorder( - borderSide: BorderSide( - width: 1, color: strokeTextField), - borderRadius: - BorderRadius.all(Radius.circular(10))), - contentPadding: EdgeInsets.only( - top: 0, bottom: 0, left: defaultPadding), - fillColor: bgTextField, - filled: true, - focusColor: Color.fromRGBO(255, 255, 255, 0.30), - enabledBorder: OutlineInputBorder( - borderSide: BorderSide( - width: 1, color: strokeTextField), - borderRadius: - BorderRadius.all(Radius.circular(10))), - hintText: 'Confirmation du Mot de passe', - hintStyle: GoogleFonts.plusJakartaSans( - color: strokeTextField), - suffixIcon: Container( - padding: EdgeInsets.only(right: 10), - margin: EdgeInsets.all(5), - height: 3, - child: InkWell( - onTap: () { - setState(() { - if (passenable) { - passenable = false; - } else { - passenable = true; - } - }); - }, // Image tapped - splashColor: Colors - .white10, // Splash color over image - child: Image( - image: passenable - ? AssetImage( - "assets/images/show_icon.png") - : AssetImage( - "assets/images/hide_icon.png"), - height: 2, - ), - )), - ), - ), - ), - Padding( - padding: - EdgeInsets.symmetric(horizontal: defaultPadding), - child: SizedBox( - width: 600, - child: LoginButton( - callback: () {}, - )), - ), - Align( - child: GestureDetector( - onTap: () { - Navigator.pushNamed(context, '/login'); - }, - child: Padding( - padding: EdgeInsets.only(top: 20), - child: RichText( - textAlign: TextAlign.center, - text: TextSpan( - text: 'Tu as déjà un compte?', - style: GoogleFonts.plusJakartaSans( - color: Colors.white, - fontWeight: FontWeight.w400, - fontSize: 15), - children: [ - TextSpan( - text: " Connexion", - style: GoogleFonts.plusJakartaSans( - fontSize: 15, - fontWeight: FontWeight.w400, - color: primaryColor)), - ], - ), - ), - ), - ), - ), - ], - )), - SizedBox(height: 50.h), - ConstrainedBox( - constraints: BoxConstraints(maxWidth: 600), - child: Row( - mainAxisAlignment: MainAxisAlignment.spaceEvenly, - children: [ - Expanded( - child: Container( - color: Color(0xFF3D3D3D), - height: 1, - ), - ), - Padding( - padding: const EdgeInsets.only( - left: defaultPadding, right: defaultPadding), - child: Text( - 'Ou', - style: GoogleFonts.plusJakartaSans( - color: Colors.white, fontWeight: FontWeight.bold), - ), - ), - Expanded( - child: Container( - height: 1, - color: Color(0xFF3D3D3D), - )), - ], - ), - ), - SizedBox(height: 47.h), - ConstrainedBox( - constraints: BoxConstraints(maxWidth: 540), - child: SizedBox( - width: 300.sp, - height: 50, - child: SignInButton( - Buttons.Google, - text: "Login with Google", - onPressed: () {}, - shape: RoundedRectangleBorder( - borderRadius: BorderRadius.all(Radius.circular(20))), - ), - ), - ), - ], - ), - )), - IgnorePointer( - child: Container( - height: 240.h, - decoration: BoxDecoration( - gradient: LinearGradient(begin: Alignment.topRight, stops: [ - 0, - 1 - ], colors: [ - bgColor.withOpacity(1), - bgColor.withOpacity(0) - ])), - ), - ), - Align( - alignment: Alignment.topCenter, - child: ConstrainedBox( - constraints: BoxConstraints(maxWidth: 800), - child: Padding( - padding: EdgeInsets.only( - top: 45.h, left: defaultPadding, right: defaultPadding), - child: ClipRRect( - borderRadius: BorderRadius.circular(10.0), - child: LinearProgressIndicator( - minHeight: 5, - value: 0.5, - backgroundColor: grayColor, - color: primaryColor, - ), - ), - ), - ), - ), - ], - ), - ); - } -} +import 'dart:ui'; + +import 'package:auto_size_text/auto_size_text.dart'; +import 'package:flutter/cupertino.dart'; +import 'package:flutter/material.dart'; +import 'package:flutter_screenutil/flutter_screenutil.dart'; +import 'package:flutter_signin_button/button_list.dart'; +import 'package:flutter_signin_button/button_view.dart'; +import 'package:google_fonts/google_fonts.dart'; +import 'package:justmusic/values/constants.dart'; + +import '../components/login_button.dart'; +import '../main.dart'; + +class RegistrationScreen extends StatefulWidget { + const RegistrationScreen({Key? key}) : super(key: key); + + @override + State createState() => _RegistrationScreenState(); +} + +class _RegistrationScreenState extends State { + bool passenable = true; + final _formKey = GlobalKey(); + final _userPseudoTextField = TextEditingController(); + final _userMailTextField = TextEditingController(); + final _passwordTextField = TextEditingController(); + final _passwordConfirmTextField = TextEditingController(); + + handleRegister() async { + if (_formKey.currentState!.validate()) { + try { + await MyApp.userViewModel.register(_userPseudoTextField.text, + _passwordTextField.text, _userMailTextField.text); + Navigator.pushNamed(context, '/explanation'); + } catch (e) { + ScaffoldMessenger.of(context).showSnackBar( + SnackBar( + content: Text( + e.toString() ?? "", + style: GoogleFonts.plusJakartaSans( + color: Colors.white, + fontWeight: FontWeight.w400, + fontSize: 20.h), + ), + backgroundColor: Colors.red, + ), + ); + } + } + } + + @override + Widget build(BuildContext context) { + return Scaffold( + backgroundColor: bgColor, + body: Form( + key: _formKey, + child: Stack( + children: [ + SingleChildScrollView( + child: SizedBox( + width: double.infinity, + child: Column( + children: [ + Padding( + padding: EdgeInsets.only(top: 100.h), + child: AutoSizeText( + "On a besoin de ça!", + style: GoogleFonts.plusJakartaSans( + color: Colors.white, + fontWeight: FontWeight.w600, + fontSize: 30.w), + maxLines: 1, + maxFontSize: 50, + overflow: TextOverflow.fade, + ), + ), + ConstrainedBox( + constraints: BoxConstraints(maxWidth: 600), + child: Column( + mainAxisAlignment: MainAxisAlignment.start, + children: [ + Padding( + padding: EdgeInsets.symmetric( + horizontal: defaultPadding), + child: Padding( + padding: EdgeInsets.only(bottom: 50.h), + child: Column( + mainAxisAlignment: MainAxisAlignment.end, + children: [ + SizedBox( + height: 15.h, + ), + SizedBox( + width: 230.h, + child: AutoSizeText( + "Promis c’est rapide.", + style: GoogleFonts.plusJakartaSans( + color: Colors.white, + fontWeight: FontWeight.w400, + fontSize: 17.w), + maxFontSize: 20, + textAlign: TextAlign.center, + ), + ), + ], + ), + ), + ), + Padding( + padding: EdgeInsets.only( + bottom: 16.h, + left: defaultPadding, + right: defaultPadding), + child: TextFormField( + controller: _userPseudoTextField, + keyboardAppearance: Brightness.dark, + validator: (value) { + if (value == null || value.isEmpty) { + return 'entrez un pseudo valide'; + } + return null; + }, + cursorColor: primaryColor, + keyboardType: TextInputType.emailAddress, + style: GoogleFonts.plusJakartaSans( + color: primaryColor, fontSize: 15), + decoration: InputDecoration( + focusedBorder: OutlineInputBorder( + borderSide: BorderSide( + width: 1.sp, + color: strokeTextField), + borderRadius: const BorderRadius.all( + Radius.circular(10))), + prefix: const Padding( + padding: EdgeInsets.only(left: 20.0)), + suffix: const Padding( + padding: EdgeInsets.only(left: 20.0)), + fillColor: bgTextField, + filled: true, + focusColor: const Color.fromRGBO( + 255, 255, 255, 0.30), + enabledBorder: const OutlineInputBorder( + borderSide: BorderSide( + width: 1, color: strokeTextField), + borderRadius: BorderRadius.all( + Radius.circular(10))), + hintText: 'Pseudo', + hintStyle: GoogleFonts.plusJakartaSans( + color: strokeTextField)), + )), + Padding( + padding: EdgeInsets.only( + bottom: 16.h, + left: defaultPadding, + right: defaultPadding), + child: TextFormField( + controller: _userMailTextField, + keyboardAppearance: Brightness.dark, + validator: (value) { + if (value == null || value.isEmpty) { + return 'entrez un email valide'; + } + return null; + }, + cursorColor: primaryColor, + keyboardType: TextInputType.emailAddress, + style: GoogleFonts.plusJakartaSans( + color: primaryColor), + decoration: InputDecoration( + focusedBorder: OutlineInputBorder( + borderSide: BorderSide( + width: 1, color: strokeTextField), + borderRadius: BorderRadius.all( + Radius.circular(10))), + prefix: const Padding( + padding: EdgeInsets.only(left: 20.0)), + suffix: const Padding( + padding: EdgeInsets.only(left: 20.0)), + fillColor: bgTextField, + filled: true, + focusColor: + Color.fromRGBO(255, 255, 255, 0.30), + enabledBorder: OutlineInputBorder( + borderSide: BorderSide( + width: 1, color: strokeTextField), + borderRadius: BorderRadius.all( + Radius.circular(10))), + hintText: 'Email', + hintStyle: GoogleFonts.plusJakartaSans( + color: strokeTextField)), + )), + Padding( + padding: EdgeInsets.only( + bottom: 16.h, + left: defaultPadding, + right: defaultPadding), + child: TextFormField( + controller: _passwordTextField, + keyboardAppearance: Brightness.dark, + obscureText: passenable, + validator: (value) { + if (value == null || value.isEmpty) { + return 'entrez un mot de passe valide'; + } + return null; + }, + cursorColor: primaryColor, + style: GoogleFonts.plusJakartaSans( + color: primaryColor), + decoration: InputDecoration( + focusedBorder: OutlineInputBorder( + borderSide: BorderSide( + width: 1, color: strokeTextField), + borderRadius: + BorderRadius.all(Radius.circular(10))), + prefix: const Padding( + padding: EdgeInsets.only(left: 20.0)), + suffix: const Padding( + padding: EdgeInsets.only(left: 20.0)), + fillColor: bgTextField, + filled: true, + focusColor: Color.fromRGBO(255, 255, 255, 0.30), + enabledBorder: OutlineInputBorder( + borderSide: BorderSide( + width: 1, color: strokeTextField), + borderRadius: + BorderRadius.all(Radius.circular(10))), + hintText: 'Mot de passe', + hintStyle: GoogleFonts.plusJakartaSans( + color: strokeTextField), + suffixIcon: Container( + padding: EdgeInsets.only(right: 10), + margin: EdgeInsets.all(5), + height: 3, + child: InkWell( + onTap: () { + setState(() { + if (passenable) { + passenable = false; + } else { + passenable = true; + } + }); + }, + // Image tapped + splashColor: Colors.white10, + // Splash color over image + child: Image( + image: passenable + ? AssetImage( + "assets/images/show_icon.png") + : AssetImage( + "assets/images/hide_icon.png"), + height: 2, + ), + )), + ), + ), + ), + Padding( + padding: EdgeInsets.only( + bottom: 16.h, + left: defaultPadding, + right: defaultPadding), + child: TextFormField( + controller: _passwordConfirmTextField, + keyboardAppearance: Brightness.dark, + obscureText: passenable, + validator: (value) { + if (value == null || value.isEmpty) { + return 'entrez un mot de passe valide'; + } else if (_passwordTextField.text != value) { + return 'les mots de passes ne sont pas identiques'; + } + return null; + }, + cursorColor: primaryColor, + keyboardType: TextInputType.emailAddress, + style: GoogleFonts.plusJakartaSans( + color: primaryColor), + decoration: InputDecoration( + focusedBorder: OutlineInputBorder( + borderSide: BorderSide( + width: 1, color: strokeTextField), + borderRadius: + BorderRadius.all(Radius.circular(10))), + prefix: const Padding( + padding: EdgeInsets.only(left: 20.0)), + suffix: const Padding( + padding: EdgeInsets.only(left: 20.0)), + fillColor: bgTextField, + filled: true, + focusColor: Color.fromRGBO(255, 255, 255, 0.30), + enabledBorder: OutlineInputBorder( + borderSide: BorderSide( + width: 1, color: strokeTextField), + borderRadius: + BorderRadius.all(Radius.circular(10))), + hintText: 'Confirmation du Mot de passe', + hintStyle: GoogleFonts.plusJakartaSans( + color: strokeTextField), + suffixIcon: Container( + padding: EdgeInsets.only(right: 10), + margin: EdgeInsets.all(5), + height: 3, + child: InkWell( + onTap: () { + setState(() { + if (passenable) { + passenable = false; + } else { + passenable = true; + } + }); + }, + // Image tapped + splashColor: Colors.white10, + // Splash color over image + child: Image( + image: passenable + ? AssetImage( + "assets/images/show_icon.png") + : AssetImage( + "assets/images/hide_icon.png"), + height: 2, + ), + )), + ), + ), + ), + Padding( + padding: EdgeInsets.symmetric( + horizontal: defaultPadding), + child: SizedBox( + width: 600, + child: LoginButton( + callback: handleRegister, + )), + ), + Align( + child: GestureDetector( + onTap: () { + Navigator.pushNamed(context, '/login'); + }, + child: Padding( + padding: EdgeInsets.only(top: 20), + child: RichText( + textAlign: TextAlign.center, + text: TextSpan( + text: 'Tu as déjà un compte?', + style: GoogleFonts.plusJakartaSans( + color: Colors.white, + fontWeight: FontWeight.w400, + fontSize: 15), + children: [ + TextSpan( + text: " Connexion", + style: GoogleFonts.plusJakartaSans( + fontSize: 15, + fontWeight: FontWeight.w400, + color: primaryColor)), + ], + ), + ), + ), + ), + ), + ], + )), + SizedBox(height: 50.h), + ConstrainedBox( + constraints: BoxConstraints(maxWidth: 600), + child: Row( + mainAxisAlignment: MainAxisAlignment.spaceEvenly, + children: [ + Expanded( + child: Container( + color: Color(0xFF3D3D3D), + height: 1, + ), + ), + Padding( + padding: const EdgeInsets.only( + left: defaultPadding, right: defaultPadding), + child: Text( + 'Ou', + style: GoogleFonts.plusJakartaSans( + color: Colors.white, + fontWeight: FontWeight.bold), + ), + ), + Expanded( + child: Container( + height: 1, + color: Color(0xFF3D3D3D), + )), + ], + ), + ), + SizedBox(height: 47.h), + ConstrainedBox( + constraints: BoxConstraints(maxWidth: 540), + child: SizedBox( + width: 300.sp, + height: 50, + child: SignInButton( + Buttons.Google, + text: "Login with Google", + onPressed: () {}, + shape: RoundedRectangleBorder( + borderRadius: + BorderRadius.all(Radius.circular(20))), + ), + ), + ), + ], + ), + )), + IgnorePointer( + child: Container( + height: 240.h, + decoration: BoxDecoration( + gradient: LinearGradient(begin: Alignment.topRight, stops: [ + 0, + 1 + ], colors: [ + bgColor.withOpacity(1), + bgColor.withOpacity(0) + ])), + ), + ), + Align( + alignment: Alignment.topCenter, + child: ConstrainedBox( + constraints: BoxConstraints(maxWidth: 800), + child: Padding( + padding: EdgeInsets.only( + top: 45.h, left: defaultPadding, right: defaultPadding), + child: ClipRRect( + borderRadius: BorderRadius.circular(10.0), + child: LinearProgressIndicator( + minHeight: 5, + value: 0.5, + backgroundColor: grayColor, + color: primaryColor, + ), + ), + ), + ), + ), + ], + ), + ), + ); + } +} diff --git a/Sources/justMUSIC/lib/screens/search_song_screen.dart b/Sources/justMUSIC/lib/screens/search_song_screen.dart index 30b1757..84b51ba 100644 --- a/Sources/justMUSIC/lib/screens/search_song_screen.dart +++ b/Sources/justMUSIC/lib/screens/search_song_screen.dart @@ -1,169 +1,169 @@ -import 'dart:async'; -import 'dart:ui'; - -import 'package:flutter/Material.dart'; -import 'package:flutter/services.dart'; -import 'package:google_fonts/google_fonts.dart'; -import 'package:justmusic/model/Music.dart'; - -import '../components/music_list_component.dart'; -import '../values/constants.dart'; -import '../main.dart'; - -class SearchSongScreen extends StatefulWidget { - const SearchSongScreen({Key? key}) : super(key: key); - - @override - State createState() => _SearchSongScreenState(); -} - -class _SearchSongScreenState extends State { - final ScrollController _scrollController = ScrollController(); - final TextEditingController _textEditingController = TextEditingController(); - - Future resetFullScreen() async { - await SystemChannels.platform.invokeMethod( - 'SystemChrome.restoreSystemUIOverlays', - ); - } - - @override - void initState() { - super.initState(); - _scrollController.addListener(_scrollListener); - } - - Future _scrollListener() async { - if (_scrollController.position.pixels == - _scrollController.position.maxScrollExtent) { - filteredData.addAll(await MyApp.musicViewModel.getMusicsWithName( - _textEditingController.text, - limit: 10, - offset: filteredData.length)); - setState(() { - filteredData = filteredData; - }); - } - if (_scrollController.offset >= - _scrollController.position.maxScrollExtent && - !_scrollController.position.outOfRange) { - setState(() { - //you can do anything here - }); - } - if (_scrollController.offset <= - _scrollController.position.minScrollExtent && - !_scrollController.position.outOfRange) { - setState(() { - Timer(Duration(milliseconds: 1), () => _scrollController.jumpTo(0)); - }); - } - } - - List filteredData = []; - - @override - Widget build(BuildContext context) { - double screenHeight = MediaQuery.of(context).size.height; - return GestureDetector( - onTap: () { - FocusScopeNode currentFocus = FocusScope.of(context); - if (!currentFocus.hasPrimaryFocus) { - currentFocus.unfocus(); - resetFullScreen(); - } - }, - child: BackdropFilter( - filter: ImageFilter.blur( - sigmaX: 60.0, - sigmaY: 60.0, - ), - child: Container( - color: bgAppBar.withOpacity(0.5), - height: screenHeight - 50, - padding: const EdgeInsets.only(top: 10), - child: Column( - children: [ - Align( - child: Container( - width: 60, - height: 5, - decoration: BoxDecoration( - color: Color(0xFF3A3A3A).withOpacity(0.6), - borderRadius: BorderRadius.circular(20))), - ), - const SizedBox( - height: 10, - ), - Padding( - padding: - const EdgeInsets.only(bottom: 10, left: 20, right: 20), - child: SizedBox( - height: 40, - child: TextField( - controller: _textEditingController, - keyboardAppearance: Brightness.dark, - onEditingComplete: resetFullScreen, - onChanged: (value) async { - if (_textEditingController.text.isEmpty) { - } else if (value == " ") { - print("popular"); - } else { - filteredData = await MyApp.musicViewModel - .getMusicsWithName(value); - setState(() { - filteredData = filteredData; - }); - } - }, - cursorColor: Colors.white, - keyboardType: TextInputType.text, - style: GoogleFonts.plusJakartaSans(color: grayText), - decoration: InputDecoration( - prefixIcon: const Icon( - Icons.search, - color: grayColor, - ), - focusedBorder: const OutlineInputBorder( - borderSide: - BorderSide(width: 1, color: grayColor), - borderRadius: - BorderRadius.all(Radius.circular(10))), - contentPadding: const EdgeInsets.only( - top: 0, - bottom: 0, - left: defaultPadding, - right: defaultPadding), - fillColor: searchBarColor, - filled: true, - focusColor: grayText, - enabledBorder: const OutlineInputBorder( - borderSide: - BorderSide(width: 1, color: grayColor), - borderRadius: - BorderRadius.all(Radius.circular(10))), - hintText: 'Chercher un son', - hintStyle: - GoogleFonts.plusJakartaSans(color: grayColor)), - ), - ), - ), - Flexible( - child: ScrollConfiguration( - behavior: ScrollBehavior().copyWith(scrollbars: true), - child: ListView.builder( - controller: _scrollController, - itemCount: filteredData.length, - itemBuilder: (context, index) { - return Padding( - padding: const EdgeInsets.symmetric(horizontal: 20), - child: MusicListComponent(music: filteredData[index]), - ); - }), - )) - ], - ), - ), - )); - } -} +import 'dart:async'; +import 'dart:ui'; + +import 'package:flutter/Material.dart'; +import 'package:flutter/services.dart'; +import 'package:google_fonts/google_fonts.dart'; +import 'package:justmusic/model/Music.dart'; + +import '../components/music_list_component.dart'; +import '../values/constants.dart'; +import '../main.dart'; + +class SearchSongScreen extends StatefulWidget { + const SearchSongScreen({Key? key}) : super(key: key); + + @override + State createState() => _SearchSongScreenState(); +} + +class _SearchSongScreenState extends State { + final ScrollController _scrollController = ScrollController(); + final TextEditingController _textEditingController = TextEditingController(); + + Future resetFullScreen() async { + await SystemChannels.platform.invokeMethod( + 'SystemChrome.restoreSystemUIOverlays', + ); + } + + @override + void initState() { + super.initState(); + _scrollController.addListener(_scrollListener); + } + + Future _scrollListener() async { + if (_scrollController.position.pixels == + _scrollController.position.maxScrollExtent) { + filteredData.addAll(await MyApp.musicViewModel.getMusicsWithName( + _textEditingController.text, + limit: 10, + offset: filteredData.length)); + setState(() { + filteredData = filteredData; + }); + } + if (_scrollController.offset >= + _scrollController.position.maxScrollExtent && + !_scrollController.position.outOfRange) { + setState(() { + //you can do anything here + }); + } + if (_scrollController.offset <= + _scrollController.position.minScrollExtent && + !_scrollController.position.outOfRange) { + setState(() { + Timer(Duration(milliseconds: 1), () => _scrollController.jumpTo(0)); + }); + } + } + + List filteredData = []; + + @override + Widget build(BuildContext context) { + double screenHeight = MediaQuery.of(context).size.height; + return GestureDetector( + onTap: () { + FocusScopeNode currentFocus = FocusScope.of(context); + if (!currentFocus.hasPrimaryFocus) { + currentFocus.unfocus(); + resetFullScreen(); + } + }, + child: BackdropFilter( + filter: ImageFilter.blur( + sigmaX: 60.0, + sigmaY: 60.0, + ), + child: Container( + color: bgAppBar.withOpacity(0.5), + height: screenHeight - 50, + padding: const EdgeInsets.only(top: 10), + child: Column( + children: [ + Align( + child: Container( + width: 60, + height: 5, + decoration: BoxDecoration( + color: Color(0xFF3A3A3A).withOpacity(0.6), + borderRadius: BorderRadius.circular(20))), + ), + const SizedBox( + height: 10, + ), + Padding( + padding: + const EdgeInsets.only(bottom: 10, left: 20, right: 20), + child: SizedBox( + height: 40, + child: TextField( + controller: _textEditingController, + keyboardAppearance: Brightness.dark, + onEditingComplete: resetFullScreen, + onChanged: (value) async { + if (_textEditingController.text.isEmpty) { + } else if (value == " ") { + print("popular"); + } else { + filteredData = await MyApp.musicViewModel + .getMusicsWithName(value); + setState(() { + filteredData = filteredData; + }); + } + }, + cursorColor: Colors.white, + keyboardType: TextInputType.text, + style: GoogleFonts.plusJakartaSans(color: grayText), + decoration: InputDecoration( + prefixIcon: const Icon( + Icons.search, + color: grayColor, + ), + focusedBorder: const OutlineInputBorder( + borderSide: + BorderSide(width: 1, color: grayColor), + borderRadius: + BorderRadius.all(Radius.circular(10))), + contentPadding: const EdgeInsets.only( + top: 0, + bottom: 0, + left: defaultPadding, + right: defaultPadding), + fillColor: searchBarColor, + filled: true, + focusColor: grayText, + enabledBorder: const OutlineInputBorder( + borderSide: + BorderSide(width: 1, color: grayColor), + borderRadius: + BorderRadius.all(Radius.circular(10))), + hintText: 'Chercher un son', + hintStyle: + GoogleFonts.plusJakartaSans(color: grayColor)), + ), + ), + ), + Flexible( + child: ScrollConfiguration( + behavior: ScrollBehavior().copyWith(scrollbars: true), + child: ListView.builder( + controller: _scrollController, + itemCount: filteredData.length, + itemBuilder: (context, index) { + return Padding( + padding: const EdgeInsets.symmetric(horizontal: 20), + child: MusicListComponent(music: filteredData[index]), + ); + }), + )) + ], + ), + ), + )); + } +} diff --git a/Sources/justMUSIC/lib/screens/welcome_screen.dart b/Sources/justMUSIC/lib/screens/welcome_screen.dart index 1d61dbc..0180102 100644 --- a/Sources/justMUSIC/lib/screens/welcome_screen.dart +++ b/Sources/justMUSIC/lib/screens/welcome_screen.dart @@ -1,98 +1,98 @@ -import 'package:flutter/cupertino.dart'; -import 'package:flutter/material.dart'; -import 'package:google_fonts/google_fonts.dart'; -import 'package:justmusic/values/constants.dart'; - -import '../components/join_button.dart'; - -class WellcomeScreen extends StatelessWidget { - const WellcomeScreen({Key? key}) : super(key: key); - - @override - Widget build(BuildContext context) { - return Scaffold( - body: Container( - padding: EdgeInsets.all(defaultPadding), - width: double.infinity, - height: double.infinity, - decoration: const BoxDecoration( - image: DecorationImage( - image: AssetImage("assets/images/wellcome_background.png"), - fit: BoxFit.cover, - ), - ), - child: Align( - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Expanded( - flex: 10, - child: Padding( - padding: EdgeInsets.only(bottom: 100), - child: Column( - mainAxisAlignment: MainAxisAlignment.end, - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Text( - "Bienvenue sur,", - style: GoogleFonts.plusJakartaSans( - color: Colors.white, - fontWeight: FontWeight.bold, - fontSize: 34), - ), - Image( - image: AssetImage("assets/images/logo.png"), - width: 230, - ), - SizedBox( - height: 25, - ), - ConstrainedBox( - constraints: BoxConstraints(maxWidth: 520), - child: Text( - "Explore les nouvelles découvertes musicales de tes amis, et partage leur ton mood.", - style: GoogleFonts.plusJakartaSans( - color: Colors.white, - fontWeight: FontWeight.w200, - fontSize: 15), - ), - ), - ], - ), - ), - ), - Expanded( - flex: 3, - child: Column( - mainAxisAlignment: MainAxisAlignment.start, - crossAxisAlignment: CrossAxisAlignment.center, - children: [ - JoinButton(), - SizedBox( - height: defaultPadding, - ), - GestureDetector( - onTap: () { - Navigator.pushNamed(context, '/login'); - }, - child: Padding( - padding: const EdgeInsets.all(3.0), - child: Text( - "Tu as déja un compte? Connexion", - style: GoogleFonts.plusJakartaSans( - color: Colors.white, - fontWeight: FontWeight.w400, - fontSize: 15), - ), - ), - ), - ], - ), - ), - ], - ), - ) /* add child content here */, - ), - ); - } -} +import 'package:flutter/cupertino.dart'; +import 'package:flutter/material.dart'; +import 'package:google_fonts/google_fonts.dart'; +import 'package:justmusic/values/constants.dart'; + +import '../components/join_button.dart'; + +class WellcomeScreen extends StatelessWidget { + const WellcomeScreen({Key? key}) : super(key: key); + + @override + Widget build(BuildContext context) { + return Scaffold( + body: Container( + padding: EdgeInsets.all(defaultPadding), + width: double.infinity, + height: double.infinity, + decoration: const BoxDecoration( + image: DecorationImage( + image: AssetImage("assets/images/wellcome_background.png"), + fit: BoxFit.cover, + ), + ), + child: Align( + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Expanded( + flex: 10, + child: Padding( + padding: EdgeInsets.only(bottom: 100), + child: Column( + mainAxisAlignment: MainAxisAlignment.end, + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Text( + "Bienvenue sur,", + style: GoogleFonts.plusJakartaSans( + color: Colors.white, + fontWeight: FontWeight.bold, + fontSize: 34), + ), + Image( + image: AssetImage("assets/images/logo.png"), + width: 230, + ), + SizedBox( + height: 25, + ), + ConstrainedBox( + constraints: BoxConstraints(maxWidth: 520), + child: Text( + "Explore les nouvelles découvertes musicales de tes amis, et partage leur ton mood.", + style: GoogleFonts.plusJakartaSans( + color: Colors.white, + fontWeight: FontWeight.w200, + fontSize: 15), + ), + ), + ], + ), + ), + ), + Expanded( + flex: 3, + child: Column( + mainAxisAlignment: MainAxisAlignment.start, + crossAxisAlignment: CrossAxisAlignment.center, + children: [ + JoinButton(), + SizedBox( + height: defaultPadding, + ), + GestureDetector( + onTap: () { + Navigator.pushNamed(context, '/login'); + }, + child: Padding( + padding: const EdgeInsets.all(3.0), + child: Text( + "Tu as déja un compte? Connexion", + style: GoogleFonts.plusJakartaSans( + color: Colors.white, + fontWeight: FontWeight.w400, + fontSize: 15), + ), + ), + ), + ], + ), + ), + ], + ), + ) /* add child content here */, + ), + ); + } +} diff --git a/Sources/justMUSIC/lib/service/AuthService.dart b/Sources/justMUSIC/lib/service/AuthService.dart index 80879cb..65828fc 100644 --- a/Sources/justMUSIC/lib/service/AuthService.dart +++ b/Sources/justMUSIC/lib/service/AuthService.dart @@ -1,59 +1,60 @@ -import 'package:firebase_auth/firebase_auth.dart'; -import '../main.dart'; - -class AuthService { - register(String pseudo, String email, String password) async { - try { - final data = await FirebaseAuth.instance.createUserWithEmailAndPassword( - email: email, - password: password, - ); - - final user = { - "mail": email, - "pseudo": pseudo, - "phone_number": "", - "picture": - "https://media.licdn.com/dms/image/D4E03AQHvc_b89ogFtQ/profile-displayphoto-shrink_400_400/0/1665060931103?e=1695859200&v=beta&t=wVLbxqeokYiPJ13nJ3SMq97iZvcm3ra0ufWFZCSzhjg", - "friends": [] - }; - - MyApp.db - .collection("users") - .doc(data.user?.uid) - .set(user) - .then((value) => print("User Added")) - .catchError((error) => print("Failed to add user: $error")); - } on FirebaseAuthException catch (e) { - if (e.code == 'weak-password') { - throw ('The password provided is too weak.'); - } else if (e.code == 'email-already-in-use') { - throw ('The account already exists for that email.'); - } - } catch (e) { - throw (e); - } - } - - login(String email, String password) async { - try { - await FirebaseAuth.instance - .signInWithEmailAndPassword(email: email, password: password); - } on FirebaseAuthException catch (e) { - if(e.code == 'user-not-found') { - throw('Mail incorrect'); - } else if(e.code == 'wrong-password') { - throw('Mot de passe incorrect'); - } else if(e.code == 'invalid-email') { - throw('Format de mail incorrect'); - } else if(e.code == 'too-many-requests') { - throw('L\'accès à ce compte a été temporairement désactivé en raison de nombreuses tentatives de connexion infructueuses. Réessayer plus tard.'); - } - rethrow; - } - } - - void signOut() async { - await FirebaseAuth.instance.signOut(); - } -} +import 'package:firebase_auth/firebase_auth.dart'; +import '../main.dart'; + +class AuthService { + register(String pseudo, String email, String password) async { + try { + final data = await FirebaseAuth.instance.createUserWithEmailAndPassword( + email: email, + password: password, + ); + + final user = { + "mail": email, + "pseudo": pseudo, + "phone_number": "", + "picture": + "https://media.licdn.com/dms/image/D4E03AQHvc_b89ogFtQ/profile-displayphoto-shrink_400_400/0/1665060931103?e=1695859200&v=beta&t=wVLbxqeokYiPJ13nJ3SMq97iZvcm3ra0ufWFZCSzhjg", + "friends": [] + }; + + MyApp.db + .collection("users") + .doc(data.user?.uid) + .set(user) + .then((value) => print("User Added")) + .catchError((error) => print("Failed to add user: $error")); + } on FirebaseAuthException catch (e) { + if (e.code == 'weak-password') { + throw ('Mot de passe trop court'); + } else if (e.code == 'email-already-in-use') { + throw ('Mail déjà utilisé'); + } else if (e.code == 'invalid-email') { + throw ('Mauvais format de mail'); + } + rethrow; + } + } + + login(String email, String password) async { + try { + await FirebaseAuth.instance + .signInWithEmailAndPassword(email: email, password: password); + } on FirebaseAuthException catch (e) { + if (e.code == 'user-not-found') { + throw ('Mail incorrect'); + } else if (e.code == 'wrong-password') { + throw ('Mot de passe incorrect'); + } else if (e.code == 'invalid-email') { + throw ('Format de mail incorrect'); + } else if (e.code == 'too-many-requests') { + throw ('L\'accès à ce compte a été temporairement désactivé en raison de nombreuses tentatives de connexion infructueuses. Réessayer plus tard.'); + } + rethrow; + } + } + + void signOut() async { + await FirebaseAuth.instance.signOut(); + } +} diff --git a/Sources/justMUSIC/lib/service/UserService.dart b/Sources/justMUSIC/lib/service/UserService.dart index b60cd92..d91e886 100644 --- a/Sources/justMUSIC/lib/service/UserService.dart +++ b/Sources/justMUSIC/lib/service/UserService.dart @@ -1,15 +1,15 @@ -import 'package:cloud_firestore/cloud_firestore.dart'; - -import '../model/User.dart'; -import '../main.dart'; - -class UserService { - acceptFriend(User user, String idFriend) { - MyApp.db.collection("users").doc(user.id).update({ - "friends": FieldValue.arrayUnion([idFriend]) - }); - MyApp.db.collection("users").doc(idFriend).update({ - "friends": FieldValue.arrayUnion([user.id]) - }); - } -} +import 'package:cloud_firestore/cloud_firestore.dart'; + +import '../model/User.dart'; +import '../main.dart'; + +class UserService { + acceptFriend(User user, String idFriend) { + MyApp.db.collection("users").doc(user.id).update({ + "friends": FieldValue.arrayUnion([idFriend]) + }); + MyApp.db.collection("users").doc(idFriend).update({ + "friends": FieldValue.arrayUnion([user.id]) + }); + } +} diff --git a/Sources/justMUSIC/lib/view_model/MusicViewModel.dart b/Sources/justMUSIC/lib/view_model/MusicViewModel.dart index 668526a..5fe3443 100644 --- a/Sources/justMUSIC/lib/view_model/MusicViewModel.dart +++ b/Sources/justMUSIC/lib/view_model/MusicViewModel.dart @@ -1,203 +1,203 @@ -import 'dart:convert'; - -import 'package:justmusic/view_model/TokenSpotify.dart'; -import 'package:http/http.dart' as http; -import '../model/Artist.dart'; -import '../model/Music.dart'; - -class MusicViewModel { - final String API_URL = "https://api.spotify.com/v1"; - late TokenSpotify _token; - - MusicViewModel() { - _token = new TokenSpotify(); - } - - // Methods - Future getMusic(String id) async { - var accessToken = await _token.getAccessToken(); - var response = await http.get(Uri.parse('$API_URL/tracks/$id'), headers: { - 'Authorization': 'Bearer $accessToken', - }); - - if (response.statusCode == 200) { - final responseData = jsonDecode(response.body); - List artists = - List.from(responseData['artists'].map((artist) { - return Artist(artist['id'], artist['name'], ''); - })); - - return Music( - responseData['id'], - responseData['name'], - responseData['album']['images'][0]['url'], - responseData['preview_url'], - DateTime.parse(responseData['album']['release_date']), - responseData['duration_ms'] / 1000, - responseData['explicit'], - artists); - } else { - throw Exception( - 'Error retrieving music information : ${response.statusCode} ${response.reasonPhrase}'); - } - } - - List _getMusicsFromResponse(Map responseData) { - List musics = []; - - List tracks = responseData['tracks']['items']; - for (var track in tracks) { - List artists = List.from(track['artists'].map((artist) { - return Artist(artist['id'], artist['name'], ''); - })); - - musics.add(Music( - track['id'], - track['name'], - track['album']['images'][0]['url'], - track['preview_url'], - DateTime.now(), - track['duration_ms'] / 1000, - track['explicit'], - artists)); - } - - return musics; - } - - Future> getMusicsWithName(String name, - {int limit = 20, int offset = 0, String market = "FR"}) async { - var accessToken = await _token.getAccessToken(); - var response = await http.get( - Uri.parse( - '$API_URL/search?q=track%3A$name&type=track&market=fr&limit=$limit&offset=$offset'), - headers: { - 'Authorization': 'Bearer $accessToken', - }); - - if (response.statusCode == 200) { - Map responseData = jsonDecode(response.body); - return _getMusicsFromResponse(responseData); - } else { - throw Exception( - 'Error while retrieving music : ${response.statusCode} ${response.reasonPhrase}'); - } - } - - Future> getMusicsWithArtistName(String name, - {int limit = 20, int offset = 0, String market = "FR"}) async { - var accessToken = await _token.getAccessToken(); - var response = await http.get( - Uri.parse( - '$API_URL/search?q=artist%3A$name&type=track&market=fr&limit=$limit&offset=$offset'), - headers: { - 'Authorization': 'Bearer $accessToken', - }); - - if (response.statusCode == 200) { - Map responseData = jsonDecode(response.body); - return _getMusicsFromResponse(responseData); - } else { - throw Exception( - 'Error while retrieving music : ${response.statusCode} ${response.reasonPhrase}'); - } - } - - Future getArtistWithName(String name, {String market = "FR"}) async { - var accessToken = await _token.getAccessToken(); - var response = await http.get( - Uri.parse( - '$API_URL/search?q=artist%3A$name&type=artist&market=$market'), - headers: { - 'Authorization': 'Bearer $accessToken', - }); - - if (response.statusCode == 200) { - final responseData = jsonDecode(response.body); - List artists = - List.from(responseData['artists']['items'].map((artist) { - String image = ''; - if (!artist['images'].isEmpty) { - image = artist['images'][0]['url']; - } - return Artist(artist['id'], artist['name'], image); - })); - - for (Artist a in artists) { - if (a.name?.toLowerCase() == name.toLowerCase()) { - return a; - } - } - - throw Exception('Artist not found : ${name}'); - } else { - throw Exception( - 'Error retrieving artist information : ${response.statusCode} ${response.reasonPhrase}'); - } - } - - Future> getArtistsWithName(String name, - {int limit = 20, int offset = 0, String market = "FR"}) async { - var accessToken = await _token.getAccessToken(); - var response = await http.get( - Uri.parse( - '$API_URL/search?q=artist%3A$name&type=artist&market=$market&limit=$limit&offset=$offset'), - headers: { - 'Authorization': 'Bearer $accessToken', - }); - - if (response.statusCode == 200) { - final responseData = jsonDecode(response.body); - List artists = - List.from(responseData['artists']['items'].map((artist) { - String image = ''; - if (!artist['images'].isEmpty) { - image = artist['images'][0]['url']; - } - return Artist(artist['id'], artist['name'], image); - })); - - return artists; - } else { - throw Exception( - 'Error while retrieving artist : ${response.statusCode} ${response.reasonPhrase}'); - } - } - - Future> getTopMusicsWithArtistId(String id, - {String market = "FR"}) async { - var accessToken = await _token.getAccessToken(); - var response = await http.get( - Uri.parse('$API_URL/artists/$id/top-tracks?market=$market'), - headers: { - 'Authorization': 'Bearer $accessToken', - }); - - if (response.statusCode == 200) { - Map responseData = jsonDecode(response.body); - List musics = []; - - List tracks = responseData['tracks']; - for (var track in tracks) { - List artists = List.from(track['artists'].map((artist) { - return Artist(artist['id'], artist['name'], ''); - })); - - musics.add(Music( - track['id'], - track['name'], - track['album']['images'][0]['url'], - track['preview_url'], - DateTime.now(), - track['duration_ms'] / 1000, - track['explicit'], - artists)); - } - - return musics; - } else { - throw Exception( - 'Error while retrieving music : ${response.statusCode} ${response.reasonPhrase}'); - } - } -} +import 'dart:convert'; + +import 'package:justmusic/view_model/TokenSpotify.dart'; +import 'package:http/http.dart' as http; +import '../model/Artist.dart'; +import '../model/Music.dart'; + +class MusicViewModel { + final String API_URL = "https://api.spotify.com/v1"; + late TokenSpotify _token; + + MusicViewModel() { + _token = new TokenSpotify(); + } + + // Methods + Future getMusic(String id) async { + var accessToken = await _token.getAccessToken(); + var response = await http.get(Uri.parse('$API_URL/tracks/$id'), headers: { + 'Authorization': 'Bearer $accessToken', + }); + + if (response.statusCode == 200) { + final responseData = jsonDecode(response.body); + List artists = + List.from(responseData['artists'].map((artist) { + return Artist(artist['id'], artist['name'], ''); + })); + + return Music( + responseData['id'], + responseData['name'], + responseData['album']['images'][0]['url'], + responseData['preview_url'], + DateTime.parse(responseData['album']['release_date']), + responseData['duration_ms'] / 1000, + responseData['explicit'], + artists); + } else { + throw Exception( + 'Error retrieving music information : ${response.statusCode} ${response.reasonPhrase}'); + } + } + + List _getMusicsFromResponse(Map responseData) { + List musics = []; + + List tracks = responseData['tracks']['items']; + for (var track in tracks) { + List artists = List.from(track['artists'].map((artist) { + return Artist(artist['id'], artist['name'], ''); + })); + + musics.add(Music( + track['id'], + track['name'], + track['album']['images'][0]['url'], + track['preview_url'], + DateTime.now(), + track['duration_ms'] / 1000, + track['explicit'], + artists)); + } + + return musics; + } + + Future> getMusicsWithName(String name, + {int limit = 20, int offset = 0, String market = "FR"}) async { + var accessToken = await _token.getAccessToken(); + var response = await http.get( + Uri.parse( + '$API_URL/search?q=track%3A$name&type=track&market=fr&limit=$limit&offset=$offset'), + headers: { + 'Authorization': 'Bearer $accessToken', + }); + + if (response.statusCode == 200) { + Map responseData = jsonDecode(response.body); + return _getMusicsFromResponse(responseData); + } else { + throw Exception( + 'Error while retrieving music : ${response.statusCode} ${response.reasonPhrase}'); + } + } + + Future> getMusicsWithArtistName(String name, + {int limit = 20, int offset = 0, String market = "FR"}) async { + var accessToken = await _token.getAccessToken(); + var response = await http.get( + Uri.parse( + '$API_URL/search?q=artist%3A$name&type=track&market=fr&limit=$limit&offset=$offset'), + headers: { + 'Authorization': 'Bearer $accessToken', + }); + + if (response.statusCode == 200) { + Map responseData = jsonDecode(response.body); + return _getMusicsFromResponse(responseData); + } else { + throw Exception( + 'Error while retrieving music : ${response.statusCode} ${response.reasonPhrase}'); + } + } + + Future getArtistWithName(String name, {String market = "FR"}) async { + var accessToken = await _token.getAccessToken(); + var response = await http.get( + Uri.parse( + '$API_URL/search?q=artist%3A$name&type=artist&market=$market'), + headers: { + 'Authorization': 'Bearer $accessToken', + }); + + if (response.statusCode == 200) { + final responseData = jsonDecode(response.body); + List artists = + List.from(responseData['artists']['items'].map((artist) { + String image = ''; + if (!artist['images'].isEmpty) { + image = artist['images'][0]['url']; + } + return Artist(artist['id'], artist['name'], image); + })); + + for (Artist a in artists) { + if (a.name?.toLowerCase() == name.toLowerCase()) { + return a; + } + } + + throw Exception('Artist not found : ${name}'); + } else { + throw Exception( + 'Error retrieving artist information : ${response.statusCode} ${response.reasonPhrase}'); + } + } + + Future> getArtistsWithName(String name, + {int limit = 20, int offset = 0, String market = "FR"}) async { + var accessToken = await _token.getAccessToken(); + var response = await http.get( + Uri.parse( + '$API_URL/search?q=artist%3A$name&type=artist&market=$market&limit=$limit&offset=$offset'), + headers: { + 'Authorization': 'Bearer $accessToken', + }); + + if (response.statusCode == 200) { + final responseData = jsonDecode(response.body); + List artists = + List.from(responseData['artists']['items'].map((artist) { + String image = ''; + if (!artist['images'].isEmpty) { + image = artist['images'][0]['url']; + } + return Artist(artist['id'], artist['name'], image); + })); + + return artists; + } else { + throw Exception( + 'Error while retrieving artist : ${response.statusCode} ${response.reasonPhrase}'); + } + } + + Future> getTopMusicsWithArtistId(String id, + {String market = "FR"}) async { + var accessToken = await _token.getAccessToken(); + var response = await http.get( + Uri.parse('$API_URL/artists/$id/top-tracks?market=$market'), + headers: { + 'Authorization': 'Bearer $accessToken', + }); + + if (response.statusCode == 200) { + Map responseData = jsonDecode(response.body); + List musics = []; + + List tracks = responseData['tracks']; + for (var track in tracks) { + List artists = List.from(track['artists'].map((artist) { + return Artist(artist['id'], artist['name'], ''); + })); + + musics.add(Music( + track['id'], + track['name'], + track['album']['images'][0]['url'], + track['preview_url'], + DateTime.now(), + track['duration_ms'] / 1000, + track['explicit'], + artists)); + } + + return musics; + } else { + throw Exception( + 'Error while retrieving music : ${response.statusCode} ${response.reasonPhrase}'); + } + } +} diff --git a/Sources/justMUSIC/lib/view_model/UserViewModel.dart b/Sources/justMUSIC/lib/view_model/UserViewModel.dart index 29200d2..d793449 100644 --- a/Sources/justMUSIC/lib/view_model/UserViewModel.dart +++ b/Sources/justMUSIC/lib/view_model/UserViewModel.dart @@ -1,53 +1,57 @@ -import 'package:firebase_auth/firebase_auth.dart' as firebase_auth; -import 'package:justmusic/service/AuthService.dart'; - -import '../model/User.dart'; -import '../model/mapper/UserMapper.dart'; -import '../main.dart'; - -class UserViewModel { - late User _userCurrent; - final AuthService _authService = AuthService(); - - User get userCurrent => _userCurrent; - - set userCurrent(User value) { - _userCurrent = value; - } // Constructor - - UserViewModel(); - - // Methods - Future getUser(String id) async { - final user = await MyApp.db.collection("users").doc(id).get(); - return UserMapper.toModel(user, null); - } - - login(String pseudo, String password) async { - try { - await _authService.login(pseudo, password); - final user = await MyApp.db - .collection("users") - .doc(firebase_auth.FirebaseAuth.instance.currentUser?.uid) - .get(); - User data = UserMapper.toModel(user, null); - _userCurrent = data; - } catch (e) { - rethrow; - } - } - - register(String pseudo, String password, String email) async { - _authService.register(pseudo, email, password); - final user = await MyApp.db - .collection("users") - .doc(firebase_auth.FirebaseAuth.instance.currentUser?.uid) - .get(); - User? data = UserMapper.toModel(user, null); - _userCurrent = data; - } - - logout() { - _authService.signOut(); - } -} +import 'package:firebase_auth/firebase_auth.dart' as firebase_auth; +import 'package:justmusic/service/AuthService.dart'; + +import '../model/User.dart'; +import '../model/mapper/UserMapper.dart'; +import '../main.dart'; + +class UserViewModel { + late User _userCurrent; + final AuthService _authService = AuthService(); + + User get userCurrent => _userCurrent; + + set userCurrent(User value) { + _userCurrent = value; + } // Constructor + + UserViewModel(); + + // Methods + Future getUser(String id) async { + final user = await MyApp.db.collection("users").doc(id).get(); + return UserMapper.toModel(user, null); + } + + login(String pseudo, String password) async { + try { + await _authService.login(pseudo, password); + final user = await MyApp.db + .collection("users") + .doc(firebase_auth.FirebaseAuth.instance.currentUser?.uid) + .get(); + User data = UserMapper.toModel(user, null); + _userCurrent = data; + } catch (e) { + rethrow; + } + } + + register(String pseudo, String password, String email) async { + try { + await _authService.register(pseudo, email, password); + final user = await MyApp.db + .collection("users") + .doc(firebase_auth.FirebaseAuth.instance.currentUser?.uid) + .get(); + User data = UserMapper.toModel(user, null); + _userCurrent = data; + } catch (e) { + rethrow; + } + } + + logout() { + _authService.signOut(); + } +} diff --git a/Sources/justMUSIC/pubspec.lock b/Sources/justMUSIC/pubspec.lock index 894b62f..5a37499 100644 --- a/Sources/justMUSIC/pubspec.lock +++ b/Sources/justMUSIC/pubspec.lock @@ -1,602 +1,602 @@ -# Generated by pub -# See https://dart.dev/tools/pub/glossary#lockfile -packages: - _flutterfire_internals: - dependency: transitive - description: - name: _flutterfire_internals - sha256: "5dce45a06d386358334eb1689108db6455d90ceb0d75848d5f4819283d4ee2b8" - url: "https://pub.dev" - source: hosted - version: "1.3.4" - async: - dependency: transitive - description: - name: async - sha256: bfe67ef28df125b7dddcea62755991f807aa39a2492a23e1550161692950bbe0 - url: "https://pub.dev" - source: hosted - version: "2.10.0" - audioplayers: - dependency: "direct main" - description: - name: audioplayers - sha256: "61583554386721772f9309f509e17712865b38565a903c761f96b1115a979282" - url: "https://pub.dev" - source: hosted - version: "4.1.0" - audioplayers_android: - dependency: transitive - description: - name: audioplayers_android - sha256: dbdc9b7f2aa2440314c638aa55aadd45c7705e8340d5eddf2e3fb8da32d4ae2c - url: "https://pub.dev" - source: hosted - version: "3.0.2" - audioplayers_darwin: - dependency: transitive - description: - name: audioplayers_darwin - sha256: "6aea96df1d12f7ad5a71d88c6d1b22a216211a9564219920124c16768e456e9d" - url: "https://pub.dev" - source: hosted - version: "4.1.0" - audioplayers_linux: - dependency: transitive - description: - name: audioplayers_linux - sha256: "396b62ac62c92dd26c3bc5106583747f57a8b325ebd2b41e5576f840cfc61338" - url: "https://pub.dev" - source: hosted - version: "2.1.0" - audioplayers_platform_interface: - dependency: transitive - description: - name: audioplayers_platform_interface - sha256: f7daaed4659143094151ecf6bacd927d29ab8acffba98c110c59f0b81ae51143 - url: "https://pub.dev" - source: hosted - version: "5.0.1" - audioplayers_web: - dependency: transitive - description: - name: audioplayers_web - sha256: ec84fd46eed1577148ed4113f5998a36a18da4fce7170c37ce3e21b631393339 - url: "https://pub.dev" - source: hosted - version: "3.1.0" - audioplayers_windows: - dependency: transitive - description: - name: audioplayers_windows - sha256: "1d3aaac98a192b8488167711ba1e67d8b96333e8d0572ede4e2912e5bbce69a3" - url: "https://pub.dev" - source: hosted - version: "2.0.2" - auto_size_text: - dependency: "direct main" - description: - name: auto_size_text - sha256: "3f5261cd3fb5f2a9ab4e2fc3fba84fd9fcaac8821f20a1d4e71f557521b22599" - url: "https://pub.dev" - source: hosted - version: "3.0.0" - boolean_selector: - dependency: transitive - description: - name: boolean_selector - sha256: "6cfb5af12253eaf2b368f07bacc5a80d1301a071c73360d746b7f2e32d762c66" - url: "https://pub.dev" - source: hosted - version: "2.1.1" - characters: - dependency: transitive - description: - name: characters - sha256: e6a326c8af69605aec75ed6c187d06b349707a27fbff8222ca9cc2cff167975c - url: "https://pub.dev" - source: hosted - version: "1.2.1" - circular_reveal_animation: - dependency: "direct main" - description: - name: circular_reveal_animation - sha256: "198f5a1fa27384dcf950807e0ae07a0da857c04df6233f7468755ee9db102b0c" - url: "https://pub.dev" - source: hosted - version: "2.0.1" - clock: - dependency: transitive - description: - name: clock - sha256: cb6d7f03e1de671e34607e909a7213e31d7752be4fb66a86d29fe1eb14bfb5cf - url: "https://pub.dev" - source: hosted - version: "1.1.1" - cloud_firestore: - dependency: "direct main" - description: - name: cloud_firestore - sha256: f1a06ad4499ed9ab73703560d44893e6b9e66ce3923c9121f4ef3981c972057f - url: "https://pub.dev" - source: hosted - version: "4.8.4" - cloud_firestore_platform_interface: - dependency: transitive - description: - name: cloud_firestore_platform_interface - sha256: "86bd1865abbeb09a7d09da3e70364a09f894937270651fc611a1c6d6a9f7b02c" - url: "https://pub.dev" - source: hosted - version: "5.15.3" - cloud_firestore_web: - dependency: transitive - description: - name: cloud_firestore_web - sha256: ac2eeb2a7ab1928c3aacc30eed750fa839d6f620e112a5459e321df217be2f47 - url: "https://pub.dev" - source: hosted - version: "3.6.3" - collection: - dependency: transitive - description: - name: collection - sha256: cfc915e6923fe5ce6e153b0723c753045de46de1b4d63771530504004a45fae0 - url: "https://pub.dev" - source: hosted - version: "1.17.0" - crypto: - dependency: transitive - description: - name: crypto - sha256: aa274aa7774f8964e4f4f38cc994db7b6158dd36e9187aaceaddc994b35c6c67 - url: "https://pub.dev" - source: hosted - version: "3.0.2" - cupertino_icons: - dependency: "direct main" - description: - name: cupertino_icons - sha256: e35129dc44c9118cee2a5603506d823bab99c68393879edb440e0090d07586be - url: "https://pub.dev" - source: hosted - version: "1.0.5" - custom_draggable_widget: - dependency: "direct main" - description: - name: custom_draggable_widget - sha256: "15718003ebcebb84acdf0c625831a880d139a284d8de9d943ef0d0a669f10159" - url: "https://pub.dev" - source: hosted - version: "0.0.2" - fake_async: - dependency: transitive - description: - name: fake_async - sha256: "511392330127add0b769b75a987850d136345d9227c6b94c96a04cf4a391bf78" - url: "https://pub.dev" - source: hosted - version: "1.3.1" - ffi: - dependency: transitive - description: - name: ffi - sha256: ed5337a5660c506388a9f012be0288fb38b49020ce2b45fe1f8b8323fe429f99 - url: "https://pub.dev" - source: hosted - version: "2.0.2" - file: - dependency: transitive - description: - name: file - sha256: "1b92bec4fc2a72f59a8e15af5f52cd441e4a7860b49499d69dfa817af20e925d" - url: "https://pub.dev" - source: hosted - version: "6.1.4" - firebase_auth: - dependency: "direct main" - description: - name: firebase_auth - sha256: "49fd35ce06f2530dd460e5dc123235731cb61dd7c76b0af4b6e190404880d04d" - url: "https://pub.dev" - source: hosted - version: "4.7.2" - firebase_auth_platform_interface: - dependency: transitive - description: - name: firebase_auth_platform_interface - sha256: "817f3ceb84ef5e9adaaf50cf7a19255f6ffcdd12c6f9e9aa4cf00fc7f2eb3cfb" - url: "https://pub.dev" - source: hosted - version: "6.16.1" - firebase_auth_web: - dependency: transitive - description: - name: firebase_auth_web - sha256: e9044778287f1ff8f9f4cee7e247b03ec87bb8977e0e65ad27dc337e196132e8 - url: "https://pub.dev" - source: hosted - version: "5.6.2" - firebase_core: - dependency: "direct main" - description: - name: firebase_core - sha256: "2e9324f719e90200dc7d3c4f5d2abc26052f9f2b995d3b6626c47a0dfe1c8192" - url: "https://pub.dev" - source: hosted - version: "2.15.0" - firebase_core_platform_interface: - dependency: transitive - description: - name: firebase_core_platform_interface - sha256: b63e3be6c96ef5c33bdec1aab23c91eb00696f6452f0519401d640938c94cba2 - url: "https://pub.dev" - source: hosted - version: "4.8.0" - firebase_core_web: - dependency: transitive - description: - name: firebase_core_web - sha256: "0fd5c4b228de29b55fac38aed0d9e42514b3d3bd47675de52bf7f8fccaf922fa" - url: "https://pub.dev" - source: hosted - version: "2.6.0" - flutter: - dependency: "direct main" - description: flutter - source: sdk - version: "0.0.0" - flutter_animated_play_button: - dependency: "direct main" - description: - name: flutter_animated_play_button - sha256: dd955a450a4514e935e2f410afbd03b3bcf5f31b933a8f1334199caa3c6a81e2 - url: "https://pub.dev" - source: hosted - version: "0.3.0" - flutter_lints: - dependency: "direct dev" - description: - name: flutter_lints - sha256: "2118df84ef0c3ca93f96123a616ae8540879991b8b57af2f81b76a7ada49b2a4" - url: "https://pub.dev" - source: hosted - version: "2.0.2" - flutter_screenutil: - dependency: "direct main" - description: - name: flutter_screenutil - sha256: "0a122936b450324cbdfd51be0819cc6fcebb093eb65585e9cd92263f7a1a8a39" - url: "https://pub.dev" - source: hosted - version: "5.7.0" - flutter_signin_button: - dependency: "direct main" - description: - name: flutter_signin_button - sha256: a063ecc5d5308377e103c9c3a89084abf15fca4440636233af6a13abacd5dcae - url: "https://pub.dev" - source: hosted - version: "2.0.0" - flutter_test: - dependency: "direct dev" - description: flutter - source: sdk - version: "0.0.0" - flutter_web_plugins: - dependency: transitive - description: flutter - source: sdk - version: "0.0.0" - font_awesome_flutter: - dependency: transitive - description: - name: font_awesome_flutter - sha256: "1f93e5799f0e6c882819e8393a05c6ca5226010f289190f2242ec19f3f0fdba5" - url: "https://pub.dev" - source: hosted - version: "9.2.0" - google_fonts: - dependency: "direct main" - description: - name: google_fonts - sha256: "6b6f10f0ce3c42f6552d1c70d2c28d764cf22bb487f50f66cca31dcd5194f4d6" - url: "https://pub.dev" - source: hosted - version: "4.0.4" - gradiantbutton: - dependency: "direct main" - description: - name: gradiantbutton - sha256: c88ac8567242630cd14231e2a6a861da4e40a02a9a0310af360e05634890d172 - url: "https://pub.dev" - source: hosted - version: "0.0.1" - gradient_borders: - dependency: "direct main" - description: - name: gradient_borders - sha256: "69eeaff519d145a4c6c213ada1abae386bcc8981a4970d923e478ce7ba19e309" - url: "https://pub.dev" - source: hosted - version: "1.0.0" - http: - dependency: "direct main" - description: - name: http - sha256: "6aa2946395183537c8b880962d935877325d6a09a2867c3970c05c0fed6ac482" - url: "https://pub.dev" - source: hosted - version: "0.13.5" - http_parser: - dependency: transitive - description: - name: http_parser - sha256: "2aa08ce0341cc9b354a498388e30986515406668dbcc4f7c950c3e715496693b" - url: "https://pub.dev" - source: hosted - version: "4.0.2" - ionicons: - dependency: "direct main" - description: - name: ionicons - sha256: "5496bc65a16115ecf05b15b78f494ee4a8869504357668f0a11d689e970523cf" - url: "https://pub.dev" - source: hosted - version: "0.2.2" - js: - dependency: transitive - description: - name: js - sha256: "5528c2f391ededb7775ec1daa69e65a2d61276f7552de2b5f7b8d34ee9fd4ab7" - url: "https://pub.dev" - source: hosted - version: "0.6.5" - lints: - dependency: transitive - description: - name: lints - sha256: "5e4a9cd06d447758280a8ac2405101e0e2094d2a1dbdd3756aec3fe7775ba593" - url: "https://pub.dev" - source: hosted - version: "2.0.1" - matcher: - dependency: transitive - description: - name: matcher - sha256: "16db949ceee371e9b99d22f88fa3a73c4e59fd0afed0bd25fc336eb76c198b72" - url: "https://pub.dev" - source: hosted - version: "0.12.13" - material_color_utilities: - dependency: transitive - description: - name: material_color_utilities - sha256: d92141dc6fe1dad30722f9aa826c7fbc896d021d792f80678280601aff8cf724 - url: "https://pub.dev" - source: hosted - version: "0.2.0" - meta: - dependency: transitive - description: - name: meta - sha256: "6c268b42ed578a53088d834796959e4a1814b5e9e164f147f580a386e5decf42" - url: "https://pub.dev" - source: hosted - version: "1.8.0" - modal_bottom_sheet: - dependency: "direct main" - description: - name: modal_bottom_sheet - sha256: ef533916a2c3089571c32bd34e410faca77a6849a3f28f748e0794525c5658a0 - url: "https://pub.dev" - source: hosted - version: "2.1.2" - path: - dependency: transitive - description: - name: path - sha256: db9d4f58c908a4ba5953fcee2ae317c94889433e5024c27ce74a37f94267945b - url: "https://pub.dev" - source: hosted - version: "1.8.2" - path_provider: - dependency: transitive - description: - name: path_provider - sha256: "3087813781ab814e4157b172f1a11c46be20179fcc9bea043e0fba36bc0acaa2" - url: "https://pub.dev" - source: hosted - version: "2.0.15" - path_provider_android: - dependency: transitive - description: - name: path_provider_android - sha256: "2cec049d282c7f13c594b4a73976b0b4f2d7a1838a6dd5aaf7bd9719196bee86" - url: "https://pub.dev" - source: hosted - version: "2.0.27" - path_provider_foundation: - dependency: transitive - description: - name: path_provider_foundation - sha256: "916731ccbdce44d545414dd9961f26ba5fbaa74bcbb55237d8e65a623a8c7297" - url: "https://pub.dev" - source: hosted - version: "2.2.4" - path_provider_linux: - dependency: transitive - description: - name: path_provider_linux - sha256: ffbb8cc9ed2c9ec0e4b7a541e56fd79b138e8f47d2fb86815f15358a349b3b57 - url: "https://pub.dev" - source: hosted - version: "2.1.11" - path_provider_platform_interface: - dependency: transitive - description: - name: path_provider_platform_interface - sha256: "57585299a729335f1298b43245842678cb9f43a6310351b18fb577d6e33165ec" - url: "https://pub.dev" - source: hosted - version: "2.0.6" - path_provider_windows: - dependency: transitive - description: - name: path_provider_windows - sha256: "1cb68ba4cd3a795033de62ba1b7b4564dace301f952de6bfb3cd91b202b6ee96" - url: "https://pub.dev" - source: hosted - version: "2.1.7" - platform: - dependency: transitive - description: - name: platform - sha256: "4a451831508d7d6ca779f7ac6e212b4023dd5a7d08a27a63da33756410e32b76" - url: "https://pub.dev" - source: hosted - version: "3.1.0" - plugin_platform_interface: - dependency: transitive - description: - name: plugin_platform_interface - sha256: "43798d895c929056255600343db8f049921cbec94d31ec87f1dc5c16c01935dd" - url: "https://pub.dev" - source: hosted - version: "2.1.5" - sky_engine: - dependency: transitive - description: flutter - source: sdk - version: "0.0.99" - smooth_corner: - dependency: "direct main" - description: - name: smooth_corner - sha256: "1e920cffd9644d6f51f9a99674652f8c00f2e9074b275f3edde0de1441ba78e9" - url: "https://pub.dev" - source: hosted - version: "1.1.0" - source_span: - dependency: transitive - description: - name: source_span - sha256: dd904f795d4b4f3b870833847c461801f6750a9fa8e61ea5ac53f9422b31f250 - url: "https://pub.dev" - source: hosted - version: "1.9.1" - stack_trace: - dependency: transitive - description: - name: stack_trace - sha256: c3c7d8edb15bee7f0f74debd4b9c5f3c2ea86766fe4178eb2a18eb30a0bdaed5 - url: "https://pub.dev" - source: hosted - version: "1.11.0" - stream_channel: - dependency: transitive - description: - name: stream_channel - sha256: "83615bee9045c1d322bbbd1ba209b7a749c2cbcdcb3fdd1df8eb488b3279c1c8" - url: "https://pub.dev" - source: hosted - version: "2.1.1" - string_scanner: - dependency: transitive - description: - name: string_scanner - sha256: "556692adab6cfa87322a115640c11f13cb77b3f076ddcc5d6ae3c20242bedcde" - url: "https://pub.dev" - source: hosted - version: "1.2.0" - synchronized: - dependency: transitive - description: - name: synchronized - sha256: "5fcbd27688af6082f5abd611af56ee575342c30e87541d0245f7ff99faa02c60" - url: "https://pub.dev" - source: hosted - version: "3.1.0" - term_glyph: - dependency: transitive - description: - name: term_glyph - sha256: a29248a84fbb7c79282b40b8c72a1209db169a2e0542bce341da992fe1bc7e84 - url: "https://pub.dev" - source: hosted - version: "1.2.1" - test_api: - dependency: transitive - description: - name: test_api - sha256: ad540f65f92caa91bf21dfc8ffb8c589d6e4dc0c2267818b4cc2792857706206 - url: "https://pub.dev" - source: hosted - version: "0.4.16" - text_scroll: - dependency: "direct main" - description: - name: text_scroll - sha256: "7869d86a6fdd725dee56bdd150216a99f0372b82fbfcac319214dbd5f36e1908" - url: "https://pub.dev" - source: hosted - version: "0.2.0" - top_snackbar_flutter: - dependency: "direct main" - description: - name: top_snackbar_flutter - sha256: "22d14664a13db6ac714934c3382bd8d4daa57fb888a672f922df71981c5a5cb2" - url: "https://pub.dev" - source: hosted - version: "3.1.0" - typed_data: - dependency: transitive - description: - name: typed_data - sha256: facc8d6582f16042dd49f2463ff1bd6e2c9ef9f3d5da3d9b087e244a7b564b3c - url: "https://pub.dev" - source: hosted - version: "1.3.2" - uuid: - dependency: transitive - description: - name: uuid - sha256: "648e103079f7c64a36dc7d39369cabb358d377078a051d6ae2ad3aa539519313" - url: "https://pub.dev" - source: hosted - version: "3.0.7" - vector_math: - dependency: transitive - description: - name: vector_math - sha256: "80b3257d1492ce4d091729e3a67a60407d227c27241d6927be0130c98e741803" - url: "https://pub.dev" - source: hosted - version: "2.1.4" - win32: - dependency: transitive - description: - name: win32 - sha256: "5a751eddf9db89b3e5f9d50c20ab8612296e4e8db69009788d6c8b060a84191c" - url: "https://pub.dev" - source: hosted - version: "4.1.4" - xdg_directories: - dependency: transitive - description: - name: xdg_directories - sha256: e0b1147eec179d3911f1f19b59206448f78195ca1d20514134e10641b7d7fbff - url: "https://pub.dev" - source: hosted - version: "1.0.1" - zoom_tap_animation: - dependency: "direct main" - description: - name: zoom_tap_animation - sha256: d9f7a73cab65aa1546ba6886b5e21d3c8ccccb34e4e5f770301c306d4868bee0 - url: "https://pub.dev" - source: hosted - version: "1.1.0" -sdks: - dart: ">=2.18.2 <3.0.0" - flutter: ">=3.3.0" +# Generated by pub +# See https://dart.dev/tools/pub/glossary#lockfile +packages: + _flutterfire_internals: + dependency: transitive + description: + name: _flutterfire_internals + sha256: "5dce45a06d386358334eb1689108db6455d90ceb0d75848d5f4819283d4ee2b8" + url: "https://pub.dev" + source: hosted + version: "1.3.4" + async: + dependency: transitive + description: + name: async + sha256: bfe67ef28df125b7dddcea62755991f807aa39a2492a23e1550161692950bbe0 + url: "https://pub.dev" + source: hosted + version: "2.10.0" + audioplayers: + dependency: "direct main" + description: + name: audioplayers + sha256: "61583554386721772f9309f509e17712865b38565a903c761f96b1115a979282" + url: "https://pub.dev" + source: hosted + version: "4.1.0" + audioplayers_android: + dependency: transitive + description: + name: audioplayers_android + sha256: dbdc9b7f2aa2440314c638aa55aadd45c7705e8340d5eddf2e3fb8da32d4ae2c + url: "https://pub.dev" + source: hosted + version: "3.0.2" + audioplayers_darwin: + dependency: transitive + description: + name: audioplayers_darwin + sha256: "6aea96df1d12f7ad5a71d88c6d1b22a216211a9564219920124c16768e456e9d" + url: "https://pub.dev" + source: hosted + version: "4.1.0" + audioplayers_linux: + dependency: transitive + description: + name: audioplayers_linux + sha256: "396b62ac62c92dd26c3bc5106583747f57a8b325ebd2b41e5576f840cfc61338" + url: "https://pub.dev" + source: hosted + version: "2.1.0" + audioplayers_platform_interface: + dependency: transitive + description: + name: audioplayers_platform_interface + sha256: f7daaed4659143094151ecf6bacd927d29ab8acffba98c110c59f0b81ae51143 + url: "https://pub.dev" + source: hosted + version: "5.0.1" + audioplayers_web: + dependency: transitive + description: + name: audioplayers_web + sha256: ec84fd46eed1577148ed4113f5998a36a18da4fce7170c37ce3e21b631393339 + url: "https://pub.dev" + source: hosted + version: "3.1.0" + audioplayers_windows: + dependency: transitive + description: + name: audioplayers_windows + sha256: "1d3aaac98a192b8488167711ba1e67d8b96333e8d0572ede4e2912e5bbce69a3" + url: "https://pub.dev" + source: hosted + version: "2.0.2" + auto_size_text: + dependency: "direct main" + description: + name: auto_size_text + sha256: "3f5261cd3fb5f2a9ab4e2fc3fba84fd9fcaac8821f20a1d4e71f557521b22599" + url: "https://pub.dev" + source: hosted + version: "3.0.0" + boolean_selector: + dependency: transitive + description: + name: boolean_selector + sha256: "6cfb5af12253eaf2b368f07bacc5a80d1301a071c73360d746b7f2e32d762c66" + url: "https://pub.dev" + source: hosted + version: "2.1.1" + characters: + dependency: transitive + description: + name: characters + sha256: e6a326c8af69605aec75ed6c187d06b349707a27fbff8222ca9cc2cff167975c + url: "https://pub.dev" + source: hosted + version: "1.2.1" + circular_reveal_animation: + dependency: "direct main" + description: + name: circular_reveal_animation + sha256: "198f5a1fa27384dcf950807e0ae07a0da857c04df6233f7468755ee9db102b0c" + url: "https://pub.dev" + source: hosted + version: "2.0.1" + clock: + dependency: transitive + description: + name: clock + sha256: cb6d7f03e1de671e34607e909a7213e31d7752be4fb66a86d29fe1eb14bfb5cf + url: "https://pub.dev" + source: hosted + version: "1.1.1" + cloud_firestore: + dependency: "direct main" + description: + name: cloud_firestore + sha256: f1a06ad4499ed9ab73703560d44893e6b9e66ce3923c9121f4ef3981c972057f + url: "https://pub.dev" + source: hosted + version: "4.8.4" + cloud_firestore_platform_interface: + dependency: transitive + description: + name: cloud_firestore_platform_interface + sha256: "86bd1865abbeb09a7d09da3e70364a09f894937270651fc611a1c6d6a9f7b02c" + url: "https://pub.dev" + source: hosted + version: "5.15.3" + cloud_firestore_web: + dependency: transitive + description: + name: cloud_firestore_web + sha256: ac2eeb2a7ab1928c3aacc30eed750fa839d6f620e112a5459e321df217be2f47 + url: "https://pub.dev" + source: hosted + version: "3.6.3" + collection: + dependency: transitive + description: + name: collection + sha256: cfc915e6923fe5ce6e153b0723c753045de46de1b4d63771530504004a45fae0 + url: "https://pub.dev" + source: hosted + version: "1.17.0" + crypto: + dependency: transitive + description: + name: crypto + sha256: aa274aa7774f8964e4f4f38cc994db7b6158dd36e9187aaceaddc994b35c6c67 + url: "https://pub.dev" + source: hosted + version: "3.0.2" + cupertino_icons: + dependency: "direct main" + description: + name: cupertino_icons + sha256: e35129dc44c9118cee2a5603506d823bab99c68393879edb440e0090d07586be + url: "https://pub.dev" + source: hosted + version: "1.0.5" + custom_draggable_widget: + dependency: "direct main" + description: + name: custom_draggable_widget + sha256: "15718003ebcebb84acdf0c625831a880d139a284d8de9d943ef0d0a669f10159" + url: "https://pub.dev" + source: hosted + version: "0.0.2" + fake_async: + dependency: transitive + description: + name: fake_async + sha256: "511392330127add0b769b75a987850d136345d9227c6b94c96a04cf4a391bf78" + url: "https://pub.dev" + source: hosted + version: "1.3.1" + ffi: + dependency: transitive + description: + name: ffi + sha256: ed5337a5660c506388a9f012be0288fb38b49020ce2b45fe1f8b8323fe429f99 + url: "https://pub.dev" + source: hosted + version: "2.0.2" + file: + dependency: transitive + description: + name: file + sha256: "1b92bec4fc2a72f59a8e15af5f52cd441e4a7860b49499d69dfa817af20e925d" + url: "https://pub.dev" + source: hosted + version: "6.1.4" + firebase_auth: + dependency: "direct main" + description: + name: firebase_auth + sha256: "49fd35ce06f2530dd460e5dc123235731cb61dd7c76b0af4b6e190404880d04d" + url: "https://pub.dev" + source: hosted + version: "4.7.2" + firebase_auth_platform_interface: + dependency: transitive + description: + name: firebase_auth_platform_interface + sha256: "817f3ceb84ef5e9adaaf50cf7a19255f6ffcdd12c6f9e9aa4cf00fc7f2eb3cfb" + url: "https://pub.dev" + source: hosted + version: "6.16.1" + firebase_auth_web: + dependency: transitive + description: + name: firebase_auth_web + sha256: e9044778287f1ff8f9f4cee7e247b03ec87bb8977e0e65ad27dc337e196132e8 + url: "https://pub.dev" + source: hosted + version: "5.6.2" + firebase_core: + dependency: "direct main" + description: + name: firebase_core + sha256: "2e9324f719e90200dc7d3c4f5d2abc26052f9f2b995d3b6626c47a0dfe1c8192" + url: "https://pub.dev" + source: hosted + version: "2.15.0" + firebase_core_platform_interface: + dependency: transitive + description: + name: firebase_core_platform_interface + sha256: b63e3be6c96ef5c33bdec1aab23c91eb00696f6452f0519401d640938c94cba2 + url: "https://pub.dev" + source: hosted + version: "4.8.0" + firebase_core_web: + dependency: transitive + description: + name: firebase_core_web + sha256: "0fd5c4b228de29b55fac38aed0d9e42514b3d3bd47675de52bf7f8fccaf922fa" + url: "https://pub.dev" + source: hosted + version: "2.6.0" + flutter: + dependency: "direct main" + description: flutter + source: sdk + version: "0.0.0" + flutter_animated_play_button: + dependency: "direct main" + description: + name: flutter_animated_play_button + sha256: dd955a450a4514e935e2f410afbd03b3bcf5f31b933a8f1334199caa3c6a81e2 + url: "https://pub.dev" + source: hosted + version: "0.3.0" + flutter_lints: + dependency: "direct dev" + description: + name: flutter_lints + sha256: "2118df84ef0c3ca93f96123a616ae8540879991b8b57af2f81b76a7ada49b2a4" + url: "https://pub.dev" + source: hosted + version: "2.0.2" + flutter_screenutil: + dependency: "direct main" + description: + name: flutter_screenutil + sha256: "0a122936b450324cbdfd51be0819cc6fcebb093eb65585e9cd92263f7a1a8a39" + url: "https://pub.dev" + source: hosted + version: "5.7.0" + flutter_signin_button: + dependency: "direct main" + description: + name: flutter_signin_button + sha256: a063ecc5d5308377e103c9c3a89084abf15fca4440636233af6a13abacd5dcae + url: "https://pub.dev" + source: hosted + version: "2.0.0" + flutter_test: + dependency: "direct dev" + description: flutter + source: sdk + version: "0.0.0" + flutter_web_plugins: + dependency: transitive + description: flutter + source: sdk + version: "0.0.0" + font_awesome_flutter: + dependency: transitive + description: + name: font_awesome_flutter + sha256: "1f93e5799f0e6c882819e8393a05c6ca5226010f289190f2242ec19f3f0fdba5" + url: "https://pub.dev" + source: hosted + version: "9.2.0" + google_fonts: + dependency: "direct main" + description: + name: google_fonts + sha256: "6b6f10f0ce3c42f6552d1c70d2c28d764cf22bb487f50f66cca31dcd5194f4d6" + url: "https://pub.dev" + source: hosted + version: "4.0.4" + gradiantbutton: + dependency: "direct main" + description: + name: gradiantbutton + sha256: c88ac8567242630cd14231e2a6a861da4e40a02a9a0310af360e05634890d172 + url: "https://pub.dev" + source: hosted + version: "0.0.1" + gradient_borders: + dependency: "direct main" + description: + name: gradient_borders + sha256: "69eeaff519d145a4c6c213ada1abae386bcc8981a4970d923e478ce7ba19e309" + url: "https://pub.dev" + source: hosted + version: "1.0.0" + http: + dependency: "direct main" + description: + name: http + sha256: "6aa2946395183537c8b880962d935877325d6a09a2867c3970c05c0fed6ac482" + url: "https://pub.dev" + source: hosted + version: "0.13.5" + http_parser: + dependency: transitive + description: + name: http_parser + sha256: "2aa08ce0341cc9b354a498388e30986515406668dbcc4f7c950c3e715496693b" + url: "https://pub.dev" + source: hosted + version: "4.0.2" + ionicons: + dependency: "direct main" + description: + name: ionicons + sha256: "5496bc65a16115ecf05b15b78f494ee4a8869504357668f0a11d689e970523cf" + url: "https://pub.dev" + source: hosted + version: "0.2.2" + js: + dependency: transitive + description: + name: js + sha256: "5528c2f391ededb7775ec1daa69e65a2d61276f7552de2b5f7b8d34ee9fd4ab7" + url: "https://pub.dev" + source: hosted + version: "0.6.5" + lints: + dependency: transitive + description: + name: lints + sha256: "5e4a9cd06d447758280a8ac2405101e0e2094d2a1dbdd3756aec3fe7775ba593" + url: "https://pub.dev" + source: hosted + version: "2.0.1" + matcher: + dependency: transitive + description: + name: matcher + sha256: "16db949ceee371e9b99d22f88fa3a73c4e59fd0afed0bd25fc336eb76c198b72" + url: "https://pub.dev" + source: hosted + version: "0.12.13" + material_color_utilities: + dependency: transitive + description: + name: material_color_utilities + sha256: d92141dc6fe1dad30722f9aa826c7fbc896d021d792f80678280601aff8cf724 + url: "https://pub.dev" + source: hosted + version: "0.2.0" + meta: + dependency: transitive + description: + name: meta + sha256: "6c268b42ed578a53088d834796959e4a1814b5e9e164f147f580a386e5decf42" + url: "https://pub.dev" + source: hosted + version: "1.8.0" + modal_bottom_sheet: + dependency: "direct main" + description: + name: modal_bottom_sheet + sha256: ef533916a2c3089571c32bd34e410faca77a6849a3f28f748e0794525c5658a0 + url: "https://pub.dev" + source: hosted + version: "2.1.2" + path: + dependency: transitive + description: + name: path + sha256: db9d4f58c908a4ba5953fcee2ae317c94889433e5024c27ce74a37f94267945b + url: "https://pub.dev" + source: hosted + version: "1.8.2" + path_provider: + dependency: transitive + description: + name: path_provider + sha256: "3087813781ab814e4157b172f1a11c46be20179fcc9bea043e0fba36bc0acaa2" + url: "https://pub.dev" + source: hosted + version: "2.0.15" + path_provider_android: + dependency: transitive + description: + name: path_provider_android + sha256: "2cec049d282c7f13c594b4a73976b0b4f2d7a1838a6dd5aaf7bd9719196bee86" + url: "https://pub.dev" + source: hosted + version: "2.0.27" + path_provider_foundation: + dependency: transitive + description: + name: path_provider_foundation + sha256: "916731ccbdce44d545414dd9961f26ba5fbaa74bcbb55237d8e65a623a8c7297" + url: "https://pub.dev" + source: hosted + version: "2.2.4" + path_provider_linux: + dependency: transitive + description: + name: path_provider_linux + sha256: ffbb8cc9ed2c9ec0e4b7a541e56fd79b138e8f47d2fb86815f15358a349b3b57 + url: "https://pub.dev" + source: hosted + version: "2.1.11" + path_provider_platform_interface: + dependency: transitive + description: + name: path_provider_platform_interface + sha256: "57585299a729335f1298b43245842678cb9f43a6310351b18fb577d6e33165ec" + url: "https://pub.dev" + source: hosted + version: "2.0.6" + path_provider_windows: + dependency: transitive + description: + name: path_provider_windows + sha256: "1cb68ba4cd3a795033de62ba1b7b4564dace301f952de6bfb3cd91b202b6ee96" + url: "https://pub.dev" + source: hosted + version: "2.1.7" + platform: + dependency: transitive + description: + name: platform + sha256: "4a451831508d7d6ca779f7ac6e212b4023dd5a7d08a27a63da33756410e32b76" + url: "https://pub.dev" + source: hosted + version: "3.1.0" + plugin_platform_interface: + dependency: transitive + description: + name: plugin_platform_interface + sha256: "43798d895c929056255600343db8f049921cbec94d31ec87f1dc5c16c01935dd" + url: "https://pub.dev" + source: hosted + version: "2.1.5" + sky_engine: + dependency: transitive + description: flutter + source: sdk + version: "0.0.99" + smooth_corner: + dependency: "direct main" + description: + name: smooth_corner + sha256: "1e920cffd9644d6f51f9a99674652f8c00f2e9074b275f3edde0de1441ba78e9" + url: "https://pub.dev" + source: hosted + version: "1.1.0" + source_span: + dependency: transitive + description: + name: source_span + sha256: dd904f795d4b4f3b870833847c461801f6750a9fa8e61ea5ac53f9422b31f250 + url: "https://pub.dev" + source: hosted + version: "1.9.1" + stack_trace: + dependency: transitive + description: + name: stack_trace + sha256: c3c7d8edb15bee7f0f74debd4b9c5f3c2ea86766fe4178eb2a18eb30a0bdaed5 + url: "https://pub.dev" + source: hosted + version: "1.11.0" + stream_channel: + dependency: transitive + description: + name: stream_channel + sha256: "83615bee9045c1d322bbbd1ba209b7a749c2cbcdcb3fdd1df8eb488b3279c1c8" + url: "https://pub.dev" + source: hosted + version: "2.1.1" + string_scanner: + dependency: transitive + description: + name: string_scanner + sha256: "556692adab6cfa87322a115640c11f13cb77b3f076ddcc5d6ae3c20242bedcde" + url: "https://pub.dev" + source: hosted + version: "1.2.0" + synchronized: + dependency: transitive + description: + name: synchronized + sha256: "5fcbd27688af6082f5abd611af56ee575342c30e87541d0245f7ff99faa02c60" + url: "https://pub.dev" + source: hosted + version: "3.1.0" + term_glyph: + dependency: transitive + description: + name: term_glyph + sha256: a29248a84fbb7c79282b40b8c72a1209db169a2e0542bce341da992fe1bc7e84 + url: "https://pub.dev" + source: hosted + version: "1.2.1" + test_api: + dependency: transitive + description: + name: test_api + sha256: ad540f65f92caa91bf21dfc8ffb8c589d6e4dc0c2267818b4cc2792857706206 + url: "https://pub.dev" + source: hosted + version: "0.4.16" + text_scroll: + dependency: "direct main" + description: + name: text_scroll + sha256: "7869d86a6fdd725dee56bdd150216a99f0372b82fbfcac319214dbd5f36e1908" + url: "https://pub.dev" + source: hosted + version: "0.2.0" + top_snackbar_flutter: + dependency: "direct main" + description: + name: top_snackbar_flutter + sha256: "22d14664a13db6ac714934c3382bd8d4daa57fb888a672f922df71981c5a5cb2" + url: "https://pub.dev" + source: hosted + version: "3.1.0" + typed_data: + dependency: transitive + description: + name: typed_data + sha256: facc8d6582f16042dd49f2463ff1bd6e2c9ef9f3d5da3d9b087e244a7b564b3c + url: "https://pub.dev" + source: hosted + version: "1.3.2" + uuid: + dependency: transitive + description: + name: uuid + sha256: "648e103079f7c64a36dc7d39369cabb358d377078a051d6ae2ad3aa539519313" + url: "https://pub.dev" + source: hosted + version: "3.0.7" + vector_math: + dependency: transitive + description: + name: vector_math + sha256: "80b3257d1492ce4d091729e3a67a60407d227c27241d6927be0130c98e741803" + url: "https://pub.dev" + source: hosted + version: "2.1.4" + win32: + dependency: transitive + description: + name: win32 + sha256: "5a751eddf9db89b3e5f9d50c20ab8612296e4e8db69009788d6c8b060a84191c" + url: "https://pub.dev" + source: hosted + version: "4.1.4" + xdg_directories: + dependency: transitive + description: + name: xdg_directories + sha256: e0b1147eec179d3911f1f19b59206448f78195ca1d20514134e10641b7d7fbff + url: "https://pub.dev" + source: hosted + version: "1.0.1" + zoom_tap_animation: + dependency: "direct main" + description: + name: zoom_tap_animation + sha256: d9f7a73cab65aa1546ba6886b5e21d3c8ccccb34e4e5f770301c306d4868bee0 + url: "https://pub.dev" + source: hosted + version: "1.1.0" +sdks: + dart: ">=2.18.2 <3.0.0" + flutter: ">=3.3.0" diff --git a/Sources/justMUSIC/pubspec.yaml b/Sources/justMUSIC/pubspec.yaml index 9913d71..daebe28 100644 --- a/Sources/justMUSIC/pubspec.yaml +++ b/Sources/justMUSIC/pubspec.yaml @@ -1,111 +1,111 @@ -name: justmusic -description: A new Flutter project. - -# The following line prevents the package from being accidentally published to -# pub.dev using `flutter pub publish`. This is preferred for private packages. -publish_to: 'none' # Remove this line if you wish to publish to pub.dev - -# The following defines the version and build number for your application. -# A version number is three numbers separated by dots, like 1.2.43 -# followed by an optional build number separated by a +. -# Both the version and the builder number may be overridden in flutter -# build by specifying --build-name and --build-number, respectively. -# In Android, build-name is used as versionName while build-number used as versionCode. -# Read more about Android versioning at https://developer.android.com/studio/publish/versioning -# In iOS, build-name is used as CFBundleShortVersionString while build-number is used as CFBundleVersion. -# Read more about iOS versioning at -# https://developer.apple.com/library/archive/documentation/General/Reference/InfoPlistKeyReference/Articles/CoreFoundationKeys.html -# In Windows, build-name is used as the major, minor, and patch parts -# of the product and file versions while build-number is used as the build suffix. -version: 1.0.0+1 - -environment: - sdk: '>=2.18.2 <3.0.0' - -# Dependencies specify other packages that your package needs in order to work. -# To automatically upgrade your package dependencies to the latest versions -# consider running `flutter pub upgrade --major-versions`. Alternatively, -# dependencies can be manually updated by changing the version numbers below to -# the latest version available on pub.dev. To see which dependencies have newer -# versions available, run `flutter pub outdated`. -dependencies: - flutter: - sdk: flutter - http: ^0.13.5 - - - # The following adds the Cupertino Icons font to your application. - # Use with the CupertinoIcons class for iOS style icons. - cupertino_icons: ^1.0.2 - google_fonts: ^4.0.4 - gradiantbutton: ^0.0.1 - smooth_corner: ^1.1.0 - flutter_signin_button: ^2.0.0 - flutter_screenutil: ^5.7.0 - auto_size_text: ^3.0.0 - gradient_borders: ^1.0.0 - text_scroll: ^0.2.0 - circular_reveal_animation: ^2.0.1 - zoom_tap_animation: ^1.1.0 - custom_draggable_widget: ^0.0.2 - modal_bottom_sheet: ^2.1.2 - flutter_animated_play_button: ^0.3.0 - audioplayers: ^4.1.0 - ionicons: ^0.2.2 - top_snackbar_flutter: ^3.1.0 - firebase_core: ^2.15.0 - firebase_auth: ^4.7.2 - cloud_firestore: ^4.8.4 - -dev_dependencies: - flutter_test: - sdk: flutter - - # The "flutter_lints" package below contains a set of recommended lints to - # encourage good coding practices. The lint set provided by the package is - # activated in the `analysis_options.yaml` file located at the root of your - # package. See that file for information about deactivating specific lint - # rules and activating additional ones. - flutter_lints: ^2.0.0 - -# For information on the generic Dart part of this file, see the -# following page: https://dart.dev/tools/pub/pubspec - -# The following section is specific to Flutter packages. -flutter: - - # The following line ensures that the Material Icons font is - # included with your application, so that you can use the icons in - # the material Icons class. - uses-material-design: true - - # To add assets to your application, add an assets section, like this: - assets: - - assets/images/ - - assets/ - - # An image asset can refer to one or more resolution-specific "variants", see - # https://flutter.dev/assets-and-images/#resolution-aware - - # For details regarding adding assets from package dependencies, see - # https://flutter.dev/assets-and-images/#from-packages - - # To add custom fonts to your application, add a fonts section here, - # in this "flutter" section. Each entry in this list should have a - # "family" key with the font family name, and a "fonts" key with a - # list giving the asset and other descriptors for the font. For - # example: - # fonts: - # - family: Schyler - # fonts: - # - asset: fonts/Schyler-Regular.ttf - # - asset: fonts/Schyler-Italic.ttf - # style: italic - # - family: Trajan Pro - # fonts: - # - asset: fonts/TrajanPro.ttf - # - asset: fonts/TrajanPro_Bold.ttf - # weight: 700 - # - # For details regarding fonts from package dependencies, - # see https://flutter.dev/custom-fonts/#from-packages +name: justmusic +description: A new Flutter project. + +# The following line prevents the package from being accidentally published to +# pub.dev using `flutter pub publish`. This is preferred for private packages. +publish_to: 'none' # Remove this line if you wish to publish to pub.dev + +# The following defines the version and build number for your application. +# A version number is three numbers separated by dots, like 1.2.43 +# followed by an optional build number separated by a +. +# Both the version and the builder number may be overridden in flutter +# build by specifying --build-name and --build-number, respectively. +# In Android, build-name is used as versionName while build-number used as versionCode. +# Read more about Android versioning at https://developer.android.com/studio/publish/versioning +# In iOS, build-name is used as CFBundleShortVersionString while build-number is used as CFBundleVersion. +# Read more about iOS versioning at +# https://developer.apple.com/library/archive/documentation/General/Reference/InfoPlistKeyReference/Articles/CoreFoundationKeys.html +# In Windows, build-name is used as the major, minor, and patch parts +# of the product and file versions while build-number is used as the build suffix. +version: 1.0.0+1 + +environment: + sdk: '>=2.18.2 <3.0.0' + +# Dependencies specify other packages that your package needs in order to work. +# To automatically upgrade your package dependencies to the latest versions +# consider running `flutter pub upgrade --major-versions`. Alternatively, +# dependencies can be manually updated by changing the version numbers below to +# the latest version available on pub.dev. To see which dependencies have newer +# versions available, run `flutter pub outdated`. +dependencies: + flutter: + sdk: flutter + http: ^0.13.5 + + + # The following adds the Cupertino Icons font to your application. + # Use with the CupertinoIcons class for iOS style icons. + cupertino_icons: ^1.0.2 + google_fonts: ^4.0.4 + gradiantbutton: ^0.0.1 + smooth_corner: ^1.1.0 + flutter_signin_button: ^2.0.0 + flutter_screenutil: ^5.7.0 + auto_size_text: ^3.0.0 + gradient_borders: ^1.0.0 + text_scroll: ^0.2.0 + circular_reveal_animation: ^2.0.1 + zoom_tap_animation: ^1.1.0 + custom_draggable_widget: ^0.0.2 + modal_bottom_sheet: ^2.1.2 + flutter_animated_play_button: ^0.3.0 + audioplayers: ^4.1.0 + ionicons: ^0.2.2 + top_snackbar_flutter: ^3.1.0 + firebase_core: ^2.15.0 + firebase_auth: ^4.7.2 + cloud_firestore: ^4.8.4 + +dev_dependencies: + flutter_test: + sdk: flutter + + # The "flutter_lints" package below contains a set of recommended lints to + # encourage good coding practices. The lint set provided by the package is + # activated in the `analysis_options.yaml` file located at the root of your + # package. See that file for information about deactivating specific lint + # rules and activating additional ones. + flutter_lints: ^2.0.0 + +# For information on the generic Dart part of this file, see the +# following page: https://dart.dev/tools/pub/pubspec + +# The following section is specific to Flutter packages. +flutter: + + # The following line ensures that the Material Icons font is + # included with your application, so that you can use the icons in + # the material Icons class. + uses-material-design: true + + # To add assets to your application, add an assets section, like this: + assets: + - assets/images/ + - assets/ + + # An image asset can refer to one or more resolution-specific "variants", see + # https://flutter.dev/assets-and-images/#resolution-aware + + # For details regarding adding assets from package dependencies, see + # https://flutter.dev/assets-and-images/#from-packages + + # To add custom fonts to your application, add a fonts section here, + # in this "flutter" section. Each entry in this list should have a + # "family" key with the font family name, and a "fonts" key with a + # list giving the asset and other descriptors for the font. For + # example: + # fonts: + # - family: Schyler + # fonts: + # - asset: fonts/Schyler-Regular.ttf + # - asset: fonts/Schyler-Italic.ttf + # style: italic + # - family: Trajan Pro + # fonts: + # - asset: fonts/TrajanPro.ttf + # - asset: fonts/TrajanPro_Bold.ttf + # weight: 700 + # + # For details regarding fonts from package dependencies, + # see https://flutter.dev/custom-fonts/#from-packages diff --git a/Sources/justMUSIC/test/Music_test.dart b/Sources/justMUSIC/test/Music_test.dart index baf3aaa..2b958bb 100644 --- a/Sources/justMUSIC/test/Music_test.dart +++ b/Sources/justMUSIC/test/Music_test.dart @@ -1,60 +1,60 @@ -import 'package:justmusic/model/Artist.dart'; -import 'package:justmusic/model/Music.dart'; -import 'package:justmusic/view_model/MusicViewModel.dart'; - -Future main() async { - MusicViewModel musicVM = new MusicViewModel(); - Music m = await musicVM.getMusic('295SxdR1DqunCNwd0U767w'); - - print("id : ${m.id.toString()}, cover : ${m.cover}, title : ${m.title}"); - print("date : ${m.date.toString()}, preview : ${m.previewUrl}, duration : ${m.duration}, explicit : ${m.explicit}"); - for (Artist a in m.artists) { - print("id : ${a.id}, name : ${a.name}"); - } - - print('\nMusics :'); - - List musics = await musicVM.getMusicsWithName('Shavkat'); - for (Music m in musics) { - print("id : ${m.id.toString()}, cover : ${m.cover}, title : ${m.title}"); - print("date : ${m.date.toString()}, preview : ${m.previewUrl}, duration : ${m.duration}, explicit : ${m.explicit}"); - for (Artist a in m.artists) { - print("id : ${a.id}, name : ${a.name}"); - } - } - - print('\nMusics With Artist:'); - - List musics2 = await musicVM.getMusicsWithArtistName('jul'); - for (Music m in musics2) { - print("id : ${m.id.toString()}, cover : ${m.cover}, title : ${m.title}"); - print("date : ${m.date.toString()}, preview : ${m.previewUrl}, duration : ${m.duration}, explicit : ${m.explicit}"); - for (Artist a in m.artists) { - print("id : ${a.id}, name : ${a.name}"); - } - } - - print('\nArtist with Name:'); - - Artist a = await musicVM.getArtistWithName('jul'); - print("id : ${a.id}, name : ${a.name}, image : ${a.image}"); - - print('\nArtists with Name:'); - - List artists = await musicVM.getArtistsWithName('jul'); - for (Artist a in artists) { - print("id : ${a.id}, name : ${a.name}, image : ${a.image}"); - } - - print('\nTop Musics :'); - - List topMusics = await musicVM.getTopMusicsWithArtistId('3NH8t45zOTqzlZgBvZRjvB'); - for (Music m in topMusics) { - print("id : ${m.id.toString()}, cover : ${m.cover}, title : ${m.title}"); - print("date : ${m.date.toString()}, preview : ${m.previewUrl}, duration : ${m.duration}, explicit : ${m.explicit}"); - for (Artist a in m.artists) { - print("id : ${a.id}, name : ${a.name}"); - } - } - -} +import 'package:justmusic/model/Artist.dart'; +import 'package:justmusic/model/Music.dart'; +import 'package:justmusic/view_model/MusicViewModel.dart'; + +Future main() async { + MusicViewModel musicVM = new MusicViewModel(); + Music m = await musicVM.getMusic('295SxdR1DqunCNwd0U767w'); + + print("id : ${m.id.toString()}, cover : ${m.cover}, title : ${m.title}"); + print("date : ${m.date.toString()}, preview : ${m.previewUrl}, duration : ${m.duration}, explicit : ${m.explicit}"); + for (Artist a in m.artists) { + print("id : ${a.id}, name : ${a.name}"); + } + + print('\nMusics :'); + + List musics = await musicVM.getMusicsWithName('Shavkat'); + for (Music m in musics) { + print("id : ${m.id.toString()}, cover : ${m.cover}, title : ${m.title}"); + print("date : ${m.date.toString()}, preview : ${m.previewUrl}, duration : ${m.duration}, explicit : ${m.explicit}"); + for (Artist a in m.artists) { + print("id : ${a.id}, name : ${a.name}"); + } + } + + print('\nMusics With Artist:'); + + List musics2 = await musicVM.getMusicsWithArtistName('jul'); + for (Music m in musics2) { + print("id : ${m.id.toString()}, cover : ${m.cover}, title : ${m.title}"); + print("date : ${m.date.toString()}, preview : ${m.previewUrl}, duration : ${m.duration}, explicit : ${m.explicit}"); + for (Artist a in m.artists) { + print("id : ${a.id}, name : ${a.name}"); + } + } + + print('\nArtist with Name:'); + + Artist a = await musicVM.getArtistWithName('jul'); + print("id : ${a.id}, name : ${a.name}, image : ${a.image}"); + + print('\nArtists with Name:'); + + List artists = await musicVM.getArtistsWithName('jul'); + for (Artist a in artists) { + print("id : ${a.id}, name : ${a.name}, image : ${a.image}"); + } + + print('\nTop Musics :'); + + List topMusics = await musicVM.getTopMusicsWithArtistId('3NH8t45zOTqzlZgBvZRjvB'); + for (Music m in topMusics) { + print("id : ${m.id.toString()}, cover : ${m.cover}, title : ${m.title}"); + print("date : ${m.date.toString()}, preview : ${m.previewUrl}, duration : ${m.duration}, explicit : ${m.explicit}"); + for (Artist a in m.artists) { + print("id : ${a.id}, name : ${a.name}"); + } + } + +} -- 2.36.3 From 9f9b52d385e4d90b22f72c11e3b1446b6634b36a Mon Sep 17 00:00:00 2001 From: emkartal1 Date: Sun, 30 Jul 2023 19:33:56 +0200 Subject: [PATCH 7/8] Unique Id done :white_check_mark --- .../components/editable_post_component.dart | 226 +++++++------- .../lib/model/mapper/UserMapper.dart | 2 +- .../justMUSIC/lib/screens/post_screen.dart | 252 +++++++-------- .../justMUSIC/lib/screens/profile_screen.dart | 292 +++++++++--------- .../justMUSIC/lib/service/AuthService.dart | 20 ++ Sources/justMUSIC/lib/values/constants.dart | 52 ++-- .../lib/view_model/UserViewModel.dart | 11 +- Sources/justMUSIC/pubspec.lock | 34 +- 8 files changed, 459 insertions(+), 430 deletions(-) diff --git a/Sources/justMUSIC/lib/components/editable_post_component.dart b/Sources/justMUSIC/lib/components/editable_post_component.dart index b25b1c8..7cf202f 100644 --- a/Sources/justMUSIC/lib/components/editable_post_component.dart +++ b/Sources/justMUSIC/lib/components/editable_post_component.dart @@ -1,113 +1,113 @@ -import 'package:auto_size_text/auto_size_text.dart'; -import 'package:flutter/Material.dart'; -import 'package:flutter_screenutil/flutter_screenutil.dart'; -import 'package:google_fonts/google_fonts.dart'; -import 'package:justmusic/values/constants.dart'; - -class EditablePostComponent extends StatefulWidget { - const EditablePostComponent({Key? key}) : super(key: key); - - @override - State createState() => _EditablePostComponentState(); -} - -class _EditablePostComponentState extends State { - @override - Widget build(BuildContext context) { - return ClipRRect( - borderRadius: BorderRadius.circular(25), - child: Container( - constraints: BoxConstraints(maxWidth: 400), - width: double.infinity, - color: warningBttnColor, - child: Column( - children: [ - AspectRatio( - aspectRatio: 1 / 1, - child: Container( - decoration: BoxDecoration( - // add border - border: Border.all(width: 3.0, color: grayColor), - // set border radius - borderRadius: BorderRadius.circular(20), - ), - child: ClipRRect( - borderRadius: BorderRadius.circular(18), - // implement image - child: const Image( - image: AssetImage("assets/images/exemple_cover.png"), - fit: BoxFit.cover, - width: double.infinity, - ), - ), - ), - ), - Padding( - padding: EdgeInsets.fromLTRB(15, 25, 15, 25), - child: Row( - mainAxisAlignment: MainAxisAlignment.spaceBetween, - children: [ - AutoSizeText( - "France, Lyon", - style: GoogleFonts.plusJakartaSans( - color: Colors.white, fontSize: 13.sp), - maxFontSize: 20, - ), - Image( - image: AssetImage("assets/images/camera_icon.png"), - width: 30, - ), - AutoSizeText( - "10 Juil. 2023", - style: GoogleFonts.plusJakartaSans( - color: Colors.white, fontSize: 13.sp), - maxFontSize: 20, - ), - ], - ), - ), - Padding( - padding: EdgeInsets.fromLTRB(15, 0, 10, 25), - child: SizedBox( - width: double.infinity, - child: TextFormField( - keyboardAppearance: Brightness.dark, - minLines: 1, - cursorColor: primaryColor, - style: GoogleFonts.plusJakartaSans( - color: Colors.white, - fontSize: 13, - fontWeight: FontWeight.w300), - maxLines: 4, - maxLength: 120, - decoration: InputDecoration( - counterStyle: GoogleFonts.plusJakartaSans( - color: grayText, fontSize: 9), - focusedBorder: const OutlineInputBorder( - borderSide: - BorderSide(width: 0, color: Colors.transparent), - borderRadius: - BorderRadius.all(Radius.circular(10))), - contentPadding: - const EdgeInsets.only(top: 0, bottom: 0, left: 0), - fillColor: Colors.transparent, - filled: true, - focusColor: Colors.transparent, - enabledBorder: const OutlineInputBorder( - borderSide: - BorderSide(width: 0, color: Colors.transparent), - borderRadius: - BorderRadius.all(Radius.circular(10))), - hintText: 'Description...', - hintStyle: GoogleFonts.plusJakartaSans( - color: grayText, - fontSize: 13, - fontWeight: FontWeight.w300), - ), - ), - )), - ], - ), - )); - } -} +import 'package:auto_size_text/auto_size_text.dart'; +import 'package:flutter/Material.dart'; +import 'package:flutter_screenutil/flutter_screenutil.dart'; +import 'package:google_fonts/google_fonts.dart'; +import 'package:justmusic/values/constants.dart'; + +class EditablePostComponent extends StatefulWidget { + const EditablePostComponent({Key? key}) : super(key: key); + + @override + State createState() => _EditablePostComponentState(); +} + +class _EditablePostComponentState extends State { + @override + Widget build(BuildContext context) { + return ClipRRect( + borderRadius: BorderRadius.circular(25), + child: Container( + constraints: BoxConstraints(maxWidth: 400), + width: double.infinity, + color: warningBttnColor, + child: Column( + children: [ + AspectRatio( + aspectRatio: 1 / 1, + child: Container( + decoration: BoxDecoration( + // add border + border: Border.all(width: 3.0, color: grayColor), + // set border radius + borderRadius: BorderRadius.circular(20), + ), + child: ClipRRect( + borderRadius: BorderRadius.circular(18), + // implement image + child: const Image( + image: AssetImage("assets/images/exemple_cover.png"), + fit: BoxFit.cover, + width: double.infinity, + ), + ), + ), + ), + Padding( + padding: EdgeInsets.fromLTRB(15, 25, 15, 25), + child: Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + AutoSizeText( + "France, Lyon", + style: GoogleFonts.plusJakartaSans( + color: Colors.white, fontSize: 13.sp), + maxFontSize: 20, + ), + Image( + image: AssetImage("assets/images/camera_icon.png"), + width: 30, + ), + AutoSizeText( + "10 Juil. 2023", + style: GoogleFonts.plusJakartaSans( + color: Colors.white, fontSize: 13.sp), + maxFontSize: 20, + ), + ], + ), + ), + Padding( + padding: EdgeInsets.fromLTRB(15, 0, 10, 25), + child: SizedBox( + width: double.infinity, + child: TextFormField( + keyboardAppearance: Brightness.dark, + minLines: 1, + cursorColor: primaryColor, + style: GoogleFonts.plusJakartaSans( + color: Colors.white, + fontSize: 13, + fontWeight: FontWeight.w300), + maxLines: 4, + maxLength: 120, + decoration: InputDecoration( + counterStyle: GoogleFonts.plusJakartaSans( + color: grayText, fontSize: 9), + focusedBorder: const OutlineInputBorder( + borderSide: + BorderSide(width: 0, color: Colors.transparent), + borderRadius: + BorderRadius.all(Radius.circular(10))), + contentPadding: + const EdgeInsets.only(top: 0, bottom: 0, left: 0), + fillColor: Colors.transparent, + filled: true, + focusColor: Colors.transparent, + enabledBorder: const OutlineInputBorder( + borderSide: + BorderSide(width: 0, color: Colors.transparent), + borderRadius: + BorderRadius.all(Radius.circular(10))), + hintText: 'Description...', + hintStyle: GoogleFonts.plusJakartaSans( + color: grayText, + fontSize: 13, + fontWeight: FontWeight.w300), + ), + ), + )), + ], + ), + )); + } +} diff --git a/Sources/justMUSIC/lib/model/mapper/UserMapper.dart b/Sources/justMUSIC/lib/model/mapper/UserMapper.dart index 58a3f15..8ef5bbc 100644 --- a/Sources/justMUSIC/lib/model/mapper/UserMapper.dart +++ b/Sources/justMUSIC/lib/model/mapper/UserMapper.dart @@ -7,7 +7,7 @@ class UserMapper { final data = snapshot.data(); return User( data?["uid"] ?? "", - data?["pseudo"] ?? "", + data?["unique_id"] ?? "", data?["country"] ?? "", data?["mail"] ?? "", data?["profilePicture"] ?? "", diff --git a/Sources/justMUSIC/lib/screens/post_screen.dart b/Sources/justMUSIC/lib/screens/post_screen.dart index e6a625b..574eac8 100644 --- a/Sources/justMUSIC/lib/screens/post_screen.dart +++ b/Sources/justMUSIC/lib/screens/post_screen.dart @@ -1,126 +1,126 @@ -import 'dart:ui'; -import 'package:flutter/Material.dart'; -import 'package:flutter_screenutil/flutter_screenutil.dart'; -import 'package:justmusic/components/back_button.dart'; -import 'package:justmusic/screens/search_song_screen.dart'; -import '../components/editable_post_component.dart'; -import '../components/post_button_component.dart'; -import '../values/constants.dart'; - -class PostScreen extends StatefulWidget { - const PostScreen({Key? key}) : super(key: key); - - @override - State createState() => _PostScreenState(); -} - -class _PostScreenState extends State - with SingleTickerProviderStateMixin { - final scrollController = ScrollController(); - late AnimationController _controller; - late Animation _animation; - - @override - void initState() { - _controller = AnimationController( - vsync: this, - duration: const Duration(milliseconds: 400), - ); - - _animation = Tween(begin: 0.0, end: 400.0).animate( - CurvedAnimation( - parent: _controller, - curve: Curves.easeOut, - ), - ); - super.initState(); - } - - void openDetailPost() { - showModalBottomSheet( - transitionAnimationController: _controller, - barrierColor: Colors.black.withOpacity(0.7), - backgroundColor: Colors.transparent, - elevation: 1, - constraints: const BoxConstraints( - maxWidth: 600, - ), - isScrollControlled: true, - context: context, - shape: const RoundedRectangleBorder( - borderRadius: BorderRadius.only( - topLeft: Radius.circular(20), topRight: Radius.circular(20))), - builder: ((context) { - return const ClipRRect( - borderRadius: BorderRadius.only( - topLeft: Radius.circular(20), topRight: Radius.circular(20)), - child: SearchSongScreen()); - }), - ); - } - - @override - Widget build(BuildContext context) { - return Scaffold( - resizeToAvoidBottomInset: true, - backgroundColor: bgColor, - extendBodyBehindAppBar: true, - appBar: PreferredSize( - preferredSize: Size(double.infinity, 80), - child: SafeArea( - child: Padding( - padding: const EdgeInsets.only( - left: defaultPadding, - right: defaultPadding, - top: defaultPadding), - child: Row( - children: [BackButtonComponent()], - ), - ), - ), - ), - body: Container( - padding: - const EdgeInsets.only(left: defaultPadding, right: defaultPadding), - width: double.infinity, - height: double.infinity, - decoration: const BoxDecoration( - image: DecorationImage( - image: AssetImage("assets/images/background_justMusic.png"), - fit: BoxFit.cover, - ), - ), - child: Stack( - alignment: Alignment.topCenter, - children: [ - ScrollConfiguration( - behavior: ScrollBehavior().copyWith(scrollbars: false), - child: SingleChildScrollView( - controller: scrollController, - child: Column( - mainAxisAlignment: MainAxisAlignment.end, - children: [ - SizedBox( - height: 100.h, - ), - GestureDetector( - onTap: openDetailPost, - child: EditablePostComponent(), - ), - SizedBox( - height: 40.h, - ), - PostButtonComponent(), - SizedBox( - height: 40.h, - ), - ], - ), - ), - ), - ], - ), - ), - ); - } -} +import 'dart:ui'; +import 'package:flutter/Material.dart'; +import 'package:flutter_screenutil/flutter_screenutil.dart'; +import 'package:justmusic/components/back_button.dart'; +import 'package:justmusic/screens/search_song_screen.dart'; +import '../components/editable_post_component.dart'; +import '../components/post_button_component.dart'; +import '../values/constants.dart'; + +class PostScreen extends StatefulWidget { + const PostScreen({Key? key}) : super(key: key); + + @override + State createState() => _PostScreenState(); +} + +class _PostScreenState extends State + with SingleTickerProviderStateMixin { + final scrollController = ScrollController(); + late AnimationController _controller; + late Animation _animation; + + @override + void initState() { + _controller = AnimationController( + vsync: this, + duration: const Duration(milliseconds: 400), + ); + + _animation = Tween(begin: 0.0, end: 400.0).animate( + CurvedAnimation( + parent: _controller, + curve: Curves.easeOut, + ), + ); + super.initState(); + } + + void openDetailPost() { + showModalBottomSheet( + transitionAnimationController: _controller, + barrierColor: Colors.black.withOpacity(0.7), + backgroundColor: Colors.transparent, + elevation: 1, + constraints: const BoxConstraints( + maxWidth: 600, + ), + isScrollControlled: true, + context: context, + shape: const RoundedRectangleBorder( + borderRadius: BorderRadius.only( + topLeft: Radius.circular(20), topRight: Radius.circular(20))), + builder: ((context) { + return const ClipRRect( + borderRadius: BorderRadius.only( + topLeft: Radius.circular(20), topRight: Radius.circular(20)), + child: SearchSongScreen()); + }), + ); + } + + @override + Widget build(BuildContext context) { + return Scaffold( + resizeToAvoidBottomInset: true, + backgroundColor: bgColor, + extendBodyBehindAppBar: true, + appBar: PreferredSize( + preferredSize: Size(double.infinity, 80), + child: SafeArea( + child: Padding( + padding: const EdgeInsets.only( + left: defaultPadding, + right: defaultPadding, + top: defaultPadding), + child: Row( + children: [BackButtonComponent()], + ), + ), + ), + ), + body: Container( + padding: + const EdgeInsets.only(left: defaultPadding, right: defaultPadding), + width: double.infinity, + height: double.infinity, + decoration: const BoxDecoration( + image: DecorationImage( + image: AssetImage("assets/images/background_justMusic.png"), + fit: BoxFit.cover, + ), + ), + child: Stack( + alignment: Alignment.topCenter, + children: [ + ScrollConfiguration( + behavior: ScrollBehavior().copyWith(scrollbars: false), + child: SingleChildScrollView( + controller: scrollController, + child: Column( + mainAxisAlignment: MainAxisAlignment.end, + children: [ + SizedBox( + height: 100.h, + ), + GestureDetector( + onTap: openDetailPost, + child: EditablePostComponent(), + ), + SizedBox( + height: 40.h, + ), + PostButtonComponent(), + SizedBox( + height: 40.h, + ), + ], + ), + ), + ), + ], + ), + ), + ); + } +} diff --git a/Sources/justMUSIC/lib/screens/profile_screen.dart b/Sources/justMUSIC/lib/screens/profile_screen.dart index 896cd91..a362d35 100644 --- a/Sources/justMUSIC/lib/screens/profile_screen.dart +++ b/Sources/justMUSIC/lib/screens/profile_screen.dart @@ -1,146 +1,146 @@ -import 'package:flutter/cupertino.dart'; -import 'package:flutter/material.dart'; -import 'package:flutter_screenutil/flutter_screenutil.dart'; -import 'package:google_fonts/google_fonts.dart'; -import 'package:justmusic/values/icons.dart'; -import '../components/profile_component.dart'; -import '../components/setting_part_component.dart'; -import '../main.dart'; -import '../values/constants.dart'; - -class ProfileScreen extends StatefulWidget { - const ProfileScreen({Key? key}) : super(key: key); - - @override - State createState() => _ProfileScreenState(); -} - -class _ProfileScreenState extends State { - @override - Widget build(BuildContext context) { - return Scaffold( - appBar: PreferredSize( - preferredSize: Size(double.infinity, 58), - child: Container( - height: double.infinity, - color: bgAppBar, - child: Padding( - padding: const EdgeInsets.symmetric(horizontal: defaultPadding), - child: Stack( - alignment: Alignment.centerLeft, - children: [ - GestureDetector( - onTap: () { - Navigator.pop(context); - }, - child: Container( - height: 15, - width: 15, - child: Image( - image: AssetImage("assets/images/return_icon.png"), - height: 8, - ), - )), - Align( - child: Text( - "Profile", - style: GoogleFonts.plusJakartaSans( - color: Colors.white, - fontSize: 14, - fontWeight: FontWeight.bold), - ), - ) - ], - ), - ), - ), - ), - body: Container( - width: double.infinity, - height: double.infinity, - color: bgColor, - child: SingleChildScrollView( - child: Padding( - padding: const EdgeInsets.symmetric(horizontal: settingPadding), - child: Column( - mainAxisAlignment: MainAxisAlignment.start, - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Padding( - padding: EdgeInsets.only(top: 68.h, bottom: 40), - child: - ProfileComponent(user: MyApp.userViewModel.userCurrent), - ), - Padding( - padding: - const EdgeInsets.only(bottom: 12, left: defaultPadding), - child: Text( - "Compte", - style: GoogleFonts.plusJakartaSans( - color: grayText, - fontWeight: FontWeight.w800, - fontSize: 16), - ), - ), - ClipRRect( - borderRadius: BorderRadius.circular(8), - child: Column( - children: const [ - SettingPartComponent( - icon: JustMusicIcon.profile, - label: 'Compte', - ), - SettingPartComponent( - icon: JustMusicIcon.history, - label: 'Historiques des capsules', - ), - SettingPartComponent( - icon: JustMusicIcon.spotify, - label: 'Lier un compte Spotify', - ), - SettingPartComponent( - icon: JustMusicIcon.trash, - label: 'Supprimer mon compte', - ), - SettingPartComponent( - icon: JustMusicIcon.cross, - label: 'Déconnexion', - important: true, - ), - ], - ), - ), - Padding( - padding: const EdgeInsets.only( - bottom: 12, left: defaultPadding, top: 40), - child: Text( - "Préférences", - style: GoogleFonts.plusJakartaSans( - color: grayText, - fontWeight: FontWeight.w800, - fontSize: 16), - ), - ), - ClipRRect( - borderRadius: BorderRadius.circular(8), - child: Column( - children: const [ - SettingPartComponent( - icon: JustMusicIcon.theme, - label: 'Thême de l\'application', - ), - SettingPartComponent( - icon: JustMusicIcon.notification, - label: 'Notifications', - ), - ], - ), - ) - ], - ), - ), - ), - ), - ); - } -} +import 'package:flutter/cupertino.dart'; +import 'package:flutter/material.dart'; +import 'package:flutter_screenutil/flutter_screenutil.dart'; +import 'package:google_fonts/google_fonts.dart'; +import 'package:justmusic/values/icons.dart'; +import '../components/profile_component.dart'; +import '../components/setting_part_component.dart'; +import '../main.dart'; +import '../values/constants.dart'; + +class ProfileScreen extends StatefulWidget { + const ProfileScreen({Key? key}) : super(key: key); + + @override + State createState() => _ProfileScreenState(); +} + +class _ProfileScreenState extends State { + @override + Widget build(BuildContext context) { + return Scaffold( + appBar: PreferredSize( + preferredSize: Size(double.infinity, 58), + child: Container( + height: double.infinity, + color: bgAppBar, + child: Padding( + padding: const EdgeInsets.symmetric(horizontal: defaultPadding), + child: Stack( + alignment: Alignment.centerLeft, + children: [ + GestureDetector( + onTap: () { + Navigator.pop(context); + }, + child: Container( + height: 15, + width: 15, + child: Image( + image: AssetImage("assets/images/return_icon.png"), + height: 8, + ), + )), + Align( + child: Text( + "Profile", + style: GoogleFonts.plusJakartaSans( + color: Colors.white, + fontSize: 14, + fontWeight: FontWeight.bold), + ), + ) + ], + ), + ), + ), + ), + body: Container( + width: double.infinity, + height: double.infinity, + color: bgColor, + child: SingleChildScrollView( + child: Padding( + padding: const EdgeInsets.symmetric(horizontal: settingPadding), + child: Column( + mainAxisAlignment: MainAxisAlignment.start, + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Padding( + padding: EdgeInsets.only(top: 68.h, bottom: 40), + child: + ProfileComponent(user: MyApp.userViewModel.userCurrent), + ), + Padding( + padding: + const EdgeInsets.only(bottom: 12, left: defaultPadding), + child: Text( + "Compte", + style: GoogleFonts.plusJakartaSans( + color: grayText, + fontWeight: FontWeight.w800, + fontSize: 16), + ), + ), + ClipRRect( + borderRadius: BorderRadius.circular(8), + child: Column( + children: const [ + SettingPartComponent( + icon: JustMusicIcon.profile, + label: 'Compte', + ), + SettingPartComponent( + icon: JustMusicIcon.history, + label: 'Historiques des capsules', + ), + SettingPartComponent( + icon: JustMusicIcon.spotify, + label: 'Lier un compte Spotify', + ), + SettingPartComponent( + icon: JustMusicIcon.trash, + label: 'Supprimer mon compte', + ), + SettingPartComponent( + icon: JustMusicIcon.cross, + label: 'Déconnexion', + important: true, + ), + ], + ), + ), + Padding( + padding: const EdgeInsets.only( + bottom: 12, left: defaultPadding, top: 40), + child: Text( + "Préférences", + style: GoogleFonts.plusJakartaSans( + color: grayText, + fontWeight: FontWeight.w800, + fontSize: 16), + ), + ), + ClipRRect( + borderRadius: BorderRadius.circular(8), + child: Column( + children: const [ + SettingPartComponent( + icon: JustMusicIcon.theme, + label: 'Thême de l\'application', + ), + SettingPartComponent( + icon: JustMusicIcon.notification, + label: 'Notifications', + ), + ], + ), + ) + ], + ), + ), + ), + ), + ); + } +} diff --git a/Sources/justMUSIC/lib/service/AuthService.dart b/Sources/justMUSIC/lib/service/AuthService.dart index 65828fc..d7e39fa 100644 --- a/Sources/justMUSIC/lib/service/AuthService.dart +++ b/Sources/justMUSIC/lib/service/AuthService.dart @@ -1,3 +1,4 @@ +import 'package:cloud_firestore/cloud_firestore.dart'; import 'package:firebase_auth/firebase_auth.dart'; import '../main.dart'; @@ -9,10 +10,13 @@ class AuthService { password: password, ); + String uniqueId = await generateUniqueId(pseudo); + final user = { "mail": email, "pseudo": pseudo, "phone_number": "", + "unique_id": uniqueId, "picture": "https://media.licdn.com/dms/image/D4E03AQHvc_b89ogFtQ/profile-displayphoto-shrink_400_400/0/1665060931103?e=1695859200&v=beta&t=wVLbxqeokYiPJ13nJ3SMq97iZvcm3ra0ufWFZCSzhjg", "friends": [] @@ -36,6 +40,22 @@ class AuthService { } } + Future generateUniqueId(String pseudo) async { + String uniqueId = '$pseudo#0001'; + int suffix = 1; + final CollectionReference usersCollection = + FirebaseFirestore.instance.collection("users"); + final QuerySnapshot querySnapshot = + await usersCollection.where('pseudo', isEqualTo: pseudo).get(); + + for (final doc in querySnapshot.docs) { + suffix++; + uniqueId = '$pseudo#${suffix.toString().padLeft(4, '0')}'; + } + + return uniqueId; + } + login(String email, String password) async { try { await FirebaseAuth.instance diff --git a/Sources/justMUSIC/lib/values/constants.dart b/Sources/justMUSIC/lib/values/constants.dart index f29ef36..60f494f 100644 --- a/Sources/justMUSIC/lib/values/constants.dart +++ b/Sources/justMUSIC/lib/values/constants.dart @@ -1,26 +1,26 @@ -import 'package:flutter/material.dart'; - -// All needed color in the project - -const primaryColor = Color(0xFF643BF4); -const secondaryColor = Color(0xFF1C1B23); -const bgColor = Color(0xFF0C0C0C); -const grayColor = Color(0xFF242424); -const profileBttnColor = Color(0xFF232323); -const warningBttnColor = Color(0xFF141414); -const disabledBttnColor = Color(0xFF1F1B2E); -const bgTextField = Color(0xFF1C1B23); -const strokeTextField = Color(0xFF373546); -const unactiveFeed = Color(0xFF848484); -const gradiantPost = Color(0xFF0D0D0D); -const bgModal = Color(0xFF1E1E1E); -const textFieldMessage = Color(0xFF232323); -const bgComment = Color(0xFF222222); -const bgAppBar = Color(0xFF181818); -const grayText = Color(0xFF898989); -const settingColor = Color(0xFF232323); -const searchBarColor = Color(0xFF161616); -// All constants important too us - -const defaultPadding = 30.0; -const settingPadding = 12.0; +import 'package:flutter/material.dart'; + +// All needed color in the project + +const primaryColor = Color(0xFF643BF4); +const secondaryColor = Color(0xFF1C1B23); +const bgColor = Color(0xFF0C0C0C); +const grayColor = Color(0xFF242424); +const profileBttnColor = Color(0xFF232323); +const warningBttnColor = Color(0xFF141414); +const disabledBttnColor = Color(0xFF1F1B2E); +const bgTextField = Color(0xFF1C1B23); +const strokeTextField = Color(0xFF373546); +const unactiveFeed = Color(0xFF848484); +const gradiantPost = Color(0xFF0D0D0D); +const bgModal = Color(0xFF1E1E1E); +const textFieldMessage = Color(0xFF232323); +const bgComment = Color(0xFF222222); +const bgAppBar = Color(0xFF181818); +const grayText = Color(0xFF898989); +const settingColor = Color(0xFF232323); +const searchBarColor = Color(0xFF161616); +// All constants important too us + +const defaultPadding = 30.0; +const settingPadding = 12.0; diff --git a/Sources/justMUSIC/lib/view_model/UserViewModel.dart b/Sources/justMUSIC/lib/view_model/UserViewModel.dart index d793449..5d41ebc 100644 --- a/Sources/justMUSIC/lib/view_model/UserViewModel.dart +++ b/Sources/justMUSIC/lib/view_model/UserViewModel.dart @@ -37,9 +37,18 @@ class UserViewModel { } } + bool _isAlphaNumeric(String input) { + final RegExp alphaNumericRegExp = RegExp(r'^[a-zA-Z0-9]+$'); + return alphaNumericRegExp.hasMatch(input); + } + register(String pseudo, String password, String email) async { + if (!_isAlphaNumeric(pseudo)) { + throw ("Le pseudo doit contenir seulement des lettres et des chiffres"); + } + try { - await _authService.register(pseudo, email, password); + await _authService.register(pseudo.toLowerCase(), email, password); final user = await MyApp.db .collection("users") .doc(firebase_auth.FirebaseAuth.instance.currentUser?.uid) diff --git a/Sources/justMUSIC/pubspec.lock b/Sources/justMUSIC/pubspec.lock index 5a37499..f42c1e9 100644 --- a/Sources/justMUSIC/pubspec.lock +++ b/Sources/justMUSIC/pubspec.lock @@ -13,10 +13,10 @@ packages: dependency: transitive description: name: async - sha256: bfe67ef28df125b7dddcea62755991f807aa39a2492a23e1550161692950bbe0 + sha256: "947bfcf187f74dbc5e146c9eb9c0f10c9f8b30743e341481c1e2ed3ecc18c20c" url: "https://pub.dev" source: hosted - version: "2.10.0" + version: "2.11.0" audioplayers: dependency: "direct main" description: @@ -93,10 +93,10 @@ packages: dependency: transitive description: name: characters - sha256: e6a326c8af69605aec75ed6c187d06b349707a27fbff8222ca9cc2cff167975c + sha256: "04a925763edad70e8443c99234dc3328f442e811f1d8fd1a72f1c8ad0f69a605" url: "https://pub.dev" source: hosted - version: "1.2.1" + version: "1.3.0" circular_reveal_animation: dependency: "direct main" description: @@ -141,10 +141,10 @@ packages: dependency: transitive description: name: collection - sha256: cfc915e6923fe5ce6e153b0723c753045de46de1b4d63771530504004a45fae0 + sha256: "4a07be6cb69c84d677a6c3096fcf960cc3285a8330b4603e0d463d15d9bd934c" url: "https://pub.dev" source: hosted - version: "1.17.0" + version: "1.17.1" crypto: dependency: transitive description: @@ -348,10 +348,10 @@ packages: dependency: transitive description: name: js - sha256: "5528c2f391ededb7775ec1daa69e65a2d61276f7552de2b5f7b8d34ee9fd4ab7" + sha256: f2c445dce49627136094980615a031419f7f3eb393237e4ecd97ac15dea343f3 url: "https://pub.dev" source: hosted - version: "0.6.5" + version: "0.6.7" lints: dependency: transitive description: @@ -364,10 +364,10 @@ packages: dependency: transitive description: name: matcher - sha256: "16db949ceee371e9b99d22f88fa3a73c4e59fd0afed0bd25fc336eb76c198b72" + sha256: "6501fbd55da300384b768785b83e5ce66991266cec21af89ab9ae7f5ce1c4cbb" url: "https://pub.dev" source: hosted - version: "0.12.13" + version: "0.12.15" material_color_utilities: dependency: transitive description: @@ -380,10 +380,10 @@ packages: dependency: transitive description: name: meta - sha256: "6c268b42ed578a53088d834796959e4a1814b5e9e164f147f580a386e5decf42" + sha256: "3c74dbf8763d36539f114c799d8a2d87343b5067e9d796ca22b5eb8437090ee3" url: "https://pub.dev" source: hosted - version: "1.8.0" + version: "1.9.1" modal_bottom_sheet: dependency: "direct main" description: @@ -396,10 +396,10 @@ packages: dependency: transitive description: name: path - sha256: db9d4f58c908a4ba5953fcee2ae317c94889433e5024c27ce74a37f94267945b + sha256: "8829d8a55c13fc0e37127c29fedf290c102f4e40ae94ada574091fe0ff96c917" url: "https://pub.dev" source: hosted - version: "1.8.2" + version: "1.8.3" path_provider: dependency: transitive description: @@ -529,10 +529,10 @@ packages: dependency: transitive description: name: test_api - sha256: ad540f65f92caa91bf21dfc8ffb8c589d6e4dc0c2267818b4cc2792857706206 + sha256: eb6ac1540b26de412b3403a163d919ba86f6a973fe6cc50ae3541b80092fdcfb url: "https://pub.dev" source: hosted - version: "0.4.16" + version: "0.5.1" text_scroll: dependency: "direct main" description: @@ -598,5 +598,5 @@ packages: source: hosted version: "1.1.0" sdks: - dart: ">=2.18.2 <3.0.0" + dart: ">=3.0.0-0 <4.0.0" flutter: ">=3.3.0" -- 2.36.3 From 3e397733318649de644e8aa37c4bb43af580efee Mon Sep 17 00:00:00 2001 From: Lucas Delanier Date: Sun, 30 Jul 2023 22:29:08 +0200 Subject: [PATCH 8/8] fix error --- .idea/libraries/Dart_Packages.xml | 1098 +++++++---------- .../android/app/src/main/AndroidManifest.xml | 64 +- .../app/src/profile/AndroidManifest.xml | 6 +- .../lib/components/post_button_component.dart | 19 +- 4 files changed, 474 insertions(+), 713 deletions(-) diff --git a/.idea/libraries/Dart_Packages.xml b/.idea/libraries/Dart_Packages.xml index 9a7932e..5d474aa 100644 --- a/.idea/libraries/Dart_Packages.xml +++ b/.idea/libraries/Dart_Packages.xml @@ -1,1074 +1,828 @@ -<<<<<<< HEAD - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + -======= - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ->>>>>>> master \ No newline at end of file diff --git a/Sources/justMUSIC/android/app/src/main/AndroidManifest.xml b/Sources/justMUSIC/android/app/src/main/AndroidManifest.xml index e855118..d63318f 100644 --- a/Sources/justMUSIC/android/app/src/main/AndroidManifest.xml +++ b/Sources/justMUSIC/android/app/src/main/AndroidManifest.xml @@ -1,33 +1,35 @@ - - - - - - - - - - - + + + + - + android:name="io.flutter.embedding.android.NormalTheme" + android:resource="@style/NormalTheme" + /> + + + + + + + + + diff --git a/Sources/justMUSIC/android/app/src/profile/AndroidManifest.xml b/Sources/justMUSIC/android/app/src/profile/AndroidManifest.xml index 8ffe024..a5cc1f7 100644 --- a/Sources/justMUSIC/android/app/src/profile/AndroidManifest.xml +++ b/Sources/justMUSIC/android/app/src/profile/AndroidManifest.xml @@ -1,7 +1,9 @@ - + - + + \ No newline at end of file diff --git a/Sources/justMUSIC/lib/components/post_button_component.dart b/Sources/justMUSIC/lib/components/post_button_component.dart index 93f75d9..45b2c47 100644 --- a/Sources/justMUSIC/lib/components/post_button_component.dart +++ b/Sources/justMUSIC/lib/components/post_button_component.dart @@ -15,6 +15,12 @@ class _PostButtonComponentState extends State with SingleTickerProviderStateMixin { late AnimationController _controller; + @override + void dispose() { + _controller.dispose(); + super.dispose(); + } + @override void initState() { super.initState(); @@ -132,14 +138,11 @@ class _PostButtonComponentState extends State ), )), ClipOval( - child: Positioned( - left: -15, - child: Padding( - padding: const EdgeInsets.only(left: 5, top: 5), - child: Image( - image: AssetImage("assets/images/rocket_button.png"), - height: 65, - ), + child: Padding( + padding: const EdgeInsets.only(left: 5, top: 5), + child: Image( + image: AssetImage("assets/images/rocket_button.png"), + height: 65, ), ), ) -- 2.36.3