POSTS_FRIENDS_EKA-LDE #32

Merged
emre.kartal merged 8 commits from POSTS_FRIENDS_EKA-LDE into master 2 years ago

@ -0,0 +1 @@
{"nm":"newScene","ddd":0,"h":506,"w":246,"meta":{"g":"LottieFiles Figma v38"},"layers":[{"ty":4,"nm":"","sr":1,"st":0,"op":55,"ip":0,"hd":false,"ddd":0,"bm":0,"hasMask":false,"ao":0,"ks":{"a":{"a":0,"k":[0,0]},"s":{"a":0,"k":[100,100]},"sk":{"a":0,"k":0},"p":{"a":0,"k":[0,0]},"r":{"a":0,"k":0},"sa":{"a":0,"k":0},"o":{"a":0,"k":100}},"ef":[],"shapes":[{"ty":"gr","bm":0,"hd":false,"nm":"","it":[{"ty":"sh","bm":0,"hd":false,"nm":"","d":1,"ks":{"a":0,"k":{"c":true,"i":[[0,0],[18.31699999999998,-14.117000000000019],[0,0],[4.924000000000007,-5.552999999999997],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[-2.176000000000016,8.12299999999999],[0,0],[-4.0330000000000155,15.050000000000011],[0,0],[0,0]],"o":[[-15.049000000000007,-4.031999999999982],[0,0],[-8.12299999999999,-2.1759999999999877],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[7.271000000000015,-1.488999999999976],[0,0],[21.383999999999986,-8.803999999999974],[0,0],[0,0],[0,0]],"v":[[229.562,323.522],[173.235,338.521],[161.993,335.509],[142.666,343.701],[136.075,351.133],[146.207,353.848],[156.351,356.566],[164.059,369.916],[171.766,383.266],[169.048,393.41],[166.333,403.542],[176.065,401.551],[192.823,388.908],[195.836,377.666],[236.989,336.385],[239.707,326.24],[229.562,323.522]]}}},{"ty":"sh","bm":0,"hd":false,"nm":"","d":1,"ks":{"a":0,"k":{"c":true,"i":[[0,0],[1.0389999999999873,-3.8759999999999764],[3.8770000000000095,1.038000000000011],[-1.0389999999999873,3.8770000000000095],[-3.8770000000000095,-1.0389999999999873]],"o":[[3.8760000000000048,1.038000000000011],[-1.0390000000000157,3.8770000000000095],[-3.8770000000000095,-1.0389999999999873],[1.038000000000011,-3.8770000000000095],[0,0]],"v":[[205.989,339.775],[211.127,348.674],[202.227,353.813],[197.089,344.913],[205.989,339.775]]}}},{"ty":"sh","bm":0,"hd":false,"nm":"","d":1,"ks":{"a":0,"k":{"c":true,"i":[[0,0],[0,0],[0,0],[-7.138000000000005,4.120999999999981],[0,0],[0,0]],"o":[[0,0],[-6.4269999999999925,3.7110000000000127],[0,0],[0,0],[0,0],[0,0]],"v":[[149.08,369.664],[144.63,372.233],[132.909,387.9],[152.338,385.583],[156.788,383.014],[149.08,369.664]]}}},{"ty":"fl","bm":0,"hd":false,"nm":"","c":{"a":0,"k":[1,1,1]},"r":1,"o":{"a":0,"k":100}},{"ty":"tr","a":{"a":0,"k":[0,0]},"s":{"a":0,"k":[100,100]},"sk":{"a":0,"k":0},"p":{"a":0,"k":[0,0]},"r":{"a":1,"k":[{"o":{"x":0.167,"y":0.167},"i":{"x":0.833,"y":0.833},"s":[90],"t":0},{"o":{"x":0.167,"y":0.167},"i":{"x":0.833,"y":0.833},"s":[90],"t":5},{"s":[0],"t":25}]},"sa":{"a":0,"k":0},"o":{"a":1,"k":[{"o":{"x":0.167,"y":0.167},"i":{"x":0.833,"y":0.833},"s":[0],"t":0},{"o":{"x":0.167,"y":0.167},"i":{"x":0.833,"y":0.833},"s":[0],"t":5},{"s":[100],"t":25}]}}]}],"ind":1}],"v":"5.7.0","fr":60,"op":55,"ip":0,"assets":[]}

@ -65,7 +65,7 @@ class _EditablePostComponentState extends State<EditablePostComponent> with Tick
try { try {
final image = await ImagePicker().pickImage( final image = await ImagePicker().pickImage(
source: source, source: source,
imageQuality: 10 imageQuality: 20
); );
if (image == null) return; if (image == null) return;
final imageTemp = File(image.path); final imageTemp = File(image.path);

@ -1,5 +1,7 @@
import 'package:flutter/Material.dart'; import 'package:flutter/Material.dart';
import 'package:flutter_screenutil/flutter_screenutil.dart';
import 'package:google_fonts/google_fonts.dart'; import 'package:google_fonts/google_fonts.dart';
import '../main.dart';
import '../model/User.dart'; import '../model/User.dart';
import '../values/constants.dart'; import '../values/constants.dart';
@ -12,10 +14,11 @@ class ProfileListComponent extends StatefulWidget {
} }
class _ProfileListComponentState extends State<ProfileListComponent> { class _ProfileListComponentState extends State<ProfileListComponent> {
bool clicked = false; late bool clicked;
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
clicked = MyApp.userViewModel.isFriend(widget.user.id);
return Container( return Container(
padding: const EdgeInsets.only(bottom: 5), padding: const EdgeInsets.only(bottom: 5),
child: Row( child: Row(
@ -36,22 +39,38 @@ class _ProfileListComponentState extends State<ProfileListComponent> {
crossAxisAlignment: CrossAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.start,
mainAxisAlignment: MainAxisAlignment.center, mainAxisAlignment: MainAxisAlignment.center,
children: [ children: [
ScrollConfiguration( Text(
behavior: ScrollBehavior().copyWith(scrollbars: false), widget.user.pseudo,
child: Text( style: GoogleFonts.plusJakartaSans(fontSize: 16, color: Colors.white, fontWeight: FontWeight.w700),
widget.user.uniquePseudo, overflow: TextOverflow.ellipsis,
style: GoogleFonts.plusJakartaSans(fontSize: 16, color: Colors.white, fontWeight: FontWeight.w700), maxLines: 1,
overflow: TextOverflow.ellipsis,
maxLines: 1,
),
), ),
ScrollConfiguration( Row(
behavior: ScrollBehavior().copyWith(scrollbars: false), crossAxisAlignment: CrossAxisAlignment.end,
child: Text( children: [
widget.user.pseudo, Text(
widget.user.uniquePseudo,
overflow: TextOverflow.ellipsis, overflow: TextOverflow.ellipsis,
style: GoogleFonts.plusJakartaSans(color: Colors.grey, fontWeight: FontWeight.w400), style: GoogleFonts.plusJakartaSans(color: Colors.grey, fontWeight: FontWeight.w400),
)) ),
widget.user.followed.contains(MyApp.userViewModel.userCurrent.id)
? Container(
padding: const EdgeInsets.all(2),
margin: const EdgeInsets.only(left: 10),
decoration: const BoxDecoration(
color: grayColor,
borderRadius: BorderRadius.all(Radius.circular(3)),
),
child: Text(
"Vous suit",
overflow: TextOverflow.ellipsis,
style: GoogleFonts.plusJakartaSans(
color: Colors.grey.withOpacity(0.4), fontWeight: FontWeight.w700, fontSize: 12),
),
)
: Container(),
],
)
], ],
), ),
), ),
@ -62,10 +81,20 @@ class _ProfileListComponentState extends State<ProfileListComponent> {
color: selectedButton, color: selectedButton,
child: InkWell( child: InkWell(
splashColor: Colors.white.withOpacity(0.3), splashColor: Colors.white.withOpacity(0.3),
onTap: () { onTap: () async {
setState(() { await MyApp.userViewModel.addOrDeleteFriend(widget.user.id);
clicked = !clicked; ScaffoldMessenger.of(context).showSnackBar(
}); SnackBar(
content: Text(
"Vous ne suivez plus ${widget.user.pseudo}",
style: GoogleFonts.plusJakartaSans(
color: Colors.white, fontWeight: FontWeight.w400, fontSize: 20.h),
),
backgroundColor: Colors.red,
closeIconColor: Colors.white,
),
);
setState(() {});
}, },
child: Container( child: Container(
padding: EdgeInsets.fromLTRB(28, 7, 28, 7), padding: EdgeInsets.fromLTRB(28, 7, 28, 7),
@ -81,10 +110,19 @@ class _ProfileListComponentState extends State<ProfileListComponent> {
color: primaryColor, color: primaryColor,
child: InkWell( child: InkWell(
splashColor: Colors.white.withOpacity(0.3), splashColor: Colors.white.withOpacity(0.3),
onTap: () { onTap: () async {
setState(() { await MyApp.userViewModel.addOrDeleteFriend(widget.user.id);
clicked = !clicked; ScaffoldMessenger.of(context).showSnackBar(
}); SnackBar(
backgroundColor: primaryColor,
content: Text(
"Vous suivez à present ${widget.user.pseudo}",
style: GoogleFonts.plusJakartaSans(
color: Colors.white, fontWeight: FontWeight.w400, fontSize: 20.h),
),
),
);
setState(() {});
}, },
child: Container( child: Container(
padding: EdgeInsets.fromLTRB(25, 7, 25, 7), padding: EdgeInsets.fromLTRB(25, 7, 25, 7),

@ -20,7 +20,7 @@ class StatisticsComponent extends StatelessWidget {
child: Column( child: Column(
children: [ children: [
AutoSizeText( AutoSizeText(
user.followed.toString(), user.followed.length.toString(),
style: GoogleFonts.plusJakartaSans( style: GoogleFonts.plusJakartaSans(
color: Colors.white, color: Colors.white,
fontWeight: FontWeight.bold, fontWeight: FontWeight.bold,
@ -40,7 +40,7 @@ class StatisticsComponent extends StatelessWidget {
mainAxisSize: MainAxisSize.min, mainAxisSize: MainAxisSize.min,
children: [ children: [
AutoSizeText( AutoSizeText(
user.followers.toString(), user.followers.length.toString(),
style: GoogleFonts.plusJakartaSans( style: GoogleFonts.plusJakartaSans(
color: Colors.white, color: Colors.white,
fontWeight: FontWeight.bold, fontWeight: FontWeight.bold,

@ -27,9 +27,10 @@ class _TopNavBarComponentState extends State<TopNavBarComponent> with TickerProv
final DateTime midnight = DateTime(DateTime.now().year, DateTime.now().month, DateTime.now().day + 1); final DateTime midnight = DateTime(DateTime.now().year, DateTime.now().month, DateTime.now().day + 1);
void actionSurBouton() { void actionSurBouton() async {
widget.callback(choice); widget.callback(choice);
MyApp.postViewModel.getBestPosts(); await MyApp.postViewModel.getBestPosts();
await MyApp.postViewModel.getPostsFriends();
} }
@override @override
@ -138,10 +139,7 @@ class _TopNavBarComponentState extends State<TopNavBarComponent> with TickerProv
child: GestureDetector( child: GestureDetector(
behavior: HitTestBehavior.translucent, behavior: HitTestBehavior.translucent,
onTap: () async { onTap: () async {
bool returnFromOtherPage = await Navigator.of(context).push(routeAddFriend()); Navigator.of(context).push(routeAddFriend());
if (returnFromOtherPage == true) {
checkAvailable();
}
}, },
child: const Icon( child: const Icon(
Icons.person_add_alt_1_rounded, Icons.person_add_alt_1_rounded,
@ -159,7 +157,9 @@ class _TopNavBarComponentState extends State<TopNavBarComponent> with TickerProv
enableLongTapRepeatEvent: false, enableLongTapRepeatEvent: false,
longTapRepeatDuration: const Duration(milliseconds: 100), longTapRepeatDuration: const Duration(milliseconds: 100),
begin: 1.0, begin: 1.0,
onTap: () {}, onTap: () {
checkAvailable();
},
end: 0.97, end: 0.97,
beginDuration: const Duration(milliseconds: 70), beginDuration: const Duration(milliseconds: 70),
endDuration: const Duration(milliseconds: 100), endDuration: const Duration(milliseconds: 100),
@ -237,19 +237,17 @@ class _TopNavBarComponentState extends State<TopNavBarComponent> with TickerProv
flex: 1, flex: 1,
child: GestureDetector( child: GestureDetector(
onTap: () async { onTap: () async {
bool returnFromOtherPage = await Navigator.of(context).push(routeProfile()); await MyApp.userViewModel.updateUserCurrent();
if (returnFromOtherPage == true) { Navigator.of(context).push(routeProfile());
checkAvailable();
}
}, },
child: ClipOval( child: ClipOval(
child: SizedBox.fromSize( child: SizedBox.fromSize(
// Image radius // Image radius
child: Image( child: FadeInImage.assetNetwork(
image: NetworkImage(MyApp.userViewModel.userCurrent.pp), placeholder: 'assets/images/loadingPlaceholder.gif',
width: 30, image: MyApp.userViewModel.userCurrent.pp,
), width: 30,
), )),
), ),
), ),
) )

@ -8,6 +8,7 @@ import 'package:justmusic/screens/add_friend_screen.dart';
import 'package:justmusic/screens/explanations_screen.dart'; import 'package:justmusic/screens/explanations_screen.dart';
import 'package:justmusic/screens/feed_screen.dart'; import 'package:justmusic/screens/feed_screen.dart';
import 'package:justmusic/screens/login_screen.dart'; import 'package:justmusic/screens/login_screen.dart';
import 'package:justmusic/screens/launching_rocker_screen.dart';
import 'package:justmusic/screens/post_screen.dart'; import 'package:justmusic/screens/post_screen.dart';
import 'package:justmusic/screens/profile_screen.dart'; import 'package:justmusic/screens/profile_screen.dart';
import 'package:justmusic/screens/registration_screen.dart'; import 'package:justmusic/screens/registration_screen.dart';
@ -53,6 +54,7 @@ class MyApp extends StatelessWidget {
'/profile': (context) => const ProfileScreen(), '/profile': (context) => const ProfileScreen(),
'/explanation': (context) => const ExplanationsScreen(), '/explanation': (context) => const ExplanationsScreen(),
'/addFriend': (context) => const AddFriendScreen(), '/addFriend': (context) => const AddFriendScreen(),
'/launchingRocket': (context) => const LaunchingRocketScreen(),
}, },
debugShowCheckedModeBanner: false, debugShowCheckedModeBanner: false,
theme: ThemeData( theme: ThemeData(

@ -2,17 +2,15 @@ class User {
final String _id; final String _id;
String _pseudo; String _pseudo;
String _uniquePseudo; String _uniquePseudo;
String _country;
String _mail; String _mail;
String _pp; String _pp;
int _followers; List<String> _followers;
int _capsules; int _capsules;
int _followed; List<String> _followed;
List<User> friends = [];
// Constructor // Constructor
User(this._id, this._pseudo, this._uniquePseudo, this._country, this._mail, this._pp, User(this._id, this._pseudo, this._uniquePseudo, this._mail,
this._followers, this._capsules, this._followed, this.friends); this._pp, this._followers, this._capsules, this._followed);
//Getters and setters //Getters and setters
String get id => _id; String get id => _id;
@ -29,12 +27,6 @@ class User {
_uniquePseudo = value; _uniquePseudo = value;
} }
String get country => _country;
set country(String value) {
_country = value;
}
String get mail => _mail; String get mail => _mail;
set mail(String value) { set mail(String value) {
@ -53,15 +45,15 @@ class User {
_capsules = value; _capsules = value;
} }
int get followed => _followed; List<String> get followed => _followed;
set followed(int value) { set followed(List<String> value) {
_followed = value; _followed = value;
} }
int get followers => _followers; List<String> get followers => _followers;
set followers(int value) { set followers(List<String> value) {
_followers = value; _followers = value;
} }
} }

@ -2,7 +2,6 @@ import 'package:cloud_firestore/cloud_firestore.dart';
import 'package:tuple/tuple.dart'; import 'package:tuple/tuple.dart';
import '../../main.dart'; import '../../main.dart';
import '../Music.dart';
import '../Post.dart'; import '../Post.dart';
import '../User.dart'; import '../User.dart';

@ -2,20 +2,17 @@ import 'package:cloud_firestore/cloud_firestore.dart';
import 'package:justmusic/model/User.dart'; import 'package:justmusic/model/User.dart';
class UserMapper { class UserMapper {
static User toModel(DocumentSnapshot<Map<String, dynamic>> snapshot, static User toModel(DocumentSnapshot<Map<String, dynamic>> snapshot) {
SnapshotOptions? options) {
final data = snapshot.data(); final data = snapshot.data();
return User( return User(
snapshot.id, snapshot.id,
data?["pseudo"], data?["pseudo"],
data?["unique_id"], data?["unique_id"],
data?["country"] ?? "",
data?["mail"], data?["mail"],
data?["picture"], data?["picture"],
data?["followers"] ?? 0, List<String>.from(data?["followers"] as List),
data?["nbCapsules"] ?? 0, data?["nbCapsules"] ?? 0,
data?["followed"] ?? 0, List<String>.from(data?["followed"] as List));
data?['friends'] is List<User> ? List.from(data?['friends']) : []);
} }
/* /*
static Map<String, dynamic> toFirebase(User user) { static Map<String, dynamic> toFirebase(User user) {

@ -4,6 +4,7 @@ import 'package:google_fonts/google_fonts.dart';
import 'package:justmusic/values/constants.dart'; import 'package:justmusic/values/constants.dart';
import '../components/profile_list_component.dart'; import '../components/profile_list_component.dart';
import '../main.dart';
import '../model/User.dart'; import '../model/User.dart';
class AddFriendScreen extends StatefulWidget { class AddFriendScreen extends StatefulWidget {
@ -17,128 +18,14 @@ class _AddFriendScreenState extends State<AddFriendScreen> {
final ScrollController _scrollController = ScrollController(); final ScrollController _scrollController = ScrollController();
final TextEditingController _textEditingController = TextEditingController(); final TextEditingController _textEditingController = TextEditingController();
List<User> fakeList = [ List<User> _listUsers = [];
User(
"&", Future<void> updateList(String value) async {
"_pseudo", var newlistUsers = await MyApp.userViewModel.getUsersByUniqueId(value);
"_pseudo", setState(() {
"_country", _listUsers = newlistUsers;
"_mail", });
"https://firebasestorage.googleapis.com/v0/b/justmusic-435d5.appspot.com/o/RUiGpZ8AzCQPqiVJKwuQeIqiC4B2UYSIpWSnX4gJhZJzaN4q.jpg?alt=media&token=39baf86a-4d19-4534-b777-1a4feca67359", }
1,
12,
23, []),
User(
"&",
"_pseudo",
"_pseudo",
"_country",
"_mail",
"https://firebasestorage.googleapis.com/v0/b/justmusic-435d5.appspot.com/o/RUiGpZ8AzCQPqiVJKwuQeIqiC4B2bafPGRGLh2La72LkmQst.jpg?alt=media&token=ac1916f0-e08d-43bd-977a-2c2d94182609",
1,
12,
23, []),
User(
"&",
"_pseudo",
"_pseudo",
"_country",
"_mail",
"https://firebasestorage.googleapis.com/v0/b/justmusic-435d5.appspot.com/o/RUiGpZ8AzCQPqiVJKwuQeIqiC4B2bafPGRGLh2La72LkmQst.jpg?alt=media&token=ac1916f0-e08d-43bd-977a-2c2d94182609",
1,
12,
23, []),
User(
"&",
"_pseudo",
"_pseudo",
"_country",
"_mail",
"https://firebasestorage.googleapis.com/v0/b/justmusic-435d5.appspot.com/o/RUiGpZ8AzCQPqiVJKwuQeIqiC4B2bafPGRGLh2La72LkmQst.jpg?alt=media&token=ac1916f0-e08d-43bd-977a-2c2d94182609",
1,
12,
23, []),
User(
"&",
"_pseudo",
"_pseudo",
"_country",
"_mail",
"https://firebasestorage.googleapis.com/v0/b/justmusic-435d5.appspot.com/o/RUiGpZ8AzCQPqiVJKwuQeIqiC4B2bafPGRGLh2La72LkmQst.jpg?alt=media&token=ac1916f0-e08d-43bd-977a-2c2d94182609",
1,
12,
23, []),
User(
"&",
"_pseudo",
"_pseudo",
"_country",
"_mail",
"https://firebasestorage.googleapis.com/v0/b/justmusic-435d5.appspot.com/o/RUiGpZ8AzCQPqiVJKwuQeIqiC4B2bafPGRGLh2La72LkmQst.jpg?alt=media&token=ac1916f0-e08d-43bd-977a-2c2d94182609",
1,
12,
23, []),
User(
"&",
"_pseudo",
"_pseudo",
"_country",
"_mail",
"https://firebasestorage.googleapis.com/v0/b/justmusic-435d5.appspot.com/o/RUiGpZ8AzCQPqiVJKwuQeIqiC4B2bafPGRGLh2La72LkmQst.jpg?alt=media&token=ac1916f0-e08d-43bd-977a-2c2d94182609",
1,
12,
23, []),
User(
"&",
"_pseudo",
"_pseudo",
"_country",
"_mail",
"https://firebasestorage.googleapis.com/v0/b/justmusic-435d5.appspot.com/o/RUiGpZ8AzCQPqiVJKwuQeIqiC4B2bafPGRGLh2La72LkmQst.jpg?alt=media&token=ac1916f0-e08d-43bd-977a-2c2d94182609",
1,
12,
23, []),
User(
"&",
"_pseudo",
"_pseudo",
"_country",
"_mail",
"https://firebasestorage.googleapis.com/v0/b/justmusic-435d5.appspot.com/o/RUiGpZ8AzCQPqiVJKwuQeIqiC4B2bafPGRGLh2La72LkmQst.jpg?alt=media&token=ac1916f0-e08d-43bd-977a-2c2d94182609",
1,
12,
23, []),
User(
"&",
"_pseudo",
"_pseudo",
"_country",
"_mail",
"https://firebasestorage.googleapis.com/v0/b/justmusic-435d5.appspot.com/o/RUiGpZ8AzCQPqiVJKwuQeIqiC4B2bafPGRGLh2La72LkmQst.jpg?alt=media&token=ac1916f0-e08d-43bd-977a-2c2d94182609",
1,
12,
23, []),
User(
"&",
"_pseudo",
"_pseudo",
"_country",
"_mail",
"https://firebasestorage.googleapis.com/v0/b/justmusic-435d5.appspot.com/o/RUiGpZ8AzCQPqiVJKwuQeIqiC4B2bafPGRGLh2La72LkmQst.jpg?alt=media&token=ac1916f0-e08d-43bd-977a-2c2d94182609",
1,
12,
23, []),
User(
"&",
"_pseudo",
"_pseudo",
"_country",
"_mail",
"https://firebasestorage.googleapis.com/v0/b/justmusic-435d5.appspot.com/o/RUiGpZ8AzCQPqiVJKwuQeIqiC4B2bafPGRGLh2La72LkmQst.jpg?alt=media&token=ac1916f0-e08d-43bd-977a-2c2d94182609",
1,
12,
23, []),
];
Future<void> resetFullScreen() async { Future<void> resetFullScreen() async {
await SystemChannels.platform.invokeMethod<void>( await SystemChannels.platform.invokeMethod<void>(
@ -202,8 +89,12 @@ class _AddFriendScreenState extends State<AddFriendScreen> {
keyboardAppearance: Brightness.dark, keyboardAppearance: Brightness.dark,
onEditingComplete: resetFullScreen, onEditingComplete: resetFullScreen,
onSubmitted: (value) async { onSubmitted: (value) async {
if (_textEditingController.text.isEmpty) { if (_textEditingController.text.isNotEmpty) {
print("search"); updateList(value);
} else {
setState(() {
_listUsers = [];
});
} }
}, },
cursorColor: Colors.white, cursorColor: Colors.white,
@ -235,12 +126,12 @@ class _AddFriendScreenState extends State<AddFriendScreen> {
behavior: const ScrollBehavior().copyWith(scrollbars: true), behavior: const ScrollBehavior().copyWith(scrollbars: true),
child: ListView.builder( child: ListView.builder(
physics: const BouncingScrollPhysics(decelerationRate: ScrollDecelerationRate.fast), physics: const BouncingScrollPhysics(decelerationRate: ScrollDecelerationRate.fast),
itemCount: fakeList.length, itemCount: _listUsers.length,
itemBuilder: (BuildContext context, int index) { itemBuilder: (BuildContext context, int index) {
return InkWell( return InkWell(
child: Padding( child: Padding(
padding: EdgeInsets.fromLTRB(20, 0, 20, 20), padding: const EdgeInsets.fromLTRB(20, 0, 20, 20),
child: ProfileListComponent(user: fakeList[index])), child: ProfileListComponent(user: _listUsers[index])),
); );
}, },
))) )))

@ -28,6 +28,7 @@ class _FeedScreenState extends State<FeedScreen>
@override @override
void initState() { void initState() {
super.initState(); super.initState();
MyApp.postViewModel.getPostsFriends();
friendFeed = MyApp.postViewModel.postsFriends; friendFeed = MyApp.postViewModel.postsFriends;
MyApp.postViewModel.getBestPosts(); MyApp.postViewModel.getBestPosts();
discoveryFeed = MyApp.postViewModel.bestPosts; discoveryFeed = MyApp.postViewModel.bestPosts;

@ -0,0 +1,114 @@
import 'package:flutter/Material.dart';
import 'package:lottie/lottie.dart';
import '../values/constants.dart';
class LaunchingRocketScreen extends StatefulWidget {
const LaunchingRocketScreen({super.key});
@override
State<LaunchingRocketScreen> createState() => _LaunchingRocketScreenState();
}
class _LaunchingRocketScreenState extends State<LaunchingRocketScreen> with TickerProviderStateMixin {
late final AnimationController _controller;
late AnimationController _controller2;
late Animation<double> _animation;
@override
initState() {
_controller = AnimationController(vsync: this, duration: Duration(seconds: 3));
_controller2 = AnimationController(
vsync: this,
duration: Duration(milliseconds: 800),
);
final CurvedAnimation curve = CurvedAnimation(parent: _controller2, curve: Curves.easeIn);
_animation = Tween<double>(
begin: 0,
end: 1,
).animate(curve);
_controller2.addStatusListener((status) {
print("cccccccc");
if (status == AnimationStatus.completed) {
Navigator.of(context).popUntil((route) => route.settings.name == '/feed');
}
});
super.initState();
}
@override
void dispose() {
_controller.dispose();
_controller2.dispose();
super.dispose();
}
@override
Widget build(BuildContext context) {
bool animationCompleted = false;
return Scaffold(
backgroundColor: primaryColor,
body: Container(
width: double.infinity,
height: double.infinity,
child: Stack(
children: [
Lottie.asset(
'assets/animations/rocket.json',
height: 600,
frameRate: FrameRate(60),
fit: BoxFit.contain,
controller: _controller,
onLoaded: (composition) {
_controller
..duration = composition.duration
..forward().whenComplete(() {
setState(() {
animationCompleted = true;
});
_controller2.forward();
});
},
),
Center(
child: AnimatedBuilder(
animation: _animation,
builder: (context, child) {
double circlePosition = MediaQuery.of(context).size.height * _animation.value;
return CustomPaint(
painter: CirclePainter(circlePosition),
);
},
)),
],
),
),
);
}
}
class CirclePainter extends CustomPainter {
final double circlePosition;
CirclePainter(this.circlePosition);
@override
void paint(Canvas canvas, Size size) {
Paint paint = Paint()..color = Colors.white;
double radius = 50 * circlePosition; // Remplacez par le rayon souhaité de votre cercle
Offset center = Offset(size.width / 2, size.height / 2);
canvas.drawCircle(center, radius, paint);
}
@override
bool shouldRepaint(CustomPainter oldDelegate) {
return true;
}
}

@ -19,8 +19,7 @@ class PostScreen extends StatefulWidget {
State<PostScreen> createState() => _PostScreenState(); State<PostScreen> createState() => _PostScreenState();
} }
class _PostScreenState extends State<PostScreen> class _PostScreenState extends State<PostScreen> with SingleTickerProviderStateMixin {
with SingleTickerProviderStateMixin {
final scrollController = ScrollController(); final scrollController = ScrollController();
late AnimationController _controller; late AnimationController _controller;
@ -82,25 +81,22 @@ class _PostScreenState extends State<PostScreen>
isScrollControlled: true, isScrollControlled: true,
context: context, context: context,
shape: const RoundedRectangleBorder( shape: const RoundedRectangleBorder(
borderRadius: BorderRadius.only( borderRadius: BorderRadius.only(topLeft: Radius.circular(20), topRight: Radius.circular(20))),
topLeft: Radius.circular(20), topRight: Radius.circular(20))),
builder: ((context) { builder: ((context) {
return ClipRRect( return ClipRRect(
borderRadius: BorderRadius.only( borderRadius: BorderRadius.only(topLeft: Radius.circular(20), topRight: Radius.circular(20)),
topLeft: Radius.circular(20), topRight: Radius.circular(20)),
child: SearchSongScreen(callback: _selectMusic)); child: SearchSongScreen(callback: _selectMusic));
}), }),
); );
} }
handleSubmit() async { handleSubmit() async {
await MyApp.postViewModel.addPost( MyApp.postViewModel.addPost(description, (selectedMusic?.id)!, selectedImage, selectedCity);
description, (selectedMusic?.id)!, selectedImage, selectedCity);
quit(); quit();
} }
quit() { quit() {
Navigator.pop(context); Navigator.pushNamed(context, '/launchingRocket');
} }
@override @override
@ -113,10 +109,7 @@ class _PostScreenState extends State<PostScreen>
preferredSize: Size(double.infinity, 80), preferredSize: Size(double.infinity, 80),
child: SafeArea( child: SafeArea(
child: Padding( child: Padding(
padding: EdgeInsets.only( padding: EdgeInsets.only(left: defaultPadding, right: defaultPadding, top: defaultPadding),
left: defaultPadding,
right: defaultPadding,
top: defaultPadding),
child: Row( child: Row(
children: [BackButtonComponent()], children: [BackButtonComponent()],
), ),
@ -124,8 +117,7 @@ class _PostScreenState extends State<PostScreen>
), ),
), ),
body: Container( body: Container(
padding: padding: const EdgeInsets.only(left: defaultPadding, right: defaultPadding),
const EdgeInsets.only(left: defaultPadding, right: defaultPadding),
width: double.infinity, width: double.infinity,
height: double.infinity, height: double.infinity,
decoration: const BoxDecoration( decoration: const BoxDecoration(

@ -15,15 +15,12 @@ class AuthService {
final user = <String, dynamic>{ final user = <String, dynamic>{
"mail": email, "mail": email,
"pseudo": pseudo, "pseudo": pseudo,
"phone_number": "",
"unique_id": uniqueId, "unique_id": uniqueId,
"followed": 0, "followed": [],
"nbCapsules": 0, "nbCapsules": 0,
"followers": 0, "followers": [],
"picture": "picture":
"https://firebasestorage.googleapis.com/v0/b/justmusic-435d5.appspot.com/o/justMusicDefaultImage.png?alt=media&token=020d0fcb-b7df-4d4d-b380-e99597293fcc", "https://firebasestorage.googleapis.com/v0/b/justmusic-435d5.appspot.com/o/justMusicDefaultImage.png?alt=media&token=020d0fcb-b7df-4d4d-b380-e99597293fcc"
"friends": [],
"comments": []
}; };
MyApp.db MyApp.db
@ -52,10 +49,10 @@ class AuthService {
final QuerySnapshot querySnapshot = final QuerySnapshot querySnapshot =
await usersCollection.where('pseudo', isEqualTo: pseudo).get(); await usersCollection.where('pseudo', isEqualTo: pseudo).get();
for (final doc in querySnapshot.docs) { querySnapshot.docs.forEach((snapshot) {
suffix++; suffix++;
uniqueId = '$pseudo#${suffix.toString().padLeft(4, '0')}'; uniqueId = '$pseudo#${suffix.toString().padLeft(4, '0')}';
} });
return uniqueId; return uniqueId;
} }

@ -1,15 +1,14 @@
import 'dart:convert';
import 'dart:io'; import 'dart:io';
import 'package:cloud_firestore/cloud_firestore.dart'; import 'package:cloud_firestore/cloud_firestore.dart';
import 'package:intl/intl.dart';
import 'package:tuple/tuple.dart'; import 'package:tuple/tuple.dart';
import 'package:firebase_storage/firebase_storage.dart'; import 'package:firebase_storage/firebase_storage.dart';
import '../main.dart'; import '../main.dart';
class PostService { class PostService {
createPost(String? description, String idMusic, File? image, Tuple2<String, String>? location) async { createPost(String? description, String idMusic, File? image,
Tuple2<String, String>? location) async {
var id = MyApp.userViewModel.userCurrent.id; var id = MyApp.userViewModel.userCurrent.id;
final post = <String, dynamic>{ final post = <String, dynamic>{
"user_id": id, "user_id": id,
@ -43,13 +42,14 @@ class PostService {
deletePost() {} deletePost() {}
getPostsById(String id) {} Future<List<QueryDocumentSnapshot<Map<String, dynamic>>>> getPopularPosts(
{int limit = 10, int offset = 0}) async {
Future<List<QueryDocumentSnapshot<Map<String, dynamic>>>> getPopularPosts({int limit = 10, int offset = 0}) async {
DateTime twentyFourHoursAgo = DateTime.now().subtract(Duration(hours: 24)); DateTime twentyFourHoursAgo = DateTime.now().subtract(Duration(hours: 24));
Timestamp twentyFourHoursAgoTimestamp = Timestamp.fromDate(twentyFourHoursAgo); Timestamp twentyFourHoursAgoTimestamp =
Timestamp.fromDate(twentyFourHoursAgo);
QuerySnapshot<Map<String, dynamic>> response = await FirebaseFirestore.instance QuerySnapshot<Map<String, dynamic>> response = await FirebaseFirestore
.instance
.collection("posts") .collection("posts")
.where("date", isGreaterThan: twentyFourHoursAgoTimestamp) .where("date", isGreaterThan: twentyFourHoursAgoTimestamp)
.limit(limit) .limit(limit)
@ -62,16 +62,39 @@ class PostService {
return filteredPosts; return filteredPosts;
} }
Future<List<QueryDocumentSnapshot<Map<String, dynamic>>>> getPostsFriends(
{int limit = 10, int offset = 0}) async {
var response = await FirebaseFirestore
.instance
.collection("posts")
.where("user_id", whereIn: MyApp.userViewModel.userCurrent.followed)
.limit(limit)
.get();
response.docs.sort((a, b) {
DateTime aDate = a.data()['date'].toDate();
DateTime bDate = b.data()['date'].toDate();
return bDate.compareTo(aDate);
});
return response.docs;
}
Future<bool> getAvailable(String idUser) async { Future<bool> getAvailable(String idUser) async {
DateTime today = DateTime.now(); DateTime today = DateTime.now();
QuerySnapshot<Map<String, dynamic>> response = QuerySnapshot<Map<String, dynamic>> response = await FirebaseFirestore
await FirebaseFirestore.instance.collection("posts").where("user_id", isEqualTo: idUser).get(); .instance
.collection("posts")
.where("user_id", isEqualTo: idUser)
.get();
// Utiliser any() pour vérifier s'il y a au moins un document avec la date d'aujourd'hui
bool isTodayAvailable = response.docs.any((doc) { bool isTodayAvailable = response.docs.any((doc) {
DateTime date = doc["date"].toDate(); // Assuming the field name is "date" DateTime date = doc["date"].toDate(); // Assuming the field name is "date"
return date.day == today.day && date.month == today.month && date.year == today.year; return date.day == today.day &&
date.month == today.month &&
date.year == today.year;
}); });
return !isTodayAvailable; return !isTodayAvailable;

@ -1,15 +1,47 @@
import 'package:cloud_firestore/cloud_firestore.dart'; import 'package:cloud_firestore/cloud_firestore.dart';
import '../model/User.dart';
import '../main.dart'; import '../main.dart';
class UserService { class UserService {
acceptFriend(User user, String idFriend) { Future<List<QueryDocumentSnapshot<Map<String, dynamic>>>> getUsersByIdUnique(String uniqueId) async {
MyApp.db.collection("users").doc(user.id).update({ QuerySnapshot<Map<String, dynamic>> response = await FirebaseFirestore.instance
"friends": FieldValue.arrayUnion([idFriend]) .collection("users")
}); .where("unique_id", isGreaterThanOrEqualTo: uniqueId)
MyApp.db.collection("users").doc(idFriend).update({ .where("unique_id", isLessThanOrEqualTo: uniqueId + "zzzzzzzzzzzzzzzzzzzzzzzzzzzz")
"friends": FieldValue.arrayUnion([user.id]) .limit(20)
}); .get();
var users = response.docs.where((doc) {
String id = doc["unique_id"];
return id != MyApp.userViewModel.userCurrent.uniquePseudo;
}).toList();
return users;
}
addOrDeleteFriend(String id) async {
var userRef = MyApp.db.collection("users").doc(MyApp.userViewModel.userCurrent.id);
var actionUserRef = MyApp.db.collection("users").doc(id);
if (MyApp.userViewModel.isFriend(id)) {
await MyApp.db.runTransaction((transaction) async {
transaction.update(userRef, {
'followed': FieldValue.arrayRemove([id])
});
transaction.update(actionUserRef, {
'followers': FieldValue.arrayRemove([id])
});
});
MyApp.userViewModel.userCurrent.followed.remove(id);
} else {
await MyApp.db.runTransaction((transaction) async {
transaction.update(userRef, {
'followed': FieldValue.arrayUnion([id])
});
transaction.update(actionUserRef, {
'followers': FieldValue.arrayUnion([id])
});
});
MyApp.userViewModel.userCurrent.followed.add(id);
}
} }
} }

@ -27,8 +27,26 @@ class PostViewModel {
await _postService.createPost(description, idMusic, image, location); await _postService.createPost(description, idMusic, image, location);
} }
List<Post> getPostsFriends() { Future<List<Post>> getPostsFriends() async {
throw new Error(); try {
_postsFriends = [];
var responseData = await _postService.getPostsFriends();
List<String> ids = [];
var postsFutures = responseData.map((value) {
ids.add(value.data()["song_id"]);
return PostMapper.toModel(value);
}).toList();
_postsFriends = await Future.wait(postsFutures);
List<Music> musics = await MyApp.musicViewModel.getMusicsWithIds(ids);
for (int i = 0; i < _postsFriends.length; i++) {
_postsFriends[i].music = musics[i];
}
return _postsFriends;
} catch (e) {
print(e);
_postsFriends = [];
return [];
}
} }
List<Post> getMorePostsFriends() { List<Post> getMorePostsFriends() {

@ -1,5 +1,6 @@
import 'package:firebase_auth/firebase_auth.dart' as firebase_auth; import 'package:firebase_auth/firebase_auth.dart' as firebase_auth;
import 'package:justmusic/services/AuthService.dart'; import 'package:justmusic/services/AuthService.dart';
import 'package:justmusic/services/UserService.dart';
import '../model/User.dart'; import '../model/User.dart';
import '../model/mapper/UserMapper.dart'; import '../model/mapper/UserMapper.dart';
@ -8,6 +9,7 @@ import '../main.dart';
class UserViewModel { class UserViewModel {
late User _userCurrent; late User _userCurrent;
final AuthService _authService = AuthService(); final AuthService _authService = AuthService();
final UserService _userService = UserService();
User get userCurrent => _userCurrent; User get userCurrent => _userCurrent;
@ -20,17 +22,14 @@ class UserViewModel {
// Methods // Methods
Future<User?> getUser(String id) async { Future<User?> getUser(String id) async {
final user = await MyApp.db.collection("users").doc(id).get(); final user = await MyApp.db.collection("users").doc(id).get();
return UserMapper.toModel(user, null); return UserMapper.toModel(user);
} }
login(String pseudo, String password) async { login(String pseudo, String password) async {
try { try {
await _authService.login(pseudo, password); await _authService.login(pseudo, password);
final user = await MyApp.db final user = await MyApp.db.collection("users").doc(firebase_auth.FirebaseAuth.instance.currentUser?.uid).get();
.collection("users") User data = UserMapper.toModel(user);
.doc(firebase_auth.FirebaseAuth.instance.currentUser?.uid)
.get();
User data = UserMapper.toModel(user, null);
_userCurrent = data; _userCurrent = data;
} catch (e) { } catch (e) {
rethrow; rethrow;
@ -42,6 +41,16 @@ class UserViewModel {
return alphaNumericRegExp.hasMatch(input); return alphaNumericRegExp.hasMatch(input);
} }
updateUserCurrent() async {
try {
final user = await MyApp.db.collection("users").doc(firebase_auth.FirebaseAuth.instance.currentUser?.uid).get();
User data = UserMapper.toModel(user);
_userCurrent = data;
} catch (e) {
print(e);
}
}
register(String pseudo, String password, String email) async { register(String pseudo, String password, String email) async {
if (!_isAlphaNumeric(pseudo)) { if (!_isAlphaNumeric(pseudo)) {
throw ("Le pseudo doit contenir seulement des lettres et des chiffres"); throw ("Le pseudo doit contenir seulement des lettres et des chiffres");
@ -49,18 +58,40 @@ class UserViewModel {
try { try {
await _authService.register(pseudo.toLowerCase(), email, password); await _authService.register(pseudo.toLowerCase(), email, password);
final user = await MyApp.db final user = await MyApp.db.collection("users").doc(firebase_auth.FirebaseAuth.instance.currentUser?.uid).get();
.collection("users") User data = UserMapper.toModel(user);
.doc(firebase_auth.FirebaseAuth.instance.currentUser?.uid)
.get();
User data = UserMapper.toModel(user, null);
_userCurrent = data; _userCurrent = data;
} catch (e) { } catch (e) {
rethrow; rethrow;
} }
} }
Future<List<User>> getUsersByUniqueId(String uniqueId) async {
try {
var response = await _userService.getUsersByIdUnique(uniqueId.toLowerCase());
var users = response.map((value) {
return UserMapper.toModel(value);
}).toList();
return users;
} catch (e) {
return [];
}
}
addOrDeleteFriend(String id) async {
try {
await _userService.addOrDeleteFriend(id);
} catch (e) {
print(e);
rethrow;
}
}
logout() { logout() {
_authService.signOut(); _authService.signOut();
} }
bool isFriend(String id) {
return _userCurrent.followed.contains(id);
}
} }

Loading…
Cancel
Save