diff --git a/Sources/justMUSIC/assets/images/background_justMusic.png b/Sources/justMUSIC/assets/images/background_justMusic.png new file mode 100644 index 0000000..adf76c5 Binary files /dev/null and b/Sources/justMUSIC/assets/images/background_justMusic.png differ diff --git a/Sources/justMUSIC/assets/images/camera_icon.png b/Sources/justMUSIC/assets/images/camera_icon.png new file mode 100644 index 0000000..ac405eb Binary files /dev/null and b/Sources/justMUSIC/assets/images/camera_icon.png differ diff --git a/Sources/justMUSIC/assets/images/cross_icon.png b/Sources/justMUSIC/assets/images/cross_icon.png new file mode 100644 index 0000000..047be1f Binary files /dev/null and b/Sources/justMUSIC/assets/images/cross_icon.png differ diff --git a/Sources/justMUSIC/assets/images/history_icon.png b/Sources/justMUSIC/assets/images/history_icon.png new file mode 100644 index 0000000..e6edc05 Binary files /dev/null and b/Sources/justMUSIC/assets/images/history_icon.png differ diff --git a/Sources/justMUSIC/assets/images/notification_icon.png b/Sources/justMUSIC/assets/images/notification_icon.png new file mode 100644 index 0000000..148459d Binary files /dev/null and b/Sources/justMUSIC/assets/images/notification_icon.png differ diff --git a/Sources/justMUSIC/assets/images/profile_icon.png b/Sources/justMUSIC/assets/images/profile_icon.png new file mode 100644 index 0000000..bc9701b Binary files /dev/null and b/Sources/justMUSIC/assets/images/profile_icon.png differ diff --git a/Sources/justMUSIC/assets/images/spotify_icon.png b/Sources/justMUSIC/assets/images/spotify_icon.png new file mode 100644 index 0000000..4fc3427 Binary files /dev/null and b/Sources/justMUSIC/assets/images/spotify_icon.png differ diff --git a/Sources/justMUSIC/assets/images/theme_icon.png b/Sources/justMUSIC/assets/images/theme_icon.png new file mode 100644 index 0000000..b849765 Binary files /dev/null and b/Sources/justMUSIC/assets/images/theme_icon.png differ diff --git a/Sources/justMUSIC/assets/images/trash_icon.png b/Sources/justMUSIC/assets/images/trash_icon.png new file mode 100644 index 0000000..f7f8df5 Binary files /dev/null and b/Sources/justMUSIC/assets/images/trash_icon.png differ diff --git a/Sources/justMUSIC/assets/images/unknown.png b/Sources/justMUSIC/assets/images/unknown.png new file mode 100644 index 0000000..f26069a Binary files /dev/null and b/Sources/justMUSIC/assets/images/unknown.png differ diff --git a/Sources/justMUSIC/lib/components/editable_post_component.dart b/Sources/justMUSIC/lib/components/editable_post_component.dart new file mode 100644 index 0000000..c461854 --- /dev/null +++ b/Sources/justMUSIC/lib/components/editable_post_component.dart @@ -0,0 +1,105 @@ +import 'package:flutter/Material.dart'; +import 'package:flutter_screenutil/flutter_screenutil.dart'; +import 'package:google_fonts/google_fonts.dart'; +import 'package:justmusic/values/constants.dart'; + +class EditablePostComponent extends StatefulWidget { + const EditablePostComponent({Key? key}) : super(key: key); + + @override + State createState() => _EditablePostComponentState(); +} + +class _EditablePostComponentState extends State { + @override + Widget build(BuildContext context) { + return ClipRRect( + borderRadius: BorderRadius.circular(25), + child: Container( + width: double.infinity, + color: warningBttnColor, + child: Column( + children: [ + AspectRatio( + aspectRatio: 1 / 1, + child: Container( + decoration: BoxDecoration( + // add border + border: Border.all(width: 3.0, color: grayColor), + // set border radius + borderRadius: BorderRadius.circular(20), + ), + child: ClipRRect( + borderRadius: BorderRadius.circular(18), + // implement image + child: Image( + image: AssetImage("assets/images/exemple_cover.png"), + fit: BoxFit.cover, + width: double.infinity, + ), + ), + ), + ), + Padding( + padding: EdgeInsets.fromLTRB(15.sp, 25.sp, 15.sp, 25.sp), + child: Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + Text("France, Lyon", + style: GoogleFonts.plusJakartaSans( + color: Colors.white, fontSize: 13.sp)), + Image( + image: AssetImage("assets/images/camera_icon.png"), + width: 30, + ), + Text("10 Juil. 2023", + style: GoogleFonts.plusJakartaSans( + color: Colors.white, fontSize: 13.sp)), + ], + ), + ), + Padding( + padding: EdgeInsets.fromLTRB(15.sp, 0, 10.sp, 25.sp), + child: SizedBox( + width: double.infinity, + child: TextFormField( + keyboardAppearance: Brightness.dark, + minLines: 1, + cursorColor: primaryColor, + style: GoogleFonts.plusJakartaSans( + color: Colors.white, + fontSize: 13.sp, + fontWeight: FontWeight.w300), + maxLines: 4, + maxLength: 120, + decoration: InputDecoration( + counterStyle: GoogleFonts.plusJakartaSans( + color: grayText, fontSize: 9.sp), + 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), + fillColor: Colors.transparent, + filled: true, + focusColor: Colors.transparent, + enabledBorder: const OutlineInputBorder( + borderSide: + BorderSide(width: 0, color: Colors.transparent), + borderRadius: + BorderRadius.all(Radius.circular(10))), + hintText: 'Description...', + hintStyle: GoogleFonts.plusJakartaSans( + color: grayText, + fontSize: 13.sp, + fontWeight: FontWeight.w300), + ), + ), + )), + ], + ), + )); + } +} diff --git a/Sources/justMUSIC/lib/components/post_button_component.dart b/Sources/justMUSIC/lib/components/post_button_component.dart new file mode 100644 index 0000000..96c0d06 --- /dev/null +++ b/Sources/justMUSIC/lib/components/post_button_component.dart @@ -0,0 +1,32 @@ +import 'package:flutter/Material.dart'; +import 'package:google_fonts/google_fonts.dart'; +import 'package:flutter_screenutil/flutter_screenutil.dart'; + +class PostButtonComponent extends StatelessWidget { + const PostButtonComponent({Key? key}) : super(key: key); + + @override + Widget build(BuildContext context) { + return Container( + decoration: BoxDecoration( + gradient: LinearGradient(colors: [ + Color(0xFF141414), + Color(0xFF272727), + Color(0xFF141414) + ]), + borderRadius: BorderRadius.circular(10000)), + padding: EdgeInsets.symmetric(vertical: 25.sp), + width: double.infinity, + child: Align( + child: Text( + "Publier la capsule", + style: GoogleFonts.plusJakartaSans( + color: Color(0xFF474747), + fontWeight: FontWeight.w800, + fontStyle: FontStyle.italic, + fontSize: 24.sp), + ), + ), + ); + } +} diff --git a/Sources/justMUSIC/lib/components/profile_component.dart b/Sources/justMUSIC/lib/components/profile_component.dart index d5dda14..d70adb5 100644 --- a/Sources/justMUSIC/lib/components/profile_component.dart +++ b/Sources/justMUSIC/lib/components/profile_component.dart @@ -5,8 +5,11 @@ import 'package:flutter_screenutil/flutter_screenutil.dart'; import 'package:google_fonts/google_fonts.dart'; import 'package:justmusic/components/statistics_component.dart'; +import '../model/User.dart'; + class ProfileComponent extends StatelessWidget { - const ProfileComponent({Key? key}) : super(key: key); + final User user; + const ProfileComponent({Key? key, required this.user}) : super(key: key); @override Widget build(BuildContext context) { @@ -26,7 +29,7 @@ class ProfileComponent extends StatelessWidget { height: 10, ), AutoSizeText( - "@MelinaShow", + "@${user.pseudo}", style: GoogleFonts.plusJakartaSans( fontSize: 15.sp, color: Colors.white, @@ -36,7 +39,9 @@ class ProfileComponent extends StatelessWidget { SizedBox( height: 20, ), - StatisticsComponent(), + StatisticsComponent( + user: user, + ), ], ); } diff --git a/Sources/justMUSIC/lib/components/search_bar_component.dart b/Sources/justMUSIC/lib/components/search_bar_component.dart new file mode 100644 index 0000000..0aa0a3e --- /dev/null +++ b/Sources/justMUSIC/lib/components/search_bar_component.dart @@ -0,0 +1,32 @@ +import 'package:flutter/Material.dart'; +import 'package:flutter_screenutil/flutter_screenutil.dart'; +import 'package:google_fonts/google_fonts.dart'; + +import '../values/constants.dart'; + +class SearchBarComponent extends StatefulWidget { + final String? text; + const SearchBarComponent({Key? key, this.text}) : super(key: key); + + @override + State createState() => _SearchBarComponentState(); +} + +class _SearchBarComponentState extends State { + @override + Widget build(BuildContext context) { + return ClipRRect( + borderRadius: BorderRadius.all(Radius.circular(20)), + child: Container( + color: searchBarColor, + width: double.infinity, + padding: + EdgeInsets.fromLTRB(defaultPadding, 16.sp, defaultPadding, 16.sp), + child: Text( + widget.text ?? "Chercher une musique...", + style: GoogleFonts.plusJakartaSans(color: Colors.white), + ), + ), + ); + } +} diff --git a/Sources/justMUSIC/lib/components/setting_part_component.dart b/Sources/justMUSIC/lib/components/setting_part_component.dart new file mode 100644 index 0000000..4541391 --- /dev/null +++ b/Sources/justMUSIC/lib/components/setting_part_component.dart @@ -0,0 +1,69 @@ +import 'package:flutter/material.dart'; +import 'package:google_fonts/google_fonts.dart'; +import 'package:justmusic/values/icons.dart'; + +import '../values/constants.dart'; + +class SettingPartComponent extends StatelessWidget { + final JustMusicIcon icon; + final String label; + final bool important; + const SettingPartComponent( + {Key? key, + required this.icon, + required this.label, + this.important = false}) + : super(key: key); + + @override + Widget build(BuildContext context) { + return Material( + color: important ? warningBttnColor : settingColor, + borderOnForeground: false, + child: InkWell( + onTap: () { + print('InkWell was tapped!'); + }, + splashColor: Colors.transparent, + highlightColor: Colors.white.withOpacity(0.08), + child: Container( + width: double.infinity, + child: Padding( + padding: const EdgeInsets.fromLTRB( + defaultPadding, 19, defaultPadding, 19), + child: Row( + children: [ + Image( + image: AssetImage(icon.imagePath), + width: 13, + ), + const SizedBox( + width: 15, + ), + Expanded( + flex: 10, + child: Text( + label, + overflow: TextOverflow.ellipsis, + style: GoogleFonts.plusJakartaSans( + color: Colors.white, fontWeight: FontWeight.w700), + ), + ), + Spacer(), + Transform( + alignment: Alignment.center, + transform: Matrix4.rotationY(3.14159265), + child: Image( + image: AssetImage("assets/images/return_icon.png"), + height: 11, + opacity: const AlwaysStoppedAnimation(.5), + ), + ), + ], + ), + ), + ), + ), + ); + } +} diff --git a/Sources/justMUSIC/lib/components/statistics_component.dart b/Sources/justMUSIC/lib/components/statistics_component.dart index 436e37c..6324318 100644 --- a/Sources/justMUSIC/lib/components/statistics_component.dart +++ b/Sources/justMUSIC/lib/components/statistics_component.dart @@ -4,10 +4,12 @@ import 'package:flutter/material.dart'; import 'package:flutter_screenutil/flutter_screenutil.dart'; import 'package:google_fonts/google_fonts.dart'; +import '../model/User.dart'; import '../values/constants.dart'; class StatisticsComponent extends StatelessWidget { - const StatisticsComponent({Key? key}) : super(key: key); + final User user; + const StatisticsComponent({Key? key, required this.user}) : super(key: key); @override Widget build(BuildContext context) { @@ -18,7 +20,7 @@ class StatisticsComponent extends StatelessWidget { child: Column( children: [ AutoSizeText( - "114", + user.followed.toString(), style: GoogleFonts.plusJakartaSans( color: Colors.white, fontWeight: FontWeight.bold, @@ -38,7 +40,7 @@ class StatisticsComponent extends StatelessWidget { mainAxisSize: MainAxisSize.min, children: [ AutoSizeText( - "5", + user.followers.toString(), style: GoogleFonts.plusJakartaSans( color: Colors.white, fontWeight: FontWeight.bold, @@ -58,7 +60,7 @@ class StatisticsComponent extends StatelessWidget { mainAxisSize: MainAxisSize.min, children: [ AutoSizeText( - "34", + user.capsules.toString(), style: GoogleFonts.plusJakartaSans( color: Colors.white, fontWeight: FontWeight.bold, diff --git a/Sources/justMUSIC/lib/main.dart b/Sources/justMUSIC/lib/main.dart index 49cae25..f2a3bb2 100644 --- a/Sources/justMUSIC/lib/main.dart +++ b/Sources/justMUSIC/lib/main.dart @@ -1,13 +1,15 @@ import 'package:flutter/material.dart'; import 'package:flutter/services.dart'; import 'package:flutter_screenutil/flutter_screenutil.dart'; -import 'package:justmusic/screens/profile_screen.dart'; +import 'package:justmusic/screens/post_screen.dart'; +import 'package:justmusic/view_model/UserViewModel.dart'; void main() { runApp(const MyApp()); } class MyApp extends StatelessWidget { + static UserViewModel userViewModel = UserViewModel(); const MyApp({super.key}); // This widget is the root of your application. @@ -32,7 +34,7 @@ class MyApp extends StatelessWidget { primarySwatch: Colors.blue, ), home: const SafeArea( - child: ProfileScreen(), + child: PostScreen(), )); }, designSize: Size(390, 844), diff --git a/Sources/justMUSIC/lib/model/User.dart b/Sources/justMUSIC/lib/model/User.dart index f9a7607..f601867 100644 --- a/Sources/justMUSIC/lib/model/User.dart +++ b/Sources/justMUSIC/lib/model/User.dart @@ -4,10 +4,14 @@ class User { String _country; String _mail; String _pp; + int _followers; + int _capsules; + int _followed; List friends = []; // Constructor - User(this._id, this._pseudo, this._country, this._mail, this._pp); + User(this._id, this._pseudo, this._country, this._mail, this._pp, + this._followers, this._capsules, this._followed, this.friends); //Getters and setters int get id => _id; @@ -35,4 +39,22 @@ class User { set pp(String value) { _pp = value; } + + int get capsules => _capsules; + + set capsules(int value) { + _capsules = value; + } + + int get followed => _followed; + + set followed(int value) { + _followed = value; + } + + int get followers => _followers; + + set followers(int value) { + _followers = value; + } } diff --git a/Sources/justMUSIC/lib/screens/login_screen.dart b/Sources/justMUSIC/lib/screens/login_screen.dart index 128ea86..778d76d 100644 --- a/Sources/justMUSIC/lib/screens/login_screen.dart +++ b/Sources/justMUSIC/lib/screens/login_screen.dart @@ -17,7 +17,6 @@ class LoginScreen extends StatefulWidget { class _LoginScreenState extends State { bool passenable = true; - final _focusNode = FocusNode(); final _formKey = GlobalKey(); @override @@ -97,6 +96,8 @@ class _LoginScreenState extends State { CrossAxisAlignment.end, children: [ TextFormField( + keyboardAppearance: + Brightness.dark, validator: (value) { if (value == null || value.isEmpty) { @@ -147,6 +148,8 @@ class _LoginScreenState extends State { height: 18, ), TextFormField( + keyboardAppearance: + Brightness.dark, obscureText: passenable, validator: (value) { if (value == null || @@ -430,6 +433,8 @@ class _LoginScreenState extends State { CrossAxisAlignment.end, children: [ TextFormField( + keyboardAppearance: + Brightness.dark, validator: (value) { if (value == null || value.isEmpty) { @@ -480,6 +485,8 @@ class _LoginScreenState extends State { height: 18, ), TextFormField( + keyboardAppearance: + Brightness.dark, obscureText: passenable, validator: (value) { if (value == null || diff --git a/Sources/justMUSIC/lib/screens/post_screen.dart b/Sources/justMUSIC/lib/screens/post_screen.dart new file mode 100644 index 0000000..641bdfa --- /dev/null +++ b/Sources/justMUSIC/lib/screens/post_screen.dart @@ -0,0 +1,60 @@ +import 'package:flutter/Material.dart'; +import 'package:flutter_screenutil/flutter_screenutil.dart'; + +import '../components/editable_post_component.dart'; +import '../components/post_button_component.dart'; +import '../components/search_bar_component.dart'; +import '../values/constants.dart'; + +class PostScreen extends StatefulWidget { + const PostScreen({Key? key}) : super(key: key); + + @override + State createState() => _PostScreenState(); +} + +class _PostScreenState extends State { + final scrollController = ScrollController(); + @override + Widget build(BuildContext context) { + return Scaffold( + resizeToAvoidBottomInset: true, + backgroundColor: bgColor, + body: Container( + padding: EdgeInsets.only( + left: defaultPadding, top: defaultPadding, right: defaultPadding), + width: double.infinity, + height: double.infinity, + decoration: const BoxDecoration( + image: DecorationImage( + image: AssetImage("assets/images/background_justMusic.png"), + fit: BoxFit.cover, + ), + ), + child: Stack( + children: [ + SingleChildScrollView( + controller: scrollController, + child: Column( + mainAxisAlignment: MainAxisAlignment.end, + children: [ + SizedBox( + height: 150.h, + ), + EditablePostComponent(), + SizedBox( + height: 40.sp, + ), + PostButtonComponent(), + SizedBox( + height: 40.sp, + ), + ], + ), + ), + SearchBarComponent(), + ], + )), + ); + } +} diff --git a/Sources/justMUSIC/lib/screens/profile_screen.dart b/Sources/justMUSIC/lib/screens/profile_screen.dart index 9c544b5..a98b6e5 100644 --- a/Sources/justMUSIC/lib/screens/profile_screen.dart +++ b/Sources/justMUSIC/lib/screens/profile_screen.dart @@ -2,8 +2,10 @@ import 'package:flutter/cupertino.dart'; import 'package:flutter/material.dart'; import 'package:flutter_screenutil/flutter_screenutil.dart'; import 'package:google_fonts/google_fonts.dart'; - +import 'package:justmusic/values/icons.dart'; import '../components/profile_component.dart'; +import '../components/setting_part_component.dart'; +import '../main.dart'; import '../values/constants.dart'; class ProfileScreen extends StatefulWidget { @@ -57,16 +59,75 @@ class _ProfileScreenState extends State { crossAxisAlignment: CrossAxisAlignment.start, children: [ Padding( - padding: EdgeInsets.only(top: 68.h), - child: ProfileComponent(), + padding: EdgeInsets.only(top: 68.h, bottom: 40), + child: + ProfileComponent(user: MyApp.userViewModel.userCurrent), + ), + Padding( + padding: + const EdgeInsets.only(bottom: 12, left: defaultPadding), + child: Text( + "Compte", + style: GoogleFonts.plusJakartaSans( + color: grayText, + fontWeight: FontWeight.w800, + fontSize: 16), + ), + ), + ClipRRect( + borderRadius: BorderRadius.circular(8), + child: Column( + children: const [ + SettingPartComponent( + icon: JustMusicIcon.profile, + label: 'Compte', + ), + SettingPartComponent( + icon: JustMusicIcon.history, + label: 'Historiques des capsules', + ), + SettingPartComponent( + icon: JustMusicIcon.spotify, + label: 'Lier un compte Spotify', + ), + SettingPartComponent( + icon: JustMusicIcon.trash, + label: 'Supprimer mon compte', + ), + SettingPartComponent( + icon: JustMusicIcon.cross, + label: 'Déconnexion', + important: true, + ), + ], + ), ), - Text( - "Compte", - style: GoogleFonts.plusJakartaSans( - color: grayText, - fontWeight: FontWeight.w800, - fontSize: 16), + Padding( + padding: const EdgeInsets.only( + bottom: 12, left: defaultPadding, top: 40), + child: Text( + "Préférences", + style: GoogleFonts.plusJakartaSans( + color: grayText, + fontWeight: FontWeight.w800, + fontSize: 16), + ), ), + ClipRRect( + borderRadius: BorderRadius.circular(8), + child: Column( + children: const [ + SettingPartComponent( + icon: JustMusicIcon.theme, + label: 'Thême de l\'application', + ), + SettingPartComponent( + icon: JustMusicIcon.notification, + label: 'Notifications', + ), + ], + ), + ) ], ), ), diff --git a/Sources/justMUSIC/lib/screens/registration_screen.dart b/Sources/justMUSIC/lib/screens/registration_screen.dart index b686e48..679fd11 100644 --- a/Sources/justMUSIC/lib/screens/registration_screen.dart +++ b/Sources/justMUSIC/lib/screens/registration_screen.dart @@ -83,6 +83,7 @@ class _RegistrationScreenState extends State { left: defaultPadding, right: defaultPadding), child: TextFormField( + keyboardAppearance: Brightness.dark, validator: (value) { if (value == null || value.isEmpty) { return 'TODO'; @@ -120,6 +121,7 @@ class _RegistrationScreenState extends State { left: defaultPadding, right: defaultPadding), child: TextFormField( + keyboardAppearance: Brightness.dark, validator: (value) { if (value == null || value.isEmpty) { return 'TODO'; @@ -157,6 +159,7 @@ class _RegistrationScreenState extends State { left: defaultPadding, right: defaultPadding), child: TextFormField( + keyboardAppearance: Brightness.dark, obscureText: passenable, validator: (value) { if (value == null || value.isEmpty) { @@ -221,6 +224,7 @@ class _RegistrationScreenState extends State { left: defaultPadding, right: defaultPadding), child: TextFormField( + keyboardAppearance: Brightness.dark, obscureText: passenable, validator: (value) { if (value == null || value.isEmpty) { diff --git a/Sources/justMUSIC/lib/values/constants.dart b/Sources/justMUSIC/lib/values/constants.dart index fd0d761..4940a15 100644 --- a/Sources/justMUSIC/lib/values/constants.dart +++ b/Sources/justMUSIC/lib/values/constants.dart @@ -17,7 +17,8 @@ const bgModal = Color(0xFF1E1E1E); const bgComment = Color(0xFF222222); const bgAppBar = Color(0xFF181818); const grayText = Color(0xFF898989); - +const settingColor = Color(0xFF232323); +const searchBarColor = Color(0xFF161616); // All constants important too us const defaultPadding = 30.0; diff --git a/Sources/justMUSIC/lib/values/icons.dart b/Sources/justMUSIC/lib/values/icons.dart new file mode 100644 index 0000000..1cd01d1 --- /dev/null +++ b/Sources/justMUSIC/lib/values/icons.dart @@ -0,0 +1,33 @@ +enum JustMusicIcon { + profile, + spotify, + trash, + cross, + history, + theme, + notification +} + +extension MyIconExtension on JustMusicIcon { + String get imagePath { + switch (this) { + case JustMusicIcon.profile: + return 'assets/images/profile_icon.png'; + case JustMusicIcon.spotify: + return 'assets/images/spotify_icon.png'; + case JustMusicIcon.trash: + return 'assets/images/trash_icon.png'; + case JustMusicIcon.cross: + return 'assets/images/cross_icon.png'; + case JustMusicIcon.history: + return 'assets/images/history_icon.png'; + case JustMusicIcon.theme: + return 'assets/images/theme_icon.png'; + case JustMusicIcon.notification: + return 'assets/images/notification_icon.png'; + + default: + throw 'assets/images/unknown.png'; + } + } +} diff --git a/Sources/justMUSIC/lib/view_model/UserViewModel.dart b/Sources/justMUSIC/lib/view_model/UserViewModel.dart index bea7efd..2aaa1fb 100644 --- a/Sources/justMUSIC/lib/view_model/UserViewModel.dart +++ b/Sources/justMUSIC/lib/view_model/UserViewModel.dart @@ -1,9 +1,15 @@ import '../model/User.dart'; class UserViewModel { - User? _userCurrent; + User _userCurrent = User( + 1, "MelinaShow", "France", "test@gmail.com", "zezrzrzr", 5, 12, 114, []); + + User get userCurrent => _userCurrent; + + set userCurrent(User value) { + _userCurrent = value; + } // Constructor - // Constructor UserViewModel(); // Methods