diff --git a/.idea/Project_JustMusic.iml b/.idea/Project_JustMusic.iml index d0f497c..0e67cf3 100644 --- a/.idea/Project_JustMusic.iml +++ b/.idea/Project_JustMusic.iml @@ -9,5 +9,7 @@ + + \ No newline at end of file diff --git a/.idea/libraries/Dart_Packages.xml b/.idea/libraries/Dart_Packages.xml new file mode 100644 index 0000000..0a71dbc --- /dev/null +++ b/.idea/libraries/Dart_Packages.xml @@ -0,0 +1,436 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/.idea/libraries/Dart_SDK.xml b/.idea/libraries/Dart_SDK.xml new file mode 100644 index 0000000..6ae284f --- /dev/null +++ b/.idea/libraries/Dart_SDK.xml @@ -0,0 +1,27 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/Sources/justMUSIC/lib/main.dart b/Sources/justMUSIC/lib/main.dart index e016029..a633f84 100644 --- a/Sources/justMUSIC/lib/main.dart +++ b/Sources/justMUSIC/lib/main.dart @@ -1,4 +1,7 @@ import 'package:flutter/material.dart'; +import 'package:flutter/services.dart'; +import 'package:flutter_screenutil/flutter_screenutil.dart'; +import 'package:justmusic/screens/feed_screen.dart'; void main() { runApp(const MyApp()); @@ -10,106 +13,29 @@ class MyApp extends StatelessWidget { // This widget is the root of your application. @override Widget build(BuildContext context) { - return MaterialApp( - title: 'Flutter Demo', - theme: ThemeData( - // This is the theme of your application. - // - // Try running your application with "flutter run". You'll see the - // application has a blue toolbar. Then, without quitting the app, try - // changing the primarySwatch below to Colors.green and then invoke - // "hot reload" (press "r" in the console where you ran "flutter run", - // or simply save your changes to "hot reload" in a Flutter IDE). - // Notice that the counter didn't reset back to zero; the application - // is not restarted. - primarySwatch: Colors.blue, - ), - home: const MyHomePage(title: 'Flutter Demo Home Page'), - ); - } -} - -class MyHomePage extends StatefulWidget { - const MyHomePage({super.key, required this.title}); - - // This widget is the home page of your application. It is stateful, meaning - // that it has a State object (defined below) that contains fields that affect - // how it looks. - - // This class is the configuration for the state. It holds the values (in this - // case the title) provided by the parent (in this case the App widget) and - // used by the build method of the State. Fields in a Widget subclass are - // always marked "final". - - final String title; - - @override - State createState() => _MyHomePageState(); -} - -class _MyHomePageState extends State { - int _counter = 0; - - void _incrementCounter() { - setState(() { - // This call to setState tells the Flutter framework that something has - // changed in this State, which causes it to rerun the build method below - // so that the display can reflect the updated values. If we changed - // _counter without calling setState(), then the build method would not be - // called again, and so nothing would appear to happen. - _counter++; - }); - } - - @override - Widget build(BuildContext context) { - // This method is rerun every time setState is called, for instance as done - // by the _incrementCounter method above. - // - // The Flutter framework has been optimized to make rerunning build methods - // fast, so that you can just rebuild anything that needs updating rather - // than having to individually change instances of widgets. - return Scaffold( - appBar: AppBar( - // Here we take the value from the MyHomePage object that was created by - // the App.build method, and use it to set our appbar title. - title: Text(widget.title), - ), - body: Center( - // Center is a layout widget. It takes a single child and positions it - // in the middle of the parent. - child: Column( - // Column is also a layout widget. It takes a list of children and - // arranges them vertically. By default, it sizes itself to fit its - // children horizontally, and tries to be as tall as its parent. - // - // Invoke "debug painting" (press "p" in the console, choose the - // "Toggle Debug Paint" action from the Flutter Inspector in Android - // Studio, or the "Toggle Debug Paint" command in Visual Studio Code) - // to see the wireframe for each widget. - // - // Column has various properties to control how it sizes itself and - // how it positions its children. Here we use mainAxisAlignment to - // center the children vertically; the main axis here is the vertical - // axis because Columns are vertical (the cross axis would be - // horizontal). - mainAxisAlignment: MainAxisAlignment.center, - children: [ - const Text( - 'You have pushed the button this many times:', - ), - Text( - '$_counter', - style: Theme.of(context).textTheme.headline4, + SystemChrome.setEnabledSystemUIMode(SystemUiMode.immersiveSticky); + Paint.enableDithering = true; + return ScreenUtilInit( + builder: (context, child) { + return MaterialApp( + debugShowCheckedModeBanner: false, + theme: ThemeData( + // This is the theme of your application. + // + // Try running your application with "flutter run". You'll see the + // application has a blue toolbar. Then, without quitting the app, try + // changing the primarySwatch below to Colors.green and then invoke + // "hot reload" (press "r" in the console where you ran "flutter run", + // or simply save your changes to "hot reload" in a Flutter IDE). + // Notice that the counter didn't reset back to zero; the application + // is not restarted. + primarySwatch: Colors.blue, ), - ], - ), - ), - floatingActionButton: FloatingActionButton( - onPressed: _incrementCounter, - tooltip: 'Increment', - child: const Icon(Icons.add), - ), // This trailing comma makes auto-formatting nicer for build methods. + home: const SafeArea( + child: FeedScreen(), + )); + }, + designSize: Size(390, 844), ); } } diff --git a/Sources/justMUSIC/pubspec.lock b/Sources/justMUSIC/pubspec.lock index 4fe9359..adfb5cd 100644 --- a/Sources/justMUSIC/pubspec.lock +++ b/Sources/justMUSIC/pubspec.lock @@ -8,6 +8,13 @@ packages: url: "https://pub.dartlang.org" source: hosted version: "2.9.0" + auto_size_text: + dependency: "direct main" + description: + name: auto_size_text + url: "https://pub.dartlang.org" + source: hosted + version: "3.0.0" boolean_selector: dependency: transitive description: @@ -22,6 +29,13 @@ packages: url: "https://pub.dartlang.org" source: hosted version: "1.2.1" + circular_reveal_animation: + dependency: "direct main" + description: + name: circular_reveal_animation + url: "https://pub.dartlang.org" + source: hosted + version: "2.0.1" clock: dependency: transitive description: @@ -36,6 +50,13 @@ packages: url: "https://pub.dartlang.org" source: hosted version: "1.16.0" + crypto: + dependency: transitive + description: + name: crypto + url: "https://pub.dartlang.org" + source: hosted + version: "3.0.2" cupertino_icons: dependency: "direct main" description: @@ -43,6 +64,13 @@ packages: url: "https://pub.dartlang.org" source: hosted version: "1.0.5" + custom_draggable_widget: + dependency: "direct main" + description: + name: custom_draggable_widget + url: "https://pub.dartlang.org" + source: hosted + version: "0.0.2" fake_async: dependency: transitive description: @@ -50,6 +78,20 @@ packages: url: "https://pub.dartlang.org" source: hosted version: "1.3.1" + ffi: + dependency: transitive + description: + name: ffi + url: "https://pub.dartlang.org" + source: hosted + version: "2.0.2" + file: + dependency: transitive + description: + name: file + url: "https://pub.dartlang.org" + source: hosted + version: "6.1.4" flutter: dependency: "direct main" description: flutter @@ -62,11 +104,67 @@ packages: url: "https://pub.dartlang.org" source: hosted version: "2.0.2" + flutter_screenutil: + dependency: "direct main" + description: + name: flutter_screenutil + url: "https://pub.dartlang.org" + source: hosted + version: "5.7.0" + flutter_signin_button: + dependency: "direct main" + description: + name: flutter_signin_button + url: "https://pub.dartlang.org" + source: hosted + version: "2.0.0" flutter_test: dependency: "direct dev" description: flutter source: sdk version: "0.0.0" + font_awesome_flutter: + dependency: transitive + description: + name: font_awesome_flutter + url: "https://pub.dartlang.org" + source: hosted + version: "9.2.0" + google_fonts: + dependency: "direct main" + description: + name: google_fonts + url: "https://pub.dartlang.org" + source: hosted + version: "4.0.4" + gradiantbutton: + dependency: "direct main" + description: + name: gradiantbutton + url: "https://pub.dartlang.org" + source: hosted + version: "0.0.1" + gradient_borders: + dependency: "direct main" + description: + name: gradient_borders + url: "https://pub.dartlang.org" + source: hosted + version: "1.0.0" + http: + dependency: transitive + description: + name: http + url: "https://pub.dartlang.org" + source: hosted + version: "0.13.5" + http_parser: + dependency: transitive + description: + name: http_parser + url: "https://pub.dartlang.org" + source: hosted + version: "4.0.2" lints: dependency: transitive description: @@ -95,6 +193,13 @@ packages: url: "https://pub.dartlang.org" source: hosted version: "1.8.0" + modal_bottom_sheet: + dependency: "direct main" + description: + name: modal_bottom_sheet + url: "https://pub.dartlang.org" + source: hosted + version: "2.1.2" path: dependency: transitive description: @@ -102,11 +207,81 @@ packages: url: "https://pub.dartlang.org" source: hosted version: "1.8.2" + path_provider: + dependency: transitive + description: + name: path_provider + url: "https://pub.dartlang.org" + source: hosted + version: "2.0.15" + path_provider_android: + dependency: transitive + description: + name: path_provider_android + url: "https://pub.dartlang.org" + source: hosted + version: "2.0.27" + path_provider_foundation: + dependency: transitive + description: + name: path_provider_foundation + url: "https://pub.dartlang.org" + source: hosted + version: "2.2.3" + path_provider_linux: + dependency: transitive + description: + name: path_provider_linux + url: "https://pub.dartlang.org" + source: hosted + version: "2.1.11" + path_provider_platform_interface: + dependency: transitive + description: + name: path_provider_platform_interface + url: "https://pub.dartlang.org" + source: hosted + version: "2.0.6" + path_provider_windows: + dependency: transitive + description: + name: path_provider_windows + url: "https://pub.dartlang.org" + source: hosted + version: "2.1.7" + platform: + dependency: transitive + description: + name: platform + url: "https://pub.dartlang.org" + source: hosted + version: "3.1.0" + plugin_platform_interface: + dependency: transitive + description: + name: plugin_platform_interface + url: "https://pub.dartlang.org" + source: hosted + version: "2.1.4" + process: + dependency: transitive + description: + name: process + url: "https://pub.dartlang.org" + source: hosted + version: "4.2.4" sky_engine: dependency: transitive description: flutter source: sdk version: "0.0.99" + smooth_corner: + dependency: "direct main" + description: + name: smooth_corner + url: "https://pub.dartlang.org" + source: hosted + version: "1.1.0" source_span: dependency: transitive description: @@ -149,6 +324,20 @@ packages: url: "https://pub.dartlang.org" source: hosted version: "0.4.12" + text_scroll: + dependency: "direct main" + description: + name: text_scroll + url: "https://pub.dartlang.org" + source: hosted + version: "0.2.0" + typed_data: + dependency: transitive + description: + name: typed_data + url: "https://pub.dartlang.org" + source: hosted + version: "1.3.2" vector_math: dependency: transitive description: @@ -156,5 +345,27 @@ packages: url: "https://pub.dartlang.org" source: hosted version: "2.1.2" + win32: + dependency: transitive + description: + name: win32 + url: "https://pub.dartlang.org" + source: hosted + version: "4.1.4" + xdg_directories: + dependency: transitive + description: + name: xdg_directories + url: "https://pub.dartlang.org" + source: hosted + version: "1.0.0" + zoom_tap_animation: + dependency: "direct main" + description: + name: zoom_tap_animation + url: "https://pub.dartlang.org" + source: hosted + version: "1.1.0" sdks: dart: ">=2.18.2 <3.0.0" + flutter: ">=3.3.0" diff --git a/Sources/justMUSIC/pubspec.yaml b/Sources/justMUSIC/pubspec.yaml index 03f3822..0be4218 100644 --- a/Sources/justMUSIC/pubspec.yaml +++ b/Sources/justMUSIC/pubspec.yaml @@ -36,6 +36,18 @@ dependencies: # The following adds the Cupertino Icons font to your application. # Use with the CupertinoIcons class for iOS style icons. cupertino_icons: ^1.0.2 + google_fonts: ^4.0.4 + gradiantbutton: ^0.0.1 + smooth_corner: ^1.1.0 + flutter_signin_button: ^2.0.0 + flutter_screenutil: ^5.7.0 + auto_size_text: ^3.0.0 + gradient_borders: ^1.0.0 + text_scroll: ^0.2.0 + circular_reveal_animation: ^2.0.1 + zoom_tap_animation: ^1.1.0 + custom_draggable_widget: ^0.0.2 + modal_bottom_sheet: ^2.1.2 dev_dependencies: flutter_test: @@ -60,9 +72,8 @@ flutter: uses-material-design: true # To add assets to your application, add an assets section, like this: - # assets: - # - images/a_dot_burr.jpeg - # - images/a_dot_ham.jpeg + assets: + - assets/images/ # An image asset can refer to one or more resolution-specific "variants", see # https://flutter.dev/assets-and-images/#resolution-aware diff --git a/justMUSIC/assets/images/add_friend.png b/justMUSIC/assets/images/add_friend.png new file mode 100644 index 0000000..3e4195e Binary files /dev/null and b/justMUSIC/assets/images/add_friend.png differ diff --git a/justMUSIC/assets/images/exemple_cover.png b/justMUSIC/assets/images/exemple_cover.png new file mode 100644 index 0000000..0bbaebf Binary files /dev/null and b/justMUSIC/assets/images/exemple_cover.png differ diff --git a/justMUSIC/assets/images/exemple_profile.png b/justMUSIC/assets/images/exemple_profile.png new file mode 100644 index 0000000..19cf8e9 Binary files /dev/null and b/justMUSIC/assets/images/exemple_profile.png differ diff --git a/justMUSIC/assets/images/hide_icon.png b/justMUSIC/assets/images/hide_icon.png new file mode 100644 index 0000000..ee30f3e Binary files /dev/null and b/justMUSIC/assets/images/hide_icon.png differ diff --git a/justMUSIC/assets/images/logo.png b/justMUSIC/assets/images/logo.png new file mode 100644 index 0000000..a2c9c95 Binary files /dev/null and b/justMUSIC/assets/images/logo.png differ diff --git a/justMUSIC/assets/images/presentation.png b/justMUSIC/assets/images/presentation.png new file mode 100644 index 0000000..cd1e8e2 Binary files /dev/null and b/justMUSIC/assets/images/presentation.png differ diff --git a/justMUSIC/assets/images/shadow_post.png b/justMUSIC/assets/images/shadow_post.png new file mode 100644 index 0000000..bd3de94 Binary files /dev/null and b/justMUSIC/assets/images/shadow_post.png differ diff --git a/justMUSIC/assets/images/show_icon.png b/justMUSIC/assets/images/show_icon.png new file mode 100644 index 0000000..ee083c5 Binary files /dev/null and b/justMUSIC/assets/images/show_icon.png differ diff --git a/justMUSIC/assets/images/wellcome_background.png b/justMUSIC/assets/images/wellcome_background.png new file mode 100644 index 0000000..84a56c2 Binary files /dev/null and b/justMUSIC/assets/images/wellcome_background.png differ diff --git a/justMUSIC/lib/components/Finish_button.dart b/justMUSIC/lib/components/Finish_button.dart new file mode 100644 index 0000000..e6dc6e6 --- /dev/null +++ b/justMUSIC/lib/components/Finish_button.dart @@ -0,0 +1,64 @@ +import 'package:flutter/cupertino.dart'; +import 'package:flutter/material.dart'; +import 'package:flutter_screenutil/flutter_screenutil.dart'; + +class FinishButton extends StatefulWidget { + const FinishButton({Key? key}) : super(key: key); + + @override + State createState() => _FinishButtonState(); +} + +class _FinishButtonState extends State { + @override + Widget build(BuildContext context) { + return ElevatedButton( + onPressed: () {}, + style: ButtonStyle( + backgroundColor: MaterialStateProperty.all(Color(0xFF1C1C1C)), + overlayColor: + MaterialStateProperty.all(Color(0xffD3C2FF).withOpacity(0.2)), + shape: MaterialStateProperty.all(RoundedRectangleBorder( + borderRadius: BorderRadius.circular(18), + )), + padding: MaterialStateProperty.all(EdgeInsets.all(0.0)), + ), + child: Ink( + decoration: BoxDecoration( + gradient: RadialGradient( + center: Alignment(0, 3), + focalRadius: 10, + radius: 2.5, + stops: [0.4, 1.0], + colors: [Color(0xff9E78FF), Color(0xff633AF4)], + ), + borderRadius: BorderRadius.circular(18.0), + border: Border.all( + color: Color(0xff1C1C1C), + width: 5, + ), + ), + child: Container( + padding: EdgeInsets.only(top: 20.h, bottom: 20.h), + constraints: BoxConstraints(maxWidth: 600, minHeight: 50), + decoration: BoxDecoration( + boxShadow: [ + BoxShadow( + color: Color(0xff7E56F9).withOpacity(0.23), + spreadRadius: 4, + blurRadius: 40, + offset: Offset(0, 3), // changes position of shadow + ), + ], + ), + alignment: Alignment.center, + child: Text( + "Terminer", + textAlign: TextAlign.center, + style: TextStyle(color: Colors.white, fontSize: 18), + ), + ), + ), + ); + } +} diff --git a/justMUSIC/lib/components/comment_component.dart b/justMUSIC/lib/components/comment_component.dart new file mode 100644 index 0000000..924d44b --- /dev/null +++ b/justMUSIC/lib/components/comment_component.dart @@ -0,0 +1,63 @@ +import 'package:flutter/cupertino.dart'; +import 'package:flutter/material.dart'; +import 'package:google_fonts/google_fonts.dart'; + +import '../values/constants.dart'; + +class CommentComponent extends StatelessWidget { + const CommentComponent({Key? key}) : super(key: key); + + @override + Widget build(BuildContext context) { + return Container( + width: double.infinity, + decoration: BoxDecoration( + color: bgComment, borderRadius: BorderRadius.circular(10)), + padding: EdgeInsets.all(20), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Row( + crossAxisAlignment: CrossAxisAlignment.center, + children: [ + ClipOval( + child: SizedBox.fromSize( + // Image radius + child: Image( + image: AssetImage("assets/images/exemple_profile.png"), + width: 40, + ), + ), + ), + SizedBox( + width: 10, + ), + Text( + "Melina", + style: GoogleFonts.plusJakartaSans( + color: Colors.white, fontWeight: FontWeight.w600), + ), + Padding( + padding: EdgeInsets.only(top: 6, left: 10), + child: Text( + "Il y a 2 min(s)", + style: GoogleFonts.plusJakartaSans( + color: Colors.white.withOpacity(0.6), + fontWeight: FontWeight.w200, + fontSize: 10), + ), + ), + ], + ), + Text( + "J’adore ce son auss je trouve qu’il a vraiment une plume de fou le rap c’est trop bien jknei rhozi ugzeor gzhjkev huz vhzbejlh zouebvfiyzv fi hzejkfb zjf ouzebfjzebihf b zuib fiuzebfihzbejfbzejkbf hzbfiébiu zegiu fzieu iuzy giuzeg iuzg eiu zg ", + style: GoogleFonts.plusJakartaSans( + color: Colors.white.withOpacity(0.4), + fontWeight: FontWeight.w300, + fontSize: 13), + ), + ], + ), + ); + } +} diff --git a/justMUSIC/lib/components/join_button.dart b/justMUSIC/lib/components/join_button.dart new file mode 100644 index 0000000..1c141e6 --- /dev/null +++ b/justMUSIC/lib/components/join_button.dart @@ -0,0 +1,28 @@ +import 'package:flutter/cupertino.dart'; +import 'package:flutter/material.dart'; +import 'package:google_fonts/google_fonts.dart'; + +class JoinButton extends StatelessWidget { + const JoinButton({Key? key}) : super(key: key); + + @override + Widget build(BuildContext context) { + return ElevatedButton( + onPressed: () {}, + child: Text( + "Rejoindre", + style: GoogleFonts.plusJakartaSans( + fontWeight: FontWeight.w800, fontSize: 17), + ), + style: ButtonStyle( + maximumSize: MaterialStateProperty.all(const Size(800, 50)), + minimumSize: MaterialStateProperty.all(const Size(500, 50)), + backgroundColor: MaterialStateProperty.all(Colors.white), + foregroundColor: MaterialStateProperty.all(Colors.black), + shape: MaterialStateProperty.all(RoundedRectangleBorder( + borderRadius: BorderRadius.circular(100), + )), + ), + ); + } +} diff --git a/justMUSIC/lib/components/login_button.dart b/justMUSIC/lib/components/login_button.dart new file mode 100644 index 0000000..badf09f --- /dev/null +++ b/justMUSIC/lib/components/login_button.dart @@ -0,0 +1,64 @@ +import 'package:flutter/cupertino.dart'; +import 'package:flutter/material.dart'; +import 'package:flutter_screenutil/flutter_screenutil.dart'; + +class LoginButton extends StatefulWidget { + const LoginButton({Key? key}) : super(key: key); + + @override + State createState() => _LoginButtonState(); +} + +class _LoginButtonState extends State { + @override + Widget build(BuildContext context) { + return ElevatedButton( + onPressed: () {}, + style: ButtonStyle( + backgroundColor: MaterialStateProperty.all(Color(0xFF1C1C1C)), + overlayColor: + MaterialStateProperty.all(Color(0xffD3C2FF).withOpacity(0.2)), + shape: MaterialStateProperty.all(RoundedRectangleBorder( + borderRadius: BorderRadius.circular(18), + )), + padding: MaterialStateProperty.all(EdgeInsets.all(0.0)), + ), + child: Ink( + decoration: BoxDecoration( + gradient: RadialGradient( + center: Alignment(0, 3), + focalRadius: 10, + radius: 2.5, + stops: [0.4, 1.0], + colors: [Color(0xff9E78FF), Color(0xff633AF4)], + ), + borderRadius: BorderRadius.circular(18.0), + border: Border.all( + color: Color(0xff1C1C1C), + width: 5, + ), + ), + child: Container( + padding: EdgeInsets.only(top: 20.h, bottom: 20.h), + constraints: BoxConstraints(maxWidth: 600, minHeight: 50), + decoration: BoxDecoration( + boxShadow: [ + BoxShadow( + color: Color(0xff7E56F9).withOpacity(0.23), + spreadRadius: 4, + blurRadius: 40, + offset: Offset(0, 3), // changes position of shadow + ), + ], + ), + alignment: Alignment.center, + child: Text( + "Se connecter", + textAlign: TextAlign.center, + style: TextStyle(color: Colors.white, fontSize: 18), + ), + ), + ), + ); + } +} diff --git a/justMUSIC/lib/components/post_component.dart b/justMUSIC/lib/components/post_component.dart new file mode 100644 index 0000000..90332f3 --- /dev/null +++ b/justMUSIC/lib/components/post_component.dart @@ -0,0 +1,213 @@ +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'; +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'; + +class PostComponent extends StatelessWidget { + final VoidCallback? callback; + const PostComponent({Key? key, required this.callback}) : super(key: key); + @override + Widget build(BuildContext context) { + return SizedBox( + width: double.infinity, + child: Column( + children: [ + Row( + crossAxisAlignment: CrossAxisAlignment.end, + children: [ + ClipOval( + child: SizedBox.fromSize( + // Image radius + child: Image( + image: AssetImage("assets/images/exemple_profile.png"), + width: 40, + ), + ), + ), + Expanded( + flex: 8, + child: Padding( + padding: const EdgeInsets.only(left: 10), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Text( + "Melina", + style: GoogleFonts.plusJakartaSans( + color: Colors.white, fontWeight: FontWeight.w600), + ), + Text( + "France, Lyon", + style: GoogleFonts.plusJakartaSans( + color: Colors.white.withOpacity(0.4), + fontWeight: FontWeight.w300, + fontSize: 13), + ) + ], + ), + ), + ), + Text( + "Aujourd’hui, 16:43", + style: GoogleFonts.plusJakartaSans( + color: Colors.white.withOpacity(0.4), + fontWeight: FontWeight.w300, + fontSize: 13), + ), + ], + ), + SizedBox(height: 10), + ZoomTapAnimation( + onTap: callback, + 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: AssetImage("assets/images/exemple_cover.png"), + fit: BoxFit.cover, + width: double.infinity, + ), + Image( + image: AssetImage("assets/images/shadow_post.png"), + fit: BoxFit.fitHeight, + width: double.infinity, + ), + Padding( + padding: EdgeInsets.all(15), + child: AutoSizeText( + '“J’écoute en boucle ce son. B2O<3”', + style: GoogleFonts.plusJakartaSans( + color: Colors.white, + fontWeight: FontWeight.w400, + fontSize: 15.sp), + maxFontSize: 20, + maxLines: 1, + ), + ), + Positioned( + top: 0, + right: 0, + child: Padding( + padding: EdgeInsets.all(12), + child: Container( + constraints: BoxConstraints( + maxWidth: 140, maxHeight: 140), + width: 80.sp, + height: 80.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.network( + 'assets/images/exemple_profile.png', + fit: BoxFit.cover, + ), + ), + ), + )) + ], + ), + ), + ), + )), + SizedBox(height: 10), + Row( + crossAxisAlignment: CrossAxisAlignment.end, + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + Flexible( + flex: 8, + child: TextScroll( + "BOOBA", + 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( + "A.C. Milan", + 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( + "2013", + style: GoogleFonts.plusJakartaSans( + color: Colors.white.withOpacity(0.5), + fontWeight: FontWeight.w300, + fontSize: 16.h), + textAlign: TextAlign.end, + maxFontSize: 20, + ), + ], + ), + ], + ), + ); + } +} diff --git a/justMUSIC/lib/components/top_nav_bar_component.dart b/justMUSIC/lib/components/top_nav_bar_component.dart new file mode 100644 index 0000000..cb73a50 --- /dev/null +++ b/justMUSIC/lib/components/top_nav_bar_component.dart @@ -0,0 +1,142 @@ +import 'package:auto_size_text/auto_size_text.dart'; +import 'package:flutter/cupertino.dart'; +import 'package:flutter/material.dart'; +import 'package:google_fonts/google_fonts.dart'; + +import '../values/constants.dart'; + +class TopNavBarComponent extends StatefulWidget { + final Function(bool) callback; + const TopNavBarComponent({Key? key, required this.callback}) + : super(key: key); + + @override + State createState() => _TopNavBarComponentState(); +} + +class _TopNavBarComponentState extends State { + bool choice = true; + + void actionSurBouton() { + widget.callback(choice); + } + + @override + Widget build(BuildContext context) { + return Padding( + padding: const EdgeInsets.only(top: defaultPadding), + child: Container( + padding: EdgeInsets.symmetric(horizontal: defaultPadding), + width: double.infinity, + height: 100, + child: Row( + crossAxisAlignment: CrossAxisAlignment.start, + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + const Flexible( + flex: 1, + child: Image( + image: AssetImage("assets/images/add_friend.png"), + width: 25, + ), + ), + ConstrainedBox( + constraints: BoxConstraints(maxWidth: 170), + child: Column( + mainAxisAlignment: MainAxisAlignment.start, + children: [ + Image( + image: AssetImage("assets/images/logo.png"), + height: 30, + ), + Row( + crossAxisAlignment: CrossAxisAlignment.center, + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + GestureDetector( + onTap: () { + if (!choice) { + setState(() { + choice = !choice; + actionSurBouton(); + }); + } + }, + child: LayoutBuilder( + builder: (BuildContext context, + BoxConstraints constraints) { + if (choice) { + return AutoSizeText( + "Mes amis", + style: GoogleFonts.plusJakartaSans( + fontWeight: FontWeight.w500, + fontSize: 16, + color: Colors.white), + ); + } else { + return AutoSizeText( + "Mes amis", + style: GoogleFonts.plusJakartaSans( + fontWeight: FontWeight.w300, + fontSize: 16, + color: unactiveFeed), + ); + } + }, + ), + ), + GestureDetector( + onTap: () { + if (choice) { + setState(() { + choice = !choice; + actionSurBouton(); + }); + } + }, + child: LayoutBuilder( + builder: (BuildContext context, + BoxConstraints constraints) { + if (choice) { + return AutoSizeText( + "Discovery", + style: GoogleFonts.plusJakartaSans( + fontWeight: FontWeight.w300, + fontSize: 16, + color: unactiveFeed), + ); + } else { + return AutoSizeText( + "Discovery", + style: GoogleFonts.plusJakartaSans( + fontWeight: FontWeight.w500, + fontSize: 16, + color: Colors.white), + ); + } + }, + ), + ), + ], + ), + ], + ), + ), + Flexible( + flex: 1, + child: ClipOval( + child: SizedBox.fromSize( + // Image radius + child: Image( + image: AssetImage("assets/images/exemple_profile.png"), + width: 25, + ), + ), + ), + ) + ], + ), + ), + ); + } +} diff --git a/justMUSIC/lib/screens/explanations_screen.dart b/justMUSIC/lib/screens/explanations_screen.dart new file mode 100644 index 0000000..48bd345 --- /dev/null +++ b/justMUSIC/lib/screens/explanations_screen.dart @@ -0,0 +1,152 @@ +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'; + +import '../components/Finish_button.dart'; + +import '../values/constants.dart'; + +class ExplanationsScreen extends StatelessWidget { + const ExplanationsScreen({Key? key}) : super(key: key); + + @override + Widget build(BuildContext context) { + return Scaffold( + backgroundColor: bgColor, + body: Stack( + children: [ + SingleChildScrollView( + child: SizedBox( + width: double.infinity, + child: Align( + child: ConstrainedBox( + constraints: BoxConstraints(maxWidth: 600), + child: Padding( + padding: const EdgeInsets.symmetric( + horizontal: defaultPadding), + child: Container( + width: double.infinity, + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Padding( + padding: EdgeInsets.only(top: 100.h), + child: AutoSizeText( + "Bravo!", + style: GoogleFonts.plusJakartaSans( + color: Colors.white, + fontWeight: FontWeight.w600, + fontSize: 32.w), + maxLines: 1, + maxFontSize: 50, + overflow: TextOverflow.fade, + ), + ), + Padding( + padding: EdgeInsets.only(top: 20), + child: ConstrainedBox( + constraints: BoxConstraints(maxWidth: 250), + child: AutoSizeText( + "Tu fais à présent parti de la communauté.", + style: GoogleFonts.plusJakartaSans( + color: Colors.white, + fontWeight: FontWeight.w200, + fontSize: 15.w), + maxFontSize: 20, + textAlign: TextAlign.start, + ), + ), + ), + SizedBox(height: 30.h), + Align( + child: SizedBox( + width: 330.h, + child: Image( + image: AssetImage( + "assets/images/presentation.png")), + ), + ), + Align( + child: Padding( + padding: EdgeInsets.only(top: 10.h), + child: AutoSizeText( + "Découvre des sons", + style: GoogleFonts.plusJakartaSans( + color: Colors.white, + fontWeight: FontWeight.w600, + fontSize: 28.w), + maxLines: 1, + maxFontSize: 50, + overflow: TextOverflow.fade, + ), + ), + ), + Padding( + padding: EdgeInsets.only(top: 10.h, bottom: 20.h), + child: Align( + alignment: Alignment.center, + child: AutoSizeText( + "Explore ton Feed d’amis et les découvertes, pour découvrir ce qu’écoute tes amis et bien d’autres.", + style: GoogleFonts.plusJakartaSans( + color: Colors.white.withOpacity(0.6), + fontWeight: FontWeight.w200, + fontSize: 14.w), + maxFontSize: 20, + textAlign: TextAlign.center, + ), + ), + ), + const SizedBox( + width: 600, + child: Padding( + padding: EdgeInsets.only(bottom: 50), + child: FinishButton(), + ), + ), + ], + ), + ), + ), + ), + )), + ), + IgnorePointer( + child: Container( + height: 240.h, + decoration: BoxDecoration( + gradient: LinearGradient(begin: Alignment.topRight, stops: [ + 0, + 1 + ], colors: [ + bgColor.withOpacity(1), + bgColor.withOpacity(0) + ])), + ), + ), + Align( + alignment: Alignment.topCenter, + child: ConstrainedBox( + constraints: BoxConstraints(maxWidth: 800), + child: Padding( + padding: EdgeInsets.only( + top: 45.h, left: defaultPadding, right: defaultPadding), + child: ClipRRect( + borderRadius: BorderRadius.circular(10.0), + child: LinearProgressIndicator( + minHeight: 5, + value: 1, + backgroundColor: grayColor, + color: primaryColor, + ), + ), + ), + ), + ), + ], + ), + ); + } +} diff --git a/justMUSIC/lib/screens/feed_screen.dart b/justMUSIC/lib/screens/feed_screen.dart new file mode 100644 index 0000000..cae3a5d --- /dev/null +++ b/justMUSIC/lib/screens/feed_screen.dart @@ -0,0 +1,187 @@ +import 'package:circular_reveal_animation/circular_reveal_animation.dart'; +import 'package:flutter/cupertino.dart'; +import 'package:flutter/material.dart'; +import 'package:flutter_screenutil/flutter_screenutil.dart'; + +import '../components/comment_component.dart'; +import '../components/post_component.dart'; +import '../components/top_nav_bar_component.dart'; +import '../values/constants.dart'; + +class FeedScreen extends StatefulWidget { + const FeedScreen({Key? key}) : super(key: key); + + @override + State createState() => _FeedScreenState(); +} + +class _FeedScreenState extends State + with SingleTickerProviderStateMixin { + late AnimationController animationController; + late Animation animation; + late List friendFeed; + late List discoveryFeed; + late List displayFeed; + + @override + void initState() { + super.initState(); + friendFeed = [ + PostComponent( + callback: openDetailPost, + ), + PostComponent( + callback: openDetailPost, + ), + PostComponent( + callback: openDetailPost, + ), + ]; + discoveryFeed = [ + PostComponent(callback: openDetailPost), + ]; + displayFeed = friendFeed; + animationController = AnimationController( + vsync: this, + duration: Duration(milliseconds: 400), + ); + animation = CurvedAnimation( + parent: animationController, + curve: Curves.easeInOutSine, + ); + animationController.forward(); + } + + 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 = friendFeed; + animationController.forward(); + }); + } else { + setState(() { + animationController.reset(); + displayFeed = discoveryFeed; + animationController.forward(); + }); + } + } + + void openDetailPost() { + 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: ((context) { + return Container( + height: 720.h, + margin: EdgeInsets.only( + top: defaultPadding, + left: defaultPadding, + right: defaultPadding), + child: Column( + children: [ + Align( + child: Container( + width: 60, + height: 5, + decoration: BoxDecoration( + color: Colors.white, + borderRadius: BorderRadius.circular(20))), + ), + SizedBox( + height: 10, + ), + Expanded( + child: SingleChildScrollView( + child: Wrap( + // to apply margin in the main axis of the wrap + runSpacing: 10, + children: [ + PostComponent( + callback: null, + ), + Container(height: 40), + CommentComponent(), + CommentComponent(), + CommentComponent(), + Container(height: 10), + ], + ), + ), + ), + ], + )); + }), + ); + } + + @override + Widget build(BuildContext context) { + return Scaffold( + backgroundColor: bgColor, + body: Stack( + children: [ + CircularRevealAnimation( + animation: animation, +// centerAlignment: Alignment.centerRight, + centerOffset: Offset(30.w, -100), + child: SingleChildScrollView( + child: SizedBox( + width: double.infinity, + child: Align( + child: ConstrainedBox( + constraints: BoxConstraints(maxWidth: 600), + child: Padding( + padding: const EdgeInsets.symmetric( + horizontal: defaultPadding), + child: Container( + width: double.infinity, + child: Padding( + padding: EdgeInsets.only(top: 100.h), + child: SingleChildScrollView( + child: Wrap( + runSpacing: 60, + children: displayFeed, + ), + )), + ), + ), + ), + )), + ), + ), + 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/justMUSIC/lib/screens/login_screen.dart b/justMUSIC/lib/screens/login_screen.dart new file mode 100644 index 0000000..128ea86 --- /dev/null +++ b/justMUSIC/lib/screens/login_screen.dart @@ -0,0 +1,702 @@ +import 'package:flutter/cupertino.dart'; +import 'package:flutter/material.dart'; +import 'package:flutter_screenutil/flutter_screenutil.dart'; +import 'package:flutter_signin_button/button_list.dart'; +import 'package:flutter_signin_button/button_view.dart'; +import 'package:google_fonts/google_fonts.dart'; +import 'package:justmusic/values/constants.dart'; + +import '../components/login_button.dart'; + +class LoginScreen extends StatefulWidget { + const LoginScreen({Key? key}) : super(key: key); + + @override + State createState() => _LoginScreenState(); +} + +class _LoginScreenState extends State { + bool passenable = true; + final _focusNode = FocusNode(); + final _formKey = GlobalKey(); + + @override + Widget build(BuildContext context) { + return GestureDetector( + onTap: () => FocusManager.instance.primaryFocus?.unfocus(), + child: Scaffold( + resizeToAvoidBottomInset: false, + backgroundColor: bgColor, + body: LayoutBuilder( + builder: (context, constraints) { + if (constraints.maxHeight >= 740) { + return Align( + child: SizedBox( + height: double.infinity, + width: 600, + child: Column( + mainAxisAlignment: MainAxisAlignment.center, + children: [ + Expanded( + child: Padding( + padding: + EdgeInsets.only(left: 40, right: 40), + child: Form( + key: _formKey, + child: Column( + crossAxisAlignment: + CrossAxisAlignment.center, + children: [ + Flexible( + flex: 5, + child: Padding( + padding: + EdgeInsets.only(bottom: 60), + child: Column( + mainAxisAlignment: + MainAxisAlignment.end, + children: [ + Text( + "Te revoilà!", + style: GoogleFonts + .plusJakartaSans( + color: + Colors.white, + fontWeight: + FontWeight + .w600, + fontSize: 38.h), + ), + SizedBox( + height: 10, + ), + SizedBox( + width: 230.w, + child: Text( + "Bon retour parmis nous tu nous as manqué!", + style: GoogleFonts + .plusJakartaSans( + color: Colors + .white, + fontWeight: + FontWeight + .w400, + fontSize: 20.h), + textAlign: + TextAlign.center, + ), + ), + ], + ), + ), + ), + Expanded( + flex: 4, + child: Column( + crossAxisAlignment: + CrossAxisAlignment.end, + children: [ + TextFormField( + validator: (value) { + if (value == null || + value.isEmpty) { + return 'TODO'; + } + return null; + }, + cursorColor: primaryColor, + keyboardType: + TextInputType + .emailAddress, + style: GoogleFonts + .plusJakartaSans( + color: + primaryColor), + decoration: InputDecoration( + focusedBorder: OutlineInputBorder( + borderSide: BorderSide( + width: 1, + color: + strokeTextField), + borderRadius: + BorderRadius.all( + Radius.circular( + 10))), + contentPadding: + EdgeInsets.only( + top: 0, + bottom: 0, + left: + defaultPadding), + fillColor: + bgTextField, + filled: true, + focusColor: Color.fromRGBO( + 255, 255, 255, 0.30), + enabledBorder: OutlineInputBorder( + borderSide: BorderSide( + width: 1, + color: + strokeTextField), + borderRadius: + BorderRadius.all(Radius.circular(10))), + hintText: 'Email', + hintStyle: GoogleFonts.plusJakartaSans(color: strokeTextField)), + ), + SizedBox( + height: 18, + ), + TextFormField( + obscureText: passenable, + validator: (value) { + if (value == null || + value.isEmpty) { + return 'TODO'; + } + return null; + }, + cursorColor: primaryColor, + keyboardType: + TextInputType + .emailAddress, + style: GoogleFonts + .plusJakartaSans( + color: + primaryColor), + decoration: + InputDecoration( + focusedBorder: OutlineInputBorder( + borderSide: BorderSide( + width: 1, + color: + strokeTextField), + borderRadius: + BorderRadius + .all(Radius + .circular( + 10))), + contentPadding: + EdgeInsets.only( + top: 0, + bottom: 0, + left: + defaultPadding), + fillColor: bgTextField, + filled: true, + focusColor: + Color.fromRGBO(255, + 255, 255, 0.30), + enabledBorder: OutlineInputBorder( + borderSide: BorderSide( + width: 1, + color: + strokeTextField), + borderRadius: + BorderRadius + .all(Radius + .circular( + 10))), + hintText: + 'Mot de passe', + hintStyle: GoogleFonts + .plusJakartaSans( + color: + strokeTextField), + suffixIcon: Container( + padding: + EdgeInsets.only( + right: 10), + margin: + EdgeInsets.all( + 5), + height: 3, + child: InkWell( + onTap: () { + setState(() { + if (passenable) { + passenable = + false; + } else { + passenable = + true; + } + }); + }, // Image tapped + splashColor: Colors + .white10, // Splash color over image + child: Image( + image: passenable + ? AssetImage( + "assets/images/show_icon.png") + : AssetImage( + "assets/images/hide_icon.png"), + height: 2, + ), + )), + ), + ), + Padding( + padding: EdgeInsets.only( + top: 10), + child: Text( + "Mot de passe oublié?", + style: GoogleFonts + .plusJakartaSans( + color: Colors + .white), + ), + ), + SizedBox( + height: defaultPadding, + ), + SizedBox( + width: 600, + child: LoginButton()), + ], + )), + Expanded( + flex: 3, + child: Padding( + padding: + EdgeInsets.only(top: 20), + child: Column( + mainAxisAlignment: + MainAxisAlignment.start, + crossAxisAlignment: + CrossAxisAlignment + .center, + children: [ + ConstrainedBox( + constraints: + BoxConstraints( + maxWidth: 600), + child: Row( + mainAxisAlignment: + MainAxisAlignment + .spaceEvenly, + children: [ + Expanded( + child: Container( + color: Color( + 0xFF3D3D3D), + height: 1, + ), + ), + Padding( + padding: const EdgeInsets + .only( + left: + defaultPadding, + right: + defaultPadding), + child: Text( + 'Ou', + style: GoogleFonts.plusJakartaSans( + color: Colors + .white, + fontWeight: + FontWeight + .bold), + ), + ), + Expanded( + child: + Container( + height: 1, + color: Color( + 0xFF3D3D3D), + )), + ], + ), + ), + SizedBox( + height: + defaultPadding), + SignInButton( + Buttons.Google, + text: + "Login with Google", + onPressed: () {}, + ), + Padding( + padding: + EdgeInsets.only( + top: 20), + child: RichText( + textAlign: + TextAlign.center, + text: TextSpan( + text: + 'Pas encore inscrit?', + style: GoogleFonts + .plusJakartaSans( + color: Colors + .white, + fontWeight: + FontWeight + .w400, + fontSize: + 13), + children: < + TextSpan>[ + TextSpan( + text: + " S’inscire", + style: GoogleFonts.plusJakartaSans( + fontSize: + 13, + fontWeight: + FontWeight + .w400, + color: + primaryColor)), + ], + ), + ), + ) + ], + ), + )) + ], + )))) + ], + )), + ); + } else { + return Align( + child: SizedBox( + height: double.infinity, + width: 600, + child: Column( + mainAxisAlignment: MainAxisAlignment.center, + children: [ + Expanded( + child: Padding( + padding: + EdgeInsets.only(left: 40, right: 40), + child: Form( + key: _formKey, + child: Column( + crossAxisAlignment: + CrossAxisAlignment.center, + children: [ + Flexible( + flex: 2, + child: Padding( + padding: + EdgeInsets.only(bottom: 30), + child: Column( + mainAxisAlignment: + MainAxisAlignment.end, + children: [ + Text( + "Te revoilà!", + style: GoogleFonts + .plusJakartaSans( + color: + Colors.white, + fontWeight: + FontWeight + .w600, + fontSize: 38.h), + ), + SizedBox( + height: 10, + ), + SizedBox( + width: 230, + child: Text( + "Bon retour parmis nous tu nous as manqué!", + style: GoogleFonts + .plusJakartaSans( + color: Colors + .white, + fontWeight: + FontWeight + .w400, + fontSize: 20.h), + textAlign: + TextAlign.center, + ), + ), + ], + ), + ), + ), + Expanded( + flex: 4, + child: Column( + crossAxisAlignment: + CrossAxisAlignment.end, + children: [ + TextFormField( + validator: (value) { + if (value == null || + value.isEmpty) { + return 'TODO'; + } + return null; + }, + cursorColor: primaryColor, + keyboardType: + TextInputType + .emailAddress, + style: GoogleFonts + .plusJakartaSans( + color: + primaryColor), + decoration: InputDecoration( + focusedBorder: OutlineInputBorder( + borderSide: BorderSide( + width: 1, + color: + strokeTextField), + borderRadius: + BorderRadius.all( + Radius.circular( + 10))), + contentPadding: + EdgeInsets.only( + top: 0, + bottom: 0, + left: + defaultPadding), + fillColor: + bgTextField, + filled: true, + focusColor: Color.fromRGBO( + 255, 255, 255, 0.30), + enabledBorder: OutlineInputBorder( + borderSide: BorderSide( + width: 1, + color: + strokeTextField), + borderRadius: + BorderRadius.all(Radius.circular(10))), + hintText: 'Email', + hintStyle: GoogleFonts.plusJakartaSans(color: strokeTextField, fontSize: 15)), + ), + SizedBox( + height: 18, + ), + TextFormField( + obscureText: passenable, + validator: (value) { + if (value == null || + value.isEmpty) { + return 'TODO'; + } + return null; + }, + cursorColor: primaryColor, + keyboardType: + TextInputType + .emailAddress, + style: GoogleFonts + .plusJakartaSans( + color: + primaryColor), + decoration: + InputDecoration( + focusedBorder: OutlineInputBorder( + borderSide: BorderSide( + width: 1, + color: + strokeTextField), + borderRadius: + BorderRadius + .all(Radius + .circular( + 10))), + contentPadding: + EdgeInsets.only( + top: 0, + bottom: 0, + left: + defaultPadding), + fillColor: bgTextField, + filled: true, + focusColor: + Color.fromRGBO(255, + 255, 255, 0.30), + enabledBorder: OutlineInputBorder( + borderSide: BorderSide( + width: 1, + color: + strokeTextField), + borderRadius: + BorderRadius + .all(Radius + .circular( + 10))), + hintText: + 'Mot de passe', + hintStyle: GoogleFonts + .plusJakartaSans( + color: + strokeTextField), + suffixIcon: Container( + padding: + EdgeInsets.only( + right: 10), + margin: + EdgeInsets.all( + 5), + height: 3, + child: InkWell( + onTap: () { + setState(() { + if (passenable) { + passenable = + false; + } else { + passenable = + true; + } + }); + }, // Image tapped + splashColor: Colors + .white10, // Splash color over image + child: Image( + image: passenable + ? AssetImage( + "assets/images/show_icon.png") + : AssetImage( + "assets/images/hide_icon.png"), + height: 2, + ), + )), + ), + ), + Padding( + padding: EdgeInsets.only( + top: 10.h), + child: Text( + "Mot de passe oublié?", + style: GoogleFonts + .plusJakartaSans( + color: Colors + .white), + ), + ), + SizedBox( + height: defaultPadding, + ), + SizedBox( + width: 600, + child: LoginButton()), + ], + )), + Expanded( + flex: 3, + child: Padding( + padding: + EdgeInsets.only(top: 20), + child: Column( + mainAxisAlignment: + MainAxisAlignment.start, + crossAxisAlignment: + CrossAxisAlignment + .center, + children: [ + ConstrainedBox( + constraints: + BoxConstraints( + maxWidth: 600), + child: Row( + mainAxisAlignment: + MainAxisAlignment + .spaceEvenly, + children: [ + Expanded( + child: Container( + color: Color( + 0xFF3D3D3D), + height: 1, + ), + ), + Padding( + padding: const EdgeInsets + .only( + left: + defaultPadding, + right: + defaultPadding), + child: Text( + 'Ou', + style: GoogleFonts.plusJakartaSans( + color: Colors + .white, + fontWeight: + FontWeight + .bold), + ), + ), + Expanded( + child: + Container( + height: 1, + color: Color( + 0xFF3D3D3D), + )), + ], + ), + ), + SizedBox( + height: + defaultPadding), + SignInButton( + Buttons.Google, + text: + "Login with Google", + onPressed: () {}, + ), + Padding( + padding: + EdgeInsets.only( + top: 20), + child: RichText( + textAlign: + TextAlign.center, + text: TextSpan( + text: + 'Pas encore inscrit?', + style: GoogleFonts + .plusJakartaSans( + color: Colors + .white, + fontWeight: + FontWeight + .w400, + fontSize: + 13), + children: < + TextSpan>[ + TextSpan( + text: + " S’inscire", + style: GoogleFonts.plusJakartaSans( + fontSize: + 13, + fontWeight: + FontWeight + .w400, + color: + primaryColor)), + ], + ), + ), + ) + ], + ), + )) + ], + )))) + ], + )), + ); + } + }, + ))); + } +} diff --git a/justMUSIC/lib/screens/registration_screen.dart b/justMUSIC/lib/screens/registration_screen.dart new file mode 100644 index 0000000..b686e48 --- /dev/null +++ b/justMUSIC/lib/screens/registration_screen.dart @@ -0,0 +1,372 @@ +import 'dart:ui'; + +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:flutter_signin_button/button_list.dart'; +import 'package:flutter_signin_button/button_view.dart'; +import 'package:google_fonts/google_fonts.dart'; +import 'package:justmusic/values/constants.dart'; + +import '../components/login_button.dart'; + +class RegistrationScreen extends StatefulWidget { + const RegistrationScreen({Key? key}) : super(key: key); + + @override + State createState() => _RegistrationScreenState(); +} + +class _RegistrationScreenState extends State { + bool passenable = true; + + @override + Widget build(BuildContext context) { + return Scaffold( + backgroundColor: bgColor, + body: Stack( + children: [ + SingleChildScrollView( + child: SizedBox( + width: double.infinity, + child: Column( + children: [ + Padding( + padding: EdgeInsets.only(top: 100.h), + child: AutoSizeText( + "On a besoin de ça!", + style: GoogleFonts.plusJakartaSans( + color: Colors.white, + fontWeight: FontWeight.w600, + fontSize: 30.w), + maxLines: 1, + maxFontSize: 50, + overflow: TextOverflow.fade, + ), + ), + ConstrainedBox( + constraints: BoxConstraints(maxWidth: 600), + child: Column( + mainAxisAlignment: MainAxisAlignment.start, + children: [ + Padding( + padding: + EdgeInsets.symmetric(horizontal: defaultPadding), + child: Padding( + padding: EdgeInsets.only(bottom: 50.h), + child: Column( + mainAxisAlignment: MainAxisAlignment.end, + children: [ + SizedBox( + height: 15.h, + ), + SizedBox( + width: 230.h, + child: AutoSizeText( + "Promis c’est rapide.", + style: GoogleFonts.plusJakartaSans( + color: Colors.white, + fontWeight: FontWeight.w400, + fontSize: 17.w), + maxFontSize: 20, + textAlign: TextAlign.center, + ), + ), + ], + ), + ), + ), + Padding( + padding: EdgeInsets.only( + bottom: 16.h, + left: defaultPadding, + right: defaultPadding), + child: TextFormField( + validator: (value) { + if (value == null || value.isEmpty) { + return 'TODO'; + } + return null; + }, + cursorColor: primaryColor, + keyboardType: TextInputType.emailAddress, + style: GoogleFonts.plusJakartaSans( + color: primaryColor, fontSize: 15), + decoration: InputDecoration( + focusedBorder: OutlineInputBorder( + borderSide: BorderSide( + width: 1.sp, color: strokeTextField), + borderRadius: const BorderRadius.all( + Radius.circular(10))), + contentPadding: const EdgeInsets.only( + top: 0, bottom: 0, left: defaultPadding), + fillColor: bgTextField, + filled: true, + focusColor: + const Color.fromRGBO(255, 255, 255, 0.30), + enabledBorder: const OutlineInputBorder( + borderSide: BorderSide( + width: 1, color: strokeTextField), + borderRadius: BorderRadius.all( + Radius.circular(10))), + hintText: 'Pseudo', + hintStyle: GoogleFonts.plusJakartaSans( + color: strokeTextField)), + )), + Padding( + padding: EdgeInsets.only( + bottom: 16.h, + left: defaultPadding, + right: defaultPadding), + child: TextFormField( + validator: (value) { + if (value == null || value.isEmpty) { + return 'TODO'; + } + return null; + }, + cursorColor: primaryColor, + keyboardType: TextInputType.emailAddress, + style: GoogleFonts.plusJakartaSans( + color: primaryColor), + decoration: InputDecoration( + focusedBorder: OutlineInputBorder( + borderSide: BorderSide( + width: 1, color: strokeTextField), + borderRadius: BorderRadius.all( + Radius.circular(10))), + contentPadding: EdgeInsets.only( + top: 0, bottom: 0, left: defaultPadding), + fillColor: bgTextField, + filled: true, + focusColor: + Color.fromRGBO(255, 255, 255, 0.30), + enabledBorder: OutlineInputBorder( + borderSide: BorderSide( + width: 1, color: strokeTextField), + borderRadius: BorderRadius.all( + Radius.circular(10))), + hintText: 'Email', + hintStyle: GoogleFonts.plusJakartaSans( + color: strokeTextField)), + )), + Padding( + padding: EdgeInsets.only( + bottom: 16.h, + left: defaultPadding, + right: defaultPadding), + child: TextFormField( + obscureText: passenable, + validator: (value) { + if (value == null || value.isEmpty) { + return 'TODO'; + } + return null; + }, + cursorColor: primaryColor, + keyboardType: TextInputType.emailAddress, + style: GoogleFonts.plusJakartaSans( + color: primaryColor), + decoration: InputDecoration( + focusedBorder: OutlineInputBorder( + borderSide: BorderSide( + width: 1, color: strokeTextField), + borderRadius: + BorderRadius.all(Radius.circular(10))), + contentPadding: EdgeInsets.only( + top: 0, bottom: 0, left: defaultPadding), + fillColor: bgTextField, + filled: true, + focusColor: Color.fromRGBO(255, 255, 255, 0.30), + enabledBorder: OutlineInputBorder( + borderSide: BorderSide( + width: 1, color: strokeTextField), + borderRadius: + BorderRadius.all(Radius.circular(10))), + hintText: 'Mot de passe', + hintStyle: GoogleFonts.plusJakartaSans( + color: strokeTextField), + suffixIcon: Container( + padding: EdgeInsets.only(right: 10), + margin: EdgeInsets.all(5), + height: 3, + child: InkWell( + onTap: () { + setState(() { + if (passenable) { + passenable = false; + } else { + passenable = true; + } + }); + }, // Image tapped + splashColor: Colors + .white10, // Splash color over image + child: Image( + image: passenable + ? AssetImage( + "assets/images/show_icon.png") + : AssetImage( + "assets/images/hide_icon.png"), + height: 2, + ), + )), + ), + ), + ), + Padding( + padding: EdgeInsets.only( + bottom: 16.h, + left: defaultPadding, + right: defaultPadding), + child: TextFormField( + obscureText: passenable, + validator: (value) { + if (value == null || value.isEmpty) { + return 'TODO'; + } + return null; + }, + cursorColor: primaryColor, + keyboardType: TextInputType.emailAddress, + style: GoogleFonts.plusJakartaSans( + color: primaryColor), + decoration: InputDecoration( + focusedBorder: OutlineInputBorder( + borderSide: BorderSide( + width: 1, color: strokeTextField), + borderRadius: + BorderRadius.all(Radius.circular(10))), + contentPadding: EdgeInsets.only( + top: 0, bottom: 0, left: defaultPadding), + fillColor: bgTextField, + filled: true, + focusColor: Color.fromRGBO(255, 255, 255, 0.30), + enabledBorder: OutlineInputBorder( + borderSide: BorderSide( + width: 1, color: strokeTextField), + borderRadius: + BorderRadius.all(Radius.circular(10))), + hintText: 'Confirmation du Mot de passe', + hintStyle: GoogleFonts.plusJakartaSans( + color: strokeTextField), + suffixIcon: Container( + padding: EdgeInsets.only(right: 10), + margin: EdgeInsets.all(5), + height: 3, + child: InkWell( + onTap: () { + setState(() { + if (passenable) { + passenable = false; + } else { + passenable = true; + } + }); + }, // Image tapped + splashColor: Colors + .white10, // Splash color over image + child: Image( + image: passenable + ? AssetImage( + "assets/images/show_icon.png") + : AssetImage( + "assets/images/hide_icon.png"), + height: 2, + ), + )), + ), + ), + ), + Padding( + padding: + EdgeInsets.symmetric(horizontal: defaultPadding), + child: SizedBox(width: 600, child: LoginButton()), + ), + ], + )), + SizedBox(height: 50.h), + ConstrainedBox( + constraints: BoxConstraints(maxWidth: 600), + child: Row( + mainAxisAlignment: MainAxisAlignment.spaceEvenly, + children: [ + Expanded( + child: Container( + color: Color(0xFF3D3D3D), + height: 1, + ), + ), + Padding( + padding: const EdgeInsets.only( + left: defaultPadding, right: defaultPadding), + child: Text( + 'Ou', + style: GoogleFonts.plusJakartaSans( + color: Colors.white, fontWeight: FontWeight.bold), + ), + ), + Expanded( + child: Container( + height: 1, + color: Color(0xFF3D3D3D), + )), + ], + ), + ), + SizedBox(height: 47.h), + ConstrainedBox( + constraints: BoxConstraints(maxWidth: 540), + child: SizedBox( + width: 300.sp, + height: 50, + child: SignInButton( + Buttons.Google, + text: "Login with Google", + onPressed: () {}, + shape: RoundedRectangleBorder( + borderRadius: BorderRadius.all(Radius.circular(20))), + ), + ), + ), + ], + ), + )), + IgnorePointer( + child: Container( + height: 240.h, + decoration: BoxDecoration( + gradient: LinearGradient(begin: Alignment.topRight, stops: [ + 0, + 1 + ], colors: [ + bgColor.withOpacity(1), + bgColor.withOpacity(0) + ])), + ), + ), + Align( + alignment: Alignment.topCenter, + child: ConstrainedBox( + constraints: BoxConstraints(maxWidth: 800), + child: Padding( + padding: EdgeInsets.only( + top: 45.h, left: defaultPadding, right: defaultPadding), + child: ClipRRect( + borderRadius: BorderRadius.circular(10.0), + child: LinearProgressIndicator( + minHeight: 5, + value: 0.5, + backgroundColor: grayColor, + color: primaryColor, + ), + ), + ), + ), + ), + ], + ), + ); + } +} diff --git a/justMUSIC/lib/screens/welcome_screen.dart b/justMUSIC/lib/screens/welcome_screen.dart new file mode 100644 index 0000000..5ba91e5 --- /dev/null +++ b/justMUSIC/lib/screens/welcome_screen.dart @@ -0,0 +1,90 @@ +import 'package:flutter/cupertino.dart'; +import 'package:flutter/material.dart'; +import 'package:google_fonts/google_fonts.dart'; +import 'package:justmusic/values/constants.dart'; + +import '../components/join_button.dart'; + +class WellcomeScreen extends StatelessWidget { + const WellcomeScreen({Key? key}) : super(key: key); + + @override + Widget build(BuildContext context) { + return Scaffold( + body: Container( + padding: EdgeInsets.all(defaultPadding), + width: double.infinity, + height: double.infinity, + decoration: const BoxDecoration( + image: DecorationImage( + image: AssetImage("assets/images/wellcome_background.png"), + fit: BoxFit.cover, + ), + ), + child: Align( + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Expanded( + flex: 10, + child: Padding( + padding: EdgeInsets.only(bottom: 100), + child: Column( + mainAxisAlignment: MainAxisAlignment.end, + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Text( + "Bienvenue sur,", + style: GoogleFonts.plusJakartaSans( + color: Colors.white, + fontWeight: FontWeight.bold, + fontSize: 34), + ), + Image( + image: AssetImage("assets/images/logo.png"), + width: 230, + ), + SizedBox( + height: 25, + ), + ConstrainedBox( + constraints: BoxConstraints(maxWidth: 520), + child: Text( + "Explore les nouvelles découvertes musicales de tes amis, et partage leur ton mood.", + style: GoogleFonts.plusJakartaSans( + color: Colors.white, + fontWeight: FontWeight.w200, + fontSize: 15), + ), + ), + ], + ), + ), + ), + Expanded( + flex: 3, + child: Column( + mainAxisAlignment: MainAxisAlignment.start, + crossAxisAlignment: CrossAxisAlignment.center, + children: [ + JoinButton(), + SizedBox( + height: defaultPadding, + ), + Text( + "Tu as déja un compte? Connexion", + style: GoogleFonts.plusJakartaSans( + color: Colors.white, + fontWeight: FontWeight.w400, + fontSize: 15), + ), + ], + ), + ), + ], + ), + ) /* add child content here */, + ), + ); + } +} diff --git a/justMUSIC/lib/values/constants.dart b/justMUSIC/lib/values/constants.dart new file mode 100644 index 0000000..0bc9068 --- /dev/null +++ b/justMUSIC/lib/values/constants.dart @@ -0,0 +1,21 @@ +import 'package:flutter/material.dart'; + +// All needed color in the project + +const primaryColor = Color(0xFF643BF4); +const secondaryColor = Color(0xFF1C1B23); +const bgColor = Color(0xFF0C0C0C); +const grayColor = Color(0xFF242424); +const profileBttnColor = Color(0xFF232323); +const warningBttnColor = Color(0xFF141414); +const disabledBttnColor = Color(0xFF1F1B2E); +const bgTextField = Color(0xFF1C1B23); +const strokeTextField = Color(0xFF373546); +const unactiveFeed = Color(0xFF848484); +const gradiantPost = Color(0xFF0D0D0D); +const bgModal = Color(0xFF1E1E1E); +const bgComment = Color(0xFF222222); + +// All constants important too us + +const defaultPadding = 30.0;