auth-EKA-DDA #28

Merged
emre.kartal merged 9 commits from auth-EKA-DDA into master 2 years ago

File diff suppressed because it is too large Load Diff

@ -1,45 +1,30 @@
# This file tracks properties of this Flutter project. # This file tracks properties of this Flutter project.
# Used by Flutter tool to assess capabilities and perform upgrades etc. # Used by Flutter tool to assess capabilities and perform upgrades etc.
# #
# This file should be version controlled. # This file should be version controlled.
version: version:
revision: 18a827f3933c19f51862dde3fa472197683249d6 revision: f468f3366c26a5092eb964a230ce7892fda8f2f8
channel: stable channel: stable
project_type: app project_type: app
# Tracks metadata for the flutter migrate command # Tracks metadata for the flutter migrate command
migration: migration:
platforms: platforms:
- platform: root - platform: root
create_revision: 18a827f3933c19f51862dde3fa472197683249d6 create_revision: f468f3366c26a5092eb964a230ce7892fda8f2f8
base_revision: 18a827f3933c19f51862dde3fa472197683249d6 base_revision: f468f3366c26a5092eb964a230ce7892fda8f2f8
- platform: android - platform: android
create_revision: 18a827f3933c19f51862dde3fa472197683249d6 create_revision: f468f3366c26a5092eb964a230ce7892fda8f2f8
base_revision: 18a827f3933c19f51862dde3fa472197683249d6 base_revision: f468f3366c26a5092eb964a230ce7892fda8f2f8
- platform: ios
create_revision: 18a827f3933c19f51862dde3fa472197683249d6 # User provided section
base_revision: 18a827f3933c19f51862dde3fa472197683249d6
- platform: linux # List of Local paths (relative to this file) that should be
create_revision: 18a827f3933c19f51862dde3fa472197683249d6 # ignored by the migrate tool.
base_revision: 18a827f3933c19f51862dde3fa472197683249d6 #
- platform: macos # Files that are not part of the templates will be ignored by default.
create_revision: 18a827f3933c19f51862dde3fa472197683249d6 unmanaged_files:
base_revision: 18a827f3933c19f51862dde3fa472197683249d6 - 'lib/main.dart'
- platform: web - 'ios/Runner.xcodeproj/project.pbxproj'
create_revision: 18a827f3933c19f51862dde3fa472197683249d6
base_revision: 18a827f3933c19f51862dde3fa472197683249d6
- platform: windows
create_revision: 18a827f3933c19f51862dde3fa472197683249d6
base_revision: 18a827f3933c19f51862dde3fa472197683249d6
# User provided section
# List of Local paths (relative to this file) that should be
# ignored by the migrate tool.
#
# Files that are not part of the templates will be ignored by default.
unmanaged_files:
- 'lib/main.dart'
- 'ios/Runner.xcodeproj/project.pbxproj'

@ -1,71 +1,78 @@
def localProperties = new Properties() def localProperties = new Properties()
def localPropertiesFile = rootProject.file('local.properties')
if (localPropertiesFile.exists()) { def localPropertiesFile = rootProject.file('local.properties')
localPropertiesFile.withReader('UTF-8') { reader -> if (localPropertiesFile.exists()) {
localProperties.load(reader) localPropertiesFile.withReader('UTF-8') { reader ->
} localProperties.load(reader)
} }
}
def flutterRoot = localProperties.getProperty('flutter.sdk')
if (flutterRoot == null) { def flutterRoot = localProperties.getProperty('flutter.sdk')
throw new GradleException("Flutter SDK not found. Define location with flutter.sdk in the local.properties file.") if (flutterRoot == null) {
} throw new GradleException("Flutter SDK not found. Define location with flutter.sdk in the local.properties file.")
}
def flutterVersionCode = localProperties.getProperty('flutter.versionCode')
if (flutterVersionCode == null) { def flutterVersionCode = localProperties.getProperty('flutter.versionCode')
flutterVersionCode = '1' if (flutterVersionCode == null) {
} flutterVersionCode = '1'
}
def flutterVersionName = localProperties.getProperty('flutter.versionName')
if (flutterVersionName == null) { def flutterVersionName = localProperties.getProperty('flutter.versionName')
flutterVersionName = '1.0' if (flutterVersionName == null) {
} flutterVersionName = '1.0'
}
apply plugin: 'com.android.application'
apply plugin: 'kotlin-android' apply plugin: 'com.android.application'
apply from: "$flutterRoot/packages/flutter_tools/gradle/flutter.gradle" apply plugin: 'kotlin-android'
apply from: "$flutterRoot/packages/flutter_tools/gradle/flutter.gradle"
android {
compileSdkVersion 33 android {
ndkVersion flutter.ndkVersion namespace "com.example.justmusic"
compileSdkVersion 33
compileOptions { ndkVersion flutter.ndkVersion
sourceCompatibility JavaVersion.VERSION_1_8
targetCompatibility JavaVersion.VERSION_1_8
} compileOptions {
sourceCompatibility JavaVersion.VERSION_1_8
kotlinOptions { targetCompatibility JavaVersion.VERSION_1_8
jvmTarget = '1.8' }
}
kotlinOptions {
sourceSets { jvmTarget = '1.8'
main.java.srcDirs += 'src/main/kotlin' }
}
sourceSets {
defaultConfig { main.java.srcDirs += 'src/main/kotlin'
// 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. defaultConfig {
// For more information, see: https://docs.flutter.dev/deployment/android#reviewing-the-build-configuration. // TODO: Specify your own unique Application ID (https://developer.android.com/studio/build/application-id.html).
minSdkVersion flutter.minSdkVersion applicationId "com.example.justmusic"
targetSdkVersion flutter.targetSdkVersion // You can update the following values to match your application needs.
versionCode flutterVersionCode.toInteger() // For more information, see: https://docs.flutter.dev/deployment/android#reviewing-the-gradle-build-configuration.
versionName flutterVersionName minSdkVersion 19
} targetSdkVersion flutter.targetSdkVersion
versionCode flutterVersionCode.toInteger()
buildTypes { versionName flutterVersionName
release { }
// TODO: Add your own signing config for the release build.
// Signing with the debug keys for now, so `flutter run --release` works. buildTypes {
signingConfig signingConfigs.debug release {
} // TODO: Add your own signing config for the release build.
} // Signing with the debug keys for now, so `flutter run --release` works.
} signingConfig signingConfigs.debug
}
flutter { }
source '../..' }
}
flutter {
dependencies { source '../..'
implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version" }
}
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'

@ -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"
}

@ -1,34 +1,35 @@
<manifest xmlns:android="http://schemas.android.com/apk/res/android" <manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.justmusic"> package="com.example.justmusic">
<application <application
android:label="justmusic" android:label="justmusic"
android:name="${applicationName}" android:name="${applicationName}"
android:icon="@mipmap/ic_launcher"> android:icon="@mipmap/ic_launcher">
<activity <activity
android:name=".MainActivity" android:name=".MainActivity"
android:exported="true" android:exported="true"
android:launchMode="singleTop" android:launchMode="singleTop"
android:theme="@style/LaunchTheme" android:theme="@style/LaunchTheme"
android:configChanges="orientation|keyboardHidden|keyboard|screenSize|smallestScreenSize|locale|layoutDirection|fontScale|screenLayout|density|uiMode" android:configChanges="orientation|keyboardHidden|keyboard|screenSize|smallestScreenSize|locale|layoutDirection|fontScale|screenLayout|density|uiMode"
android:hardwareAccelerated="true" android:hardwareAccelerated="true"
android:windowSoftInputMode="adjustResize"> android:windowSoftInputMode="adjustResize">
<!-- Specifies an Android theme to apply to this Activity as soon as <!-- Specifies an Android theme to apply to this Activity as soon as
the Android process has started. This theme is visible to the user the Android process has started. This theme is visible to the user
while the Flutter UI initializes. After that, this theme continues while the Flutter UI initializes. After that, this theme continues
to determine the Window background behind the Flutter UI. --> to determine the Window background behind the Flutter UI. -->
<meta-data <meta-data
android:name="io.flutter.embedding.android.NormalTheme" android:name="io.flutter.embedding.android.NormalTheme"
android:resource="@style/NormalTheme" android:resource="@style/NormalTheme"
/> />
<intent-filter> <intent-filter>
<action android:name="android.intent.action.MAIN"/> <action android:name="android.intent.action.MAIN"/>
<category android:name="android.intent.category.LAUNCHER"/> <category android:name="android.intent.category.LAUNCHER"/>
</intent-filter> </intent-filter>
</activity> </activity>
<!-- Don't delete the meta-data below. <!-- Don't delete the meta-data below.
This is used by the Flutter tool to generate GeneratedPluginRegistrant.java --> This is used by the Flutter tool to generate GeneratedPluginRegistrant.java -->
<meta-data <meta-data
android:name="flutterEmbedding" android:name="flutterEmbedding"
android:value="2" /> android:value="2" />
</application> </application>
</manifest> </manifest>

@ -0,0 +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);
}
}

@ -1,8 +1,9 @@
<manifest xmlns:android="http://schemas.android.com/apk/res/android" <manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.justmusic"> package="com.example.justmusic">
<!-- The INTERNET permission is required for development. Specifically, <!-- The INTERNET permission is required for development. Specifically,
the Flutter tool needs it to communicate with the running application the Flutter tool needs it to communicate with the running application
to allow setting breakpoints, to provide hot reload, etc. to allow setting breakpoints, to provide hot reload, etc.
--> -->
<uses-permission android:name="android.permission.INTERNET"/> <uses-permission android:name="android.permission.INTERNET"/>
</manifest> <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
</manifest>

@ -1,31 +1,32 @@
buildscript { buildscript {
ext.kotlin_version = '1.9.0' ext.kotlin_version = '1.9.0'
repositories { repositories {
google() google()
mavenCentral() mavenCentral()
} }
dependencies { dependencies {
classpath 'com.android.tools.build:gradle:7.1.2' classpath 'com.android.tools.build:gradle:7.1.2'
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version" classpath 'com.google.gms:google-services:4.3.15'
} classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
} }
}
allprojects {
repositories { allprojects {
google() repositories {
mavenCentral() google()
} mavenCentral()
} }
}
rootProject.buildDir = '../build'
subprojects { rootProject.buildDir = '../build'
project.buildDir = "${rootProject.buildDir}/${project.name}" subprojects {
} project.buildDir = "${rootProject.buildDir}/${project.name}"
subprojects { }
project.evaluationDependsOn(':app') subprojects {
} project.evaluationDependsOn(':app')
}
tasks.register("clean", Delete) {
delete rootProject.buildDir tasks.register("clean", Delete) {
} delete rootProject.buildDir
}

@ -1,5 +1,5 @@
distributionBase=GRADLE_USER_HOME distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists distributionPath=wrapper/dists
zipStoreBase=GRADLE_USER_HOME zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists zipStorePath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-7.4-all.zip distributionUrl=https\://services.gradle.org/distributions/gradle-7.5-all.zip

@ -0,0 +1,34 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>CLIENT_ID</key>
<string>994903990520-n6jd98ena56kb1tvtrd67tvb5et3nfbf.apps.googleusercontent.com</string>
<key>REVERSED_CLIENT_ID</key>
<string>com.googleusercontent.apps.994903990520-n6jd98ena56kb1tvtrd67tvb5et3nfbf</string>
<key>API_KEY</key>
<string>AIzaSyBbYqsR6t7JTi8_XFNEHd43IRuKlYGeI3U</string>
<key>GCM_SENDER_ID</key>
<string>994903990520</string>
<key>PLIST_VERSION</key>
<string>1</string>
<key>BUNDLE_ID</key>
<string>com.example.justmusic</string>
<key>PROJECT_ID</key>
<string>justmusic-435d5</string>
<key>STORAGE_BUCKET</key>
<string>justmusic-435d5.appspot.com</string>
<key>IS_ADS_ENABLED</key>
<false></false>
<key>IS_ANALYTICS_ENABLED</key>
<false></false>
<key>IS_APPINVITE_ENABLED</key>
<true></true>
<key>IS_GCM_ENABLED</key>
<true></true>
<key>IS_SIGNIN_ENABLED</key>
<true></true>
<key>GOOGLE_APP_ID</key>
<string>1:994903990520:ios:93188f32e320babe0a9b0d</string>
</dict>
</plist>

@ -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"
}

@ -1,66 +1,68 @@
import 'package:flutter/cupertino.dart'; import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter_screenutil/flutter_screenutil.dart'; import 'package:flutter_screenutil/flutter_screenutil.dart';
class LoginButton extends StatefulWidget { class LoginButton extends StatefulWidget {
const LoginButton({Key? key}) : super(key: key); final Function callback;
@override const LoginButton({Key? key, required this.callback}) : super(key: key);
State<LoginButton> createState() => _LoginButtonState();
} @override
State<LoginButton> createState() => _LoginButtonState();
class _LoginButtonState extends State<LoginButton> { }
@override
Widget build(BuildContext context) { class _LoginButtonState extends State<LoginButton> {
return ElevatedButton( @override
onPressed: () { Widget build(BuildContext context) {
Navigator.pushNamed(context, '/explanation'); return ElevatedButton(
}, onPressed: () {
style: ButtonStyle( widget.callback();
backgroundColor: MaterialStateProperty.all(Color(0xFF1C1C1C)), },
overlayColor: style: ButtonStyle(
MaterialStateProperty.all(Color(0xffD3C2FF).withOpacity(0.2)), backgroundColor: MaterialStateProperty.all(Color(0xFF1C1C1C)),
shape: MaterialStateProperty.all(RoundedRectangleBorder( overlayColor:
borderRadius: BorderRadius.circular(18), MaterialStateProperty.all(Color(0xffD3C2FF).withOpacity(0.2)),
)), shape: MaterialStateProperty.all(RoundedRectangleBorder(
padding: MaterialStateProperty.all(EdgeInsets.all(0.0)), borderRadius: BorderRadius.circular(18),
), )),
child: Ink( padding: MaterialStateProperty.all(EdgeInsets.all(0.0)),
decoration: BoxDecoration( ),
gradient: RadialGradient( child: Ink(
center: Alignment(0, 3), decoration: BoxDecoration(
focalRadius: 10, gradient: RadialGradient(
radius: 2.5, center: Alignment(0, 3),
stops: <double>[0.4, 1.0], focalRadius: 10,
colors: [Color(0xff9E78FF), Color(0xff633AF4)], radius: 2.5,
), stops: <double>[0.4, 1.0],
borderRadius: BorderRadius.circular(18.0), colors: [Color(0xff9E78FF), Color(0xff633AF4)],
border: Border.all( ),
color: Color(0xff1C1C1C), borderRadius: BorderRadius.circular(18.0),
width: 5, 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), child: Container(
decoration: BoxDecoration( padding: EdgeInsets.only(top: 20.h, bottom: 20.h),
boxShadow: [ constraints: BoxConstraints(maxWidth: 600, minHeight: 50),
BoxShadow( decoration: BoxDecoration(
color: Color(0xff7E56F9).withOpacity(0.23), boxShadow: [
spreadRadius: 4, BoxShadow(
blurRadius: 40, color: Color(0xff7E56F9).withOpacity(0.23),
offset: Offset(0, 3), // changes position of shadow spreadRadius: 4,
), blurRadius: 40,
], offset: Offset(0, 3), // changes position of shadow
), ),
alignment: Alignment.center, ],
child: Text( ),
"Se connecter", alignment: Alignment.center,
textAlign: TextAlign.center, child: Text(
style: TextStyle(color: Colors.white, fontSize: 18), "Se connecter",
), textAlign: TextAlign.center,
), style: TextStyle(color: Colors.white, fontSize: 18),
), ),
); ),
} ),
} );
}
}

@ -15,6 +15,12 @@ class _PostButtonComponentState extends State<PostButtonComponent>
with SingleTickerProviderStateMixin { with SingleTickerProviderStateMixin {
late AnimationController _controller; late AnimationController _controller;
@override
void dispose() {
_controller.dispose();
super.dispose();
}
@override @override
void initState() { void initState() {
super.initState(); super.initState();
@ -132,14 +138,11 @@ class _PostButtonComponentState extends State<PostButtonComponent>
), ),
)), )),
ClipOval( ClipOval(
child: Positioned( child: Padding(
left: -15, padding: const EdgeInsets.only(left: 5, top: 5),
child: Padding( child: Image(
padding: const EdgeInsets.only(left: 5, top: 5), image: AssetImage("assets/images/rocket_button.png"),
child: Image( height: 65,
image: AssetImage("assets/images/rocket_button.png"),
height: 65,
),
), ),
), ),
) )

@ -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',
);
}

@ -1,62 +1,71 @@
import 'package:audioplayers/audioplayers.dart'; import 'package:audioplayers/audioplayers.dart';
import 'package:flutter/material.dart'; import 'package:cloud_firestore/cloud_firestore.dart';
import 'package:flutter/services.dart'; import 'package:firebase_core/firebase_core.dart';
import 'package:flutter_screenutil/flutter_screenutil.dart'; import 'package:flutter/material.dart';
import 'package:justmusic/screens/explanations_screen.dart'; import 'package:flutter/services.dart';
import 'package:justmusic/screens/feed_screen.dart'; import 'package:flutter_screenutil/flutter_screenutil.dart';
import 'package:justmusic/screens/login_screen.dart'; import 'package:justmusic/screens/explanations_screen.dart';
import 'package:justmusic/screens/post_screen.dart'; import 'package:justmusic/screens/feed_screen.dart';
import 'package:justmusic/screens/profile_screen.dart'; import 'package:justmusic/screens/login_screen.dart';
import 'package:justmusic/screens/registration_screen.dart'; import 'package:justmusic/screens/post_screen.dart';
import 'package:justmusic/screens/welcome_screen.dart'; import 'package:justmusic/screens/profile_screen.dart';
import 'package:justmusic/view_model/MusicViewModel.dart'; import 'package:justmusic/screens/registration_screen.dart';
import 'package:justmusic/view_model/UserViewModel.dart'; import 'package:justmusic/screens/welcome_screen.dart';
import 'package:justmusic/view_model/MusicViewModel.dart';
void main() { import 'package:justmusic/view_model/UserViewModel.dart';
runApp(const MyApp());
} import 'firebase_options.dart';
class MyApp extends StatelessWidget { Future<void> main() async {
static UserViewModel userViewModel = UserViewModel(); WidgetsFlutterBinding.ensureInitialized();
static MusicViewModel musicViewModel = MusicViewModel(); await Firebase.initializeApp(
static AudioPlayer audioPlayer = AudioPlayer(); options: DefaultFirebaseOptions.currentPlatform,
);
const MyApp({super.key}); runApp(const MyApp());
}
// This widget is the root of your application.
@override class MyApp extends StatelessWidget {
Widget build(BuildContext context) { static FirebaseFirestore db = FirebaseFirestore.instance;
SystemChrome.setEnabledSystemUIMode(SystemUiMode.immersiveSticky); static UserViewModel userViewModel = UserViewModel();
Paint.enableDithering = true; static MusicViewModel musicViewModel = MusicViewModel();
return ScreenUtilInit( static AudioPlayer audioPlayer = AudioPlayer();
useInheritedMediaQuery: true,
builder: (context, child) { const MyApp({super.key});
return MaterialApp(
routes: { // This widget is the root of your application.
'/welcome': (context) => WellcomeScreen(), @override
'/feed': (context) => FeedScreen(), Widget build(BuildContext context) {
'/login': (context) => LoginScreen(), SystemChrome.setEnabledSystemUIMode(SystemUiMode.immersiveSticky);
'/register': (context) => RegistrationScreen(), Paint.enableDithering = true;
'/post': (context) => PostScreen(), return ScreenUtilInit(
'/profile': (context) => ProfileScreen(), useInheritedMediaQuery: true,
'/explanation': (context) => ExplanationsScreen(), builder: (context, child) {
}, return MaterialApp(
debugShowCheckedModeBanner: false, routes: {
theme: ThemeData( '/welcome': (context) => WellcomeScreen(),
// This is the theme of your application. '/feed': (context) => FeedScreen(),
// '/login': (context) => LoginScreen(),
// Try running your application with "flutter run". You'll see the '/register': (context) => RegistrationScreen(),
// application has a blue toolbar. Then, without quitting the app, try '/post': (context) => PostScreen(),
// changing the primarySwatch below to Colors.green and then invoke '/profile': (context) => ProfileScreen(),
// "hot reload" (press "r" in the console where you ran "flutter run", '/explanation': (context) => ExplanationsScreen(),
// or simply save your changes to "hot reload" in a Flutter IDE). },
// Notice that the counter didn't reset back to zero; the application debugShowCheckedModeBanner: false,
// is not restarted. theme: ThemeData(
primarySwatch: Colors.blue, // This is the theme of your application.
), //
home: WellcomeScreen()); // Try running your application with "flutter run". You'll see the
}, // application has a blue toolbar. Then, without quitting the app, try
designSize: Size(390, 844), // 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),
);
}
}

@ -1,60 +1,60 @@
class User { class User {
final int _id; final String _id;
String _pseudo; String _pseudo;
String _country; String _country;
String _mail; String _mail;
String _pp; String _pp;
int _followers; int _followers;
int _capsules; int _capsules;
int _followed; int _followed;
List<User> friends = []; List<User> friends = [];
// Constructor // Constructor
User(this._id, this._pseudo, this._country, this._mail, this._pp, User(this._id, this._pseudo, this._country, this._mail, this._pp,
this._followers, this._capsules, this._followed, this.friends); this._followers, this._capsules, this._followed, this.friends);
//Getters and setters //Getters and setters
int get id => _id; String get id => _id;
String get pseudo => _pseudo; String get pseudo => _pseudo;
set pseudo(String value) { set pseudo(String value) {
_pseudo = value; _pseudo = value;
} }
String get country => _country; String get country => _country;
set country(String value) { set country(String value) {
_country = value; _country = value;
} }
String get mail => _mail; String get mail => _mail;
set mail(String value) { set mail(String value) {
_mail = value; _mail = value;
} }
String get pp => _pp; String get pp => _pp;
set pp(String value) { set pp(String value) {
_pp = value; _pp = value;
} }
int get capsules => _capsules; int get capsules => _capsules;
set capsules(int value) { set capsules(int value) {
_capsules = value; _capsules = value;
} }
int get followed => _followed; int get followed => _followed;
set followed(int value) { set followed(int value) {
_followed = value; _followed = value;
} }
int get followers => _followers; int get followers => _followers;
set followers(int value) { set followers(int value) {
_followers = value; _followers = value;
} }
} }

@ -0,0 +1,31 @@
import 'package:cloud_firestore/cloud_firestore.dart';
import 'package:justmusic/model/User.dart';
class UserMapper {
static User toModel(DocumentSnapshot<Map<String, dynamic>> snapshot,
SnapshotOptions? options) {
final data = snapshot.data();
return User(
data?["uid"] ?? "",
data?["unique_id"] ?? "",
data?["country"] ?? "",
data?["mail"] ?? "",
data?["profilePicture"] ?? "",
data?["followers"] ?? 0,
data?["nbCapsules"] ?? 0,
data?["followed"] ?? 0,
data?['friends'] is List<User> ? List.from(data?['friends']) : []);
}
/*
static Map<String, dynamic> 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 ()
};
}*/
}

File diff suppressed because it is too large Load Diff

@ -1,376 +1,458 @@
import 'dart:ui'; import 'dart:ui';
import 'package:auto_size_text/auto_size_text.dart'; import 'package:auto_size_text/auto_size_text.dart';
import 'package:flutter/cupertino.dart'; import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter_screenutil/flutter_screenutil.dart'; import 'package:flutter_screenutil/flutter_screenutil.dart';
import 'package:flutter_signin_button/button_list.dart'; import 'package:flutter_signin_button/button_list.dart';
import 'package:flutter_signin_button/button_view.dart'; import 'package:flutter_signin_button/button_view.dart';
import 'package:google_fonts/google_fonts.dart'; import 'package:google_fonts/google_fonts.dart';
import 'package:justmusic/values/constants.dart'; import 'package:justmusic/values/constants.dart';
import '../components/login_button.dart'; import '../components/login_button.dart';
import '../main.dart';
class RegistrationScreen extends StatefulWidget {
const RegistrationScreen({Key? key}) : super(key: key); class RegistrationScreen extends StatefulWidget {
const RegistrationScreen({Key? key}) : super(key: key);
@override
State<RegistrationScreen> createState() => _RegistrationScreenState(); @override
} State<RegistrationScreen> createState() => _RegistrationScreenState();
}
class _RegistrationScreenState extends State<RegistrationScreen> {
bool passenable = true; class _RegistrationScreenState extends State<RegistrationScreen> {
bool passenable = true;
@override final _formKey = GlobalKey<FormState>();
Widget build(BuildContext context) { final _userPseudoTextField = TextEditingController();
return Scaffold( final _userMailTextField = TextEditingController();
backgroundColor: bgColor, final _passwordTextField = TextEditingController();
body: Stack( final _passwordConfirmTextField = TextEditingController();
children: [
SingleChildScrollView( handleRegister() async {
child: SizedBox( if (_formKey.currentState!.validate()) {
width: double.infinity, try {
child: Column( await MyApp.userViewModel.register(_userPseudoTextField.text,
children: [ _passwordTextField.text, _userMailTextField.text);
Padding( Navigator.pushNamed(context, '/explanation');
padding: EdgeInsets.only(top: 100.h), } catch (e) {
child: AutoSizeText( ScaffoldMessenger.of(context).showSnackBar(
"On a besoin de ça!", SnackBar(
style: GoogleFonts.plusJakartaSans( content: Text(
color: Colors.white, e.toString() ?? "",
fontWeight: FontWeight.w600, style: GoogleFonts.plusJakartaSans(
fontSize: 30.w), color: Colors.white,
maxLines: 1, fontWeight: FontWeight.w400,
maxFontSize: 50, fontSize: 20.h),
overflow: TextOverflow.fade, ),
), backgroundColor: Colors.red,
), ),
ConstrainedBox( );
constraints: BoxConstraints(maxWidth: 600), }
child: Column( }
mainAxisAlignment: MainAxisAlignment.start, }
children: [
Padding( @override
padding: Widget build(BuildContext context) {
EdgeInsets.symmetric(horizontal: defaultPadding), return Scaffold(
child: Padding( backgroundColor: bgColor,
padding: EdgeInsets.only(bottom: 50.h), body: Form(
child: Column( key: _formKey,
mainAxisAlignment: MainAxisAlignment.end, child: Stack(
children: [ children: [
SizedBox( SingleChildScrollView(
height: 15.h, child: SizedBox(
), width: double.infinity,
SizedBox( child: Column(
width: 230.h, children: [
child: AutoSizeText( Padding(
"Promis cest rapide.", padding: EdgeInsets.only(top: 100.h),
style: GoogleFonts.plusJakartaSans( child: AutoSizeText(
color: Colors.white, "On a besoin de ça!",
fontWeight: FontWeight.w400, style: GoogleFonts.plusJakartaSans(
fontSize: 17.w), color: Colors.white,
maxFontSize: 20, fontWeight: FontWeight.w600,
textAlign: TextAlign.center, fontSize: 30.w),
), maxLines: 1,
), maxFontSize: 50,
], overflow: TextOverflow.fade,
), ),
), ),
), ConstrainedBox(
Padding( constraints: BoxConstraints(maxWidth: 600),
padding: EdgeInsets.only( child: Column(
bottom: 16.h, mainAxisAlignment: MainAxisAlignment.start,
left: defaultPadding, children: [
right: defaultPadding), Padding(
child: TextFormField( padding: EdgeInsets.symmetric(
keyboardAppearance: Brightness.dark, horizontal: defaultPadding),
validator: (value) { child: Padding(
if (value == null || value.isEmpty) { padding: EdgeInsets.only(bottom: 50.h),
return 'TODO'; child: Column(
} mainAxisAlignment: MainAxisAlignment.end,
return null; children: [
}, SizedBox(
cursorColor: primaryColor, height: 15.h,
keyboardType: TextInputType.emailAddress, ),
style: GoogleFonts.plusJakartaSans( SizedBox(
color: primaryColor, fontSize: 15), width: 230.h,
decoration: InputDecoration( child: AutoSizeText(
focusedBorder: OutlineInputBorder( "Promis cest rapide.",
borderSide: BorderSide( style: GoogleFonts.plusJakartaSans(
width: 1.sp, color: strokeTextField), color: Colors.white,
borderRadius: const BorderRadius.all( fontWeight: FontWeight.w400,
Radius.circular(10))), fontSize: 17.w),
contentPadding: const EdgeInsets.only( maxFontSize: 20,
top: 0, bottom: 0, left: defaultPadding), textAlign: TextAlign.center,
fillColor: bgTextField, ),
filled: true, ),
focusColor: ],
const Color.fromRGBO(255, 255, 255, 0.30), ),
enabledBorder: const OutlineInputBorder( ),
borderSide: BorderSide( ),
width: 1, color: strokeTextField), Padding(
borderRadius: BorderRadius.all( padding: EdgeInsets.only(
Radius.circular(10))), bottom: 16.h,
hintText: 'Pseudo', left: defaultPadding,
hintStyle: GoogleFonts.plusJakartaSans( right: defaultPadding),
color: strokeTextField)), child: TextFormField(
)), controller: _userPseudoTextField,
Padding( keyboardAppearance: Brightness.dark,
padding: EdgeInsets.only( validator: (value) {
bottom: 16.h, if (value == null || value.isEmpty) {
left: defaultPadding, return 'entrez un pseudo valide';
right: defaultPadding), }
child: TextFormField( return null;
keyboardAppearance: Brightness.dark, },
validator: (value) { cursorColor: primaryColor,
if (value == null || value.isEmpty) { keyboardType: TextInputType.emailAddress,
return 'TODO'; style: GoogleFonts.plusJakartaSans(
} color: primaryColor, fontSize: 15),
return null; decoration: InputDecoration(
}, focusedBorder: OutlineInputBorder(
cursorColor: primaryColor, borderSide: BorderSide(
keyboardType: TextInputType.emailAddress, width: 1.sp,
style: GoogleFonts.plusJakartaSans( color: strokeTextField),
color: primaryColor), borderRadius: const BorderRadius.all(
decoration: InputDecoration( Radius.circular(10))),
focusedBorder: OutlineInputBorder( prefix: const Padding(
borderSide: BorderSide( padding: EdgeInsets.only(left: 20.0)),
width: 1, color: strokeTextField), suffix: const Padding(
borderRadius: BorderRadius.all( padding: EdgeInsets.only(left: 20.0)),
Radius.circular(10))), fillColor: bgTextField,
contentPadding: EdgeInsets.only( filled: true,
top: 0, bottom: 0, left: defaultPadding), focusColor: const Color.fromRGBO(
fillColor: bgTextField, 255, 255, 255, 0.30),
filled: true, enabledBorder: const OutlineInputBorder(
focusColor: borderSide: BorderSide(
Color.fromRGBO(255, 255, 255, 0.30), width: 1, color: strokeTextField),
enabledBorder: OutlineInputBorder( borderRadius: BorderRadius.all(
borderSide: BorderSide( Radius.circular(10))),
width: 1, color: strokeTextField), hintText: 'Pseudo',
borderRadius: BorderRadius.all( hintStyle: GoogleFonts.plusJakartaSans(
Radius.circular(10))), color: strokeTextField)),
hintText: 'Email', )),
hintStyle: GoogleFonts.plusJakartaSans( Padding(
color: strokeTextField)), padding: EdgeInsets.only(
)), bottom: 16.h,
Padding( left: defaultPadding,
padding: EdgeInsets.only( right: defaultPadding),
bottom: 16.h, child: TextFormField(
left: defaultPadding, controller: _userMailTextField,
right: defaultPadding), keyboardAppearance: Brightness.dark,
child: TextFormField( validator: (value) {
keyboardAppearance: Brightness.dark, if (value == null || value.isEmpty) {
obscureText: passenable, return 'entrez un email valide';
validator: (value) { }
if (value == null || value.isEmpty) { return null;
return 'TODO'; },
} cursorColor: primaryColor,
return null; keyboardType: TextInputType.emailAddress,
}, style: GoogleFonts.plusJakartaSans(
cursorColor: primaryColor, color: primaryColor),
keyboardType: TextInputType.emailAddress, decoration: InputDecoration(
style: GoogleFonts.plusJakartaSans( focusedBorder: OutlineInputBorder(
color: primaryColor), borderSide: BorderSide(
decoration: InputDecoration( width: 1, color: strokeTextField),
focusedBorder: OutlineInputBorder( borderRadius: BorderRadius.all(
borderSide: BorderSide( Radius.circular(10))),
width: 1, color: strokeTextField), prefix: const Padding(
borderRadius: padding: EdgeInsets.only(left: 20.0)),
BorderRadius.all(Radius.circular(10))), suffix: const Padding(
contentPadding: EdgeInsets.only( padding: EdgeInsets.only(left: 20.0)),
top: 0, bottom: 0, left: defaultPadding), fillColor: bgTextField,
fillColor: bgTextField, filled: true,
filled: true, focusColor:
focusColor: Color.fromRGBO(255, 255, 255, 0.30), Color.fromRGBO(255, 255, 255, 0.30),
enabledBorder: OutlineInputBorder( enabledBorder: OutlineInputBorder(
borderSide: BorderSide( borderSide: BorderSide(
width: 1, color: strokeTextField), width: 1, color: strokeTextField),
borderRadius: borderRadius: BorderRadius.all(
BorderRadius.all(Radius.circular(10))), Radius.circular(10))),
hintText: 'Mot de passe', hintText: 'Email',
hintStyle: GoogleFonts.plusJakartaSans( hintStyle: GoogleFonts.plusJakartaSans(
color: strokeTextField), color: strokeTextField)),
suffixIcon: Container( )),
padding: EdgeInsets.only(right: 10), Padding(
margin: EdgeInsets.all(5), padding: EdgeInsets.only(
height: 3, bottom: 16.h,
child: InkWell( left: defaultPadding,
onTap: () { right: defaultPadding),
setState(() { child: TextFormField(
if (passenable) { controller: _passwordTextField,
passenable = false; keyboardAppearance: Brightness.dark,
} else { obscureText: passenable,
passenable = true; validator: (value) {
} if (value == null || value.isEmpty) {
}); return 'entrez un mot de passe valide';
}, // Image tapped }
splashColor: Colors return null;
.white10, // Splash color over image },
child: Image( cursorColor: primaryColor,
image: passenable style: GoogleFonts.plusJakartaSans(
? AssetImage( color: primaryColor),
"assets/images/show_icon.png") decoration: InputDecoration(
: AssetImage( focusedBorder: OutlineInputBorder(
"assets/images/hide_icon.png"), borderSide: BorderSide(
height: 2, width: 1, color: strokeTextField),
), borderRadius:
)), BorderRadius.all(Radius.circular(10))),
), prefix: const Padding(
), padding: EdgeInsets.only(left: 20.0)),
), suffix: const Padding(
Padding( padding: EdgeInsets.only(left: 20.0)),
padding: EdgeInsets.only( fillColor: bgTextField,
bottom: 16.h, filled: true,
left: defaultPadding, focusColor: Color.fromRGBO(255, 255, 255, 0.30),
right: defaultPadding), enabledBorder: OutlineInputBorder(
child: TextFormField( borderSide: BorderSide(
keyboardAppearance: Brightness.dark, width: 1, color: strokeTextField),
obscureText: passenable, borderRadius:
validator: (value) { BorderRadius.all(Radius.circular(10))),
if (value == null || value.isEmpty) { hintText: 'Mot de passe',
return 'TODO'; hintStyle: GoogleFonts.plusJakartaSans(
} color: strokeTextField),
return null; suffixIcon: Container(
}, padding: EdgeInsets.only(right: 10),
cursorColor: primaryColor, margin: EdgeInsets.all(5),
keyboardType: TextInputType.emailAddress, height: 3,
style: GoogleFonts.plusJakartaSans( child: InkWell(
color: primaryColor), onTap: () {
decoration: InputDecoration( setState(() {
focusedBorder: OutlineInputBorder( if (passenable) {
borderSide: BorderSide( passenable = false;
width: 1, color: strokeTextField), } else {
borderRadius: passenable = true;
BorderRadius.all(Radius.circular(10))), }
contentPadding: EdgeInsets.only( });
top: 0, bottom: 0, left: defaultPadding), },
fillColor: bgTextField, // Image tapped
filled: true, splashColor: Colors.white10,
focusColor: Color.fromRGBO(255, 255, 255, 0.30), // Splash color over image
enabledBorder: OutlineInputBorder( child: Image(
borderSide: BorderSide( image: passenable
width: 1, color: strokeTextField), ? AssetImage(
borderRadius: "assets/images/show_icon.png")
BorderRadius.all(Radius.circular(10))), : AssetImage(
hintText: 'Confirmation du Mot de passe', "assets/images/hide_icon.png"),
hintStyle: GoogleFonts.plusJakartaSans( height: 2,
color: strokeTextField), ),
suffixIcon: Container( )),
padding: EdgeInsets.only(right: 10), ),
margin: EdgeInsets.all(5), ),
height: 3, ),
child: InkWell( Padding(
onTap: () { padding: EdgeInsets.only(
setState(() { bottom: 16.h,
if (passenable) { left: defaultPadding,
passenable = false; right: defaultPadding),
} else { child: TextFormField(
passenable = true; controller: _passwordConfirmTextField,
} keyboardAppearance: Brightness.dark,
}); obscureText: passenable,
}, // Image tapped validator: (value) {
splashColor: Colors if (value == null || value.isEmpty) {
.white10, // Splash color over image return 'entrez un mot de passe valide';
child: Image( } else if (_passwordTextField.text != value) {
image: passenable return 'les mots de passes ne sont pas identiques';
? AssetImage( }
"assets/images/show_icon.png") return null;
: AssetImage( },
"assets/images/hide_icon.png"), cursorColor: primaryColor,
height: 2, keyboardType: TextInputType.emailAddress,
), style: GoogleFonts.plusJakartaSans(
)), color: primaryColor),
), decoration: InputDecoration(
), focusedBorder: OutlineInputBorder(
), borderSide: BorderSide(
Padding( width: 1, color: strokeTextField),
padding: borderRadius:
EdgeInsets.symmetric(horizontal: defaultPadding), BorderRadius.all(Radius.circular(10))),
child: SizedBox(width: 600, child: LoginButton()), prefix: const Padding(
), padding: EdgeInsets.only(left: 20.0)),
], suffix: const Padding(
)), padding: EdgeInsets.only(left: 20.0)),
SizedBox(height: 50.h), fillColor: bgTextField,
ConstrainedBox( filled: true,
constraints: BoxConstraints(maxWidth: 600), focusColor: Color.fromRGBO(255, 255, 255, 0.30),
child: Row( enabledBorder: OutlineInputBorder(
mainAxisAlignment: MainAxisAlignment.spaceEvenly, borderSide: BorderSide(
children: [ width: 1, color: strokeTextField),
Expanded( borderRadius:
child: Container( BorderRadius.all(Radius.circular(10))),
color: Color(0xFF3D3D3D), hintText: 'Confirmation du Mot de passe',
height: 1, hintStyle: GoogleFonts.plusJakartaSans(
), color: strokeTextField),
), suffixIcon: Container(
Padding( padding: EdgeInsets.only(right: 10),
padding: const EdgeInsets.only( margin: EdgeInsets.all(5),
left: defaultPadding, right: defaultPadding), height: 3,
child: Text( child: InkWell(
'Ou', onTap: () {
style: GoogleFonts.plusJakartaSans( setState(() {
color: Colors.white, fontWeight: FontWeight.bold), if (passenable) {
), passenable = false;
), } else {
Expanded( passenable = true;
child: Container( }
height: 1, });
color: Color(0xFF3D3D3D), },
)), // Image tapped
], splashColor: Colors.white10,
), // Splash color over image
), child: Image(
SizedBox(height: 47.h), image: passenable
ConstrainedBox( ? AssetImage(
constraints: BoxConstraints(maxWidth: 540), "assets/images/show_icon.png")
child: SizedBox( : AssetImage(
width: 300.sp, "assets/images/hide_icon.png"),
height: 50, height: 2,
child: SignInButton( ),
Buttons.Google, )),
text: "Login with Google", ),
onPressed: () {}, ),
shape: RoundedRectangleBorder( ),
borderRadius: BorderRadius.all(Radius.circular(20))), Padding(
), padding: EdgeInsets.symmetric(
), horizontal: defaultPadding),
), child: SizedBox(
], width: 600,
), child: LoginButton(
)), callback: handleRegister,
IgnorePointer( )),
child: Container( ),
height: 240.h, Align(
decoration: BoxDecoration( child: GestureDetector(
gradient: LinearGradient(begin: Alignment.topRight, stops: [ onTap: () {
0, Navigator.pushNamed(context, '/login');
1 },
], colors: [ child: Padding(
bgColor.withOpacity(1), padding: EdgeInsets.only(top: 20),
bgColor.withOpacity(0) child: RichText(
])), textAlign: TextAlign.center,
), text: TextSpan(
), text: 'Tu as déjà un compte?',
Align( style: GoogleFonts.plusJakartaSans(
alignment: Alignment.topCenter, color: Colors.white,
child: ConstrainedBox( fontWeight: FontWeight.w400,
constraints: BoxConstraints(maxWidth: 800), fontSize: 15),
child: Padding( children: <TextSpan>[
padding: EdgeInsets.only( TextSpan(
top: 45.h, left: defaultPadding, right: defaultPadding), text: " Connexion",
child: ClipRRect( style: GoogleFonts.plusJakartaSans(
borderRadius: BorderRadius.circular(10.0), fontSize: 15,
child: LinearProgressIndicator( fontWeight: FontWeight.w400,
minHeight: 5, color: primaryColor)),
value: 0.5, ],
backgroundColor: grayColor, ),
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,
),
),
),
),
),
],
),
),
);
}
}

@ -1,90 +1,98 @@
import 'package:flutter/cupertino.dart'; import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:google_fonts/google_fonts.dart'; import 'package:google_fonts/google_fonts.dart';
import 'package:justmusic/values/constants.dart'; import 'package:justmusic/values/constants.dart';
import '../components/join_button.dart'; import '../components/join_button.dart';
class WellcomeScreen extends StatelessWidget { class WellcomeScreen extends StatelessWidget {
const WellcomeScreen({Key? key}) : super(key: key); const WellcomeScreen({Key? key}) : super(key: key);
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
return Scaffold( return Scaffold(
body: Container( body: Container(
padding: EdgeInsets.all(defaultPadding), padding: EdgeInsets.all(defaultPadding),
width: double.infinity, width: double.infinity,
height: double.infinity, height: double.infinity,
decoration: const BoxDecoration( decoration: const BoxDecoration(
image: DecorationImage( image: DecorationImage(
image: AssetImage("assets/images/wellcome_background.png"), image: AssetImage("assets/images/wellcome_background.png"),
fit: BoxFit.cover, fit: BoxFit.cover,
), ),
), ),
child: Align( child: Align(
child: Column( child: Column(
crossAxisAlignment: CrossAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.start,
children: [ children: [
Expanded( Expanded(
flex: 10, flex: 10,
child: Padding( child: Padding(
padding: EdgeInsets.only(bottom: 100), padding: EdgeInsets.only(bottom: 100),
child: Column( child: Column(
mainAxisAlignment: MainAxisAlignment.end, mainAxisAlignment: MainAxisAlignment.end,
crossAxisAlignment: CrossAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.start,
children: [ children: [
Text( Text(
"Bienvenue sur,", "Bienvenue sur,",
style: GoogleFonts.plusJakartaSans( style: GoogleFonts.plusJakartaSans(
color: Colors.white, color: Colors.white,
fontWeight: FontWeight.bold, fontWeight: FontWeight.bold,
fontSize: 34), fontSize: 34),
), ),
Image( Image(
image: AssetImage("assets/images/logo.png"), image: AssetImage("assets/images/logo.png"),
width: 230, width: 230,
), ),
SizedBox( SizedBox(
height: 25, height: 25,
), ),
ConstrainedBox( ConstrainedBox(
constraints: BoxConstraints(maxWidth: 520), constraints: BoxConstraints(maxWidth: 520),
child: Text( child: Text(
"Explore les nouvelles découvertes musicales de tes amis, et partage leur ton mood.", "Explore les nouvelles découvertes musicales de tes amis, et partage leur ton mood.",
style: GoogleFonts.plusJakartaSans( style: GoogleFonts.plusJakartaSans(
color: Colors.white, color: Colors.white,
fontWeight: FontWeight.w200, fontWeight: FontWeight.w200,
fontSize: 15), fontSize: 15),
), ),
), ),
], ],
), ),
), ),
), ),
Expanded( Expanded(
flex: 3, flex: 3,
child: Column( child: Column(
mainAxisAlignment: MainAxisAlignment.start, mainAxisAlignment: MainAxisAlignment.start,
crossAxisAlignment: CrossAxisAlignment.center, crossAxisAlignment: CrossAxisAlignment.center,
children: [ children: [
JoinButton(), JoinButton(),
SizedBox( SizedBox(
height: defaultPadding, height: defaultPadding,
), ),
Text( GestureDetector(
"Tu as déja un compte? Connexion", onTap: () {
style: GoogleFonts.plusJakartaSans( Navigator.pushNamed(context, '/login');
color: Colors.white, },
fontWeight: FontWeight.w400, child: Padding(
fontSize: 15), 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 */, ),
), ),
); ),
} ],
} ),
),
],
),
) /* add child content here */,
),
);
}
}

@ -0,0 +1,80 @@
import 'package:cloud_firestore/cloud_firestore.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,
);
String uniqueId = await generateUniqueId(pseudo);
final user = <String, dynamic>{
"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": []
};
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;
}
}
Future<String> 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
.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();
}
}

@ -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])
});
}
}

@ -0,0 +1 @@
const geoKey = "85a2724ad38b3994c2b7ebe1d239bbff";

@ -1,19 +1,66 @@
import '../model/User.dart'; import 'package:firebase_auth/firebase_auth.dart' as firebase_auth;
import 'package:justmusic/service/AuthService.dart';
class UserViewModel {
User _userCurrent = User( import '../model/User.dart';
1, "MelinaShow", "France", "test@gmail.com", "zezrzrzr", 5, 12, 114, []); import '../model/mapper/UserMapper.dart';
import '../main.dart';
User get userCurrent => _userCurrent;
class UserViewModel {
set userCurrent(User value) { late User _userCurrent;
_userCurrent = value; final AuthService _authService = AuthService();
} // Constructor
User get userCurrent => _userCurrent;
UserViewModel();
set userCurrent(User value) {
// Methods _userCurrent = value;
User getUser(int id) { } // Constructor
throw new Error();
} UserViewModel();
}
// Methods
Future<User?> 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;
}
}
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.toLowerCase(), 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();
}
}

@ -1,6 +1,14 @@
# Generated by pub # Generated by pub
# See https://dart.dev/tools/pub/glossary#lockfile # See https://dart.dev/tools/pub/glossary#lockfile
packages: packages:
_flutterfire_internals:
dependency: transitive
description:
name: _flutterfire_internals
sha256: "5dce45a06d386358334eb1689108db6455d90ceb0d75848d5f4819283d4ee2b8"
url: "https://pub.dev"
source: hosted
version: "1.3.4"
animated_appear: animated_appear:
dependency: "direct main" dependency: "direct main"
description: description:
@ -113,6 +121,30 @@ packages:
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "1.1.1" 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: collection:
dependency: transitive dependency: transitive
description: description:
@ -209,6 +241,54 @@ packages:
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "0.9.3" version: "0.9.3"
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: flutter:
dependency: "direct main" dependency: "direct main"
description: flutter description: flutter

@ -53,6 +53,9 @@ dependencies:
audioplayers: ^4.1.0 audioplayers: ^4.1.0
ionicons: ^0.2.2 ionicons: ^0.2.2
top_snackbar_flutter: ^3.1.0 top_snackbar_flutter: ^3.1.0
firebase_core: ^2.15.0
firebase_auth: ^4.7.2
cloud_firestore: ^4.8.4
image_picker: ^1.0.1 image_picker: ^1.0.1
insta_image_viewer: ^1.0.2 insta_image_viewer: ^1.0.2
pinch_zoom: ^1.0.0 pinch_zoom: ^1.0.0

@ -80,3 +80,4 @@ Future<void> main() async {
} }
} }

Loading…
Cancel
Save