diff --git a/.idea/libraries/Dart_Packages.xml b/.idea/libraries/Dart_Packages.xml index 1d44074..d31b78d 100644 --- a/.idea/libraries/Dart_Packages.xml +++ b/.idea/libraries/Dart_Packages.xml @@ -156,13 +156,6 @@ - - - - - - @@ -191,6 +184,13 @@ + + + + + + @@ -324,13 +324,6 @@ - - - - - - @@ -527,13 +520,6 @@ - - - - - - @@ -562,13 +548,6 @@ - - - - - - @@ -681,13 +660,6 @@ - - - - - - @@ -850,6 +822,7 @@ + diff --git a/Sources/justMUSIC/assets/images/empty_bg.png b/Sources/justMUSIC/assets/images/empty_bg.png new file mode 100644 index 0000000..96db989 Binary files /dev/null and b/Sources/justMUSIC/assets/images/empty_bg.png differ diff --git a/Sources/justMUSIC/lib/components/editable_post_component.dart b/Sources/justMUSIC/lib/components/editable_post_component.dart index 52fa145..25eec5a 100644 --- a/Sources/justMUSIC/lib/components/editable_post_component.dart +++ b/Sources/justMUSIC/lib/components/editable_post_component.dart @@ -35,8 +35,7 @@ class EditablePostComponent extends StatefulWidget { State createState() => _EditablePostComponentState(); } -class _EditablePostComponentState extends State - with TickerProviderStateMixin { +class _EditablePostComponentState extends State with TickerProviderStateMixin { final ImagePicker picker = ImagePicker(); late Animation animation; late AnimationController animationController; @@ -64,7 +63,10 @@ class _EditablePostComponentState extends State Future pickImage(ImageSource source) async { try { - final image = await ImagePicker().pickImage(source: source); + final image = await ImagePicker().pickImage( + source: source, + imageQuality: 25, + ); if (image == null) return; final imageTemp = File(image.path); setState(() { @@ -102,12 +104,10 @@ class _EditablePostComponentState extends State isScrollControlled: true, context: context, shape: const RoundedRectangleBorder( - borderRadius: BorderRadius.only( - topLeft: Radius.circular(20), topRight: Radius.circular(20))), + borderRadius: BorderRadius.only(topLeft: Radius.circular(20), topRight: Radius.circular(20))), builder: ((context) { return ClipRRect( - borderRadius: BorderRadius.only( - topLeft: Radius.circular(20), topRight: Radius.circular(20)), + borderRadius: BorderRadius.only(topLeft: Radius.circular(20), topRight: Radius.circular(20)), child: SearchCityScreen(callback: _selectLocation)); }), ); @@ -153,8 +153,7 @@ class _EditablePostComponentState extends State width: double.infinity, ) : Image( - image: - NetworkImage(widget.music?.cover ?? ""), + image: NetworkImage(widget.music?.cover ?? ""), fit: BoxFit.cover, width: double.infinity, ), @@ -178,10 +177,7 @@ class _EditablePostComponentState extends State ), color: grayColor, borderRadius: BorderRadius.circular(20), - border: Border.all( - style: BorderStyle.solid, - color: Colors.white, - width: 4)), + border: Border.all(style: BorderStyle.solid, color: Colors.white, width: 4)), child: ClipRRect( borderRadius: BorderRadius.circular(20), child: InstaImageViewer( @@ -209,18 +205,13 @@ class _EditablePostComponentState extends State child: TextScroll( (widget.music?.title)!, style: GoogleFonts.plusJakartaSans( - height: 1, - color: Colors.white, - fontWeight: FontWeight.w600, - fontSize: 26.h), + height: 1, color: Colors.white, fontWeight: FontWeight.w600, fontSize: 26.h), mode: TextScrollMode.endless, pauseBetween: Duration(milliseconds: 500), - velocity: - Velocity(pixelsPerSecond: Offset(20, 0)), + velocity: Velocity(pixelsPerSecond: Offset(20, 0)), )), Padding( - padding: EdgeInsets.only( - bottom: 10.h, right: 5.w, left: 5.w), + padding: EdgeInsets.only(bottom: 10.h, right: 5.w, left: 5.w), child: ClipOval( child: Container( width: 5.h, @@ -236,13 +227,9 @@ class _EditablePostComponentState extends State child: TextScroll( (widget.music?.artists[0].name)!, style: GoogleFonts.plusJakartaSans( - height: 1, - color: Colors.white, - fontWeight: FontWeight.w300, - fontSize: 16.h), + height: 1, color: Colors.white, fontWeight: FontWeight.w300, fontSize: 16.h), mode: TextScrollMode.endless, - velocity: - Velocity(pixelsPerSecond: Offset(50, 20)), + velocity: Velocity(pixelsPerSecond: Offset(50, 20)), pauseBetween: Duration(milliseconds: 500), ), )), @@ -250,9 +237,7 @@ class _EditablePostComponentState extends State AutoSizeText( widget.music?.date.toString() ?? "unknown", style: GoogleFonts.plusJakartaSans( - color: Colors.white.withOpacity(0.5), - fontWeight: FontWeight.w300, - fontSize: 16.h), + color: Colors.white.withOpacity(0.5), fontWeight: FontWeight.w300, fontSize: 16.h), textAlign: TextAlign.end, maxFontSize: 20, ), @@ -306,35 +291,25 @@ class _EditablePostComponentState extends State keyboardAppearance: Brightness.dark, minLines: 1, cursorColor: primaryColor, - style: GoogleFonts.plusJakartaSans( - color: Colors.white, - fontSize: 13, - fontWeight: FontWeight.w300), + style: + GoogleFonts.plusJakartaSans(color: Colors.white, fontSize: 13, fontWeight: FontWeight.w300), maxLines: 4, maxLength: 120, decoration: InputDecoration( - counterStyle: GoogleFonts.plusJakartaSans( - color: grayText, fontSize: 9), + counterStyle: GoogleFonts.plusJakartaSans(color: grayText, fontSize: 9), focusedBorder: const OutlineInputBorder( - borderSide: - BorderSide(width: 0, color: Colors.transparent), - borderRadius: - BorderRadius.all(Radius.circular(10))), - contentPadding: - const EdgeInsets.only(top: 0, bottom: 0, left: 0), + borderSide: BorderSide(width: 0, color: Colors.transparent), + borderRadius: BorderRadius.all(Radius.circular(10))), + contentPadding: const EdgeInsets.only(top: 0, bottom: 0, left: 0), fillColor: Colors.transparent, filled: true, focusColor: Colors.transparent, enabledBorder: const OutlineInputBorder( - borderSide: - BorderSide(width: 0, color: Colors.transparent), - borderRadius: - BorderRadius.all(Radius.circular(10))), + borderSide: BorderSide(width: 0, color: Colors.transparent), + borderRadius: BorderRadius.all(Radius.circular(10))), hintText: 'Description...', - hintStyle: GoogleFonts.plusJakartaSans( - color: grayText, - fontSize: 13, - fontWeight: FontWeight.w300), + hintStyle: + GoogleFonts.plusJakartaSans(color: grayText, fontSize: 13, fontWeight: FontWeight.w300), ), ), )), diff --git a/Sources/justMUSIC/lib/components/post_component.dart b/Sources/justMUSIC/lib/components/post_component.dart index 8b2c594..4d1de01 100644 --- a/Sources/justMUSIC/lib/components/post_component.dart +++ b/Sources/justMUSIC/lib/components/post_component.dart @@ -1,5 +1,4 @@ import 'package:auto_size_text/auto_size_text.dart'; -import 'package:flutter/cupertino.dart'; import 'package:flutter/material.dart'; import 'package:flutter_screenutil/flutter_screenutil.dart'; import 'package:google_fonts/google_fonts.dart'; @@ -336,16 +335,18 @@ class _PostComponentState extends State with TickerProviderStateM fit: BoxFit.fitHeight, width: double.infinity, ), - 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.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, diff --git a/Sources/justMUSIC/lib/screens/feed_screen.dart b/Sources/justMUSIC/lib/screens/feed_screen.dart index 5b0e2de..82026ff 100644 --- a/Sources/justMUSIC/lib/screens/feed_screen.dart +++ b/Sources/justMUSIC/lib/screens/feed_screen.dart @@ -1,5 +1,4 @@ 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'; @@ -49,6 +48,14 @@ class _FeedScreenState extends State with SingleTickerProviderStateM ); } + Future _refresh() async { + print("refresh"); + discoveryFeed = await MyApp.postViewModel.getBestPosts(); + setState(() { + displayFeed = discoveryFeed.reversed.toList(); + }); + } + void changeFeed(bool choice) { // Mettez ici le code pour l'action que vous souhaitez effectuer avec le paramètre if (choice) { @@ -120,9 +127,14 @@ class _FeedScreenState extends State with SingleTickerProviderStateM index: index, ), Container(height: 5), - Text('${displayFeed[index].description ?? ""}', - style: GoogleFonts.plusJakartaSans(color: Colors.white, fontWeight: FontWeight.w200)), - Container(height: 20), + displayFeed[index].description == null + ? Container() + : Padding( + padding: const EdgeInsets.only(bottom: 20), + child: Text('${displayFeed[index].description ?? ""}', + style: GoogleFonts.plusJakartaSans( + color: Colors.white, fontWeight: FontWeight.w200)), + ), Align( child: RichText( text: TextSpan( @@ -214,58 +226,109 @@ class _FeedScreenState extends State with SingleTickerProviderStateM @override Widget build(BuildContext context) { return Scaffold( - resizeToAvoidBottomInset: true, - backgroundColor: bgColor, - extendBodyBehindAppBar: true, - body: Container( - width: double.infinity, - child: Stack( - fit: StackFit.expand, - children: [ - Align( - child: CircularRevealAnimation( - animation: animation, - centerOffset: Offset(30.w, -100), - child: Container( - constraints: BoxConstraints(maxWidth: 600), - padding: EdgeInsets.fromLTRB(defaultPadding, 100.h, defaultPadding, 0), - child: ListView.builder( - physics: const BouncingScrollPhysics(decelerationRate: ScrollDecelerationRate.fast), - 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), - ); - }, - )), - ), - ), - 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)])), + 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), + ), + ), + ], ), - ), - ), - Align( - alignment: Alignment.topCenter, - child: ConstrainedBox( - constraints: BoxConstraints(maxWidth: 800), - child: TopNavBarComponent(callback: changeFeed), - ), - ), - ], - ), - ), - ); + ) + : Container( + width: double.infinity, + child: Stack( + fit: StackFit.expand, + children: [ + Align( + child: CircularRevealAnimation( + animation: animation, + centerOffset: Offset(30.w, -100), + child: Container( + constraints: BoxConstraints(maxWidth: 600), + padding: EdgeInsets.fromLTRB(defaultPadding, 100.h, defaultPadding, 0), + child: RefreshIndicator( + displacement: 20, + triggerMode: RefreshIndicatorTriggerMode.onEdge, + onRefresh: _refresh, + child: ListView.builder( + physics: const BouncingScrollPhysics(decelerationRate: ScrollDecelerationRate.fast), + 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), + ); + }, + ), + )), + ), + ), + 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), + ), + ), + ], + ), + )); } } diff --git a/Sources/justMUSIC/lib/services/PostService.dart b/Sources/justMUSIC/lib/services/PostService.dart index 55921f5..205c8fa 100644 --- a/Sources/justMUSIC/lib/services/PostService.dart +++ b/Sources/justMUSIC/lib/services/PostService.dart @@ -8,8 +8,7 @@ import 'package:firebase_storage/firebase_storage.dart'; import '../main.dart'; class PostService { - createPost(String? description, String idMusic, File? image, - Tuple2? location) async { + createPost(String? description, String idMusic, File? image, Tuple2? location) async { var id = MyApp.userViewModel.userCurrent.id; final post = { "user_id": id, @@ -29,6 +28,7 @@ class PostService { if (userSnapshot.exists) { int currentNbCapsules = userSnapshot.data()?['nbCapsules'] ?? 0; transaction.update(userRef, {'nbCapsules': currentNbCapsules + 1}); + MyApp.userViewModel.userCurrent.capsules++; } }); @@ -44,13 +44,9 @@ class PostService { getPostsById(String id) {} - Future>>> getPopularPosts( - {int limit = 10, int offset = 0}) async { - QuerySnapshot> response = await FirebaseFirestore.instance - .collection("posts") - .limit(limit) - .orderBy("likes").get(); + Future>>> getPopularPosts({int limit = 10, int offset = 0}) async { + QuerySnapshot> response = + await FirebaseFirestore.instance.collection("posts").limit(limit).orderBy("likes").get(); return response.docs; - } } diff --git a/Sources/justMUSIC/lib/view_model/PostViewModel.dart b/Sources/justMUSIC/lib/view_model/PostViewModel.dart index 8bd6d55..9c5aee8 100644 --- a/Sources/justMUSIC/lib/view_model/PostViewModel.dart +++ b/Sources/justMUSIC/lib/view_model/PostViewModel.dart @@ -34,7 +34,7 @@ class PostViewModel { throw new Error(); } - getBestPosts() async { + Future> getBestPosts() async { try { var responseData = await _postService.getPopularPosts(); List ids = []; @@ -47,8 +47,10 @@ class PostViewModel { for (int i = 0; i < _bestPosts.length; i++) { _bestPosts[i].music = musics[i]; } + return _bestPosts; } catch (e) { print(e); + return []; } } diff --git a/Sources/justMUSIC/pubspec.lock b/Sources/justMUSIC/pubspec.lock index 3d4cd76..6de85fb 100644 --- a/Sources/justMUSIC/pubspec.lock +++ b/Sources/justMUSIC/pubspec.lock @@ -209,6 +209,14 @@ packages: url: "https://pub.dev" source: hosted version: "0.0.2" + custom_refresh_indicator: + dependency: "direct main" + description: + name: custom_refresh_indicator + sha256: "65a463f09623f6baf75e45e0c9034e9304810be3f5dfb00a54edde7252f4a524" + url: "https://pub.dev" + source: hosted + version: "2.2.1" fake_async: dependency: transitive description: diff --git a/Sources/justMUSIC/pubspec.yaml b/Sources/justMUSIC/pubspec.yaml index 730fa0d..ab36a1a 100644 --- a/Sources/justMUSIC/pubspec.yaml +++ b/Sources/justMUSIC/pubspec.yaml @@ -68,6 +68,7 @@ dependencies: flutter_countdown_timer: ^4.1.0 intl: ^0.18.1 lottie: ^2.5.0 + custom_refresh_indicator: ^2.2.1 dev_dependencies: flutter_test: