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 {
final image = await ImagePicker().pickImage(
source: source,
imageQuality: 10
imageQuality: 20
);
if (image == null) return;
final imageTemp = File(image.path);

@ -1,5 +1,7 @@
import 'package:flutter/Material.dart';
import 'package:flutter_screenutil/flutter_screenutil.dart';
import 'package:google_fonts/google_fonts.dart';
import '../main.dart';
import '../model/User.dart';
import '../values/constants.dart';
@ -12,10 +14,11 @@ class ProfileListComponent extends StatefulWidget {
}
class _ProfileListComponentState extends State<ProfileListComponent> {
bool clicked = false;
late bool clicked;
@override
Widget build(BuildContext context) {
clicked = MyApp.userViewModel.isFriend(widget.user.id);
return Container(
padding: const EdgeInsets.only(bottom: 5),
child: Row(
@ -36,22 +39,38 @@ class _ProfileListComponentState extends State<ProfileListComponent> {
crossAxisAlignment: CrossAxisAlignment.start,
mainAxisAlignment: MainAxisAlignment.center,
children: [
ScrollConfiguration(
behavior: ScrollBehavior().copyWith(scrollbars: false),
child: Text(
widget.user.uniquePseudo,
Text(
widget.user.pseudo,
style: GoogleFonts.plusJakartaSans(fontSize: 16, color: Colors.white, fontWeight: FontWeight.w700),
overflow: TextOverflow.ellipsis,
maxLines: 1,
),
Row(
crossAxisAlignment: CrossAxisAlignment.end,
children: [
Text(
widget.user.uniquePseudo,
overflow: TextOverflow.ellipsis,
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)),
),
ScrollConfiguration(
behavior: ScrollBehavior().copyWith(scrollbars: false),
child: Text(
widget.user.pseudo,
"Vous suit",
overflow: TextOverflow.ellipsis,
style: GoogleFonts.plusJakartaSans(color: Colors.grey, fontWeight: FontWeight.w400),
))
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,
child: InkWell(
splashColor: Colors.white.withOpacity(0.3),
onTap: () {
setState(() {
clicked = !clicked;
});
onTap: () async {
await MyApp.userViewModel.addOrDeleteFriend(widget.user.id);
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(
padding: EdgeInsets.fromLTRB(28, 7, 28, 7),
@ -81,10 +110,19 @@ class _ProfileListComponentState extends State<ProfileListComponent> {
color: primaryColor,
child: InkWell(
splashColor: Colors.white.withOpacity(0.3),
onTap: () {
setState(() {
clicked = !clicked;
});
onTap: () async {
await MyApp.userViewModel.addOrDeleteFriend(widget.user.id);
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(
padding: EdgeInsets.fromLTRB(25, 7, 25, 7),

@ -20,7 +20,7 @@ class StatisticsComponent extends StatelessWidget {
child: Column(
children: [
AutoSizeText(
user.followed.toString(),
user.followed.length.toString(),
style: GoogleFonts.plusJakartaSans(
color: Colors.white,
fontWeight: FontWeight.bold,
@ -40,7 +40,7 @@ class StatisticsComponent extends StatelessWidget {
mainAxisSize: MainAxisSize.min,
children: [
AutoSizeText(
user.followers.toString(),
user.followers.length.toString(),
style: GoogleFonts.plusJakartaSans(
color: Colors.white,
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);
void actionSurBouton() {
void actionSurBouton() async {
widget.callback(choice);
MyApp.postViewModel.getBestPosts();
await MyApp.postViewModel.getBestPosts();
await MyApp.postViewModel.getPostsFriends();
}
@override
@ -138,10 +139,7 @@ class _TopNavBarComponentState extends State<TopNavBarComponent> with TickerProv
child: GestureDetector(
behavior: HitTestBehavior.translucent,
onTap: () async {
bool returnFromOtherPage = await Navigator.of(context).push(routeAddFriend());
if (returnFromOtherPage == true) {
checkAvailable();
}
Navigator.of(context).push(routeAddFriend());
},
child: const Icon(
Icons.person_add_alt_1_rounded,
@ -159,7 +157,9 @@ class _TopNavBarComponentState extends State<TopNavBarComponent> with TickerProv
enableLongTapRepeatEvent: false,
longTapRepeatDuration: const Duration(milliseconds: 100),
begin: 1.0,
onTap: () {},
onTap: () {
checkAvailable();
},
end: 0.97,
beginDuration: const Duration(milliseconds: 70),
endDuration: const Duration(milliseconds: 100),
@ -237,19 +237,17 @@ class _TopNavBarComponentState extends State<TopNavBarComponent> with TickerProv
flex: 1,
child: GestureDetector(
onTap: () async {
bool returnFromOtherPage = await Navigator.of(context).push(routeProfile());
if (returnFromOtherPage == true) {
checkAvailable();
}
await MyApp.userViewModel.updateUserCurrent();
Navigator.of(context).push(routeProfile());
},
child: ClipOval(
child: SizedBox.fromSize(
// Image radius
child: Image(
image: NetworkImage(MyApp.userViewModel.userCurrent.pp),
child: FadeInImage.assetNetwork(
placeholder: 'assets/images/loadingPlaceholder.gif',
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/feed_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/profile_screen.dart';
import 'package:justmusic/screens/registration_screen.dart';
@ -53,6 +54,7 @@ class MyApp extends StatelessWidget {
'/profile': (context) => const ProfileScreen(),
'/explanation': (context) => const ExplanationsScreen(),
'/addFriend': (context) => const AddFriendScreen(),
'/launchingRocket': (context) => const LaunchingRocketScreen(),
},
debugShowCheckedModeBanner: false,
theme: ThemeData(

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

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

@ -2,20 +2,17 @@ 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) {
static User toModel(DocumentSnapshot<Map<String, dynamic>> snapshot) {
final data = snapshot.data();
return User(
snapshot.id,
data?["pseudo"],
data?["unique_id"],
data?["country"] ?? "",
data?["mail"],
data?["picture"],
data?["followers"] ?? 0,
List<String>.from(data?["followers"] as List),
data?["nbCapsules"] ?? 0,
data?["followed"] ?? 0,
data?['friends'] is List<User> ? List.from(data?['friends']) : []);
List<String>.from(data?["followed"] as List));
}
/*
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 '../components/profile_list_component.dart';
import '../main.dart';
import '../model/User.dart';
class AddFriendScreen extends StatefulWidget {
@ -17,128 +18,14 @@ class _AddFriendScreenState extends State<AddFriendScreen> {
final ScrollController _scrollController = ScrollController();
final TextEditingController _textEditingController = TextEditingController();
List<User> fakeList = [
User(
"&",
"_pseudo",
"_pseudo",
"_country",
"_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, []),
];
List<User> _listUsers = [];
Future<void> updateList(String value) async {
var newlistUsers = await MyApp.userViewModel.getUsersByUniqueId(value);
setState(() {
_listUsers = newlistUsers;
});
}
Future<void> resetFullScreen() async {
await SystemChannels.platform.invokeMethod<void>(
@ -202,8 +89,12 @@ class _AddFriendScreenState extends State<AddFriendScreen> {
keyboardAppearance: Brightness.dark,
onEditingComplete: resetFullScreen,
onSubmitted: (value) async {
if (_textEditingController.text.isEmpty) {
print("search");
if (_textEditingController.text.isNotEmpty) {
updateList(value);
} else {
setState(() {
_listUsers = [];
});
}
},
cursorColor: Colors.white,
@ -235,12 +126,12 @@ class _AddFriendScreenState extends State<AddFriendScreen> {
behavior: const ScrollBehavior().copyWith(scrollbars: true),
child: ListView.builder(
physics: const BouncingScrollPhysics(decelerationRate: ScrollDecelerationRate.fast),
itemCount: fakeList.length,
itemCount: _listUsers.length,
itemBuilder: (BuildContext context, int index) {
return InkWell(
child: Padding(
padding: EdgeInsets.fromLTRB(20, 0, 20, 20),
child: ProfileListComponent(user: fakeList[index])),
padding: const EdgeInsets.fromLTRB(20, 0, 20, 20),
child: ProfileListComponent(user: _listUsers[index])),
);
},
)))

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

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

@ -1,15 +1,14 @@
import 'dart:convert';
import 'dart:io';
import 'package:cloud_firestore/cloud_firestore.dart';
import 'package:intl/intl.dart';
import 'package:tuple/tuple.dart';
import 'package:firebase_storage/firebase_storage.dart';
import '../main.dart';
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;
final post = <String, dynamic>{
"user_id": id,
@ -43,13 +42,14 @@ class PostService {
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));
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")
.where("date", isGreaterThan: twentyFourHoursAgoTimestamp)
.limit(limit)
@ -62,16 +62,39 @@ class PostService {
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 {
DateTime today = DateTime.now();
QuerySnapshot<Map<String, dynamic>> response =
await FirebaseFirestore.instance.collection("posts").where("user_id", isEqualTo: idUser).get();
QuerySnapshot<Map<String, dynamic>> response = await FirebaseFirestore
.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) {
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;

@ -1,15 +1,47 @@
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])
Future<List<QueryDocumentSnapshot<Map<String, dynamic>>>> getUsersByIdUnique(String uniqueId) async {
QuerySnapshot<Map<String, dynamic>> response = await FirebaseFirestore.instance
.collection("users")
.where("unique_id", isGreaterThanOrEqualTo: uniqueId)
.where("unique_id", isLessThanOrEqualTo: uniqueId + "zzzzzzzzzzzzzzzzzzzzzzzzzzzz")
.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.db.collection("users").doc(idFriend).update({
"friends": FieldValue.arrayUnion([user.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);
}
List<Post> getPostsFriends() {
throw new Error();
Future<List<Post>> getPostsFriends() async {
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() {

@ -1,5 +1,6 @@
import 'package:firebase_auth/firebase_auth.dart' as firebase_auth;
import 'package:justmusic/services/AuthService.dart';
import 'package:justmusic/services/UserService.dart';
import '../model/User.dart';
import '../model/mapper/UserMapper.dart';
@ -8,6 +9,7 @@ import '../main.dart';
class UserViewModel {
late User _userCurrent;
final AuthService _authService = AuthService();
final UserService _userService = UserService();
User get userCurrent => _userCurrent;
@ -20,17 +22,14 @@ class UserViewModel {
// Methods
Future<User?> getUser(String id) async {
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 {
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);
final user = await MyApp.db.collection("users").doc(firebase_auth.FirebaseAuth.instance.currentUser?.uid).get();
User data = UserMapper.toModel(user);
_userCurrent = data;
} catch (e) {
rethrow;
@ -42,6 +41,16 @@ class UserViewModel {
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 {
if (!_isAlphaNumeric(pseudo)) {
throw ("Le pseudo doit contenir seulement des lettres et des chiffres");
@ -49,18 +58,40 @@ class UserViewModel {
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);
final user = await MyApp.db.collection("users").doc(firebase_auth.FirebaseAuth.instance.currentUser?.uid).get();
User data = UserMapper.toModel(user);
_userCurrent = data;
} catch (e) {
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() {
_authService.signOut();
}
bool isFriend(String id) {
return _userCurrent.followed.contains(id);
}
}

Loading…
Cancel
Save