Merge pull request 'NOTIFICATION_EKA' (#42) from NOTIFICATION_EKA into master
continuous-integration/drone/push Build is passing
Details
continuous-integration/drone/push Build is passing
Details
Reviewed-on: #42FAVORITE_MUSICS_EKA
commit
fd9b015fa3
@ -1,438 +1,438 @@
|
||||
import 'package:auto_size_text/auto_size_text.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_screenutil/flutter_screenutil.dart';
|
||||
import 'package:google_fonts/google_fonts.dart';
|
||||
import 'package:gradient_borders/box_borders/gradient_box_border.dart';
|
||||
import 'package:text_scroll/text_scroll.dart';
|
||||
import 'package:zoom_tap_animation/zoom_tap_animation.dart';
|
||||
|
||||
import '../model/Post.dart';
|
||||
|
||||
class PostComponent extends StatefulWidget {
|
||||
final Function(int)? callback;
|
||||
final Post post;
|
||||
final int index;
|
||||
|
||||
PostComponent({Key? key, required this.callback, required this.post, required this.index}) : super(key: key);
|
||||
|
||||
@override
|
||||
State<PostComponent> createState() => _PostComponentState();
|
||||
}
|
||||
|
||||
class _PostComponentState extends State<PostComponent> with TickerProviderStateMixin {
|
||||
bool choice = false;
|
||||
DateTime today = DateTime.now();
|
||||
|
||||
void switchChoice() {
|
||||
setState(() {
|
||||
choice = !choice;
|
||||
});
|
||||
}
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
print("post: ${widget.post.date.toString()}");
|
||||
print("ajrd: ${DateTime.now().toString()}");
|
||||
super.initState();
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return GestureDetector(
|
||||
onTap: switchChoice,
|
||||
child: LayoutBuilder(
|
||||
builder: (BuildContext context, BoxConstraints constraints) {
|
||||
if (widget.callback == null) {
|
||||
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(
|
||||
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(
|
||||
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(
|
||||
"hier, ${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: () {
|
||||
widget.callback!(widget.index);
|
||||
},
|
||||
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(widget.post.music.cover!),
|
||||
fit: BoxFit.cover,
|
||||
width: double.infinity,
|
||||
),
|
||||
Image(
|
||||
image: AssetImage("assets/images/shadow_post.png"),
|
||||
opacity: AnimationController(vsync: this, value: 0.7),
|
||||
fit: BoxFit.fitHeight,
|
||||
width: double.infinity,
|
||||
),
|
||||
widget.post.description == null
|
||||
? Container()
|
||||
: Padding(
|
||||
padding: EdgeInsets.all(15),
|
||||
child: AutoSizeText(
|
||||
'“${widget.post.description}”',
|
||||
style: GoogleFonts.plusJakartaSans(
|
||||
color: Colors.white, fontWeight: FontWeight.w400, fontSize: 15.sp),
|
||||
maxFontSize: 20,
|
||||
maxLines: 1,
|
||||
),
|
||||
),
|
||||
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(widget.post.selfie!),
|
||||
fit: BoxFit.cover,
|
||||
),
|
||||
),
|
||||
),
|
||||
))
|
||||
: Container(),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
)),
|
||||
SizedBox(height: 15),
|
||||
SizedBox(
|
||||
height: 60,
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Row(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
mainAxisAlignment: MainAxisAlignment.start,
|
||||
children: [
|
||||
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.w600, fontSize: 26.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, fontWeight: FontWeight.w600, fontSize: 26.h),
|
||||
textAlign: TextAlign.end,
|
||||
maxFontSize: 20,
|
||||
),
|
||||
],
|
||||
),
|
||||
Expanded(
|
||||
flex: 8,
|
||||
child: TextScroll(
|
||||
widget.post.music.artists.first.name!,
|
||||
style: GoogleFonts.plusJakartaSans(
|
||||
height: 1,
|
||||
color: Colors.white.withOpacity(0.5),
|
||||
fontWeight: FontWeight.w300,
|
||||
fontSize: 16.h),
|
||||
mode: TextScrollMode.endless,
|
||||
pauseBetween: Duration(milliseconds: 500),
|
||||
velocity: Velocity(pixelsPerSecond: Offset(20, 0)),
|
||||
)),
|
||||
],
|
||||
),
|
||||
)
|
||||
],
|
||||
));
|
||||
},
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
import 'package:auto_size_text/auto_size_text.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_screenutil/flutter_screenutil.dart';
|
||||
import 'package:google_fonts/google_fonts.dart';
|
||||
import 'package:gradient_borders/box_borders/gradient_box_border.dart';
|
||||
import 'package:text_scroll/text_scroll.dart';
|
||||
import 'package:zoom_tap_animation/zoom_tap_animation.dart';
|
||||
|
||||
import '../model/Post.dart';
|
||||
|
||||
class PostComponent extends StatefulWidget {
|
||||
final Function(int)? callback;
|
||||
final Post post;
|
||||
final int index;
|
||||
|
||||
PostComponent({Key? key, required this.callback, required this.post, required this.index}) : super(key: key);
|
||||
|
||||
@override
|
||||
State<PostComponent> createState() => _PostComponentState();
|
||||
}
|
||||
|
||||
class _PostComponentState extends State<PostComponent> with TickerProviderStateMixin {
|
||||
bool choice = false;
|
||||
DateTime today = DateTime.now();
|
||||
|
||||
void switchChoice() {
|
||||
setState(() {
|
||||
choice = !choice;
|
||||
});
|
||||
}
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
print("post: ${widget.post.date.toString()}");
|
||||
print("ajrd: ${DateTime.now().toString()}");
|
||||
super.initState();
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return GestureDetector(
|
||||
onTap: switchChoice,
|
||||
child: LayoutBuilder(
|
||||
builder: (BuildContext context, BoxConstraints constraints) {
|
||||
if (widget.callback == null) {
|
||||
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(
|
||||
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(
|
||||
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(
|
||||
"hier, ${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: () {
|
||||
widget.callback!(widget.index);
|
||||
},
|
||||
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(widget.post.music.cover!),
|
||||
fit: BoxFit.cover,
|
||||
width: double.infinity,
|
||||
),
|
||||
Image(
|
||||
image: AssetImage("assets/images/shadow_post.png"),
|
||||
opacity: AnimationController(vsync: this, value: 0.7),
|
||||
fit: BoxFit.fitHeight,
|
||||
width: double.infinity,
|
||||
),
|
||||
widget.post.description == null
|
||||
? Container()
|
||||
: Padding(
|
||||
padding: EdgeInsets.all(15),
|
||||
child: AutoSizeText(
|
||||
'“${widget.post.description}”',
|
||||
style: GoogleFonts.plusJakartaSans(
|
||||
color: Colors.white, fontWeight: FontWeight.w400, fontSize: 15.sp),
|
||||
maxFontSize: 20,
|
||||
maxLines: 1,
|
||||
),
|
||||
),
|
||||
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(widget.post.selfie!),
|
||||
fit: BoxFit.cover,
|
||||
),
|
||||
),
|
||||
),
|
||||
))
|
||||
: Container(),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
)),
|
||||
SizedBox(height: 15),
|
||||
SizedBox(
|
||||
height: 60,
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Row(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
mainAxisAlignment: MainAxisAlignment.start,
|
||||
children: [
|
||||
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.w600, fontSize: 26.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, fontWeight: FontWeight.w600, fontSize: 26.h),
|
||||
textAlign: TextAlign.end,
|
||||
maxFontSize: 20,
|
||||
),
|
||||
],
|
||||
),
|
||||
Expanded(
|
||||
flex: 8,
|
||||
child: TextScroll(
|
||||
widget.post.music.artists.first.name!,
|
||||
style: GoogleFonts.plusJakartaSans(
|
||||
height: 1,
|
||||
color: Colors.white.withOpacity(0.5),
|
||||
fontWeight: FontWeight.w300,
|
||||
fontSize: 16.h),
|
||||
mode: TextScrollMode.endless,
|
||||
pauseBetween: Duration(milliseconds: 500),
|
||||
velocity: Velocity(pixelsPerSecond: Offset(20, 0)),
|
||||
)),
|
||||
],
|
||||
),
|
||||
)
|
||||
],
|
||||
));
|
||||
},
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
@ -1,13 +1,14 @@
|
||||
import 'package:cloud_firestore/cloud_firestore.dart';
|
||||
|
||||
import '../../main.dart';
|
||||
import '../Comment.dart';
|
||||
import '../User.dart';
|
||||
|
||||
class CommentMapper {
|
||||
static Future<Comment> toModel(DocumentSnapshot<Map<String, dynamic>> snapshot) async {
|
||||
final data = snapshot.data();
|
||||
User? user = await MyApp.userViewModel.getUser(data?['user_id']);
|
||||
return Comment(snapshot.id, user!, data?["text"] ?? "", data?["date"].toDate());
|
||||
}
|
||||
}
|
||||
import 'package:cloud_firestore/cloud_firestore.dart';
|
||||
|
||||
import '../../main.dart';
|
||||
import '../Comment.dart';
|
||||
import '../User.dart';
|
||||
|
||||
class CommentMapper {
|
||||
static Future<Comment> toModel(
|
||||
DocumentSnapshot<Map<String, dynamic>> snapshot) async {
|
||||
final data = snapshot.data();
|
||||
User? user = await MyApp.userViewModel.getUser(data?['user_id']);
|
||||
return Comment(snapshot.id, user!, data?["text"], data?["date"].toDate());
|
||||
}
|
||||
}
|
||||
|
@ -1,242 +1,273 @@
|
||||
import 'dart:async';
|
||||
import 'package:circular_reveal_animation/circular_reveal_animation.dart';
|
||||
import 'package:flutter/cupertino.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter/services.dart';
|
||||
import 'package:flutter_screenutil/flutter_screenutil.dart';
|
||||
import 'package:google_fonts/google_fonts.dart';
|
||||
import 'package:justmusic/main.dart';
|
||||
import 'package:justmusic/main.dart';
|
||||
import 'package:tuple/tuple.dart';
|
||||
import '../components/post_component.dart';
|
||||
import '../components/top_nav_bar_component.dart';
|
||||
import '../model/Post.dart';
|
||||
import '../values/constants.dart';
|
||||
import 'detail_post_screen.dart';
|
||||
|
||||
class FeedScreen extends StatefulWidget {
|
||||
const FeedScreen({Key? key}) : super(key: key);
|
||||
|
||||
@override
|
||||
State<FeedScreen> createState() => _FeedScreenState();
|
||||
}
|
||||
|
||||
class _FeedScreenState extends State<FeedScreen> with SingleTickerProviderStateMixin {
|
||||
late AnimationController animationController;
|
||||
late Animation<double> animation;
|
||||
late List<Post> friendFeed;
|
||||
Timer? timer;
|
||||
|
||||
late List<Post> discoveryFeed;
|
||||
late List<Post> displayFeed;
|
||||
bool isDismissed = true;
|
||||
bool choiceFeed = false;
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
super.initState();
|
||||
friendFeed = MyApp.postViewModel.postsFriends;
|
||||
discoveryFeed = MyApp.postViewModel.bestPosts;
|
||||
animationController = AnimationController(
|
||||
vsync: this,
|
||||
duration: Duration(milliseconds: 400),
|
||||
);
|
||||
animation = CurvedAnimation(
|
||||
parent: animationController,
|
||||
curve: Curves.easeInOutSine,
|
||||
);
|
||||
animationController.forward();
|
||||
}
|
||||
|
||||
Future _refresh() async {
|
||||
if (choiceFeed) {
|
||||
await MyApp.postViewModel.getBestPosts();
|
||||
setState(() {});
|
||||
} else {
|
||||
await MyApp.postViewModel.getPostsFriends();
|
||||
setState(() {});
|
||||
}
|
||||
}
|
||||
|
||||
void changeFeed(bool choice) {
|
||||
// Mettez ici le code pour l'action que vous souhaitez effectuer avec le paramètre
|
||||
if (choice) {
|
||||
setState(() {
|
||||
animationController.reset();
|
||||
displayFeed = MyApp.postViewModel.postsFriends.reversed.toList();
|
||||
animationController.forward();
|
||||
choiceFeed = false;
|
||||
});
|
||||
} else {
|
||||
setState(() {
|
||||
animationController.reset();
|
||||
displayFeed = MyApp.postViewModel.bestPosts.reversed.toList();
|
||||
animationController.forward();
|
||||
choiceFeed = true;
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
void openDetailPost(int index) {
|
||||
showModalBottomSheet(
|
||||
backgroundColor: bgModal,
|
||||
elevation: 1,
|
||||
constraints: const BoxConstraints(
|
||||
maxWidth: 600,
|
||||
),
|
||||
isScrollControlled: true,
|
||||
context: context,
|
||||
shape: const RoundedRectangleBorder(
|
||||
borderRadius: BorderRadius.only(topLeft: Radius.circular(20), topRight: Radius.circular(20))),
|
||||
builder: ((BuildContext context) {
|
||||
return ClipRRect(
|
||||
borderRadius: BorderRadius.only(topLeft: Radius.circular(20), topRight: Radius.circular(20)),
|
||||
child: DetailPostScreen(post: displayFeed[index]));
|
||||
}),
|
||||
);
|
||||
}
|
||||
|
||||
_fetchData() async {
|
||||
friendFeed = await MyApp.postViewModel.getPostsFriends();
|
||||
discoveryFeed = await MyApp.postViewModel.getBestPosts();
|
||||
return Tuple2(friendFeed, displayFeed);
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
if (choiceFeed) {
|
||||
displayFeed = MyApp.postViewModel.postsFriends.reversed.toList();
|
||||
} else {
|
||||
displayFeed = MyApp.postViewModel.bestPosts.reversed.toList();
|
||||
}
|
||||
_fetchData();
|
||||
|
||||
return Scaffold(
|
||||
resizeToAvoidBottomInset: true,
|
||||
backgroundColor: bgColor,
|
||||
extendBodyBehindAppBar: true,
|
||||
body: displayFeed.isEmpty
|
||||
? Container(
|
||||
width: double.infinity,
|
||||
child: Stack(
|
||||
fit: StackFit.expand,
|
||||
children: [
|
||||
Container(
|
||||
decoration: const BoxDecoration(
|
||||
image: DecorationImage(
|
||||
image: AssetImage("assets/images/empty_bg.png"), fit: BoxFit.cover, opacity: 0.3),
|
||||
),
|
||||
child: Padding(
|
||||
padding: EdgeInsets.only(top: 140.h, left: defaultPadding),
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Text("Suis tes amis pour voir leurs capsules",
|
||||
style: GoogleFonts.plusJakartaSans(
|
||||
color: Colors.white, fontSize: 23, fontWeight: FontWeight.w800))
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
Align(
|
||||
alignment: Alignment.topCenter,
|
||||
child: IgnorePointer(
|
||||
child: Container(
|
||||
height: 240.h,
|
||||
decoration: BoxDecoration(
|
||||
gradient: LinearGradient(
|
||||
begin: Alignment.topRight,
|
||||
stops: [0.3, 1],
|
||||
colors: [bgColor.withOpacity(0.9), bgColor.withOpacity(0)])),
|
||||
),
|
||||
),
|
||||
),
|
||||
Align(
|
||||
alignment: Alignment.topCenter,
|
||||
child: ConstrainedBox(
|
||||
constraints: BoxConstraints(maxWidth: 800),
|
||||
child: TopNavBarComponent(callback: changeFeed),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
)
|
||||
: Container(
|
||||
width: double.infinity,
|
||||
height: double.infinity,
|
||||
child: Stack(
|
||||
fit: StackFit.expand,
|
||||
children: [
|
||||
Expanded(
|
||||
child: Align(
|
||||
alignment: Alignment.topCenter,
|
||||
child: CircularRevealAnimation(
|
||||
animation: animation,
|
||||
centerOffset: Offset(30.w, -100),
|
||||
child: Expanded(
|
||||
child: Container(
|
||||
height: double.infinity,
|
||||
constraints: BoxConstraints(maxWidth: 600),
|
||||
padding: EdgeInsets.fromLTRB(defaultPadding, 100.h, defaultPadding, 0),
|
||||
child: Expanded(
|
||||
child: FutureBuilder(
|
||||
future: _fetchData(),
|
||||
builder: (BuildContext context, AsyncSnapshot<dynamic> snapshot) {
|
||||
if (snapshot.hasData) {
|
||||
return RefreshIndicator(
|
||||
displacement: 20,
|
||||
triggerMode: RefreshIndicatorTriggerMode.onEdge,
|
||||
onRefresh: _refresh,
|
||||
child: Expanded(
|
||||
child: ListView.builder(
|
||||
physics: const AlwaysScrollableScrollPhysics(),
|
||||
clipBehavior: Clip.none,
|
||||
shrinkWrap: true,
|
||||
itemCount: displayFeed.length,
|
||||
itemBuilder: (BuildContext context, int index) {
|
||||
return Padding(
|
||||
padding: const EdgeInsets.only(bottom: 40),
|
||||
child: PostComponent(
|
||||
callback: openDetailPost, post: displayFeed[index], index: index),
|
||||
);
|
||||
},
|
||||
),
|
||||
),
|
||||
);
|
||||
} else {
|
||||
return Center(
|
||||
child: CupertinoActivityIndicator(),
|
||||
);
|
||||
}
|
||||
},
|
||||
),
|
||||
)),
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
Align(
|
||||
alignment: Alignment.topCenter,
|
||||
child: IgnorePointer(
|
||||
child: Container(
|
||||
height: 240.h,
|
||||
decoration: BoxDecoration(
|
||||
gradient: LinearGradient(
|
||||
begin: Alignment.topRight,
|
||||
stops: [0.3, 1],
|
||||
colors: [bgColor.withOpacity(0.9), bgColor.withOpacity(0)])),
|
||||
),
|
||||
),
|
||||
),
|
||||
Align(
|
||||
alignment: Alignment.topCenter,
|
||||
child: ConstrainedBox(
|
||||
constraints: BoxConstraints(maxWidth: 800),
|
||||
child: TopNavBarComponent(callback: changeFeed),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
));
|
||||
}
|
||||
}
|
||||
import 'dart:async';
|
||||
import 'package:circular_reveal_animation/circular_reveal_animation.dart';
|
||||
import 'package:flutter/cupertino.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter/services.dart';
|
||||
import 'package:flutter_screenutil/flutter_screenutil.dart';
|
||||
import 'package:google_fonts/google_fonts.dart';
|
||||
import 'package:justmusic/main.dart';
|
||||
import 'package:justmusic/main.dart';
|
||||
import 'package:tuple/tuple.dart';
|
||||
import '../components/post_component.dart';
|
||||
import '../components/top_nav_bar_component.dart';
|
||||
import '../model/Post.dart';
|
||||
import '../values/constants.dart';
|
||||
import 'detail_post_screen.dart';
|
||||
|
||||
class FeedScreen extends StatefulWidget {
|
||||
const FeedScreen({Key? key}) : super(key: key);
|
||||
|
||||
@override
|
||||
State<FeedScreen> createState() => _FeedScreenState();
|
||||
}
|
||||
|
||||
class _FeedScreenState extends State<FeedScreen>
|
||||
with SingleTickerProviderStateMixin {
|
||||
late AnimationController animationController;
|
||||
late Animation<double> animation;
|
||||
late List<Post> friendFeed;
|
||||
Timer? timer;
|
||||
|
||||
late List<Post> discoveryFeed;
|
||||
late List<Post> displayFeed;
|
||||
bool isDismissed = true;
|
||||
bool choiceFeed = false;
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
super.initState();
|
||||
friendFeed = MyApp.postViewModel.postsFriends;
|
||||
discoveryFeed = MyApp.postViewModel.bestPosts;
|
||||
animationController = AnimationController(
|
||||
vsync: this,
|
||||
duration: Duration(milliseconds: 400),
|
||||
);
|
||||
animation = CurvedAnimation(
|
||||
parent: animationController,
|
||||
curve: Curves.easeInOutSine,
|
||||
);
|
||||
animationController.forward();
|
||||
}
|
||||
|
||||
Future _refresh() async {
|
||||
if (choiceFeed) {
|
||||
await MyApp.postViewModel.getBestPosts();
|
||||
setState(() {});
|
||||
} else {
|
||||
await MyApp.postViewModel.getPostsFriends();
|
||||
setState(() {});
|
||||
}
|
||||
}
|
||||
|
||||
void changeFeed(bool choice) {
|
||||
// Mettez ici le code pour l'action que vous souhaitez effectuer avec le paramètre
|
||||
if (choice) {
|
||||
setState(() {
|
||||
animationController.reset();
|
||||
displayFeed = MyApp.postViewModel.postsFriends.reversed.toList();
|
||||
animationController.forward();
|
||||
choiceFeed = false;
|
||||
});
|
||||
} else {
|
||||
setState(() {
|
||||
animationController.reset();
|
||||
displayFeed = MyApp.postViewModel.bestPosts.reversed.toList();
|
||||
animationController.forward();
|
||||
choiceFeed = true;
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
void openDetailPost(int index) {
|
||||
showModalBottomSheet(
|
||||
backgroundColor: bgModal,
|
||||
elevation: 1,
|
||||
constraints: const BoxConstraints(
|
||||
maxWidth: 600,
|
||||
),
|
||||
isScrollControlled: true,
|
||||
context: context,
|
||||
shape: const RoundedRectangleBorder(
|
||||
borderRadius: BorderRadius.only(
|
||||
topLeft: Radius.circular(20), topRight: Radius.circular(20))),
|
||||
builder: ((BuildContext context) {
|
||||
return ClipRRect(
|
||||
borderRadius: BorderRadius.only(
|
||||
topLeft: Radius.circular(20), topRight: Radius.circular(20)),
|
||||
child: DetailPostScreen(post: displayFeed[index]));
|
||||
}),
|
||||
);
|
||||
}
|
||||
|
||||
_fetchData() async {
|
||||
friendFeed = await MyApp.postViewModel.getPostsFriends();
|
||||
discoveryFeed = await MyApp.postViewModel.getBestPosts();
|
||||
return Tuple2(friendFeed, displayFeed);
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
if (choiceFeed) {
|
||||
displayFeed = MyApp.postViewModel.postsFriends.reversed.toList();
|
||||
} else {
|
||||
displayFeed = MyApp.postViewModel.bestPosts.reversed.toList();
|
||||
}
|
||||
_fetchData();
|
||||
|
||||
return Scaffold(
|
||||
resizeToAvoidBottomInset: true,
|
||||
backgroundColor: bgColor,
|
||||
extendBodyBehindAppBar: true,
|
||||
body: displayFeed.isEmpty
|
||||
? Container(
|
||||
width: double.infinity,
|
||||
child: Stack(
|
||||
fit: StackFit.expand,
|
||||
children: [
|
||||
Container(
|
||||
decoration: const BoxDecoration(
|
||||
image: DecorationImage(
|
||||
image: AssetImage("assets/images/empty_bg.png"),
|
||||
fit: BoxFit.cover,
|
||||
opacity: 0.3),
|
||||
),
|
||||
child: Padding(
|
||||
padding:
|
||||
EdgeInsets.only(top: 140.h, left: defaultPadding),
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Text("Suis tes amis pour voir leurs capsules",
|
||||
style: GoogleFonts.plusJakartaSans(
|
||||
color: Colors.white,
|
||||
fontSize: 23,
|
||||
fontWeight: FontWeight.w800))
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
Align(
|
||||
alignment: Alignment.topCenter,
|
||||
child: IgnorePointer(
|
||||
child: Container(
|
||||
height: 240.h,
|
||||
decoration: BoxDecoration(
|
||||
gradient: LinearGradient(
|
||||
begin: Alignment.topRight,
|
||||
stops: [
|
||||
0.3,
|
||||
1
|
||||
],
|
||||
colors: [
|
||||
bgColor.withOpacity(0.9),
|
||||
bgColor.withOpacity(0)
|
||||
])),
|
||||
),
|
||||
),
|
||||
),
|
||||
Align(
|
||||
alignment: Alignment.topCenter,
|
||||
child: ConstrainedBox(
|
||||
constraints: BoxConstraints(maxWidth: 800),
|
||||
child: TopNavBarComponent(callback: changeFeed),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
)
|
||||
: Container(
|
||||
width: double.infinity,
|
||||
height: double.infinity,
|
||||
child: Stack(
|
||||
fit: StackFit.expand,
|
||||
children: [
|
||||
Expanded(
|
||||
child: Align(
|
||||
alignment: Alignment.topCenter,
|
||||
child: CircularRevealAnimation(
|
||||
animation: animation,
|
||||
centerOffset: Offset(30.w, -100),
|
||||
child: Expanded(
|
||||
child: Container(
|
||||
height: double.infinity,
|
||||
constraints: BoxConstraints(maxWidth: 600),
|
||||
padding: EdgeInsets.fromLTRB(
|
||||
defaultPadding, 100.h, defaultPadding, 0),
|
||||
child: Expanded(
|
||||
child: FutureBuilder(
|
||||
future: _fetchData(),
|
||||
builder: (BuildContext context,
|
||||
AsyncSnapshot<dynamic> snapshot) {
|
||||
if (snapshot.hasData) {
|
||||
return RefreshIndicator(
|
||||
displacement: 20,
|
||||
triggerMode:
|
||||
RefreshIndicatorTriggerMode
|
||||
.onEdge,
|
||||
onRefresh: _refresh,
|
||||
child: Expanded(
|
||||
child: ListView.builder(
|
||||
physics:
|
||||
const AlwaysScrollableScrollPhysics(),
|
||||
clipBehavior: Clip.none,
|
||||
shrinkWrap: true,
|
||||
itemCount: displayFeed.length,
|
||||
itemBuilder:
|
||||
(BuildContext context,
|
||||
int index) {
|
||||
return Padding(
|
||||
padding:
|
||||
const EdgeInsets.only(
|
||||
bottom: 40),
|
||||
child: PostComponent(
|
||||
callback: openDetailPost,
|
||||
post: displayFeed[index],
|
||||
index: index),
|
||||
);
|
||||
},
|
||||
),
|
||||
),
|
||||
);
|
||||
} else {
|
||||
return Center(
|
||||
child: CupertinoActivityIndicator(),
|
||||
);
|
||||
}
|
||||
},
|
||||
),
|
||||
)),
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
Align(
|
||||
alignment: Alignment.topCenter,
|
||||
child: IgnorePointer(
|
||||
child: Container(
|
||||
height: 240.h,
|
||||
decoration: BoxDecoration(
|
||||
gradient: LinearGradient(
|
||||
begin: Alignment.topRight,
|
||||
stops: [
|
||||
0.3,
|
||||
1
|
||||
],
|
||||
colors: [
|
||||
bgColor.withOpacity(0.9),
|
||||
bgColor.withOpacity(0)
|
||||
])),
|
||||
),
|
||||
),
|
||||
),
|
||||
Align(
|
||||
alignment: Alignment.topCenter,
|
||||
child: ConstrainedBox(
|
||||
constraints: BoxConstraints(maxWidth: 800),
|
||||
child: TopNavBarComponent(callback: changeFeed),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
));
|
||||
}
|
||||
}
|
||||
|
@ -1,22 +1,28 @@
|
||||
import 'package:cloud_firestore/cloud_firestore.dart';
|
||||
|
||||
import '../main.dart';
|
||||
|
||||
class CommentService {
|
||||
createComment(String text, String idPost) async {
|
||||
var id = MyApp.userViewModel.userCurrent.id;
|
||||
final comment = <String, dynamic>{"user_id": id, "text": text, "date": DateTime.now(), "post_id": idPost};
|
||||
|
||||
await MyApp.db.collection("comments").add(comment);
|
||||
}
|
||||
|
||||
Future<List<QueryDocumentSnapshot<Map<String, dynamic>>>> getCommentsByPostId(String id) async {
|
||||
var response = await FirebaseFirestore.instance
|
||||
.collection("comments")
|
||||
.where("post_id", isEqualTo: id)
|
||||
.orderBy("date", descending: true)
|
||||
.get();
|
||||
|
||||
return response.docs;
|
||||
}
|
||||
}
|
||||
import 'package:cloud_firestore/cloud_firestore.dart';
|
||||
|
||||
import '../main.dart';
|
||||
|
||||
class CommentService {
|
||||
createComment(String text, String idPost) async {
|
||||
var id = MyApp.userViewModel.userCurrent.id;
|
||||
final comment = <String, dynamic>{
|
||||
"user_id": id,
|
||||
"text": text,
|
||||
"date": DateTime.now(),
|
||||
"post_id": idPost
|
||||
};
|
||||
|
||||
await MyApp.db.collection("comments").add(comment);
|
||||
}
|
||||
|
||||
Future<List<QueryDocumentSnapshot<Map<String, dynamic>>>> getCommentsByPostId(
|
||||
String id) async {
|
||||
var response = await FirebaseFirestore.instance
|
||||
.collection("comments")
|
||||
.where("post_id", isEqualTo: id)
|
||||
.orderBy("date", descending: true)
|
||||
.get();
|
||||
|
||||
return response.docs;
|
||||
}
|
||||
}
|
||||
|
@ -0,0 +1,31 @@
|
||||
import 'dart:convert';
|
||||
import 'package:http/http.dart' as http;
|
||||
|
||||
class NotificationService {
|
||||
sendPushMessage(String token, String title, String body) async {
|
||||
try {
|
||||
await http.post(Uri.parse('https://fcm.googleapis.com/fcm/send'),
|
||||
headers: <String, String>{
|
||||
'Content-Type': 'application/json',
|
||||
'Authorization':
|
||||
'key=AAAA56TmIPg:APA91bFeKMr_i6CbUuuUdFI1XkdaNE2A7OVHzxrPIsOSlDfhR6qzZwof7JNGxthWUKj1dRHQMheWNYaLbf3AtXUp9o4DX_gB2073yR4urqUEh9CjvnxVws_9g1cWMgmFS3EpaQEA3icC'
|
||||
},
|
||||
body: jsonEncode(<String, dynamic>{
|
||||
'priority': 'high',
|
||||
'data': <String, dynamic>{
|
||||
'click_action': 'FLUTTER_NOTIFICATION_CLICK',
|
||||
'status': 'done',
|
||||
'body': body,
|
||||
'title': title
|
||||
},
|
||||
"notification": <String, dynamic>{
|
||||
"title": title,
|
||||
"body": body,
|
||||
},
|
||||
"to": token,
|
||||
}));
|
||||
} catch (e) {
|
||||
print("error push notification");
|
||||
}
|
||||
}
|
||||
}
|
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,6 @@
|
||||
import 'package:justmusic/services/NotificationService.dart';
|
||||
|
||||
Future<void> main() async {
|
||||
var notif = NotificationService();
|
||||
await notif.sendPushMessage("cAJAJw_aR7yPQbFTMS-r6H:APA91bEZs34Ab3-xSYeIGykHrxD5pRj-OyODaEcNBPtds1eLzEH0uzFkzCSQY7BvZQHEFPfeHSN7nri4webskXbu1zzgwe9NIdPagsc6IHaouuewWqWd9V7ucTeDeYt1Sbby4-pb6jtA", "Just Music", "Vien voir les nouveautés");
|
||||
}
|
Loading…
Reference in new issue