Merge branch 'PROFIL_PAGE_LDE'
continuous-integration/drone/push Build is passing Details

FAVORITE_MUSICS_EKA^2
Lucas Delanier 2 years ago
commit 9c3f3024cc

@ -1,7 +1,7 @@
<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">

@ -44,7 +44,7 @@ class _ButtonPlayComponentState extends State<ButtonPlayComponent> {
child: Icon( child: Icon(
isPlaying ? Icons.pause_circle : Icons.play_circle, isPlaying ? Icons.pause_circle : Icons.play_circle,
color: Colors.white, color: Colors.white,
size: 53, size: 45,
), ),
)); ));
} }

@ -1,8 +1,6 @@
import 'dart:io'; import 'dart:io';
import 'package:animated_appear/animated_appear.dart'; import 'package:animated_appear/animated_appear.dart';
import 'package:auto_size_text/auto_size_text.dart'; import 'package:auto_size_text/auto_size_text.dart';
import 'package:circular_reveal_animation/circular_reveal_animation.dart';
import 'package:flutter/Material.dart'; import 'package:flutter/Material.dart';
import 'package:flutter/cupertino.dart'; import 'package:flutter/cupertino.dart';
import 'package:flutter/services.dart'; import 'package:flutter/services.dart';
@ -143,8 +141,14 @@ class _EditablePostComponentState extends State<EditablePostComponent> with Tick
// implement image // implement image
child: widget.music == null child: widget.music == null
? Container( ? Container(
color: grayColor,
width: double.infinity, width: double.infinity,
child: Center(
child: Icon(
Icons.headphones,
color: grayColor.withOpacity(0.4),
size: 150,
),
),
) )
: Image( : Image(
image: NetworkImage(widget.music?.cover ?? ""), image: NetworkImage(widget.music?.cover ?? ""),

@ -0,0 +1,52 @@
import 'package:flutter/Material.dart';
import 'package:google_fonts/google_fonts.dart';
import '../values/constants.dart';
class LittleCapsule extends StatelessWidget {
final bool isEmpty;
final DateTime date;
const LittleCapsule({super.key, required this.isEmpty, required this.date});
@override
Widget build(BuildContext context) {
if (isEmpty) {
return Flexible(
child: Container(
constraints: BoxConstraints(maxWidth: 45, maxHeight: 45),
decoration: BoxDecoration(
color: searchBarColor,
borderRadius: BorderRadius.circular(5),
border: Border.all(color: Color(0xFF282828), width: 1),
),
child: const Center(
child: Icon(
Icons.rocket_launch,
color: Color(0xFF464646),
size: 18,
),
),
),
);
}
return Flexible(
child: Container(
constraints: BoxConstraints(maxWidth: 45, maxHeight: 45),
decoration: BoxDecoration(
gradient: LinearGradient(
colors: [bgModal, bgModal.withOpacity(0)],
begin: Alignment.topCenter,
end: Alignment.bottomCenter,
stops: [0, 1]),
borderRadius: BorderRadius.circular(5),
),
child: Center(
child: Text(
date.day.toString(),
style: GoogleFonts.plusJakartaSans(color: Color(0xFF464646), fontWeight: FontWeight.w800, fontSize: 17),
),
),
),
);
}
}

@ -3,6 +3,7 @@ import 'package:flutter/material.dart';
import 'package:flutter_screenutil/flutter_screenutil.dart'; import 'package:flutter_screenutil/flutter_screenutil.dart';
import 'package:google_fonts/google_fonts.dart'; import 'package:google_fonts/google_fonts.dart';
import 'package:gradient_borders/box_borders/gradient_box_border.dart'; import 'package:gradient_borders/box_borders/gradient_box_border.dart';
import 'package:justmusic/components/profil_picture_component.dart';
import 'package:text_scroll/text_scroll.dart'; import 'package:text_scroll/text_scroll.dart';
import 'package:zoom_tap_animation/zoom_tap_animation.dart'; import 'package:zoom_tap_animation/zoom_tap_animation.dart';
@ -40,212 +41,14 @@ class _PostComponentState extends State<PostComponent> with TickerProviderStateM
Widget build(BuildContext context) { Widget build(BuildContext context) {
return GestureDetector( return GestureDetector(
onTap: switchChoice, onTap: switchChoice,
child: LayoutBuilder( child: SizedBox(
builder: (BuildContext context, BoxConstraints constraints) {
if (widget.callback == null) {
return SizedBox(
width: double.infinity, width: double.infinity,
child: Column( child: Column(
children: [ children: [
Row( Row(
crossAxisAlignment: CrossAxisAlignment.end, crossAxisAlignment: CrossAxisAlignment.end,
children: [ children: [
ClipOval( ProfilPictureComponent(user: widget.post.user),
child: SizedBox.fromSize(
// Image radius
child: Image(
image: NetworkImage(widget.post.user.pp),
width: 40,
),
),
),
Expanded(
flex: 8,
child: Padding(
padding: const EdgeInsets.only(left: 10),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
widget.post.user.pseudo,
style: GoogleFonts.plusJakartaSans(color: Colors.white, fontWeight: FontWeight.w600),
),
widget.post.location.item2 != null
? Text(
"${widget.post.location.item1}, ${widget.post.location.item2}",
style: GoogleFonts.plusJakartaSans(
color: Colors.white.withOpacity(0.4),
fontWeight: FontWeight.w300,
fontSize: 13),
)
: Text(
"",
style: GoogleFonts.plusJakartaSans(
color: Colors.white.withOpacity(0.4),
fontWeight: FontWeight.w300,
fontSize: 13),
)
],
),
),
),
DateTime(today.year, today.month, today.day).isAtSameMomentAs(
DateTime(widget.post.date.year, widget.post.date.month, widget.post.date.day))
? Text(
"Aujourd'hui, ${widget.post.date.hour}:${widget.post.date.minute}",
style: GoogleFonts.plusJakartaSans(
color: Colors.white.withOpacity(0.4), fontWeight: FontWeight.w300, fontSize: 13),
)
: Text(
"${widget.post.date.day}/${widget.post.date.month}/${widget.post.date.year}-${widget.post.date.hour}:${widget.post.date.minute}",
style: GoogleFonts.plusJakartaSans(
color: Colors.white.withOpacity(0.4), fontWeight: FontWeight.w300, fontSize: 13),
),
],
),
SizedBox(height: 10),
ZoomTapAnimation(
onTap: () {
if (widget.post.selfie != null) {
switchChoice();
}
},
enableLongTapRepeatEvent: false,
longTapRepeatDuration: const Duration(milliseconds: 100),
begin: 1.0,
end: 0.99,
beginDuration: const Duration(milliseconds: 70),
endDuration: const Duration(milliseconds: 100),
beginCurve: Curves.decelerate,
endCurve: Curves.easeInOutSine,
child: AspectRatio(
aspectRatio: 1 / 1,
child: Container(
decoration: BoxDecoration(
// add border
border: const GradientBoxBorder(
gradient: LinearGradient(colors: [
Colors.transparent,
Color(0xFF323232),
], begin: Alignment.topCenter, end: Alignment.bottomCenter),
width: 2.5,
),
// set border radius
borderRadius: BorderRadius.circular(20),
),
child: ClipRRect(
borderRadius: BorderRadius.circular(18),
// implement image
child: Stack(
alignment: Alignment.bottomCenter,
children: [
Image(
image: NetworkImage(choice ? widget.post.selfie! : widget.post.music.cover!),
fit: BoxFit.cover,
width: double.infinity,
),
widget.post.selfie != null
? Positioned(
top: 0,
right: 0,
child: Padding(
padding: EdgeInsets.all(12),
child: Container(
constraints: BoxConstraints(maxWidth: 140, maxHeight: 140),
width: 90.sp,
height: 90.sp,
decoration: BoxDecoration(
color: Colors.white,
// add border
border: Border.all(width: 3, color: Colors.white),
// set border radius
borderRadius: BorderRadius.circular(15),
),
child: ClipRRect(
borderRadius: BorderRadius.circular(13),
// implement image
child: Image(
image: NetworkImage(
choice ? widget.post.music.cover! : widget.post.selfie!),
fit: BoxFit.cover,
),
),
),
))
: Container(),
],
),
),
),
)),
SizedBox(height: 15),
Row(
crossAxisAlignment: CrossAxisAlignment.end,
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Flexible(
flex: 8,
child: TextScroll(
widget.post.music.artists.first.name!,
style: GoogleFonts.plusJakartaSans(
height: 1, color: Colors.white, fontWeight: FontWeight.w600, fontSize: 26.h),
mode: TextScrollMode.endless,
pauseBetween: Duration(milliseconds: 500),
velocity: Velocity(pixelsPerSecond: Offset(20, 0)),
)),
Padding(
padding: EdgeInsets.only(bottom: 10.h, right: 5.w, left: 5.w),
child: ClipOval(
child: Container(
width: 5.h,
height: 5.h,
color: Colors.white,
),
),
),
Expanded(
flex: 8,
child: Padding(
padding: EdgeInsets.only(bottom: 2),
child: TextScroll(
widget.post.music.title!,
style: GoogleFonts.plusJakartaSans(
height: 1, color: Colors.white, fontWeight: FontWeight.w300, fontSize: 16.h),
mode: TextScrollMode.endless,
velocity: Velocity(pixelsPerSecond: Offset(50, 20)),
pauseBetween: Duration(milliseconds: 500),
),
)),
Container(width: 10),
AutoSizeText(
widget.post.music.date.toString(),
style: GoogleFonts.plusJakartaSans(
color: Colors.white.withOpacity(0.5), fontWeight: FontWeight.w300, fontSize: 16.h),
textAlign: TextAlign.end,
maxFontSize: 20,
),
],
),
],
));
}
return SizedBox(
width: double.infinity,
child: Column(
children: [
Row(
crossAxisAlignment: CrossAxisAlignment.end,
children: [
ClipOval(
child: SizedBox.fromSize(
// Image radius
child: Image(
image: NetworkImage(widget.post.user.pp),
width: 40,
),
),
),
Expanded( Expanded(
flex: 8, flex: 8,
child: Padding( child: Padding(
@ -381,9 +184,7 @@ class _PostComponentState extends State<PostComponent> with TickerProviderStateM
), ),
)), )),
SizedBox(height: 15), SizedBox(height: 15),
SizedBox( Column(
height: 40,
child: Column(
crossAxisAlignment: CrossAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.start,
children: [ children: [
Row( Row(
@ -413,26 +214,17 @@ class _PostComponentState extends State<PostComponent> with TickerProviderStateM
), ),
], ],
), ),
Expanded( TextScroll(
flex: 8,
child: TextScroll(
widget.post.music.artists.first.name!, widget.post.music.artists.first.name!,
style: GoogleFonts.plusJakartaSans( style: GoogleFonts.plusJakartaSans(
height: 1, height: 1, color: Colors.white.withOpacity(0.5), fontWeight: FontWeight.w300, fontSize: 16.h),
color: Colors.white.withOpacity(0.5),
fontWeight: FontWeight.w300,
fontSize: 16.h),
mode: TextScrollMode.endless, mode: TextScrollMode.endless,
pauseBetween: Duration(milliseconds: 500), pauseBetween: Duration(milliseconds: 500),
velocity: Velocity(pixelsPerSecond: Offset(20, 0)), velocity: Velocity(pixelsPerSecond: Offset(20, 0)),
)),
],
), ),
)
], ],
));
},
), ),
); ],
)));
} }
} }

@ -0,0 +1,33 @@
import 'package:flutter/Material.dart';
import 'package:justmusic/screens/user_screen.dart';
import '../config/routes.dart';
import '../model/User.dart';
class ProfilPictureComponent extends StatelessWidget {
final User user;
const ProfilPictureComponent({super.key, required this.user});
void _openDetail(BuildContext context) {
print("cc");
Navigator.of(context).push(routeUser(user));
}
@override
Widget build(BuildContext context) {
return GestureDetector(
onTap: () {
_openDetail(context);
},
child: ClipOval(
child: SizedBox.fromSize(
// Image radius
child: Image(
image: NetworkImage(user.pp),
width: 40,
),
),
),
);
}
}

@ -1,6 +1,7 @@
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:google_fonts/google_fonts.dart'; import 'package:google_fonts/google_fonts.dart';
import 'package:justmusic/components/profil_picture_component.dart';
import '../main.dart'; import '../main.dart';
import '../model/User.dart'; import '../model/User.dart';
import '../values/constants.dart'; import '../values/constants.dart';
@ -23,13 +24,7 @@ class _ProfileListComponentState extends State<ProfileListComponent> {
padding: const EdgeInsets.only(bottom: 5), padding: const EdgeInsets.only(bottom: 5),
child: Row( child: Row(
children: [ children: [
ClipOval( ProfilPictureComponent(user: widget.user),
child: FadeInImage.assetNetwork(
height: 50,
width: 50,
fit: BoxFit.cover,
placeholder: "assets/images/loadingPlaceholder.gif",
image: widget.user.pp)),
const SizedBox( const SizedBox(
width: 10, width: 10,
), ),

@ -0,0 +1,125 @@
import 'package:firebase_auth/firebase_auth.dart';
import 'package:flutter/Material.dart';
import 'package:google_fonts/google_fonts.dart';
import '../main.dart';
import '../model/User.dart' as justMusic;
import '../values/constants.dart';
import 'little_post_recap_component.dart';
class RecapComponent extends StatelessWidget {
final justMusic.User user;
const RecapComponent({super.key, required this.user});
Future<List<bool>>? _fetchdata() async {
return await MyApp.postViewModel.recapSevenDays(user.id);
}
@override
Widget build(BuildContext context) {
List<String> weekDays = ['L', 'M', 'M', 'J', 'V', 'S', 'D'];
DateTime currentDate = DateTime.now();
return Container(
decoration: BoxDecoration(
color: profileBttnColor,
borderRadius: BorderRadius.circular(10),
border: Border.all(color: grayColor, width: 1)),
height: 120,
clipBehavior: Clip.hardEdge,
child: Column(
children: [
Expanded(
child: Container(
padding: EdgeInsets.symmetric(horizontal: 10),
decoration: BoxDecoration(
color: postbutton,
borderRadius: BorderRadius.only(topRight: Radius.circular(10), topLeft: Radius.circular(10)),
),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
crossAxisAlignment: CrossAxisAlignment.center,
children: [
Flexible(
child: Center(
child: Text(
weekDays[currentDate.subtract(Duration(days: 6)).weekday - 1].substring(0, 1),
style: GoogleFonts.plusJakartaSans(color: Colors.white, fontWeight: FontWeight.w800, fontSize: 17),
),
)),
Flexible(
child: Center(
child: Text(
weekDays[currentDate.subtract(Duration(days: 5)).weekday - 1].substring(0, 1),
style: GoogleFonts.plusJakartaSans(color: Colors.white, fontWeight: FontWeight.w800, fontSize: 17),
),
)),
Flexible(
child: Center(
child: Text(
weekDays[currentDate.subtract(Duration(days: 4)).weekday - 1].substring(0, 1),
style: GoogleFonts.plusJakartaSans(color: Colors.white, fontWeight: FontWeight.w800, fontSize: 17),
),
)),
Flexible(
child: Center(
child: Text(
weekDays[currentDate.subtract(Duration(days: 3)).weekday - 1].substring(0, 1),
style: GoogleFonts.plusJakartaSans(color: Colors.white, fontWeight: FontWeight.w800, fontSize: 17),
),
)),
Flexible(
child: Center(
child: Text(
weekDays[currentDate.subtract(Duration(days: 2)).weekday - 1].substring(0, 1),
style: GoogleFonts.plusJakartaSans(color: Colors.white, fontWeight: FontWeight.w800, fontSize: 17),
),
)),
Flexible(
child: Center(
child: Text(
weekDays[currentDate.subtract(Duration(days: 1)).weekday - 1].substring(0, 1),
style: GoogleFonts.plusJakartaSans(color: Colors.white, fontWeight: FontWeight.w800, fontSize: 17),
),
)),
Flexible(
child: Center(
child: Text(
weekDays[currentDate.subtract(Duration(days: 0)).weekday - 1].substring(0, 1),
style: GoogleFonts.plusJakartaSans(color: Colors.white, fontWeight: FontWeight.w800, fontSize: 17),
),
)),
],
),
)),
FutureBuilder<List<bool>>(
future: _fetchdata(), // a previously-obtained Future<String> or null
builder: (BuildContext context, AsyncSnapshot<List<bool>> snapshot) {
if (snapshot.hasData) {
return Padding(
padding: EdgeInsets.all(12),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
crossAxisAlignment: CrossAxisAlignment.end,
children: [
LittleCapsule(
isEmpty: snapshot.data![0],
date: currentDate.subtract(const Duration(days: 6)),
),
LittleCapsule(isEmpty: snapshot.data![1], date: currentDate.subtract(const Duration(days: 5))),
LittleCapsule(isEmpty: snapshot.data![2], date: currentDate.subtract(const Duration(days: 4))),
LittleCapsule(isEmpty: snapshot.data![3], date: currentDate.subtract(const Duration(days: 3))),
LittleCapsule(isEmpty: snapshot.data![4], date: currentDate.subtract(const Duration(days: 2))),
LittleCapsule(isEmpty: snapshot.data![5], date: currentDate.subtract(const Duration(days: 1))),
LittleCapsule(isEmpty: snapshot.data![6], date: currentDate.subtract(const Duration(days: 0))),
],
),
);
} else {
return Container();
}
}),
],
),
);
}
}

@ -9,7 +9,9 @@ class SettingPartComponent extends StatelessWidget {
final JustMusicIcon icon; final JustMusicIcon icon;
final String label; final String label;
final bool important; final bool important;
const SettingPartComponent({Key? key, required this.icon, required this.label, this.important = false}) final VoidCallback? action;
const SettingPartComponent(
{Key? key, required this.icon, required this.label, this.important = false, required this.action})
: super(key: key); : super(key: key);
@override @override
@ -24,11 +26,7 @@ class SettingPartComponent extends StatelessWidget {
color: important ? warningBttnColor : settingColor, color: important ? warningBttnColor : settingColor,
borderOnForeground: false, borderOnForeground: false,
child: InkWell( child: InkWell(
onTap: () { onTap: action,
if (icon == JustMusicIcon.cross) {
logout();
}
},
splashColor: Colors.transparent, splashColor: Colors.transparent,
highlightColor: Colors.white.withOpacity(0.08), highlightColor: Colors.white.withOpacity(0.08),
child: Container( child: Container(

@ -27,8 +27,7 @@ class _TopNavBarComponentState extends State<TopNavBarComponent> with TickerProv
bool isDismissed = true; bool isDismissed = true;
final DateTime midnight = DateTime( final DateTime midnight = DateTime(DateTime.now().year, DateTime.now().month, DateTime.now().day + 1);
DateTime.now().year, DateTime.now().month, DateTime.now().day + 1);
void actionSurBouton(bool choice) async { void actionSurBouton(bool choice) async {
widget.callback(choice); widget.callback(choice);
@ -47,8 +46,7 @@ class _TopNavBarComponentState extends State<TopNavBarComponent> with TickerProv
var now = tz.TZDateTime.now(franceTimeZone); var now = tz.TZDateTime.now(franceTimeZone);
// Calculate the midnight time for the next day in France timezone // Calculate the midnight time for the next day in France timezone
var midnight = var midnight = tz.TZDateTime(franceTimeZone, now.year, now.month, now.day + 1);
tz.TZDateTime(franceTimeZone, now.year, now.month, now.day + 1);
bool res = await MyApp.postViewModel.getAvailable(); bool res = await MyApp.postViewModel.getAvailable();
if (res) { if (res) {
@ -67,8 +65,7 @@ class _TopNavBarComponentState extends State<TopNavBarComponent> with TickerProv
alignment: Alignment.centerLeft, alignment: Alignment.centerLeft,
child: Text( child: Text(
"Capsule disponible", "Capsule disponible",
style: style: GoogleFonts.plusJakartaSans(color: Colors.grey, fontSize: 15),
GoogleFonts.plusJakartaSans(color: Colors.grey, fontSize: 15),
), ),
), ),
flushbarStyle: FlushbarStyle.FLOATING, flushbarStyle: FlushbarStyle.FLOATING,
@ -105,8 +102,7 @@ class _TopNavBarComponentState extends State<TopNavBarComponent> with TickerProv
alignment: Alignment.centerLeft, alignment: Alignment.centerLeft,
child: CountdownTimer( child: CountdownTimer(
endTime: midnight.millisecondsSinceEpoch, endTime: midnight.millisecondsSinceEpoch,
textStyle: textStyle: GoogleFonts.plusJakartaSans(color: Colors.grey, fontSize: 15),
GoogleFonts.plusJakartaSans(color: Colors.grey, fontSize: 15),
), ),
), ),
flushbarStyle: FlushbarStyle.FLOATING, flushbarStyle: FlushbarStyle.FLOATING,
@ -153,7 +149,7 @@ class _TopNavBarComponentState extends State<TopNavBarComponent> with TickerProv
flex: 1, flex: 1,
child: GestureDetector( child: GestureDetector(
behavior: HitTestBehavior.translucent, behavior: HitTestBehavior.translucent,
onTap: () async { onTap: () {
Navigator.of(context).push(routeAddFriend()); Navigator.of(context).push(routeAddFriend());
}, },
child: const Icon( child: const Icon(
@ -199,30 +195,23 @@ class _TopNavBarComponentState extends State<TopNavBarComponent> with TickerProv
} }
}, },
child: LayoutBuilder( child: LayoutBuilder(
builder: (BuildContext context, builder: (BuildContext context, BoxConstraints constraints) {
BoxConstraints constraints) {
if (choice) { if (choice) {
return Padding( return Padding(
padding: const EdgeInsets.only( padding: const EdgeInsets.only(left: 8, top: 0, right: 8, bottom: 6),
left: 8, top: 0, right: 8, bottom: 6),
child: AutoSizeText( child: AutoSizeText(
"Mes amis", "Mes amis",
style: GoogleFonts.plusJakartaSans( style: GoogleFonts.plusJakartaSans(
fontWeight: FontWeight.w500, fontWeight: FontWeight.w500, fontSize: 16, color: Colors.white),
fontSize: 16,
color: Colors.white),
), ),
); );
} else { } else {
return Padding( return Padding(
padding: const EdgeInsets.only( padding: const EdgeInsets.only(left: 8, top: 0, right: 8, bottom: 6),
left: 8, top: 0, right: 8, bottom: 6),
child: AutoSizeText( child: AutoSizeText(
"Mes amis", "Mes amis",
style: GoogleFonts.plusJakartaSans( style: GoogleFonts.plusJakartaSans(
fontWeight: FontWeight.w300, fontWeight: FontWeight.w300, fontSize: 16, color: unactiveFeed),
fontSize: 16,
color: unactiveFeed),
)); ));
} }
}, },
@ -239,29 +228,22 @@ class _TopNavBarComponentState extends State<TopNavBarComponent> with TickerProv
} }
}, },
child: LayoutBuilder( child: LayoutBuilder(
builder: (BuildContext context, builder: (BuildContext context, BoxConstraints constraints) {
BoxConstraints constraints) {
if (choice) { if (choice) {
return Padding( return Padding(
padding: const EdgeInsets.only( padding: const EdgeInsets.only(left: 8, top: 0, right: 8, bottom: 6),
left: 8, top: 0, right: 8, bottom: 6),
child: AutoSizeText( child: AutoSizeText(
"Discovery", "Discovery",
style: GoogleFonts.plusJakartaSans( style: GoogleFonts.plusJakartaSans(
fontWeight: FontWeight.w300, fontWeight: FontWeight.w300, fontSize: 16, color: unactiveFeed),
fontSize: 16,
color: unactiveFeed),
)); ));
} else { } else {
return Padding( return Padding(
padding: const EdgeInsets.only( padding: const EdgeInsets.only(left: 8, top: 0, right: 8, bottom: 6),
left: 8, top: 0, right: 8, bottom: 6),
child: AutoSizeText( child: AutoSizeText(
"Discovery", "Discovery",
style: GoogleFonts.plusJakartaSans( style: GoogleFonts.plusJakartaSans(
fontWeight: FontWeight.w500, fontWeight: FontWeight.w500, fontSize: 16, color: Colors.white),
fontSize: 16,
color: Colors.white),
)); ));
} }
}, },

@ -2,6 +2,9 @@ import 'package:flutter/Material.dart';
import 'package:justmusic/screens/add_friend_screen.dart'; import 'package:justmusic/screens/add_friend_screen.dart';
import 'package:justmusic/screens/feed_screen.dart'; import 'package:justmusic/screens/feed_screen.dart';
import 'package:justmusic/screens/profile_screen.dart'; import 'package:justmusic/screens/profile_screen.dart';
import 'package:justmusic/screens/user_screen.dart';
import '../model/User.dart';
Route routeProfile() { Route routeProfile() {
return PageRouteBuilder( return PageRouteBuilder(
@ -50,3 +53,21 @@ Route routeRocket() {
}, },
); );
} }
Route routeUser(User user) {
return PageRouteBuilder(
pageBuilder: (context, animation, secondaryAnimation) => UserScreen(user: user),
transitionsBuilder: (context, animation, secondaryAnimation, child) {
const begin = Offset(1.0, 0.0);
const end = Offset.zero;
const curve = Curves.ease;
var tween = Tween(begin: begin, end: end).chain(CurveTween(curve: curve));
return SlideTransition(
position: animation.drive(tween),
child: child,
);
},
);
}

@ -17,6 +17,7 @@ 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';
import 'package:justmusic/screens/user_screen.dart';
import 'package:justmusic/screens/welcome_screen.dart'; import 'package:justmusic/screens/welcome_screen.dart';
import 'package:justmusic/view_model/CommentViewModel.dart'; import 'package:justmusic/view_model/CommentViewModel.dart';
import 'package:justmusic/view_model/MusicViewModel.dart'; import 'package:justmusic/view_model/MusicViewModel.dart';
@ -67,8 +68,7 @@ class _MyAppState extends State<MyApp> {
print('User is currently signed out!'); print('User is currently signed out!');
return null; return null;
} else { } else {
MyApp.userViewModel.userCurrent = MyApp.userViewModel.userCurrent = (await (MyApp.userViewModel.getUser(user.uid)))!;
(await (MyApp.userViewModel.getUser(user.uid)))!;
userCurrent = Stream.value(MyApp.userViewModel.userCurrent); userCurrent = Stream.value(MyApp.userViewModel.userCurrent);
print('User is signed in!'); print('User is signed in!');
} }
@ -106,38 +106,7 @@ class _MyAppState extends State<MyApp> {
theme: ThemeData( theme: ThemeData(
primarySwatch: Colors.blue, primarySwatch: Colors.blue,
), ),
home: StreamBuilder<User?>( home: WellcomeScreen());
stream: FirebaseAuth.instance.authStateChanges(),
builder: (context, snapshot) {
if (snapshot.connectionState == ConnectionState.waiting) {
return LoadingScreen();
} else if (snapshot.hasData) {
return FutureBuilder<userJustMusic.User?>(
future: MyApp.userViewModel.getUser(snapshot.data!.uid),
builder: (context, userSnapshot) {
if (userSnapshot.connectionState ==
ConnectionState.waiting) {
return LoadingScreen();
} else if (userSnapshot.hasData) {
MyApp.userViewModel.userCurrent = userSnapshot.data!;
return AnimatedSwitcher(
duration: Duration(milliseconds: 1000),
transitionBuilder: (child, animation) {
return FadeTransition(
opacity: animation, child: child);
},
child: FeedScreen(),
);
} else {
return WellcomeScreen();
}
},
);
} else {
return WellcomeScreen();
}
},
));
}, },
designSize: Size(390, 844), designSize: Size(390, 844),
); );

@ -9,6 +9,7 @@ import 'package:text_scroll/text_scroll.dart';
import 'package:zoom_tap_animation/zoom_tap_animation.dart'; import 'package:zoom_tap_animation/zoom_tap_animation.dart';
import '../components/button_play_component.dart'; import '../components/button_play_component.dart';
import '../components/comment_component.dart'; import '../components/comment_component.dart';
import '../components/profil_picture_component.dart';
import '../main.dart'; import '../main.dart';
import '../model/Post.dart'; import '../model/Post.dart';
import '../model/Comment.dart'; import '../model/Comment.dart';
@ -60,7 +61,15 @@ class _DetailPostScreenState extends State<DetailPostScreen> {
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
return Container( return GestureDetector(
onTap: () {
FocusScopeNode currentFocus = FocusScope.of(context);
if (!currentFocus.hasPrimaryFocus) {
currentFocus.unfocus();
resetFullScreen();
}
},
child: Container(
height: 760.h, height: 760.h,
child: Column( child: Column(
children: [ children: [
@ -115,10 +124,7 @@ class _DetailPostScreenState extends State<DetailPostScreen> {
child: ClipOval( child: ClipOval(
child: SizedBox.fromSize( child: SizedBox.fromSize(
// Image radius // Image radius
child: Image( child: ProfilPictureComponent(user: widget.post.user),
image: NetworkImage(widget.post.user.pp),
width: 45,
),
), ),
), ),
) )
@ -146,20 +152,17 @@ class _DetailPostScreenState extends State<DetailPostScreen> {
fontWeight: FontWeight.w800, fontWeight: FontWeight.w800,
fontSize: 22, fontSize: 22,
), ),
mode: TextScrollMode mode: TextScrollMode.endless,
.endless, pauseBetween: Duration(milliseconds: 500),
pauseBetween: Duration( velocity: Velocity(pixelsPerSecond: Offset(20, 0)),
milliseconds: 500),
velocity: Velocity(
pixelsPerSecond:
Offset(20, 0)),
), ),
), ),
), ),
Padding( Padding(
padding: const EdgeInsets.only(left: 20.0), padding: const EdgeInsets.only(left: 20.0),
child: choice child: choice
? DateTime(today.year, today.month, today.day).isAtSameMomentAs( ? DateTime(today.year, today.month, today.day)
.isAtSameMomentAs(
DateTime( DateTime(
widget.post.date.year, widget.post.date.year,
widget.post.date.month, widget.post.date.month,
@ -280,10 +283,11 @@ class _DetailPostScreenState extends State<DetailPostScreen> {
onTap: () { onTap: () {
myFocusNode.requestFocus(); myFocusNode.requestFocus();
}, },
child: child: SvgPicture.asset("assets/images/chat.svg",
SvgPicture.asset("assets/images/chat.svg", semanticsLabel: 'Chat Logo'), semanticsLabel: 'Chat Logo'),
), ),
SvgPicture.asset("assets/images/add.svg", semanticsLabel: 'Add playlist Logo'), SvgPicture.asset("assets/images/add.svg",
semanticsLabel: 'Add playlist Logo'),
SvgPicture.asset("assets/images/save.svg", semanticsLabel: 'Save Logo'), SvgPicture.asset("assets/images/save.svg", semanticsLabel: 'Save Logo'),
SvgPicture.asset("assets/images/report.svg", semanticsLabel: 'Report Logo'), SvgPicture.asset("assets/images/report.svg", semanticsLabel: 'Report Logo'),
], ],
@ -293,7 +297,6 @@ class _DetailPostScreenState extends State<DetailPostScreen> {
future: MyApp.commentViewModel.getCommentsByPostId(widget.post.id), future: MyApp.commentViewModel.getCommentsByPostId(widget.post.id),
builder: (BuildContext context, AsyncSnapshot<List<Comment>> snapshot) { builder: (BuildContext context, AsyncSnapshot<List<Comment>> snapshot) {
if (snapshot.hasData) { if (snapshot.hasData) {
print("test:");
return Column( return Column(
children: [ children: [
snapshot.data!.length > 0 snapshot.data!.length > 0
@ -379,7 +382,8 @@ class _DetailPostScreenState extends State<DetailPostScreen> {
borderRadius: BorderRadius.circular(15), borderRadius: BorderRadius.circular(15),
// implementer l'image // implementer l'image
child: Image( child: Image(
image: NetworkImage(choice ? widget.post.music.cover! : widget.post.selfie!), image:
NetworkImage(choice ? widget.post.music.cover! : widget.post.selfie!),
fit: BoxFit.cover, fit: BoxFit.cover,
), ),
), ),
@ -445,21 +449,40 @@ class _DetailPostScreenState extends State<DetailPostScreen> {
focusNode: myFocusNode, focusNode: myFocusNode,
onSubmitted: (value) async { onSubmitted: (value) async {
if (value.isNotEmpty) { if (value.isNotEmpty) {
await MyApp.commentViewModel.addComment(value, widget.post.id); await MyApp.commentViewModel.addComment(value, widget.post.id, widget.post.user);
} }
setState(() { setState(() {
_textController.clear(); _textController.clear();
}); });
}, },
onChanged: (value) {
setState(() {});
},
cursorColor: primaryColor, cursorColor: primaryColor,
keyboardType: TextInputType.emailAddress, keyboardType: TextInputType.emailAddress,
style: GoogleFonts.plusJakartaSans(color: Colors.white), style: GoogleFonts.plusJakartaSans(color: Colors.white),
decoration: InputDecoration( decoration: InputDecoration(
suffixIcon: Icon( suffixIcon: _textController.text.isEmpty
? Container(
height: 20,
width: 20,
)
: IconButton(
onPressed: () async {
if (_textController.text.isNotEmpty) {
await MyApp.commentViewModel
.addComment(_textController.text, widget.post.id, widget.post.user);
}
myFocusNode.unfocus();
setState(() {
_textController.clear();
});
},
icon: Icon(
Icons.send, Icons.send,
color: grayText, color: primaryColor,
size: 20, size: 20,
), )),
focusedBorder: OutlineInputBorder( focusedBorder: OutlineInputBorder(
borderSide: BorderSide(width: 1, color: grayText), borderSide: BorderSide(width: 1, color: grayText),
borderRadius: BorderRadius.all(Radius.circular(100)), borderRadius: BorderRadius.all(Radius.circular(100)),
@ -485,14 +508,13 @@ class _DetailPostScreenState extends State<DetailPostScreen> {
), ),
], ],
), ),
); ));
} }
} }
class MyBehavior extends ScrollBehavior { class MyBehavior extends ScrollBehavior {
@override @override
Widget buildOverscrollIndicator( Widget buildOverscrollIndicator(BuildContext context, Widget child, ScrollableDetails details) {
BuildContext context, Widget child, ScrollableDetails details) {
return child; return child;
} }
} }

@ -56,6 +56,7 @@ class _FeedScreenState extends State<FeedScreen> with SingleTickerProviderStateM
@override @override
void dispose() { void dispose() {
controller.dispose();
animationController.dispose(); animationController.dispose();
super.dispose(); super.dispose();
} }
@ -120,7 +121,7 @@ class _FeedScreenState extends State<FeedScreen> with SingleTickerProviderStateM
bool empty = bool empty =
(choiceFeed == true && displayFeed.item1.isEmpty) || (choiceFeed == false && displayFeed.item2.isEmpty); (choiceFeed == true && displayFeed.item1.isEmpty) || (choiceFeed == false && displayFeed.item2.isEmpty);
return Scaffold( return Scaffold(
resizeToAvoidBottomInset: true, resizeToAvoidBottomInset: false,
backgroundColor: bgColor, backgroundColor: bgColor,
extendBodyBehindAppBar: true, extendBodyBehindAppBar: true,
body: Container( body: Container(

@ -1,3 +1,4 @@
import 'package:firebase_auth/firebase_auth.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';
@ -5,6 +6,7 @@ import 'package:google_fonts/google_fonts.dart';
import 'package:justmusic/values/icons.dart'; import 'package:justmusic/values/icons.dart';
import '../components/profile_component.dart'; import '../components/profile_component.dart';
import '../components/setting_part_component.dart'; import '../components/setting_part_component.dart';
import '../config/routes.dart';
import '../main.dart'; import '../main.dart';
import '../values/constants.dart'; import '../values/constants.dart';
@ -18,6 +20,16 @@ class ProfileScreen extends StatefulWidget {
class _ProfileScreenState extends State<ProfileScreen> { class _ProfileScreenState extends State<ProfileScreen> {
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
Future<void> logout() async {
print("cc");
await FirebaseAuth.instance.signOut();
Navigator.pushNamed(context, '/welcome');
}
void _openDetail() {
Navigator.of(context).push(routeUser(MyApp.userViewModel.userCurrent));
}
return Scaffold( return Scaffold(
appBar: PreferredSize( appBar: PreferredSize(
preferredSize: Size(double.infinity, 58), preferredSize: Size(double.infinity, 58),
@ -84,23 +96,28 @@ class _ProfileScreenState extends State<ProfileScreen> {
SettingPartComponent( SettingPartComponent(
icon: JustMusicIcon.profile, icon: JustMusicIcon.profile,
label: 'Compte', label: 'Compte',
action: _openDetail,
), ),
SettingPartComponent( const SettingPartComponent(
icon: JustMusicIcon.history, icon: JustMusicIcon.history,
label: 'Historiques des capsules', label: 'Historiques des capsules',
action: null,
), ),
SettingPartComponent( const SettingPartComponent(
icon: JustMusicIcon.spotify, icon: JustMusicIcon.spotify,
label: 'Lier un compte Spotify', label: 'Lier un compte Spotify',
action: null,
), ),
SettingPartComponent( const SettingPartComponent(
icon: JustMusicIcon.trash, icon: JustMusicIcon.trash,
label: 'Supprimer mon compte', label: 'Supprimer mon compte',
action: null,
), ),
SettingPartComponent( SettingPartComponent(
icon: JustMusicIcon.cross, icon: JustMusicIcon.cross,
label: 'Déconnexion', label: 'Déconnexion',
important: true, important: true,
action: logout,
), ),
], ],
), ),
@ -114,15 +131,17 @@ class _ProfileScreenState extends State<ProfileScreen> {
), ),
ClipRRect( ClipRRect(
borderRadius: BorderRadius.circular(8), borderRadius: BorderRadius.circular(8),
child: Column( child: const Column(
children: const [ children: [
SettingPartComponent( SettingPartComponent(
icon: JustMusicIcon.theme, icon: JustMusicIcon.theme,
label: 'Thême de l\'application', label: 'Thême de l\'application',
action: null,
), ),
SettingPartComponent( SettingPartComponent(
icon: JustMusicIcon.notification, icon: JustMusicIcon.notification,
label: 'Notifications', label: 'Notifications',
action: null,
), ),
], ],
), ),

@ -21,6 +21,7 @@ class SearchSongScreen extends StatefulWidget {
class _SearchSongScreenState extends State<SearchSongScreen> { class _SearchSongScreenState extends State<SearchSongScreen> {
final ScrollController _scrollController = ScrollController(); final ScrollController _scrollController = ScrollController();
final TextEditingController _textEditingController = TextEditingController(); final TextEditingController _textEditingController = TextEditingController();
int? playingIndex; int? playingIndex;
Future<void> resetFullScreen() async { Future<void> resetFullScreen() async {
@ -32,9 +33,18 @@ class _SearchSongScreenState extends State<SearchSongScreen> {
@override @override
void initState() { void initState() {
super.initState(); super.initState();
fetchTrendingMusic();
_scrollController.addListener(_scrollListener); _scrollController.addListener(_scrollListener);
} }
Future<void> fetchTrendingMusic() async {
await MyApp.musicViewModel.getMusicsWithPlaylistId('37i9dQZF1DX1X23oiQRTB5').then((value) {
setState(() {
filteredData = value;
});
});
}
Future<void> _scrollListener() async { Future<void> _scrollListener() async {
if (_scrollController.position.pixels == _scrollController.position.maxScrollExtent) { if (_scrollController.position.pixels == _scrollController.position.maxScrollExtent) {
filteredData.addAll(await MyApp.musicViewModel filteredData.addAll(await MyApp.musicViewModel
@ -120,8 +130,7 @@ class _SearchSongScreenState extends State<SearchSongScreen> {
onEditingComplete: resetFullScreen, onEditingComplete: resetFullScreen,
onSubmitted: (value) async { onSubmitted: (value) async {
if (_textEditingController.text.isEmpty) { if (_textEditingController.text.isEmpty) {
} else if (value == " ") { fetchTrendingMusic();
print("popular");
} else { } else {
filteredData = await MyApp.musicViewModel.getMusicsWithNameOrArtistName(value); filteredData = await MyApp.musicViewModel.getMusicsWithNameOrArtistName(value);
setState(() { setState(() {

@ -0,0 +1,157 @@
import 'package:flutter/Material.dart';
import 'package:flutter_screenutil/flutter_screenutil.dart';
import 'package:google_fonts/google_fonts.dart';
import '../components/profile_component.dart';
import '../components/recap_component.dart';
import '../main.dart';
import '../model/User.dart';
import '../values/constants.dart';
class UserScreen extends StatefulWidget {
final User user;
const UserScreen({super.key, required this.user});
@override
State<UserScreen> createState() => _UserScreenState();
}
class _UserScreenState extends State<UserScreen> {
late bool isClicked;
@override
Widget build(BuildContext context) {
isClicked = MyApp.userViewModel.isFriend(widget.user.id);
return Scaffold(
appBar: PreferredSize(
preferredSize: Size(double.infinity, 58),
child: Container(
height: double.infinity,
color: bgAppBar,
child: Padding(
padding: const EdgeInsets.symmetric(horizontal: defaultPadding),
child: Stack(
alignment: Alignment.centerLeft,
children: [
GestureDetector(
behavior: HitTestBehavior.translucent,
onTap: () {
Navigator.pop(context, true);
},
child: Container(
padding: EdgeInsets.symmetric(horizontal: 10),
height: 30,
width: 30,
child: Image(
image: AssetImage("assets/images/return_icon.png"),
height: 8,
),
)),
Align(
child: Text(
widget.user.pseudo,
style: GoogleFonts.plusJakartaSans(color: Colors.white, fontSize: 14, fontWeight: FontWeight.bold),
),
)
],
),
),
),
),
body: Container(
width: double.infinity,
height: double.infinity,
color: bgColor,
child: SingleChildScrollView(
physics: const BouncingScrollPhysics(decelerationRate: ScrollDecelerationRate.fast),
child: Padding(
padding: const EdgeInsets.symmetric(horizontal: settingPadding),
child: Column(
mainAxisAlignment: MainAxisAlignment.start,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Padding(
padding: EdgeInsets.only(top: 68.h, bottom: 40),
child: ProfileComponent(user: widget.user),
),
MyApp.userViewModel.userCurrent.id != widget.user.id
? Align(
alignment: Alignment.topCenter,
child: isClicked
? SizedBox(
// Définir une largeur minimale pour le bouton "Ajouter"
width: 120, // Réglez cette valeur en fonction de vos besoins
child: Material(
borderRadius: BorderRadius.all(Radius.circular(5)),
color: selectedButton,
child: InkWell(
splashColor: Colors.white.withOpacity(0.3),
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),
decoration: BoxDecoration(borderRadius: BorderRadius.all(Radius.circular(7))),
child: Center(
child: Text("Ajouté",
style: GoogleFonts.plusJakartaSans(
color: Colors.white, fontWeight: FontWeight.w600, fontSize: 13)),
),
))),
)
: SizedBox(
// Définir une largeur minimale pour le bouton "Ajouter"
width: 120, // Réglez cette valeur en fonction de vos besoins
child: Material(
borderRadius: BorderRadius.all(Radius.circular(5)),
color: primaryColor,
child: InkWell(
splashColor: Colors.white.withOpacity(0.3),
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),
decoration: BoxDecoration(borderRadius: BorderRadius.all(Radius.circular(7))),
child: Center(
child: Text("Ajouter",
style: GoogleFonts.plusJakartaSans(
color: Colors.white, fontWeight: FontWeight.w600, fontSize: 13)),
),
)))),
)
: Container(),
SizedBox(
height: 40,
),
RecapComponent(user: widget.user)
],
),
),
),
),
);
}
}

@ -7,8 +7,7 @@ import 'package:firebase_storage/firebase_storage.dart';
import '../main.dart'; import '../main.dart';
class PostService { class PostService {
createPost(String? description, String idMusic, File? image, createPost(String? description, String idMusic, File? image, Tuple2<String, String>? location) async {
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,
@ -42,14 +41,11 @@ class PostService {
deletePost() {} deletePost() {}
Future<List<QueryDocumentSnapshot<Map<String, dynamic>>>> getPopularPosts( Future<List<QueryDocumentSnapshot<Map<String, dynamic>>>> getPopularPosts({int limit = 10, int offset = 0}) async {
{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 twentyFourHoursAgoTimestamp = Timestamp.fromDate(twentyFourHoursAgo);
Timestamp.fromDate(twentyFourHoursAgo);
QuerySnapshot<Map<String, dynamic>> response = await FirebaseFirestore QuerySnapshot<Map<String, dynamic>> response = await FirebaseFirestore.instance
.instance
.collection("posts") .collection("posts")
.where("date", isGreaterThan: twentyFourHoursAgoTimestamp) .where("date", isGreaterThan: twentyFourHoursAgoTimestamp)
.limit(limit) .limit(limit)
@ -67,8 +63,7 @@ class PostService {
return Timestamp.fromDate(twentyFourHoursAgo); return Timestamp.fromDate(twentyFourHoursAgo);
} }
Future<List<QueryDocumentSnapshot<Map<String, dynamic>>>> getPostsFriends( Future<List<QueryDocumentSnapshot<Map<String, dynamic>>>> getPostsFriends({int limit = 10, int offset = 0}) async {
{int limit = 10, int offset = 0}) async {
var timestamp = _getTwentyFourHoursAgoTimestamp(); var timestamp = _getTwentyFourHoursAgoTimestamp();
var response = await FirebaseFirestore.instance var response = await FirebaseFirestore.instance
.collection("posts") .collection("posts")
@ -84,17 +79,12 @@ class PostService {
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 = await FirebaseFirestore QuerySnapshot<Map<String, dynamic>> response =
.instance await FirebaseFirestore.instance.collection("posts").where("user_id", isEqualTo: idUser).get();
.collection("posts")
.where("user_id", isEqualTo: idUser)
.get();
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 && return date.day == today.day && date.month == today.month && date.year == today.year;
date.month == today.month &&
date.year == today.year;
}); });
return !isTodayAvailable; return !isTodayAvailable;
@ -103,17 +93,13 @@ class PostService {
Future<List<bool>> recapSevenDays(String id) async { Future<List<bool>> recapSevenDays(String id) async {
List<bool> recapList = []; List<bool> recapList = [];
DateTime sevenDaysAgo = DateTime.now().subtract(Duration(days: 7)); DateTime sevenDaysAgo = DateTime.now().subtract(Duration(days: 6));
QuerySnapshot<Map<String, dynamic>> response = await FirebaseFirestore QuerySnapshot<Map<String, dynamic>> response =
.instance await FirebaseFirestore.instance.collection("posts").where("user_id", isEqualTo: id).get();
.collection("posts")
.where("user_id", isEqualTo: id)
.get();
List<Map<String, dynamic>?> postList = response.docs List<Map<String, dynamic>?> postList =
.map((DocumentSnapshot<Map<String, dynamic>> doc) => doc.data()) response.docs.map((DocumentSnapshot<Map<String, dynamic>> doc) => doc.data()).toList();
.toList();
for (int i = 0; i < 7; i++) { for (int i = 0; i < 7; i++) {
DateTime date = sevenDaysAgo.add(Duration(days: i)); DateTime date = sevenDaysAgo.add(Duration(days: i));

@ -1,19 +1,24 @@
import 'package:justmusic/model/mapper/CommentMapper.dart'; import 'package:justmusic/model/mapper/CommentMapper.dart';
import '../model/Comment.dart'; import '../model/Comment.dart';
import '../model/User.dart';
import '../services/CommentService.dart'; import '../services/CommentService.dart';
import '../services/NotificationService.dart';
class CommentViewModel { class CommentViewModel {
List<Comment> _comments = []; List<Comment> _comments = [];
final CommentService _commentService = CommentService(); final CommentService _commentService = CommentService();
final NotificationService _notificationService = NotificationService();
// Constructor // Constructor
CommentViewModel(); CommentViewModel();
// Methods // Methods
addComment(String text, String idPost) async { addComment(String text, String idPost, User receiver) async {
try { try {
print(receiver.token);
await _commentService.createComment(text, idPost); await _commentService.createComment(text, idPost);
_notificationService.sendNotifyComment(receiver.token, text);
} catch (e) { } catch (e) {
print(e); print(e);
rethrow; rethrow;

Loading…
Cancel
Save