From b13ae4da7b1b842cf2b8753acb587266b610ed24 Mon Sep 17 00:00:00 2001 From: iampawan Date: Tue, 2 Feb 2021 17:02:42 +0530 Subject: [PATCH 01/29] Day 2 completed --- lib/home_page.dart | 20 ++++++++++++++++++++ lib/main.dart | 12 +++--------- 2 files changed, 23 insertions(+), 9 deletions(-) create mode 100644 lib/home_page.dart diff --git a/lib/home_page.dart b/lib/home_page.dart new file mode 100644 index 0000000..487caed --- /dev/null +++ b/lib/home_page.dart @@ -0,0 +1,20 @@ +import 'package:flutter/material.dart'; + +class HomePage extends StatelessWidget { + final int days = 30; + final String name = "Codepur"; + @override + Widget build(BuildContext context) { + return Scaffold( + appBar: AppBar( + title: Text("Catalog App"), + ), + body: Center( + child: Container( + child: Text("Welcome to $days days of flutter by $name"), + ), + ), + drawer: Drawer(), + ); + } +} diff --git a/lib/main.dart b/lib/main.dart index dda5a28..f5342be 100644 --- a/lib/main.dart +++ b/lib/main.dart @@ -1,22 +1,16 @@ import 'package:flutter/material.dart'; +import 'home_page.dart'; + void main() { runApp(MyApp()); } class MyApp extends StatelessWidget { - const MyApp({Key key}) : super(key: key); - @override Widget build(BuildContext context) { return MaterialApp( - home: Material( - child: Center( - child: Container( - child: Text("Welcome to 30 days of flutter"), - ), - ), - ), + home: HomePage(), ); } } From 499559b3d88ccf1126e31fc6b2177b5564442ed8 Mon Sep 17 00:00:00 2001 From: iampawan Date: Wed, 3 Feb 2021 17:03:23 +0530 Subject: [PATCH 02/29] Day 3 completed --- lib/main.dart | 15 +++++++++++++-- lib/{ => pages}/home_page.dart | 0 lib/pages/login_page.dart | 19 +++++++++++++++++++ 3 files changed, 32 insertions(+), 2 deletions(-) rename lib/{ => pages}/home_page.dart (100%) create mode 100644 lib/pages/login_page.dart diff --git a/lib/main.dart b/lib/main.dart index f5342be..04600d7 100644 --- a/lib/main.dart +++ b/lib/main.dart @@ -1,6 +1,7 @@ import 'package:flutter/material.dart'; +import 'package:flutter_catalog/pages/login_page.dart'; -import 'home_page.dart'; +import 'pages/home_page.dart'; void main() { runApp(MyApp()); @@ -10,7 +11,17 @@ class MyApp extends StatelessWidget { @override Widget build(BuildContext context) { return MaterialApp( - home: HomePage(), + themeMode: ThemeMode.light, + theme: ThemeData(primarySwatch: Colors.deepPurple), + darkTheme: ThemeData( + brightness: Brightness.dark, + ), + initialRoute: "/home", + routes: { + "/": (context) => LoginPage(), + "/home": (context) => HomePage(), + "/login": (context) => LoginPage() + }, ); } } diff --git a/lib/home_page.dart b/lib/pages/home_page.dart similarity index 100% rename from lib/home_page.dart rename to lib/pages/home_page.dart diff --git a/lib/pages/login_page.dart b/lib/pages/login_page.dart new file mode 100644 index 0000000..2f307e0 --- /dev/null +++ b/lib/pages/login_page.dart @@ -0,0 +1,19 @@ +import 'package:flutter/material.dart'; + +class LoginPage extends StatelessWidget { + @override + Widget build(BuildContext context) { + return Material( + child: Center( + child: Text( + "Login Page", + style: TextStyle( + fontSize: 20, + color: Colors.blue, + fontWeight: FontWeight.bold, + ), + ), + ), + ); + } +} From c59068594f78049a53979432a1054fd5e333fdc7 Mon Sep 17 00:00:00 2001 From: iampawan Date: Thu, 4 Feb 2021 17:09:58 +0530 Subject: [PATCH 03/29] Day 4 completed --- assets/images/login_image.png | Bin 0 -> 24603 bytes ios/Podfile.lock | 6 +++ lib/main.dart | 9 ++-- lib/pages/login_page.dart | 64 ++++++++++++++++++++----- pubspec.lock | 85 ++++++++++++++++++++++++++++++++++ pubspec.yaml | 5 +- 6 files changed, 153 insertions(+), 16 deletions(-) create mode 100644 assets/images/login_image.png diff --git a/assets/images/login_image.png b/assets/images/login_image.png new file mode 100644 index 0000000000000000000000000000000000000000..b175b35282b8b8dbf263f64bfb2222d435346819 GIT binary patch literal 24603 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 z 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 LoginPage(), "/home": (context) => HomePage(), diff --git a/lib/pages/login_page.dart b/lib/pages/login_page.dart index 2f307e0..73465b5 100644 --- a/lib/pages/login_page.dart +++ b/lib/pages/login_page.dart @@ -4,16 +4,58 @@ class LoginPage extends StatelessWidget { @override Widget build(BuildContext context) { return Material( - child: Center( - child: Text( - "Login Page", - style: TextStyle( - fontSize: 20, - color: Colors.blue, - fontWeight: FontWeight.bold, - ), - ), - ), - ); + color: Colors.white, + child: Column( + children: [ + Image.asset( + "assets/images/login_image.png", + fit: BoxFit.cover, + ), + SizedBox( + height: 20.0, + ), + Text( + "Welcome", + style: TextStyle( + fontSize: 24, + fontWeight: FontWeight.bold, + ), + ), + SizedBox( + height: 20.0, + ), + Padding( + padding: + const EdgeInsets.symmetric(vertical: 16.0, horizontal: 32.0), + child: Column( + children: [ + TextFormField( + decoration: InputDecoration( + hintText: "Enter username", + labelText: "Username", + ), + ), + TextFormField( + obscureText: true, + decoration: InputDecoration( + hintText: "Enter password", + labelText: "Password", + ), + ), + SizedBox( + height: 20.0, + ), + ElevatedButton( + child: Text("Login"), + style: TextButton.styleFrom(), + onPressed: () { + print("Hi Codepur"); + }, + ) + ], + ), + ) + ], + )); } } diff --git a/pubspec.lock b/pubspec.lock index 62bef60..479a041 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -113,6 +113,13 @@ packages: url: "https://pub.dartlang.org" source: hosted version: "1.2.0-nullsafety.3" + ffi: + dependency: transitive + description: + name: ffi + url: "https://pub.dartlang.org" + source: hosted + version: "0.1.3" file: dependency: transitive description: @@ -147,6 +154,27 @@ packages: url: "https://pub.dartlang.org" source: hosted version: "1.2.0" + google_fonts: + dependency: "direct main" + description: + name: google_fonts + url: "https://pub.dartlang.org" + source: hosted + version: "1.1.2" + http: + dependency: transitive + description: + name: http + url: "https://pub.dartlang.org" + source: hosted + version: "0.12.2" + http_parser: + dependency: transitive + description: + name: http_parser + url: "https://pub.dartlang.org" + source: hosted + version: "3.1.4" integration_test: dependency: "direct dev" description: flutter @@ -222,6 +250,41 @@ packages: url: "https://pub.dartlang.org" source: hosted version: "1.8.0-nullsafety.3" + path_provider: + dependency: transitive + description: + name: path_provider + url: "https://pub.dartlang.org" + source: hosted + version: "1.6.27" + path_provider_linux: + dependency: transitive + description: + name: path_provider_linux + url: "https://pub.dartlang.org" + source: hosted + version: "0.0.1+2" + path_provider_macos: + dependency: transitive + description: + name: path_provider_macos + url: "https://pub.dartlang.org" + source: hosted + version: "0.0.4+8" + path_provider_platform_interface: + dependency: transitive + description: + name: path_provider_platform_interface + url: "https://pub.dartlang.org" + source: hosted + version: "1.0.4" + path_provider_windows: + dependency: transitive + description: + name: path_provider_windows + url: "https://pub.dartlang.org" + source: hosted + version: "0.0.4+3" pedantic: dependency: transitive description: @@ -236,6 +299,13 @@ packages: url: "https://pub.dartlang.org" source: hosted version: "3.0.0-nullsafety.4" + plugin_platform_interface: + dependency: transitive + description: + name: plugin_platform_interface + url: "https://pub.dartlang.org" + source: hosted + version: "1.0.3" pool: dependency: transitive description: @@ -374,6 +444,20 @@ 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: "1.7.4+1" + xdg_directories: + dependency: transitive + description: + name: xdg_directories + url: "https://pub.dartlang.org" + source: hosted + version: "0.1.2" yaml: dependency: transitive description: @@ -383,3 +467,4 @@ packages: version: "2.2.1" sdks: dart: ">=2.12.0-0.0 <3.0.0" + flutter: ">=1.17.0 <2.0.0" diff --git a/pubspec.yaml b/pubspec.yaml index 8efae22..baebcf5 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -27,6 +27,7 @@ dependencies: # The following adds the Cupertino Icons font to your application. # Use with the CupertinoIcons class for iOS style icons. cupertino_icons: ^1.0.1 + google_fonts: ^1.1.2 dev_dependencies: flutter_test: @@ -45,8 +46,8 @@ flutter: uses-material-design: true # To add assets to your application, add an assets section, like this: - # assets: - # - images/a_dot_burr.jpeg + assets: + - assets/images/ # - images/a_dot_ham.jpeg # An image asset can refer to one or more resolution-specific "variants", see From 84fef5767beff22bc769d977b7486009ea7a0b8e Mon Sep 17 00:00:00 2001 From: iampawan Date: Fri, 5 Feb 2021 18:22:21 +0530 Subject: [PATCH 04/29] day 5 completed --- lib/main.dart | 5 +- lib/pages/login_page.dart | 99 ++++++++++++++++++++------------------- lib/utils/routes.dart | 4 ++ 3 files changed, 58 insertions(+), 50 deletions(-) create mode 100644 lib/utils/routes.dart diff --git a/lib/main.dart b/lib/main.dart index 81f5db5..7ba9441 100644 --- a/lib/main.dart +++ b/lib/main.dart @@ -1,5 +1,6 @@ import 'package:flutter/material.dart'; import 'package:flutter_catalog/pages/login_page.dart'; +import 'package:flutter_catalog/utils/routes.dart'; import 'package:google_fonts/google_fonts.dart'; import 'pages/home_page.dart'; @@ -22,8 +23,8 @@ class MyApp extends StatelessWidget { initialRoute: "/", routes: { "/": (context) => LoginPage(), - "/home": (context) => HomePage(), - "/login": (context) => LoginPage() + MyRoutes.homeRoute: (context) => HomePage(), + MyRoutes.loginRoute: (context) => LoginPage() }, ); } diff --git a/lib/pages/login_page.dart b/lib/pages/login_page.dart index 73465b5..541acbc 100644 --- a/lib/pages/login_page.dart +++ b/lib/pages/login_page.dart @@ -1,61 +1,64 @@ import 'package:flutter/material.dart'; +import 'package:flutter_catalog/utils/routes.dart'; class LoginPage extends StatelessWidget { @override Widget build(BuildContext context) { return Material( color: Colors.white, - child: Column( - children: [ - Image.asset( - "assets/images/login_image.png", - fit: BoxFit.cover, - ), - SizedBox( - height: 20.0, - ), - Text( - "Welcome", - style: TextStyle( - fontSize: 24, - fontWeight: FontWeight.bold, + child: SingleChildScrollView( + child: Column( + children: [ + Image.asset( + "assets/images/login_image.png", + fit: BoxFit.cover, ), - ), - SizedBox( - height: 20.0, - ), - Padding( - padding: - const EdgeInsets.symmetric(vertical: 16.0, horizontal: 32.0), - child: Column( - children: [ - TextFormField( - decoration: InputDecoration( - hintText: "Enter username", - labelText: "Username", + SizedBox( + height: 20.0, + ), + Text( + "Welcome", + style: TextStyle( + fontSize: 28, + fontWeight: FontWeight.bold, + ), + ), + SizedBox( + height: 20.0, + ), + Padding( + padding: const EdgeInsets.symmetric( + vertical: 16.0, horizontal: 32.0), + child: Column( + children: [ + TextFormField( + decoration: InputDecoration( + hintText: "Enter username", + labelText: "Username", + ), ), - ), - TextFormField( - obscureText: true, - decoration: InputDecoration( - hintText: "Enter password", - labelText: "Password", + TextFormField( + obscureText: true, + decoration: InputDecoration( + hintText: "Enter password", + labelText: "Password", + ), ), - ), - SizedBox( - height: 20.0, - ), - ElevatedButton( - child: Text("Login"), - style: TextButton.styleFrom(), - onPressed: () { - print("Hi Codepur"); - }, - ) - ], - ), - ) - ], + SizedBox( + height: 40.0, + ), + ElevatedButton( + child: Text("Login"), + style: TextButton.styleFrom(minimumSize: Size(150, 40)), + onPressed: () { + Navigator.pushNamed(context, MyRoutes.homeRoute); + }, + ) + ], + ), + ) + ], + ), )); } } diff --git a/lib/utils/routes.dart b/lib/utils/routes.dart new file mode 100644 index 0000000..510c16a --- /dev/null +++ b/lib/utils/routes.dart @@ -0,0 +1,4 @@ +class MyRoutes { + static String loginRoute = "/login"; + static String homeRoute = "/home"; +} From 0e57c79befdf26615e4491467a219b69d3538b70 Mon Sep 17 00:00:00 2001 From: iampawan Date: Sat, 6 Feb 2021 17:17:30 +0530 Subject: [PATCH 05/29] day 6 completed --- lib/pages/login_page.dart | 60 ++++++++++++++++++++++++++++++++++----- 1 file changed, 53 insertions(+), 7 deletions(-) diff --git a/lib/pages/login_page.dart b/lib/pages/login_page.dart index 541acbc..2739751 100644 --- a/lib/pages/login_page.dart +++ b/lib/pages/login_page.dart @@ -1,7 +1,15 @@ import 'package:flutter/material.dart'; import 'package:flutter_catalog/utils/routes.dart'; -class LoginPage extends StatelessWidget { +class LoginPage extends StatefulWidget { + @override + _LoginPageState createState() => _LoginPageState(); +} + +class _LoginPageState extends State { + String name = ""; + bool changeButton = false; + @override Widget build(BuildContext context) { return Material( @@ -17,7 +25,7 @@ class LoginPage extends StatelessWidget { height: 20.0, ), Text( - "Welcome", + "Welcome $name", style: TextStyle( fontSize: 28, fontWeight: FontWeight.bold, @@ -36,6 +44,10 @@ class LoginPage extends StatelessWidget { hintText: "Enter username", labelText: "Username", ), + onChanged: (value) { + name = value; + setState(() {}); + }, ), TextFormField( obscureText: true, @@ -47,13 +59,47 @@ class LoginPage extends StatelessWidget { SizedBox( height: 40.0, ), - ElevatedButton( - child: Text("Login"), - style: TextButton.styleFrom(minimumSize: Size(150, 40)), - onPressed: () { + + InkWell( + onTap: () async { + setState(() { + changeButton = true; + }); + await Future.delayed(Duration(seconds: 1)); Navigator.pushNamed(context, MyRoutes.homeRoute); }, - ) + child: AnimatedContainer( + duration: Duration(seconds: 1), + width: changeButton ? 50 : 150, + height: 50, + alignment: Alignment.center, + child: changeButton + ? Icon( + Icons.done, + color: Colors.white, + ) + : Text( + "Login", + style: TextStyle( + color: Colors.white, + fontWeight: FontWeight.bold, + fontSize: 18), + ), + decoration: BoxDecoration( + color: Colors.deepPurple, + borderRadius: + BorderRadius.circular(changeButton ? 50 : 8), + ), + ), + ), + + // ElevatedButton( + // child: Text("Login"), + // style: TextButton.styleFrom(minimumSize: Size(150, 40)), + // onPressed: () { + // Navigator.pushNamed(context, MyRoutes.homeRoute); + // }, + // ) ], ), ) From e7578cffb012838d1051c85b0766169821e918a0 Mon Sep 17 00:00:00 2001 From: iampawan Date: Mon, 8 Feb 2021 16:55:37 +0530 Subject: [PATCH 06/29] Day 8 completed --- assets/images/hey.png | Bin 0 -> 49839 bytes lib/pages/login_page.dart | 185 +++++++++++++++++++++----------------- 2 files changed, 102 insertions(+), 83 deletions(-) create mode 100644 assets/images/hey.png diff --git a/assets/images/hey.png b/assets/images/hey.png new file mode 100644 index 0000000000000000000000000000000000000000..caeca234ec31e9b3457e1a33b133c391358fc6dd GIT binary patch literal 49839 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 q+2UWi{)=G$I-dV#i+?HceiNQqaxs|$&7n* { String name = ""; bool changeButton = false; + final _formKey = GlobalKey(); + + moveToHome(BuildContext context) async { + if (_formKey.currentState.validate()) { + setState(() { + changeButton = true; + }); + await Future.delayed(Duration(seconds: 1)); + await Navigator.pushNamed(context, MyRoutes.homeRoute); + setState(() { + changeButton = false; + }); + } + } + @override Widget build(BuildContext context) { return Material( color: Colors.white, child: SingleChildScrollView( - child: Column( - children: [ - Image.asset( - "assets/images/login_image.png", - fit: BoxFit.cover, - ), - SizedBox( - height: 20.0, - ), - Text( - "Welcome $name", - style: TextStyle( - fontSize: 28, - fontWeight: FontWeight.bold, + child: Form( + key: _formKey, + child: Column( + children: [ + Image.asset( + "assets/images/hey.png", + fit: BoxFit.cover, ), - ), - SizedBox( - height: 20.0, - ), - Padding( - padding: const EdgeInsets.symmetric( - vertical: 16.0, horizontal: 32.0), - child: Column( - children: [ - TextFormField( - decoration: InputDecoration( - hintText: "Enter username", - labelText: "Username", - ), - onChanged: (value) { - name = value; - setState(() {}); - }, - ), - TextFormField( - obscureText: true, - decoration: InputDecoration( - hintText: "Enter password", - labelText: "Password", + SizedBox( + height: 20.0, + ), + Text( + "Welcome $name", + style: TextStyle( + fontSize: 28, + fontWeight: FontWeight.bold, + ), + ), + SizedBox( + height: 20.0, + ), + Padding( + padding: const EdgeInsets.symmetric( + vertical: 16.0, horizontal: 32.0), + child: Column( + children: [ + TextFormField( + decoration: InputDecoration( + hintText: "Enter username", + labelText: "Username", + ), + validator: (value) { + if (value.isEmpty) { + return "Username cannot be empty"; + } + + return null; + }, + onChanged: (value) { + name = value; + setState(() {}); + }, ), - ), - SizedBox( - height: 40.0, - ), + TextFormField( + obscureText: true, + decoration: InputDecoration( + hintText: "Enter password", + labelText: "Password", + ), + validator: (value) { + if (value.isEmpty) { + return "Password cannot be empty"; + } else if (value.length < 6) { + return "Password length should be atleast 6"; + } - InkWell( - onTap: () async { - setState(() { - changeButton = true; - }); - await Future.delayed(Duration(seconds: 1)); - Navigator.pushNamed(context, MyRoutes.homeRoute); - }, - child: AnimatedContainer( - duration: Duration(seconds: 1), - width: changeButton ? 50 : 150, - height: 50, - alignment: Alignment.center, - child: changeButton - ? Icon( - Icons.done, - color: Colors.white, - ) - : Text( - "Login", - style: TextStyle( + return null; + }, + ), + SizedBox( + height: 40.0, + ), + Material( + color: Colors.deepPurple, + borderRadius: + BorderRadius.circular(changeButton ? 50 : 8), + child: InkWell( + onTap: () => moveToHome(context), + child: AnimatedContainer( + duration: Duration(seconds: 1), + width: changeButton ? 50 : 150, + height: 50, + alignment: Alignment.center, + child: changeButton + ? Icon( + Icons.done, color: Colors.white, - fontWeight: FontWeight.bold, - fontSize: 18), - ), - decoration: BoxDecoration( - color: Colors.deepPurple, - borderRadius: - BorderRadius.circular(changeButton ? 50 : 8), + ) + : Text( + "Login", + style: TextStyle( + color: Colors.white, + fontWeight: FontWeight.bold, + fontSize: 18), + ), + ), ), ), - ), - - // ElevatedButton( - // child: Text("Login"), - // style: TextButton.styleFrom(minimumSize: Size(150, 40)), - // onPressed: () { - // Navigator.pushNamed(context, MyRoutes.homeRoute); - // }, - // ) - ], - ), - ) - ], + ], + ), + ) + ], + ), ), )); } From 06cf8dc54890a9f5987d4c18cf87adc85210e5cc Mon Sep 17 00:00:00 2001 From: iampawan Date: Tue, 9 Feb 2021 18:55:16 +0530 Subject: [PATCH 07/29] Dau 9 complered --- lib/main.dart | 3 +- lib/pages/home_page.dart | 3 +- lib/widgets/drawer.dart | 70 ++++++++++++++++++++++++++++++++++++++++ 3 files changed, 74 insertions(+), 2 deletions(-) create mode 100644 lib/widgets/drawer.dart diff --git a/lib/main.dart b/lib/main.dart index 7ba9441..9ea57bb 100644 --- a/lib/main.dart +++ b/lib/main.dart @@ -20,7 +20,8 @@ class MyApp extends StatelessWidget { darkTheme: ThemeData( brightness: Brightness.dark, ), - initialRoute: "/", + debugShowCheckedModeBanner: false, + initialRoute: MyRoutes.homeRoute, routes: { "/": (context) => LoginPage(), MyRoutes.homeRoute: (context) => HomePage(), diff --git a/lib/pages/home_page.dart b/lib/pages/home_page.dart index 487caed..43112ee 100644 --- a/lib/pages/home_page.dart +++ b/lib/pages/home_page.dart @@ -1,4 +1,5 @@ import 'package:flutter/material.dart'; +import 'package:flutter_catalog/widgets/drawer.dart'; class HomePage extends StatelessWidget { final int days = 30; @@ -14,7 +15,7 @@ class HomePage extends StatelessWidget { child: Text("Welcome to $days days of flutter by $name"), ), ), - drawer: Drawer(), + drawer: MyDrawer(), ); } } diff --git a/lib/widgets/drawer.dart b/lib/widgets/drawer.dart new file mode 100644 index 0000000..298d27b --- /dev/null +++ b/lib/widgets/drawer.dart @@ -0,0 +1,70 @@ +import 'package:flutter/cupertino.dart'; +import 'package:flutter/material.dart'; + +class MyDrawer extends StatelessWidget { + @override + Widget build(BuildContext context) { + final imageUrl = + "https://avatars.githubusercontent.com/u/12619420?s=460&u=26db98cbde1dd34c7c67b85c240505a436b2c36d&v=4"; + return Drawer( + child: Container( + color: Colors.deepPurple, + child: ListView( + padding: EdgeInsets.zero, + children: [ + DrawerHeader( + padding: EdgeInsets.zero, + child: UserAccountsDrawerHeader( + margin: EdgeInsets.zero, + accountName: Text("Pawan Kumar"), + accountEmail: Text("mtechviral@gmail.com"), + currentAccountPicture: CircleAvatar( + backgroundImage: NetworkImage(imageUrl), + ), + ), + ), + ListTile( + leading: Icon( + CupertinoIcons.home, + color: Colors.white, + ), + title: Text( + "Home", + textScaleFactor: 1.2, + style: TextStyle( + color: Colors.white, + ), + ), + ), + ListTile( + leading: Icon( + CupertinoIcons.profile_circled, + color: Colors.white, + ), + title: Text( + "Profile", + textScaleFactor: 1.2, + style: TextStyle( + color: Colors.white, + ), + ), + ), + ListTile( + leading: Icon( + CupertinoIcons.mail, + color: Colors.white, + ), + title: Text( + "Email me", + textScaleFactor: 1.2, + style: TextStyle( + color: Colors.white, + ), + ), + ) + ], + ), + ), + ); + } +} From 7ca256153a3c6f8da0bd859aa5321ae12363cc0d Mon Sep 17 00:00:00 2001 From: iampawan Date: Wed, 10 Feb 2021 19:37:45 +0530 Subject: [PATCH 08/29] themes extracted --- lib/main.dart | 11 +++-------- lib/widgets/themes.dart | 18 ++++++++++++++++++ 2 files changed, 21 insertions(+), 8 deletions(-) create mode 100644 lib/widgets/themes.dart diff --git a/lib/main.dart b/lib/main.dart index 9ea57bb..1091413 100644 --- a/lib/main.dart +++ b/lib/main.dart @@ -1,8 +1,8 @@ import 'package:flutter/material.dart'; import 'package:flutter_catalog/pages/login_page.dart'; import 'package:flutter_catalog/utils/routes.dart'; -import 'package:google_fonts/google_fonts.dart'; import 'pages/home_page.dart'; +import 'widgets/themes.dart'; void main() { runApp(MyApp()); @@ -13,13 +13,8 @@ class MyApp extends StatelessWidget { Widget build(BuildContext context) { return MaterialApp( themeMode: ThemeMode.light, - theme: ThemeData( - primarySwatch: Colors.deepPurple, - fontFamily: GoogleFonts.lato().fontFamily, - ), - darkTheme: ThemeData( - brightness: Brightness.dark, - ), + theme: MyTheme.lightTheme(context), + darkTheme: MyTheme.darkTheme(context), debugShowCheckedModeBanner: false, initialRoute: MyRoutes.homeRoute, routes: { diff --git a/lib/widgets/themes.dart b/lib/widgets/themes.dart new file mode 100644 index 0000000..158a8d1 --- /dev/null +++ b/lib/widgets/themes.dart @@ -0,0 +1,18 @@ +import 'package:flutter/material.dart'; +import 'package:google_fonts/google_fonts.dart'; + +class MyTheme { + static ThemeData lightTheme(BuildContext context) => ThemeData( + primarySwatch: Colors.deepPurple, + fontFamily: GoogleFonts.lato().fontFamily, + appBarTheme: AppBarTheme( + color: Colors.white, + elevation: 0.0, + iconTheme: IconThemeData(color: Colors.black), + textTheme: Theme.of(context).textTheme, + )); + + static ThemeData darkTheme(BuildContext context) => ThemeData( + brightness: Brightness.dark, + ); +} From 02f7ca0a43705d89ef9836eebec74ece6e331d93 Mon Sep 17 00:00:00 2001 From: iampawan Date: Wed, 10 Feb 2021 21:47:54 +0530 Subject: [PATCH 09/29] day 10 completed --- lib/models/catalog.dart | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) create mode 100644 lib/models/catalog.dart diff --git a/lib/models/catalog.dart b/lib/models/catalog.dart new file mode 100644 index 0000000..5986006 --- /dev/null +++ b/lib/models/catalog.dart @@ -0,0 +1,21 @@ +class Item { + final String id; + final String name; + final String desc; + final num price; + final String color; + final String image; + + Item({this.id, this.name, this.desc, this.price, this.color, this.image}); +} + +final products = [ + Item( + id: "Codepur001", + name: "iPhone 12 Pro", + desc: "Apple iPhone 12th generation", + price: 999, + color: "#33505a", + image: + "https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcRISJ6msIu4AU9_M9ZnJVQVFmfuhfyJjEtbUm3ZK11_8IV9TV25-1uM5wHjiFNwKy99w0mR5Hk&usqp=CAc") +]; From dc0c49da4e4a608f37a2bddd738538bd4fb81b35 Mon Sep 17 00:00:00 2001 From: iampawan Date: Thu, 11 Feb 2021 18:55:03 +0530 Subject: [PATCH 10/29] Day 11 completed --- lib/pages/home_page.dart | 1 + 1 file changed, 1 insertion(+) diff --git a/lib/pages/home_page.dart b/lib/pages/home_page.dart index 43112ee..75ce5be 100644 --- a/lib/pages/home_page.dart +++ b/lib/pages/home_page.dart @@ -1,6 +1,7 @@ import 'package:flutter/material.dart'; import 'package:flutter_catalog/widgets/drawer.dart'; +//* Day 11 we learned about context, constraints class HomePage extends StatelessWidget { final int days = 30; final String name = "Codepur"; From 1a6bd7235849cd87299375abd0eb8d5cad613f34 Mon Sep 17 00:00:00 2001 From: iampawan Date: Fri, 12 Feb 2021 19:33:42 +0530 Subject: [PATCH 11/29] Day 12 completed --- lib/models/catalog.dart | 26 ++++++++++++++------------ lib/pages/home_page.dart | 16 ++++++++++++---- lib/widgets/item_widget.dart | 32 ++++++++++++++++++++++++++++++++ 3 files changed, 58 insertions(+), 16 deletions(-) create mode 100644 lib/widgets/item_widget.dart diff --git a/lib/models/catalog.dart b/lib/models/catalog.dart index 5986006..da10336 100644 --- a/lib/models/catalog.dart +++ b/lib/models/catalog.dart @@ -1,5 +1,18 @@ +class CatalogModel { + static final items = [ + Item( + id: 1, + name: "iPhone 12 Pro", + desc: "Apple iPhone 12th generation", + price: 999, + color: "#33505a", + image: + "https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcRISJ6msIu4AU9_M9ZnJVQVFmfuhfyJjEtbUm3ZK11_8IV9TV25-1uM5wHjiFNwKy99w0mR5Hk&usqp=CAc") + ]; +} + class Item { - final String id; + final int id; final String name; final String desc; final num price; @@ -8,14 +21,3 @@ class Item { Item({this.id, this.name, this.desc, this.price, this.color, this.image}); } - -final products = [ - Item( - id: "Codepur001", - name: "iPhone 12 Pro", - desc: "Apple iPhone 12th generation", - price: 999, - color: "#33505a", - image: - "https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcRISJ6msIu4AU9_M9ZnJVQVFmfuhfyJjEtbUm3ZK11_8IV9TV25-1uM5wHjiFNwKy99w0mR5Hk&usqp=CAc") -]; diff --git a/lib/pages/home_page.dart b/lib/pages/home_page.dart index 75ce5be..16f1ec8 100644 --- a/lib/pages/home_page.dart +++ b/lib/pages/home_page.dart @@ -1,19 +1,27 @@ import 'package:flutter/material.dart'; +import 'package:flutter_catalog/models/catalog.dart'; import 'package:flutter_catalog/widgets/drawer.dart'; +import 'package:flutter_catalog/widgets/item_widget.dart'; -//* Day 11 we learned about context, constraints class HomePage extends StatelessWidget { final int days = 30; final String name = "Codepur"; @override Widget build(BuildContext context) { + final dummyList = List.generate(20, (index) => CatalogModel.items[0]); return Scaffold( appBar: AppBar( title: Text("Catalog App"), ), - body: Center( - child: Container( - child: Text("Welcome to $days days of flutter by $name"), + body: Padding( + padding: const EdgeInsets.all(16.0), + child: ListView.builder( + itemCount: dummyList.length, + itemBuilder: (context, index) { + return ItemWidget( + item: dummyList[index], + ); + }, ), ), drawer: MyDrawer(), diff --git a/lib/widgets/item_widget.dart b/lib/widgets/item_widget.dart new file mode 100644 index 0000000..7bc5396 --- /dev/null +++ b/lib/widgets/item_widget.dart @@ -0,0 +1,32 @@ +import 'package:flutter/material.dart'; +import 'package:flutter_catalog/models/catalog.dart'; + +class ItemWidget extends StatelessWidget { + final Item item; + + const ItemWidget({Key key, @required this.item}) + : assert(item != null), + super(key: key); + + @override + Widget build(BuildContext context) { + return Card( + child: ListTile( + onTap: () { + print("${item.name} pressed"); + }, + leading: Image.network(item.image), + title: Text(item.name), + subtitle: Text(item.desc), + trailing: Text( + "\$${item.price}", + textScaleFactor: 1.5, + style: TextStyle( + color: Colors.deepPurple, + fontWeight: FontWeight.bold, + ), + ), + ), + ); + } +} From 1d481bf2385d19120e01f5c3ce7817f0d7083cc1 Mon Sep 17 00:00:00 2001 From: iampawan Date: Sat, 13 Feb 2021 15:37:10 +0530 Subject: [PATCH 12/29] day13 completed --- assets/files/catalog.json | 68 +++++++++++++++++++++++++++++++++++++++ lib/pages/home_page.dart | 25 +++++++++++++- pubspec.yaml | 1 + 3 files changed, 93 insertions(+), 1 deletion(-) create mode 100644 assets/files/catalog.json diff --git a/assets/files/catalog.json b/assets/files/catalog.json new file mode 100644 index 0000000..a86aa8a --- /dev/null +++ b/assets/files/catalog.json @@ -0,0 +1,68 @@ +{ + "products": [ + { + "id": 1, + "name": "iPhone 12 Pro", + "desc": "Apple iPhone 12th generation", + "price": 999, + "color": "#33505a", + "image": "https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcRISJ6msIu4AU9_M9ZnJVQVFmfuhfyJjEtbUm3ZK11_8IV9TV25-1uM5wHjiFNwKy99w0mR5Hk&usqp=CAc" + }, + { + "id": 2, + "name": "Pixel 5", + "desc": "Google Pixel phone 5th generation", + "price": 699, + "color": "#00ac51", + "image": "https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcSd0JhwLvm_uLDLc-la7hK9WyVpe9naJFcebKfhcICiq2KtvXDePNAU_9QO06LPcQ0K0fLByc7m&usqp=CAc" + }, + { + "id": 3, + "name": "M1 Macbook Air", + "desc": "Apple Macbook air with apple silicon", + "price": 1099, + "color": "#e0bfae", + "image": "https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcSMOMstwtmLnjFb3NHiDJ_kcQnueNVH-rv_3ps96HZmXlFumKWaiBqq_L4Uoyx3iFiNTrXNEbyB&usqp=CAc" + }, + { + "id": 4, + "name": "Playstation 5", + "desc": "Sony Playstation 5th generation", + "price": 500, + "color": "#544ee4", + "image": "https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcSMOMstwtmLnjFb3NHiDJ_kcQnueNVH-rv_3ps96HZmXlFumKWaiBqq_L4Uoyx3iFiNTrXNEbyB&usqp=CAc" + }, + { + "id": 5, + "name": "Airpods Pro", + "desc": "Apple Aipods Pro 1st generation", + "price": 200, + "color": "#e3e4e9", + "image": "https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcQROEs084z65psoo06zYl5R0tUzywOVKVQZzmzqCj3PDP1vVJTWv3gGwGMFENSy4qV4n7sEQjE&usqp=CAc" + }, + { + "id": 6, + "name": "iPad Pro", + "desc": "Apple iPad Pro 2020 edition", + "price": 799, + "color": "#f73984", + "image": "https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcSNzUeRQ5uH7E3hpECib8qxdhfHv6SnUGT7mOsew_xiOoqRR7ZpdH-TQ4J6-HuIEfqHimYyPXWH&usqp=CAc" + }, + { + "id": 7, + "name": "Galaxy S21 Ultra", + "desc": "Samsung Galaxy S21 Ultra 2021 edition", + "price": 1299, + "color": "#1c1c1c", + "image": "https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcTT_PZcc0wicVYR992s5QCIDLYy8t-z-9kibTUdWZBN2sd86aaqdAJfhvxAwZNWV9wfdzDikpr1&usqp=CAc" + }, + { + "id": 8, + "name": "Galaxy S21", + "desc": "Samsung Galaxy S21 2021 edition", + "price": 899, + "color": "#7c95eb", + "image": "https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcRBNHd7FwarbxA1xdMFt24KazjcR4dWPH_t_T5dz4YNK1s7rJAQ8gOIuR_NRw6eeiQgFhbZ9sAN&usqp=CAc" + } + ] +} \ No newline at end of file diff --git a/lib/pages/home_page.dart b/lib/pages/home_page.dart index 16f1ec8..9db00ed 100644 --- a/lib/pages/home_page.dart +++ b/lib/pages/home_page.dart @@ -1,11 +1,34 @@ import 'package:flutter/material.dart'; +import 'package:flutter/services.dart'; +import 'dart:convert'; import 'package:flutter_catalog/models/catalog.dart'; import 'package:flutter_catalog/widgets/drawer.dart'; import 'package:flutter_catalog/widgets/item_widget.dart'; -class HomePage extends StatelessWidget { +class HomePage extends StatefulWidget { + @override + _HomePageState createState() => _HomePageState(); +} + +class _HomePageState extends State { final int days = 30; + final String name = "Codepur"; + + @override + void initState() { + super.initState(); + loadData(); + } + + loadData() async { + final catalogJson = + await rootBundle.loadString("assets/files/catalog.json"); + final decodedData = jsonDecode(catalogJson); + var productsData = decodedData["products"]; + print(productsData); + } + @override Widget build(BuildContext context) { final dummyList = List.generate(20, (index) => CatalogModel.items[0]); diff --git a/pubspec.yaml b/pubspec.yaml index baebcf5..077b911 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -48,6 +48,7 @@ flutter: # To add assets to your application, add an assets section, like this: assets: - assets/images/ + - assets/files/ # - images/a_dot_ham.jpeg # An image asset can refer to one or more resolution-specific "variants", see From da37eea6a4908a4900c8d0dc3c353d6eb0086cb5 Mon Sep 17 00:00:00 2001 From: iampawan Date: Tue, 16 Feb 2021 19:50:21 +0530 Subject: [PATCH 13/29] fixes --- integration_test/app_test.dart | 2 +- ios/Flutter/Debug.xcconfig | 1 + ios/Flutter/Release.xcconfig | 1 + pubspec.lock | 184 ++++----------------------------- 4 files changed, 25 insertions(+), 163 deletions(-) diff --git a/integration_test/app_test.dart b/integration_test/app_test.dart index bbf8055..51fd2f5 100644 --- a/integration_test/app_test.dart +++ b/integration_test/app_test.dart @@ -11,7 +11,7 @@ import 'package:integration_test/integration_test.dart'; import 'package:flutter_catalog/main.dart' as app; -void main() => run(_testMain); +// void main() => run(_testMain); void _testMain() { testWidgets('Counter increments smoke test', (WidgetTester tester) async { diff --git a/ios/Flutter/Debug.xcconfig b/ios/Flutter/Debug.xcconfig index e8efba1..b2f5fae 100644 --- a/ios/Flutter/Debug.xcconfig +++ b/ios/Flutter/Debug.xcconfig @@ -1,2 +1,3 @@ +#include? "Pods/Target Support Files/Pods-Runner/Pods-Runner.debug.xcconfig" #include "Pods/Target Support Files/Pods-Runner/Pods-Runner.debug.xcconfig" #include "Generated.xcconfig" diff --git a/ios/Flutter/Release.xcconfig b/ios/Flutter/Release.xcconfig index 399e934..88c2914 100644 --- a/ios/Flutter/Release.xcconfig +++ b/ios/Flutter/Release.xcconfig @@ -1,2 +1,3 @@ +#include? "Pods/Target Support Files/Pods-Runner/Pods-Runner.release.xcconfig" #include "Pods/Target Support Files/Pods-Runner/Pods-Runner.release.xcconfig" #include "Generated.xcconfig" diff --git a/pubspec.lock b/pubspec.lock index 479a041..146e4d1 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -1,20 +1,6 @@ # Generated by pub # See https://dart.dev/tools/pub/glossary#lockfile packages: - _fe_analyzer_shared: - dependency: transitive - description: - name: _fe_analyzer_shared - url: "https://pub.dartlang.org" - source: hosted - version: "12.0.0" - analyzer: - dependency: transitive - description: - name: analyzer - url: "https://pub.dartlang.org" - source: hosted - version: "0.40.6" archive: dependency: transitive description: @@ -35,49 +21,42 @@ packages: name: async url: "https://pub.dartlang.org" source: hosted - version: "2.5.0-nullsafety.3" + version: "2.5.0" boolean_selector: dependency: transitive description: name: boolean_selector url: "https://pub.dartlang.org" source: hosted - version: "2.1.0-nullsafety.3" + version: "2.1.0" characters: dependency: transitive description: name: characters url: "https://pub.dartlang.org" source: hosted - version: "1.1.0-nullsafety.5" + version: "1.1.0" charcode: dependency: transitive description: name: charcode url: "https://pub.dartlang.org" source: hosted - version: "1.2.0-nullsafety.3" - cli_util: - dependency: transitive - description: - name: cli_util - url: "https://pub.dartlang.org" - source: hosted - version: "0.2.0" + version: "1.2.0" clock: dependency: transitive description: name: clock url: "https://pub.dartlang.org" source: hosted - version: "1.1.0-nullsafety.3" + version: "1.1.0" collection: dependency: transitive description: name: collection url: "https://pub.dartlang.org" source: hosted - version: "1.15.0-nullsafety.5" + version: "1.15.0" convert: dependency: transitive description: @@ -85,13 +64,6 @@ packages: url: "https://pub.dartlang.org" source: hosted version: "2.1.1" - coverage: - dependency: transitive - description: - name: coverage - url: "https://pub.dartlang.org" - source: hosted - version: "0.14.2" crypto: dependency: transitive description: @@ -112,7 +84,7 @@ packages: name: fake_async url: "https://pub.dartlang.org" source: hosted - version: "1.2.0-nullsafety.3" + version: "1.2.0" ffi: dependency: transitive description: @@ -126,7 +98,7 @@ packages: name: file url: "https://pub.dartlang.org" source: hosted - version: "6.0.0-nullsafety.4" + version: "6.0.0" flutter: dependency: "direct main" description: flutter @@ -147,13 +119,6 @@ packages: description: flutter source: sdk version: "0.0.0" - glob: - dependency: transitive - description: - name: glob - url: "https://pub.dartlang.org" - source: hosted - version: "1.2.0" google_fonts: dependency: "direct main" description: @@ -180,76 +145,27 @@ packages: description: flutter source: sdk version: "0.9.2+2" - io: - dependency: transitive - description: - name: io - url: "https://pub.dartlang.org" - source: hosted - version: "0.3.4" - js: - dependency: transitive - description: - name: js - url: "https://pub.dartlang.org" - source: hosted - version: "0.6.3-nullsafety.3" - json_rpc_2: - dependency: transitive - description: - name: json_rpc_2 - url: "https://pub.dartlang.org" - source: hosted - version: "2.2.2" - logging: - dependency: transitive - description: - name: logging - url: "https://pub.dartlang.org" - source: hosted - version: "0.11.4" matcher: dependency: transitive description: name: matcher url: "https://pub.dartlang.org" source: hosted - version: "0.12.10-nullsafety.3" + version: "0.12.10" meta: dependency: transitive description: name: meta url: "https://pub.dartlang.org" source: hosted - version: "1.3.0-nullsafety.6" - node_interop: - dependency: transitive - description: - name: node_interop - url: "https://pub.dartlang.org" - source: hosted - version: "1.2.1" - node_io: - dependency: transitive - description: - name: node_io - url: "https://pub.dartlang.org" - source: hosted - version: "1.1.1" - package_config: - dependency: transitive - description: - name: package_config - url: "https://pub.dartlang.org" - source: hosted - version: "1.9.3" + version: "1.3.0" path: dependency: transitive description: name: path url: "https://pub.dartlang.org" source: hosted - version: "1.8.0-nullsafety.3" + version: "1.8.0" path_provider: dependency: transitive description: @@ -298,7 +214,7 @@ packages: name: platform url: "https://pub.dartlang.org" source: hosted - version: "3.0.0-nullsafety.4" + version: "3.0.0" plugin_platform_interface: dependency: transitive description: @@ -306,74 +222,46 @@ packages: url: "https://pub.dartlang.org" source: hosted version: "1.0.3" - pool: - dependency: transitive - description: - name: pool - url: "https://pub.dartlang.org" - source: hosted - version: "1.5.0-nullsafety.3" process: dependency: transitive description: name: process url: "https://pub.dartlang.org" source: hosted - version: "4.0.0-nullsafety.4" - pub_semver: - dependency: transitive - description: - name: pub_semver - url: "https://pub.dartlang.org" - source: hosted - version: "1.4.4" + version: "4.0.0" sky_engine: dependency: transitive description: flutter source: sdk version: "0.0.99" - source_map_stack_trace: - dependency: transitive - description: - name: source_map_stack_trace - url: "https://pub.dartlang.org" - source: hosted - version: "2.1.0-nullsafety.4" - source_maps: - dependency: transitive - description: - name: source_maps - url: "https://pub.dartlang.org" - source: hosted - version: "0.10.10-nullsafety.3" source_span: dependency: transitive description: name: source_span url: "https://pub.dartlang.org" source: hosted - version: "1.8.0-nullsafety.4" + version: "1.8.0" stack_trace: dependency: transitive description: name: stack_trace url: "https://pub.dartlang.org" source: hosted - version: "1.10.0-nullsafety.6" + version: "1.10.0" stream_channel: dependency: transitive description: name: stream_channel url: "https://pub.dartlang.org" source: hosted - version: "2.1.0-nullsafety.3" + version: "2.1.0" string_scanner: dependency: transitive description: name: string_scanner url: "https://pub.dartlang.org" source: hosted - version: "1.1.0-nullsafety.3" + version: "1.1.0" sync_http: dependency: transitive description: @@ -387,35 +275,28 @@ packages: name: term_glyph url: "https://pub.dartlang.org" source: hosted - version: "1.2.0-nullsafety.3" + version: "1.2.0" test_api: dependency: transitive description: name: test_api url: "https://pub.dartlang.org" source: hosted - version: "0.2.19-nullsafety.6" - test_core: - dependency: transitive - description: - name: test_core - url: "https://pub.dartlang.org" - source: hosted - version: "0.3.12-nullsafety.9" + version: "0.2.19" typed_data: dependency: transitive description: name: typed_data url: "https://pub.dartlang.org" source: hosted - version: "1.3.0-nullsafety.5" + version: "1.3.0" vector_math: dependency: transitive description: name: vector_math url: "https://pub.dartlang.org" source: hosted - version: "2.1.0-nullsafety.5" + version: "2.1.0" vm_service: dependency: transitive description: @@ -423,20 +304,6 @@ packages: url: "https://pub.dartlang.org" source: hosted version: "5.5.0" - watcher: - dependency: transitive - description: - name: watcher - url: "https://pub.dartlang.org" - source: hosted - version: "0.9.7+15" - web_socket_channel: - dependency: transitive - description: - name: web_socket_channel - url: "https://pub.dartlang.org" - source: hosted - version: "1.1.0" webdriver: dependency: transitive description: @@ -458,13 +325,6 @@ packages: url: "https://pub.dartlang.org" source: hosted version: "0.1.2" - yaml: - dependency: transitive - description: - name: yaml - url: "https://pub.dartlang.org" - source: hosted - version: "2.2.1" sdks: dart: ">=2.12.0-0.0 <3.0.0" - flutter: ">=1.17.0 <2.0.0" + flutter: ">=1.17.0" From 5b9ec55190895f714dbe0340c942854378d62200 Mon Sep 17 00:00:00 2001 From: iampawan Date: Tue, 16 Feb 2021 20:46:58 +0530 Subject: [PATCH 14/29] day 15 completed --- lib/models/catalog.dart | 96 +++++++++++++++++++++++++++++++++++----- lib/pages/home_page.dart | 25 ++++++----- 2 files changed, 100 insertions(+), 21 deletions(-) diff --git a/lib/models/catalog.dart b/lib/models/catalog.dart index da10336..d13e24a 100644 --- a/lib/models/catalog.dart +++ b/lib/models/catalog.dart @@ -1,14 +1,7 @@ +import 'dart:convert'; + class CatalogModel { - static final items = [ - Item( - id: 1, - name: "iPhone 12 Pro", - desc: "Apple iPhone 12th generation", - price: 999, - color: "#33505a", - image: - "https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcRISJ6msIu4AU9_M9ZnJVQVFmfuhfyJjEtbUm3ZK11_8IV9TV25-1uM5wHjiFNwKy99w0mR5Hk&usqp=CAc") - ]; + static List items; } class Item { @@ -19,5 +12,86 @@ class Item { final String color; final String image; - Item({this.id, this.name, this.desc, this.price, this.color, this.image}); + Item({ + this.id, + this.name, + this.desc, + this.price, + this.color, + this.image, + }); + + Item copyWith({ + int id, + String name, + String desc, + num price, + String color, + String image, + }) { + return Item( + id: id ?? this.id, + name: name ?? this.name, + desc: desc ?? this.desc, + price: price ?? this.price, + color: color ?? this.color, + image: image ?? this.image, + ); + } + + Map toMap() { + return { + 'id': id, + 'name': name, + 'desc': desc, + 'price': price, + 'color': color, + 'image': image, + }; + } + + factory Item.fromMap(Map map) { + if (map == null) return null; + + return Item( + id: map['id'], + name: map['name'], + desc: map['desc'], + price: map['price'], + color: map['color'], + image: map['image'], + ); + } + + String toJson() => json.encode(toMap()); + + factory Item.fromJson(String source) => Item.fromMap(json.decode(source)); + + @override + String toString() { + return 'Item(id: $id, name: $name, desc: $desc, price: $price, color: $color, image: $image)'; + } + + @override + bool operator ==(Object o) { + if (identical(this, o)) return true; + + return o is Item && + o.id == id && + o.name == name && + o.desc == desc && + o.price == price && + o.color == color && + o.image == image; + } + + @override + int get hashCode { + return id.hashCode ^ + name.hashCode ^ + desc.hashCode ^ + price.hashCode ^ + color.hashCode ^ + image.hashCode; + } } diff --git a/lib/pages/home_page.dart b/lib/pages/home_page.dart index 9db00ed..30040c3 100644 --- a/lib/pages/home_page.dart +++ b/lib/pages/home_page.dart @@ -22,30 +22,35 @@ class _HomePageState extends State { } loadData() async { + await Future.delayed(Duration(seconds: 2)); final catalogJson = await rootBundle.loadString("assets/files/catalog.json"); final decodedData = jsonDecode(catalogJson); var productsData = decodedData["products"]; - print(productsData); + CatalogModel.items = List.from(productsData) + .map((item) => Item.fromMap(item)) + .toList(); + setState(() {}); } @override Widget build(BuildContext context) { - final dummyList = List.generate(20, (index) => CatalogModel.items[0]); return Scaffold( appBar: AppBar( title: Text("Catalog App"), ), body: Padding( padding: const EdgeInsets.all(16.0), - child: ListView.builder( - itemCount: dummyList.length, - itemBuilder: (context, index) { - return ItemWidget( - item: dummyList[index], - ); - }, - ), + child: (CatalogModel.items != null && CatalogModel.items.isNotEmpty) + ? ListView.builder( + itemCount: CatalogModel.items.length, + itemBuilder: (context, index) => ItemWidget( + item: CatalogModel.items[index], + ), + ) + : Center( + child: CircularProgressIndicator(), + ), ), drawer: MyDrawer(), ); From 1472bce27b0d2686dd4e03784bd34a6ecd9b88de Mon Sep 17 00:00:00 2001 From: iampawan Date: Tue, 16 Feb 2021 21:25:34 +0530 Subject: [PATCH 15/29] day 16 completed --- lib/pages/home_page.dart | 42 ++++++++++++++++++++++++++++++++++++---- 1 file changed, 38 insertions(+), 4 deletions(-) diff --git a/lib/pages/home_page.dart b/lib/pages/home_page.dart index 30040c3..b59ff85 100644 --- a/lib/pages/home_page.dart +++ b/lib/pages/home_page.dart @@ -42,11 +42,45 @@ class _HomePageState extends State { body: Padding( padding: const EdgeInsets.all(16.0), child: (CatalogModel.items != null && CatalogModel.items.isNotEmpty) - ? ListView.builder( - itemCount: CatalogModel.items.length, - itemBuilder: (context, index) => ItemWidget( - item: CatalogModel.items[index], + ? GridView.builder( + gridDelegate: SliverGridDelegateWithFixedCrossAxisCount( + crossAxisCount: 2, + mainAxisSpacing: 16, + crossAxisSpacing: 16, ), + itemBuilder: (context, index) { + final item = CatalogModel.items[index]; + return Card( + clipBehavior: Clip.antiAlias, + shape: RoundedRectangleBorder( + borderRadius: BorderRadius.circular(10)), + child: GridTile( + header: Container( + child: Text( + item.name, + style: TextStyle(color: Colors.white), + ), + padding: const EdgeInsets.all(12), + decoration: BoxDecoration( + color: Colors.deepPurple, + ), + ), + child: Image.network( + item.image, + ), + footer: Container( + child: Text( + item.price.toString(), + style: TextStyle(color: Colors.white), + ), + padding: const EdgeInsets.all(12), + decoration: BoxDecoration( + color: Colors.black, + ), + ), + )); + }, + itemCount: CatalogModel.items.length, ) : Center( child: CircularProgressIndicator(), From d3df629e78e4a5bf8035d997476b0521ce7e4164 Mon Sep 17 00:00:00 2001 From: iampawan Date: Thu, 18 Feb 2021 21:42:15 +0530 Subject: [PATCH 16/29] Day 17 completed --- assets/files/catalog.json | 16 ++-- lib/pages/home_page.dart | 156 ++++++++++++++++++++++++++------------ lib/widgets/themes.dart | 6 +- pubspec.lock | 42 ++++++++++ pubspec.yaml | 8 +- 5 files changed, 162 insertions(+), 66 deletions(-) diff --git a/assets/files/catalog.json b/assets/files/catalog.json index a86aa8a..c52284b 100644 --- a/assets/files/catalog.json +++ b/assets/files/catalog.json @@ -6,7 +6,7 @@ "desc": "Apple iPhone 12th generation", "price": 999, "color": "#33505a", - "image": "https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcRISJ6msIu4AU9_M9ZnJVQVFmfuhfyJjEtbUm3ZK11_8IV9TV25-1uM5wHjiFNwKy99w0mR5Hk&usqp=CAc" + "image": "https://store.storeimages.cdn-apple.com/4982/as-images.apple.com/is/iphone-12-pro-blue-hero?wid=940&hei=1112&fmt=png-alpha&qlt=80&.v=1604021661000" }, { "id": 2, @@ -14,7 +14,7 @@ "desc": "Google Pixel phone 5th generation", "price": 699, "color": "#00ac51", - "image": "https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcSd0JhwLvm_uLDLc-la7hK9WyVpe9naJFcebKfhcICiq2KtvXDePNAU_9QO06LPcQ0K0fLByc7m&usqp=CAc" + "image": "https://www.telstra.com.au/content/dam/tcom/lego/2020/plans-devices/mobiles/google-pixel-5/shared-google-pixel-5-black-05-900x1200.png" }, { "id": 3, @@ -22,7 +22,7 @@ "desc": "Apple Macbook air with apple silicon", "price": 1099, "color": "#e0bfae", - "image": "https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcSMOMstwtmLnjFb3NHiDJ_kcQnueNVH-rv_3ps96HZmXlFumKWaiBqq_L4Uoyx3iFiNTrXNEbyB&usqp=CAc" + "image": "https://support.apple.com/library/APPLE/APPLECARE_ALLGEOS/SP825/macbookair.png" }, { "id": 4, @@ -30,7 +30,7 @@ "desc": "Sony Playstation 5th generation", "price": 500, "color": "#544ee4", - "image": "https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcSMOMstwtmLnjFb3NHiDJ_kcQnueNVH-rv_3ps96HZmXlFumKWaiBqq_L4Uoyx3iFiNTrXNEbyB&usqp=CAc" + "image": "https://i1.wp.com/freepngimages.com/wp-content/uploads/2020/07/Playstation-5-games-console-transparent-background-png-image.png?fit=1000%2C1000" }, { "id": 5, @@ -38,7 +38,7 @@ "desc": "Apple Aipods Pro 1st generation", "price": 200, "color": "#e3e4e9", - "image": "https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcQROEs084z65psoo06zYl5R0tUzywOVKVQZzmzqCj3PDP1vVJTWv3gGwGMFENSy4qV4n7sEQjE&usqp=CAc" + "image": "https://crdms.images.consumerreports.org/c_lfill,w_598/prod/products/cr/models/400116-wireless-portable-headphones-apple-airpods-pro-10009323.png" }, { "id": 6, @@ -46,7 +46,7 @@ "desc": "Apple iPad Pro 2020 edition", "price": 799, "color": "#f73984", - "image": "https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcSNzUeRQ5uH7E3hpECib8qxdhfHv6SnUGT7mOsew_xiOoqRR7ZpdH-TQ4J6-HuIEfqHimYyPXWH&usqp=CAc" + "image": "https://store.storeimages.cdn-apple.com/4982/as-images.apple.com/is/ipad-pro-12-select-wifi-silver-202003_FMT_WHH?wid=940&hei=1112&fmt=png-alpha&qlt=80&.v=1583551131102" }, { "id": 7, @@ -54,7 +54,7 @@ "desc": "Samsung Galaxy S21 Ultra 2021 edition", "price": 1299, "color": "#1c1c1c", - "image": "https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcTT_PZcc0wicVYR992s5QCIDLYy8t-z-9kibTUdWZBN2sd86aaqdAJfhvxAwZNWV9wfdzDikpr1&usqp=CAc" + "image": "https://lh3.googleusercontent.com/qRQPjHrhRVIs-xnfNSyiPXOH2vH97ylMacgbTKebqJtRfNH3LlYo8pN-5igsLDWUH62tGl5zNpTsl5xd8SprzGmXoCEmWFOi2-2cQVGS-r3PaRXHt62DmJHq-jrYX0UQvWZ9BA=s800-c" }, { "id": 8, @@ -62,7 +62,7 @@ "desc": "Samsung Galaxy S21 2021 edition", "price": 899, "color": "#7c95eb", - "image": "https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcRBNHd7FwarbxA1xdMFt24KazjcR4dWPH_t_T5dz4YNK1s7rJAQ8gOIuR_NRw6eeiQgFhbZ9sAN&usqp=CAc" + "image": "https://images.samsung.com/is/image/samsung/p6pim/za/galaxy-s21/gallery/za-clear-cover-galaxy-s21-5g-ef-qg991ttegww-363168624?$720_576_PNG$" } ] } \ No newline at end of file diff --git a/lib/pages/home_page.dart b/lib/pages/home_page.dart index b59ff85..fc8ca10 100644 --- a/lib/pages/home_page.dart +++ b/lib/pages/home_page.dart @@ -4,6 +4,8 @@ import 'dart:convert'; import 'package:flutter_catalog/models/catalog.dart'; import 'package:flutter_catalog/widgets/drawer.dart'; import 'package:flutter_catalog/widgets/item_widget.dart'; +import 'package:flutter_catalog/widgets/themes.dart'; +import 'package:velocity_x/velocity_x.dart'; class HomePage extends StatefulWidget { @override @@ -36,57 +38,111 @@ class _HomePageState extends State { @override Widget build(BuildContext context) { return Scaffold( - appBar: AppBar( - title: Text("Catalog App"), - ), - body: Padding( - padding: const EdgeInsets.all(16.0), - child: (CatalogModel.items != null && CatalogModel.items.isNotEmpty) - ? GridView.builder( - gridDelegate: SliverGridDelegateWithFixedCrossAxisCount( - crossAxisCount: 2, - mainAxisSpacing: 16, - crossAxisSpacing: 16, - ), - itemBuilder: (context, index) { - final item = CatalogModel.items[index]; - return Card( - clipBehavior: Clip.antiAlias, - shape: RoundedRectangleBorder( - borderRadius: BorderRadius.circular(10)), - child: GridTile( - header: Container( - child: Text( - item.name, - style: TextStyle(color: Colors.white), - ), - padding: const EdgeInsets.all(12), - decoration: BoxDecoration( - color: Colors.deepPurple, - ), - ), - child: Image.network( - item.image, - ), - footer: Container( - child: Text( - item.price.toString(), - style: TextStyle(color: Colors.white), - ), - padding: const EdgeInsets.all(12), - decoration: BoxDecoration( - color: Colors.black, - ), + backgroundColor: MyTheme.creamColor, + body: SafeArea( + child: Container( + padding: Vx.m32, + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + CatalogHeader(), + if (CatalogModel.items != null && CatalogModel.items.isNotEmpty) + CatalogList().expand() + else + Center( + child: CircularProgressIndicator(), + ) + ], + ), + ), + )); + } +} + +class CatalogHeader extends StatelessWidget { + @override + Widget build(BuildContext context) { + return Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + "Catalog App".text.xl5.bold.color(MyTheme.darkBluishColor).make(), + "Trending products".text.xl2.make(), + ], + ); + } +} + +class CatalogList extends StatelessWidget { + @override + Widget build(BuildContext context) { + return ListView.builder( + shrinkWrap: true, + itemCount: CatalogModel.items.length, + itemBuilder: (context, index) { + final catalog = CatalogModel.items[index]; + return CatalogItem(catalog: catalog); + }, + ); + } +} + +class CatalogItem extends StatelessWidget { + final Item catalog; + + const CatalogItem({Key key, @required this.catalog}) + : assert(catalog != null), + super(key: key); + + @override + Widget build(BuildContext context) { + return VxBox( + child: Row( + children: [ + CatalogImage( + image: catalog.image, + ), + Expanded( + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + mainAxisAlignment: MainAxisAlignment.center, + children: [ + catalog.name.text.lg.color(MyTheme.darkBluishColor).bold.make(), + catalog.desc.text.textStyle(context.captionStyle).make(), + 10.heightBox, + ButtonBar( + alignment: MainAxisAlignment.spaceBetween, + buttonPadding: EdgeInsets.zero, + children: [ + "\$${catalog.price}".text.bold.xl.make(), + ElevatedButton( + onPressed: () {}, + style: ButtonStyle( + backgroundColor: MaterialStateProperty.all( + MyTheme.darkBluishColor, ), - )); - }, - itemCount: CatalogModel.items.length, - ) - : Center( - child: CircularProgressIndicator(), - ), + shape: MaterialStateProperty.all( + StadiumBorder(), + )), + child: "Buy".text.make(), + ) + ], + ).pOnly(right: 8.0) + ], + )) + ], ), - drawer: MyDrawer(), - ); + ).white.rounded.square(150).make().py16(); + } +} + +class CatalogImage extends StatelessWidget { + final String image; + + const CatalogImage({Key key, @required this.image}) : super(key: key); + @override + Widget build(BuildContext context) { + return Image.network( + image, + ).box.rounded.p8.color(MyTheme.creamColor).make().p16().w40(context); } } diff --git a/lib/widgets/themes.dart b/lib/widgets/themes.dart index 158a8d1..5cbbda0 100644 --- a/lib/widgets/themes.dart +++ b/lib/widgets/themes.dart @@ -4,7 +4,7 @@ import 'package:google_fonts/google_fonts.dart'; class MyTheme { static ThemeData lightTheme(BuildContext context) => ThemeData( primarySwatch: Colors.deepPurple, - fontFamily: GoogleFonts.lato().fontFamily, + fontFamily: GoogleFonts.poppins().fontFamily, appBarTheme: AppBarTheme( color: Colors.white, elevation: 0.0, @@ -15,4 +15,8 @@ class MyTheme { static ThemeData darkTheme(BuildContext context) => ThemeData( brightness: Brightness.dark, ); + + //Colors + static Color creamColor = Color(0xfff5f5f5); + static Color darkBluishColor = Color(0xff403b58); } diff --git a/pubspec.lock b/pubspec.lock index 146e4d1..7bae492 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -1,6 +1,13 @@ # Generated by pub # See https://dart.dev/tools/pub/glossary#lockfile packages: + animator: + dependency: transitive + description: + name: animator + url: "https://pub.dartlang.org" + source: hosted + version: "2.0.2" archive: dependency: transitive description: @@ -22,6 +29,13 @@ packages: url: "https://pub.dartlang.org" source: hosted version: "2.5.0" + auto_size_text: + dependency: transitive + description: + name: auto_size_text + url: "https://pub.dartlang.org" + source: hosted + version: "2.1.0" boolean_selector: dependency: transitive description: @@ -145,6 +159,13 @@ packages: description: flutter source: sdk version: "0.9.2+2" + intl: + dependency: transitive + description: + name: intl + url: "https://pub.dartlang.org" + source: hosted + version: "0.16.1" matcher: dependency: transitive description: @@ -248,6 +269,13 @@ packages: url: "https://pub.dartlang.org" source: hosted version: "1.10.0" + states_rebuilder: + dependency: transitive + description: + name: states_rebuilder + url: "https://pub.dartlang.org" + source: hosted + version: "3.2.0" stream_channel: dependency: transitive description: @@ -297,6 +325,13 @@ packages: url: "https://pub.dartlang.org" source: hosted version: "2.1.0" + velocity_x: + dependency: "direct main" + description: + name: velocity_x + url: "https://pub.dartlang.org" + source: hosted + version: "1.4.1" vm_service: dependency: transitive description: @@ -304,6 +339,13 @@ packages: url: "https://pub.dartlang.org" source: hosted version: "5.5.0" + vxstate: + dependency: transitive + description: + name: vxstate + url: "https://pub.dartlang.org" + source: hosted + version: "1.0.1" webdriver: dependency: transitive description: diff --git a/pubspec.yaml b/pubspec.yaml index 077b911..793406d 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -23,11 +23,9 @@ environment: dependencies: flutter: sdk: flutter - - # The following adds the Cupertino Icons font to your application. - # Use with the CupertinoIcons class for iOS style icons. cupertino_icons: ^1.0.1 google_fonts: ^1.1.2 + velocity_x: ^1.4.1 dev_dependencies: flutter_test: @@ -37,7 +35,6 @@ dev_dependencies: # For information on the generic Dart part of this file, see the # following page: https://dart.dev/tools/pub/pubspec - # The following section is specific to Flutter. flutter: # The following line ensures that the Material Icons font is @@ -50,13 +47,10 @@ flutter: - assets/images/ - assets/files/ # - images/a_dot_ham.jpeg - # An image asset can refer to one or more resolution-specific "variants", see # https://flutter.dev/assets-and-images/#resolution-aware. - # For details regarding adding assets from package dependencies, see # https://flutter.dev/assets-and-images/#from-packages - # To add custom fonts to your application, add a fonts section here, # in this "flutter" section. Each entry in this list should have a # "family" key with the font family name, and a "fonts" key with a From 47a8711e0278f59feeb9aab9e7c224638bdb0d09 Mon Sep 17 00:00:00 2001 From: iampawan Date: Fri, 19 Feb 2021 17:31:31 +0530 Subject: [PATCH 17/29] Day 18 completed --- lib/pages/home_detail_page.dart | 71 ++++++++++++++ lib/pages/home_page.dart | 98 +------------------- lib/utils/routes.dart | 1 + lib/widgets/home_widgets/catalog_header.dart | 16 ++++ lib/widgets/home_widgets/catalog_image.dart | 15 +++ lib/widgets/home_widgets/catalog_list.dart | 83 +++++++++++++++++ 6 files changed, 190 insertions(+), 94 deletions(-) create mode 100644 lib/pages/home_detail_page.dart create mode 100644 lib/widgets/home_widgets/catalog_header.dart create mode 100644 lib/widgets/home_widgets/catalog_image.dart create mode 100644 lib/widgets/home_widgets/catalog_list.dart diff --git a/lib/pages/home_detail_page.dart b/lib/pages/home_detail_page.dart new file mode 100644 index 0000000..0eb4a33 --- /dev/null +++ b/lib/pages/home_detail_page.dart @@ -0,0 +1,71 @@ +import 'package:flutter/material.dart'; +import 'package:flutter_catalog/models/catalog.dart'; +import 'package:flutter_catalog/widgets/themes.dart'; +import 'package:velocity_x/velocity_x.dart'; + +class HomeDetailPage extends StatelessWidget { + final Item catalog; + + const HomeDetailPage({Key key, @required this.catalog}) + : assert(catalog != null), + super(key: key); + @override + Widget build(BuildContext context) { + return Scaffold( + appBar: AppBar(), + backgroundColor: MyTheme.creamColor, + bottomNavigationBar: Container( + color: Colors.white, + child: ButtonBar( + alignment: MainAxisAlignment.spaceBetween, + buttonPadding: EdgeInsets.zero, + children: [ + "\$${catalog.price}".text.bold.xl4.red800.make(), + ElevatedButton( + onPressed: () {}, + style: ButtonStyle( + backgroundColor: MaterialStateProperty.all( + MyTheme.darkBluishColor, + ), + shape: MaterialStateProperty.all( + StadiumBorder(), + )), + child: "Buy".text.make(), + ).wh(100, 50) + ], + ).p32(), + ), + body: SafeArea( + bottom: false, + child: Column( + children: [ + Hero( + tag: Key(catalog.id.toString()), + child: Image.network(catalog.image), + ).h32(context), + Expanded( + child: VxArc( + height: 30.0, + arcType: VxArcType.CONVEY, + edge: VxEdge.TOP, + child: Container( + color: Colors.white, + width: context.screenWidth, + child: Column( + children: [ + catalog.name.text.xl4 + .color(MyTheme.darkBluishColor) + .bold + .make(), + catalog.desc.text.textStyle(context.captionStyle).xl.make(), + 10.heightBox, + ], + ).py64(), + ), + )) + ], + ), + ), + ); + } +} diff --git a/lib/pages/home_page.dart b/lib/pages/home_page.dart index fc8ca10..2a153df 100644 --- a/lib/pages/home_page.dart +++ b/lib/pages/home_page.dart @@ -2,8 +2,8 @@ import 'package:flutter/material.dart'; import 'package:flutter/services.dart'; import 'dart:convert'; import 'package:flutter_catalog/models/catalog.dart'; -import 'package:flutter_catalog/widgets/drawer.dart'; -import 'package:flutter_catalog/widgets/item_widget.dart'; +import 'package:flutter_catalog/widgets/home_widgets/catalog_header.dart'; +import 'package:flutter_catalog/widgets/home_widgets/catalog_list.dart'; import 'package:flutter_catalog/widgets/themes.dart'; import 'package:velocity_x/velocity_x.dart'; @@ -47,102 +47,12 @@ class _HomePageState extends State { children: [ CatalogHeader(), if (CatalogModel.items != null && CatalogModel.items.isNotEmpty) - CatalogList().expand() + CatalogList().py16().expand() else - Center( - child: CircularProgressIndicator(), - ) + CircularProgressIndicator().centered().expand(), ], ), ), )); } } - -class CatalogHeader extends StatelessWidget { - @override - Widget build(BuildContext context) { - return Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - "Catalog App".text.xl5.bold.color(MyTheme.darkBluishColor).make(), - "Trending products".text.xl2.make(), - ], - ); - } -} - -class CatalogList extends StatelessWidget { - @override - Widget build(BuildContext context) { - return ListView.builder( - shrinkWrap: true, - itemCount: CatalogModel.items.length, - itemBuilder: (context, index) { - final catalog = CatalogModel.items[index]; - return CatalogItem(catalog: catalog); - }, - ); - } -} - -class CatalogItem extends StatelessWidget { - final Item catalog; - - const CatalogItem({Key key, @required this.catalog}) - : assert(catalog != null), - super(key: key); - - @override - Widget build(BuildContext context) { - return VxBox( - child: Row( - children: [ - CatalogImage( - image: catalog.image, - ), - Expanded( - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - mainAxisAlignment: MainAxisAlignment.center, - children: [ - catalog.name.text.lg.color(MyTheme.darkBluishColor).bold.make(), - catalog.desc.text.textStyle(context.captionStyle).make(), - 10.heightBox, - ButtonBar( - alignment: MainAxisAlignment.spaceBetween, - buttonPadding: EdgeInsets.zero, - children: [ - "\$${catalog.price}".text.bold.xl.make(), - ElevatedButton( - onPressed: () {}, - style: ButtonStyle( - backgroundColor: MaterialStateProperty.all( - MyTheme.darkBluishColor, - ), - shape: MaterialStateProperty.all( - StadiumBorder(), - )), - child: "Buy".text.make(), - ) - ], - ).pOnly(right: 8.0) - ], - )) - ], - ), - ).white.rounded.square(150).make().py16(); - } -} - -class CatalogImage extends StatelessWidget { - final String image; - - const CatalogImage({Key key, @required this.image}) : super(key: key); - @override - Widget build(BuildContext context) { - return Image.network( - image, - ).box.rounded.p8.color(MyTheme.creamColor).make().p16().w40(context); - } -} diff --git a/lib/utils/routes.dart b/lib/utils/routes.dart index 510c16a..0beb868 100644 --- a/lib/utils/routes.dart +++ b/lib/utils/routes.dart @@ -1,4 +1,5 @@ class MyRoutes { static String loginRoute = "/login"; static String homeRoute = "/home"; + static String homeDetailsRoute = "/detail"; } diff --git a/lib/widgets/home_widgets/catalog_header.dart b/lib/widgets/home_widgets/catalog_header.dart new file mode 100644 index 0000000..97a1115 --- /dev/null +++ b/lib/widgets/home_widgets/catalog_header.dart @@ -0,0 +1,16 @@ +import 'package:flutter/material.dart'; +import 'package:flutter_catalog/widgets/themes.dart'; +import 'package:velocity_x/velocity_x.dart'; + +class CatalogHeader extends StatelessWidget { + @override + Widget build(BuildContext context) { + return Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + "Catalog App".text.xl5.bold.color(MyTheme.darkBluishColor).make(), + "Trending products".text.xl2.make(), + ], + ); + } +} diff --git a/lib/widgets/home_widgets/catalog_image.dart b/lib/widgets/home_widgets/catalog_image.dart new file mode 100644 index 0000000..15b751e --- /dev/null +++ b/lib/widgets/home_widgets/catalog_image.dart @@ -0,0 +1,15 @@ +import 'package:flutter/material.dart'; +import 'package:flutter_catalog/widgets/themes.dart'; +import 'package:velocity_x/velocity_x.dart'; + +class CatalogImage extends StatelessWidget { + final String image; + + const CatalogImage({Key key, @required this.image}) : super(key: key); + @override + Widget build(BuildContext context) { + return Image.network( + image, + ).box.rounded.p8.color(MyTheme.creamColor).make().p16().w40(context); + } +} diff --git a/lib/widgets/home_widgets/catalog_list.dart b/lib/widgets/home_widgets/catalog_list.dart new file mode 100644 index 0000000..b4d5a70 --- /dev/null +++ b/lib/widgets/home_widgets/catalog_list.dart @@ -0,0 +1,83 @@ +import 'package:flutter/material.dart'; +import 'package:flutter_catalog/models/catalog.dart'; +import 'package:flutter_catalog/pages/home_detail_page.dart'; +import 'package:flutter_catalog/widgets/themes.dart'; +import 'package:velocity_x/velocity_x.dart'; + +import 'catalog_image.dart'; + +class CatalogList extends StatelessWidget { + @override + Widget build(BuildContext context) { + return ListView.builder( + shrinkWrap: true, + itemCount: CatalogModel.items.length, + itemBuilder: (context, index) { + final catalog = CatalogModel.items[index]; + return InkWell( + onTap: () => Navigator.push( + context, + MaterialPageRoute( + builder: (context) => HomeDetailPage( + catalog: catalog, + ), + ), + ), + child: CatalogItem(catalog: catalog), + ); + }, + ); + } +} + +class CatalogItem extends StatelessWidget { + final Item catalog; + + const CatalogItem({Key key, @required this.catalog}) + : assert(catalog != null), + super(key: key); + + @override + Widget build(BuildContext context) { + return VxBox( + child: Row( + children: [ + Hero( + tag: Key(catalog.id.toString()), + child: CatalogImage( + image: catalog.image, + ), + ), + Expanded( + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + mainAxisAlignment: MainAxisAlignment.center, + children: [ + catalog.name.text.lg.color(MyTheme.darkBluishColor).bold.make(), + catalog.desc.text.textStyle(context.captionStyle).make(), + 10.heightBox, + ButtonBar( + alignment: MainAxisAlignment.spaceBetween, + buttonPadding: EdgeInsets.zero, + children: [ + "\$${catalog.price}".text.bold.xl.make(), + ElevatedButton( + onPressed: () {}, + style: ButtonStyle( + backgroundColor: MaterialStateProperty.all( + MyTheme.darkBluishColor, + ), + shape: MaterialStateProperty.all( + StadiumBorder(), + )), + child: "Buy".text.make(), + ) + ], + ).pOnly(right: 8.0) + ], + )) + ], + ), + ).white.rounded.square(150).make().py16(); + } +} From a0357a5a0ab6a49d044663a57a5c4c654c4e57eb Mon Sep 17 00:00:00 2001 From: iampawan Date: Sun, 28 Feb 2021 17:15:58 +0530 Subject: [PATCH 18/29] Day 19 completed --- ios/Podfile.lock | 2 +- .../contents.xcworkspacedata | 2 +- lib/main.dart | 4 +++- lib/pages/cart_page.dart | 16 +++++++++++++++ lib/pages/home_detail_page.dart | 20 ++++++++++--------- lib/pages/home_page.dart | 7 +++++++ lib/utils/routes.dart | 1 + lib/widgets/home_widgets/catalog_list.dart | 2 +- 8 files changed, 41 insertions(+), 13 deletions(-) create mode 100644 lib/pages/cart_page.dart diff --git a/ios/Podfile.lock b/ios/Podfile.lock index c4f87eb..8fd4783 100644 --- a/ios/Podfile.lock +++ b/ios/Podfile.lock @@ -20,7 +20,7 @@ EXTERNAL SOURCES: SPEC CHECKSUMS: Flutter: 434fef37c0980e73bb6479ef766c45957d4b510c - integration_test: 5ed24a436eb7ec17b6a13046e9bf7ca4a404e59e + integration_test: 6eb66a19f7104200dcfdd62bc0077e1b09686e4f path_provider: abfe2b5c733d04e238b0d8691db0cfd63a27a93c PODFILE CHECKSUM: aafe91acc616949ddb318b77800a7f51bffa2a4c diff --git a/ios/Runner.xcodeproj/project.xcworkspace/contents.xcworkspacedata b/ios/Runner.xcodeproj/project.xcworkspace/contents.xcworkspacedata index 1d526a1..919434a 100644 --- a/ios/Runner.xcodeproj/project.xcworkspace/contents.xcworkspacedata +++ b/ios/Runner.xcodeproj/project.xcworkspace/contents.xcworkspacedata @@ -2,6 +2,6 @@ + location = "self:"> diff --git a/lib/main.dart b/lib/main.dart index 1091413..9fb9e58 100644 --- a/lib/main.dart +++ b/lib/main.dart @@ -1,4 +1,5 @@ import 'package:flutter/material.dart'; +import 'package:flutter_catalog/pages/cart_page.dart'; import 'package:flutter_catalog/pages/login_page.dart'; import 'package:flutter_catalog/utils/routes.dart'; import 'pages/home_page.dart'; @@ -20,7 +21,8 @@ class MyApp extends StatelessWidget { routes: { "/": (context) => LoginPage(), MyRoutes.homeRoute: (context) => HomePage(), - MyRoutes.loginRoute: (context) => LoginPage() + MyRoutes.loginRoute: (context) => LoginPage(), + MyRoutes.cartRoute: (context) => CartPage(), }, ); } diff --git a/lib/pages/cart_page.dart b/lib/pages/cart_page.dart new file mode 100644 index 0000000..d03c3ff --- /dev/null +++ b/lib/pages/cart_page.dart @@ -0,0 +1,16 @@ +import 'package:flutter/material.dart'; +import 'package:flutter_catalog/widgets/themes.dart'; +import 'package:velocity_x/velocity_x.dart'; + +class CartPage extends StatelessWidget { + @override + Widget build(BuildContext context) { + return Scaffold( + backgroundColor: MyTheme.creamColor, + appBar: AppBar( + backgroundColor: Colors.transparent, + title: "Cart".text.make(), + ), + ); + } +} diff --git a/lib/pages/home_detail_page.dart b/lib/pages/home_detail_page.dart index 0eb4a33..d6c570c 100644 --- a/lib/pages/home_detail_page.dart +++ b/lib/pages/home_detail_page.dart @@ -12,7 +12,7 @@ class HomeDetailPage extends StatelessWidget { @override Widget build(BuildContext context) { return Scaffold( - appBar: AppBar(), + appBar: AppBar(backgroundColor: Colors.transparent), backgroundColor: MyTheme.creamColor, bottomNavigationBar: Container( color: Colors.white, @@ -24,14 +24,11 @@ class HomeDetailPage extends StatelessWidget { ElevatedButton( onPressed: () {}, style: ButtonStyle( - backgroundColor: MaterialStateProperty.all( - MyTheme.darkBluishColor, - ), - shape: MaterialStateProperty.all( - StadiumBorder(), - )), - child: "Buy".text.make(), - ).wh(100, 50) + backgroundColor: + MaterialStateProperty.all(MyTheme.darkBluishColor), + shape: MaterialStateProperty.all(StadiumBorder())), + child: "Add to cart".text.make(), + ).wh(120, 50) ], ).p32(), ), @@ -59,6 +56,11 @@ class HomeDetailPage extends StatelessWidget { .make(), catalog.desc.text.textStyle(context.captionStyle).xl.make(), 10.heightBox, + "Dolor sea takimata ipsum sea eirmod aliquyam est. Eos ipsum voluptua eirmod elitr, no dolor dolor amet eirmod dolor labore dolores magna. Amet vero vero vero kasd, dolore sea sed sit invidunt nonumy est sit clita. Diam aliquyam amet tempor diam no aliquyam invidunt. Elitr lorem eirmod dolore clita. Rebum." + .text + .textStyle(context.captionStyle) + .make() + .p16() ], ).py64(), ), diff --git a/lib/pages/home_page.dart b/lib/pages/home_page.dart index 2a153df..9a0a678 100644 --- a/lib/pages/home_page.dart +++ b/lib/pages/home_page.dart @@ -1,7 +1,9 @@ +import 'package:flutter/cupertino.dart'; import 'package:flutter/material.dart'; import 'package:flutter/services.dart'; import 'dart:convert'; import 'package:flutter_catalog/models/catalog.dart'; +import 'package:flutter_catalog/utils/routes.dart'; import 'package:flutter_catalog/widgets/home_widgets/catalog_header.dart'; import 'package:flutter_catalog/widgets/home_widgets/catalog_list.dart'; import 'package:flutter_catalog/widgets/themes.dart'; @@ -39,6 +41,11 @@ class _HomePageState extends State { Widget build(BuildContext context) { return Scaffold( backgroundColor: MyTheme.creamColor, + floatingActionButton: FloatingActionButton( + onPressed: () => Navigator.pushNamed(context, MyRoutes.cartRoute), + backgroundColor: MyTheme.darkBluishColor, + child: Icon(CupertinoIcons.cart), + ), body: SafeArea( child: Container( padding: Vx.m32, diff --git a/lib/utils/routes.dart b/lib/utils/routes.dart index 0beb868..9832f8b 100644 --- a/lib/utils/routes.dart +++ b/lib/utils/routes.dart @@ -2,4 +2,5 @@ class MyRoutes { static String loginRoute = "/login"; static String homeRoute = "/home"; static String homeDetailsRoute = "/detail"; + static String cartRoute = "/cart"; } diff --git a/lib/widgets/home_widgets/catalog_list.dart b/lib/widgets/home_widgets/catalog_list.dart index b4d5a70..8615e68 100644 --- a/lib/widgets/home_widgets/catalog_list.dart +++ b/lib/widgets/home_widgets/catalog_list.dart @@ -70,7 +70,7 @@ class CatalogItem extends StatelessWidget { shape: MaterialStateProperty.all( StadiumBorder(), )), - child: "Buy".text.make(), + child: "Add to cart".text.make(), ) ], ).pOnly(right: 8.0) From aed9dcc0c9d0838f68667d826fcefb67b41dc89b Mon Sep 17 00:00:00 2001 From: iampawan Date: Mon, 1 Mar 2021 16:59:54 +0530 Subject: [PATCH 19/29] Day 20 completed --- lib/main.dart | 4 ++-- lib/pages/home_detail_page.dart | 10 +++++----- lib/pages/home_page.dart | 9 ++++++--- lib/pages/login_page.dart | 5 +++-- lib/widgets/home_widgets/catalog_header.dart | 2 +- lib/widgets/home_widgets/catalog_image.dart | 3 +-- lib/widgets/home_widgets/catalog_list.dart | 7 +++---- lib/widgets/themes.dart | 21 ++++++++++++++++++-- 8 files changed, 40 insertions(+), 21 deletions(-) diff --git a/lib/main.dart b/lib/main.dart index 9fb9e58..559e502 100644 --- a/lib/main.dart +++ b/lib/main.dart @@ -13,11 +13,11 @@ class MyApp extends StatelessWidget { @override Widget build(BuildContext context) { return MaterialApp( - themeMode: ThemeMode.light, + themeMode: ThemeMode.system, theme: MyTheme.lightTheme(context), darkTheme: MyTheme.darkTheme(context), debugShowCheckedModeBanner: false, - initialRoute: MyRoutes.homeRoute, + initialRoute: MyRoutes.loginRoute, routes: { "/": (context) => LoginPage(), MyRoutes.homeRoute: (context) => HomePage(), diff --git a/lib/pages/home_detail_page.dart b/lib/pages/home_detail_page.dart index d6c570c..0b42ea1 100644 --- a/lib/pages/home_detail_page.dart +++ b/lib/pages/home_detail_page.dart @@ -13,9 +13,9 @@ class HomeDetailPage extends StatelessWidget { Widget build(BuildContext context) { return Scaffold( appBar: AppBar(backgroundColor: Colors.transparent), - backgroundColor: MyTheme.creamColor, + backgroundColor: context.canvasColor, bottomNavigationBar: Container( - color: Colors.white, + color: context.cardColor, child: ButtonBar( alignment: MainAxisAlignment.spaceBetween, buttonPadding: EdgeInsets.zero, @@ -25,7 +25,7 @@ class HomeDetailPage extends StatelessWidget { onPressed: () {}, style: ButtonStyle( backgroundColor: - MaterialStateProperty.all(MyTheme.darkBluishColor), + MaterialStateProperty.all(context.theme.buttonColor), shape: MaterialStateProperty.all(StadiumBorder())), child: "Add to cart".text.make(), ).wh(120, 50) @@ -46,12 +46,12 @@ class HomeDetailPage extends StatelessWidget { arcType: VxArcType.CONVEY, edge: VxEdge.TOP, child: Container( - color: Colors.white, + color: context.cardColor, width: context.screenWidth, child: Column( children: [ catalog.name.text.xl4 - .color(MyTheme.darkBluishColor) + .color(context.accentColor) .bold .make(), catalog.desc.text.textStyle(context.captionStyle).xl.make(), diff --git a/lib/pages/home_page.dart b/lib/pages/home_page.dart index 9a0a678..d98df02 100644 --- a/lib/pages/home_page.dart +++ b/lib/pages/home_page.dart @@ -40,11 +40,14 @@ class _HomePageState extends State { @override Widget build(BuildContext context) { return Scaffold( - backgroundColor: MyTheme.creamColor, + backgroundColor: context.canvasColor, floatingActionButton: FloatingActionButton( onPressed: () => Navigator.pushNamed(context, MyRoutes.cartRoute), - backgroundColor: MyTheme.darkBluishColor, - child: Icon(CupertinoIcons.cart), + backgroundColor: context.theme.buttonColor, + child: Icon( + CupertinoIcons.cart, + color: Colors.white, + ), ), body: SafeArea( child: Container( diff --git a/lib/pages/login_page.dart b/lib/pages/login_page.dart index d176d74..5ce6d6f 100644 --- a/lib/pages/login_page.dart +++ b/lib/pages/login_page.dart @@ -1,5 +1,6 @@ import 'package:flutter/material.dart'; import 'package:flutter_catalog/utils/routes.dart'; +import 'package:velocity_x/velocity_x.dart'; class LoginPage extends StatefulWidget { @override @@ -28,7 +29,7 @@ class _LoginPageState extends State { @override Widget build(BuildContext context) { return Material( - color: Colors.white, + color: context.canvasColor, child: SingleChildScrollView( child: Form( key: _formKey, @@ -93,7 +94,7 @@ class _LoginPageState extends State { height: 40.0, ), Material( - color: Colors.deepPurple, + color: context.theme.buttonColor, borderRadius: BorderRadius.circular(changeButton ? 50 : 8), child: InkWell( diff --git a/lib/widgets/home_widgets/catalog_header.dart b/lib/widgets/home_widgets/catalog_header.dart index 97a1115..ff5c993 100644 --- a/lib/widgets/home_widgets/catalog_header.dart +++ b/lib/widgets/home_widgets/catalog_header.dart @@ -8,7 +8,7 @@ class CatalogHeader extends StatelessWidget { return Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ - "Catalog App".text.xl5.bold.color(MyTheme.darkBluishColor).make(), + "Catalog App".text.xl5.bold.color(context.theme.accentColor).make(), "Trending products".text.xl2.make(), ], ); diff --git a/lib/widgets/home_widgets/catalog_image.dart b/lib/widgets/home_widgets/catalog_image.dart index 15b751e..8724a53 100644 --- a/lib/widgets/home_widgets/catalog_image.dart +++ b/lib/widgets/home_widgets/catalog_image.dart @@ -1,5 +1,4 @@ import 'package:flutter/material.dart'; -import 'package:flutter_catalog/widgets/themes.dart'; import 'package:velocity_x/velocity_x.dart'; class CatalogImage extends StatelessWidget { @@ -10,6 +9,6 @@ class CatalogImage extends StatelessWidget { Widget build(BuildContext context) { return Image.network( image, - ).box.rounded.p8.color(MyTheme.creamColor).make().p16().w40(context); + ).box.rounded.p8.color(context.canvasColor).make().p16().w40(context); } } diff --git a/lib/widgets/home_widgets/catalog_list.dart b/lib/widgets/home_widgets/catalog_list.dart index 8615e68..5a4c23b 100644 --- a/lib/widgets/home_widgets/catalog_list.dart +++ b/lib/widgets/home_widgets/catalog_list.dart @@ -53,7 +53,7 @@ class CatalogItem extends StatelessWidget { crossAxisAlignment: CrossAxisAlignment.start, mainAxisAlignment: MainAxisAlignment.center, children: [ - catalog.name.text.lg.color(MyTheme.darkBluishColor).bold.make(), + catalog.name.text.lg.color(context.accentColor).bold.make(), catalog.desc.text.textStyle(context.captionStyle).make(), 10.heightBox, ButtonBar( @@ -65,8 +65,7 @@ class CatalogItem extends StatelessWidget { onPressed: () {}, style: ButtonStyle( backgroundColor: MaterialStateProperty.all( - MyTheme.darkBluishColor, - ), + context.theme.buttonColor), shape: MaterialStateProperty.all( StadiumBorder(), )), @@ -78,6 +77,6 @@ class CatalogItem extends StatelessWidget { )) ], ), - ).white.rounded.square(150).make().py16(); + ).color(context.cardColor).rounded.square(150).make().py16(); } } diff --git a/lib/widgets/themes.dart b/lib/widgets/themes.dart index 5cbbda0..9f35742 100644 --- a/lib/widgets/themes.dart +++ b/lib/widgets/themes.dart @@ -1,10 +1,15 @@ import 'package:flutter/material.dart'; import 'package:google_fonts/google_fonts.dart'; +import 'package:velocity_x/velocity_x.dart'; class MyTheme { static ThemeData lightTheme(BuildContext context) => ThemeData( primarySwatch: Colors.deepPurple, fontFamily: GoogleFonts.poppins().fontFamily, + cardColor: Colors.white, + canvasColor: creamColor, + buttonColor: darkBluishColor, + accentColor: darkBluishColor, appBarTheme: AppBarTheme( color: Colors.white, elevation: 0.0, @@ -13,10 +18,22 @@ class MyTheme { )); static ThemeData darkTheme(BuildContext context) => ThemeData( - brightness: Brightness.dark, - ); + brightness: Brightness.dark, + fontFamily: GoogleFonts.poppins().fontFamily, + cardColor: Colors.black, + canvasColor: darkCreamColor, + buttonColor: lightBluishColor, + accentColor: Colors.white, + appBarTheme: AppBarTheme( + color: Colors.black, + elevation: 0.0, + iconTheme: IconThemeData(color: Colors.white), + textTheme: Theme.of(context).textTheme, + )); //Colors static Color creamColor = Color(0xfff5f5f5); + static Color darkCreamColor = Vx.gray900; static Color darkBluishColor = Color(0xff403b58); + static Color lightBluishColor = Vx.indigo500; } From f38fbecf389b92b025534481b64213b68a811f8b Mon Sep 17 00:00:00 2001 From: iampawan Date: Sat, 6 Mar 2021 13:16:04 +0530 Subject: [PATCH 20/29] Day 21 completed --- lib/main.dart | 2 +- lib/models/catalog.dart | 7 +++++++ lib/pages/cart_page.dart | 3 +-- lib/widgets/home_widgets/catalog_list.dart | 6 ++---- lib/widgets/themes.dart | 5 ++++- 5 files changed, 15 insertions(+), 8 deletions(-) diff --git a/lib/main.dart b/lib/main.dart index 559e502..683c7a0 100644 --- a/lib/main.dart +++ b/lib/main.dart @@ -17,7 +17,7 @@ class MyApp extends StatelessWidget { theme: MyTheme.lightTheme(context), darkTheme: MyTheme.darkTheme(context), debugShowCheckedModeBanner: false, - initialRoute: MyRoutes.loginRoute, + initialRoute: MyRoutes.homeRoute, routes: { "/": (context) => LoginPage(), MyRoutes.homeRoute: (context) => HomePage(), diff --git a/lib/models/catalog.dart b/lib/models/catalog.dart index d13e24a..1a77f04 100644 --- a/lib/models/catalog.dart +++ b/lib/models/catalog.dart @@ -2,6 +2,13 @@ import 'dart:convert'; class CatalogModel { static List items; + + // Get Item by ID + static Item getById(int id) => + items.firstWhere((element) => element.id == id, orElse: null); + + // Get Item by position + static Item getByPosition(int pos) => items[pos]; } class Item { diff --git a/lib/pages/cart_page.dart b/lib/pages/cart_page.dart index d03c3ff..1d8d01f 100644 --- a/lib/pages/cart_page.dart +++ b/lib/pages/cart_page.dart @@ -1,12 +1,11 @@ import 'package:flutter/material.dart'; -import 'package:flutter_catalog/widgets/themes.dart'; import 'package:velocity_x/velocity_x.dart'; class CartPage extends StatelessWidget { @override Widget build(BuildContext context) { return Scaffold( - backgroundColor: MyTheme.creamColor, + backgroundColor: context.canvasColor, appBar: AppBar( backgroundColor: Colors.transparent, title: "Cart".text.make(), diff --git a/lib/widgets/home_widgets/catalog_list.dart b/lib/widgets/home_widgets/catalog_list.dart index 5a4c23b..acc275e 100644 --- a/lib/widgets/home_widgets/catalog_list.dart +++ b/lib/widgets/home_widgets/catalog_list.dart @@ -13,14 +13,12 @@ class CatalogList extends StatelessWidget { shrinkWrap: true, itemCount: CatalogModel.items.length, itemBuilder: (context, index) { - final catalog = CatalogModel.items[index]; + final catalog = CatalogModel.getByPosition(index); return InkWell( onTap: () => Navigator.push( context, MaterialPageRoute( - builder: (context) => HomeDetailPage( - catalog: catalog, - ), + builder: (context) => HomeDetailPage(catalog: catalog), ), ), child: CatalogItem(catalog: catalog), diff --git a/lib/widgets/themes.dart b/lib/widgets/themes.dart index 9f35742..e6d3ed2 100644 --- a/lib/widgets/themes.dart +++ b/lib/widgets/themes.dart @@ -28,7 +28,10 @@ class MyTheme { color: Colors.black, elevation: 0.0, iconTheme: IconThemeData(color: Colors.white), - textTheme: Theme.of(context).textTheme, + textTheme: Theme.of(context).textTheme.copyWith( + headline6: + context.textTheme.headline6.copyWith(color: Colors.white), + ), )); //Colors From 736f5d09b972ee5497bed91d599e59b879434ef3 Mon Sep 17 00:00:00 2001 From: iampawan Date: Sat, 6 Mar 2021 13:30:58 +0530 Subject: [PATCH 21/29] day 22 completed --- lib/pages/cart_page.dart | 52 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 52 insertions(+) diff --git a/lib/pages/cart_page.dart b/lib/pages/cart_page.dart index 1d8d01f..7117db9 100644 --- a/lib/pages/cart_page.dart +++ b/lib/pages/cart_page.dart @@ -10,6 +10,58 @@ class CartPage extends StatelessWidget { backgroundColor: Colors.transparent, title: "Cart".text.make(), ), + body: Column( + children: [ + _CartList().p32().expand(), + Divider(), + _CartTotal(), + ], + ), + ); + } +} + +class _CartTotal extends StatelessWidget { + @override + Widget build(BuildContext context) { + return SizedBox( + height: 200, + child: Row( + mainAxisAlignment: MainAxisAlignment.spaceAround, + children: [ + "\$9999".text.xl5.color(context.theme.accentColor).make(), + 30.widthBox, + ElevatedButton( + onPressed: () {}, + style: ButtonStyle( + backgroundColor: + MaterialStateProperty.all(context.theme.buttonColor)), + child: "Buy".text.white.make(), + ).w32(context) + ], + ), + ); + } +} + +class _CartList extends StatefulWidget { + @override + __CartListState createState() => __CartListState(); +} + +class __CartListState extends State<_CartList> { + @override + Widget build(BuildContext context) { + return ListView.builder( + itemCount: 5, + itemBuilder: (context, index) => ListTile( + leading: Icon(Icons.done), + trailing: IconButton( + icon: Icon(Icons.remove_circle_outline), + onPressed: () {}, + ), + title: "Item 1".text.make(), + ), ); } } From f00fe802bb3be8197a31741f7b51ba9c3aed1063 Mon Sep 17 00:00:00 2001 From: iampawan Date: Sat, 6 Mar 2021 13:47:12 +0530 Subject: [PATCH 22/29] Day 23 completed --- lib/models/cart.dart | 36 ++++++++++++++++++++++ lib/models/catalog.dart | 4 +-- lib/pages/cart_page.dart | 6 +++- lib/widgets/home_widgets/catalog_list.dart | 2 +- 4 files changed, 44 insertions(+), 4 deletions(-) create mode 100644 lib/models/cart.dart diff --git a/lib/models/cart.dart b/lib/models/cart.dart new file mode 100644 index 0000000..3f93c17 --- /dev/null +++ b/lib/models/cart.dart @@ -0,0 +1,36 @@ +import 'package:flutter_catalog/models/catalog.dart'; + +class CartModel { + // catalog field + CatalogModel _catalog; + + // Collection of IDs - store Ids of each item + final List _itemIds = []; + + // Get Catalog + CatalogModel get catalog => _catalog; + + set catalog(CatalogModel newCatalog) { + assert(newCatalog != null); + _catalog = newCatalog; + } + + // Get items in the cart + List get items => _itemIds.map((id) => _catalog.getById(id)).toList(); + + // Get total price + num get totalPrice => + items.fold(0, (total, current) => total + current.price); + + // Add Item + + void add(Item item) { + _itemIds.add(item.id); + } + + // Remove Item + + void remove(Item item) { + _itemIds.remove(item.id); + } +} diff --git a/lib/models/catalog.dart b/lib/models/catalog.dart index 1a77f04..1b88d1e 100644 --- a/lib/models/catalog.dart +++ b/lib/models/catalog.dart @@ -4,11 +4,11 @@ class CatalogModel { static List items; // Get Item by ID - static Item getById(int id) => + Item getById(int id) => items.firstWhere((element) => element.id == id, orElse: null); // Get Item by position - static Item getByPosition(int pos) => items[pos]; + Item getByPosition(int pos) => items[pos]; } class Item { diff --git a/lib/pages/cart_page.dart b/lib/pages/cart_page.dart index 7117db9..cfbb634 100644 --- a/lib/pages/cart_page.dart +++ b/lib/pages/cart_page.dart @@ -32,7 +32,11 @@ class _CartTotal extends StatelessWidget { "\$9999".text.xl5.color(context.theme.accentColor).make(), 30.widthBox, ElevatedButton( - onPressed: () {}, + onPressed: () { + ScaffoldMessenger.of(context).showSnackBar(SnackBar( + content: "Buying not supported yet.".text.make(), + )); + }, style: ButtonStyle( backgroundColor: MaterialStateProperty.all(context.theme.buttonColor)), diff --git a/lib/widgets/home_widgets/catalog_list.dart b/lib/widgets/home_widgets/catalog_list.dart index acc275e..729bb0c 100644 --- a/lib/widgets/home_widgets/catalog_list.dart +++ b/lib/widgets/home_widgets/catalog_list.dart @@ -13,7 +13,7 @@ class CatalogList extends StatelessWidget { shrinkWrap: true, itemCount: CatalogModel.items.length, itemBuilder: (context, index) { - final catalog = CatalogModel.getByPosition(index); + final catalog = CatalogModel.items[index]; return InkWell( onTap: () => Navigator.push( context, From 4d8b927302e6995ad46876e4e3daac5ea6b52fc8 Mon Sep 17 00:00:00 2001 From: iampawan Date: Sat, 6 Mar 2021 14:02:09 +0530 Subject: [PATCH 23/29] Day 24 completed --- lib/models/cart.dart | 6 +++ lib/models/catalog.dart | 6 +++ lib/pages/cart_page.dart | 13 ++++-- lib/widgets/home_widgets/catalog_list.dart | 47 +++++++++++++++++----- 4 files changed, 59 insertions(+), 13 deletions(-) diff --git a/lib/models/cart.dart b/lib/models/cart.dart index 3f93c17..0ed28f8 100644 --- a/lib/models/cart.dart +++ b/lib/models/cart.dart @@ -1,6 +1,12 @@ import 'package:flutter_catalog/models/catalog.dart'; class CartModel { + static final cartModel = CartModel._internal(); + + CartModel._internal(); + + factory CartModel() => cartModel; + // catalog field CatalogModel _catalog; diff --git a/lib/models/catalog.dart b/lib/models/catalog.dart index 1b88d1e..d8395b7 100644 --- a/lib/models/catalog.dart +++ b/lib/models/catalog.dart @@ -1,6 +1,12 @@ import 'dart:convert'; class CatalogModel { + static final catModel = CatalogModel._internal(); + + CatalogModel._internal(); + + factory CatalogModel() => catModel; + static List items; // Get Item by ID diff --git a/lib/pages/cart_page.dart b/lib/pages/cart_page.dart index cfbb634..205a3e1 100644 --- a/lib/pages/cart_page.dart +++ b/lib/pages/cart_page.dart @@ -1,4 +1,5 @@ import 'package:flutter/material.dart'; +import 'package:flutter_catalog/models/cart.dart'; import 'package:velocity_x/velocity_x.dart'; class CartPage extends StatelessWidget { @@ -24,12 +25,17 @@ class CartPage extends StatelessWidget { class _CartTotal extends StatelessWidget { @override Widget build(BuildContext context) { + final _cart = CartModel(); return SizedBox( height: 200, child: Row( mainAxisAlignment: MainAxisAlignment.spaceAround, children: [ - "\$9999".text.xl5.color(context.theme.accentColor).make(), + "\$${_cart.totalPrice}" + .text + .xl5 + .color(context.theme.accentColor) + .make(), 30.widthBox, ElevatedButton( onPressed: () { @@ -54,17 +60,18 @@ class _CartList extends StatefulWidget { } class __CartListState extends State<_CartList> { + final _cart = CartModel(); @override Widget build(BuildContext context) { return ListView.builder( - itemCount: 5, + itemCount: _cart.items?.length, itemBuilder: (context, index) => ListTile( leading: Icon(Icons.done), trailing: IconButton( icon: Icon(Icons.remove_circle_outline), onPressed: () {}, ), - title: "Item 1".text.make(), + title: _cart.items[index].name.text.make(), ), ); } diff --git a/lib/widgets/home_widgets/catalog_list.dart b/lib/widgets/home_widgets/catalog_list.dart index 729bb0c..febf070 100644 --- a/lib/widgets/home_widgets/catalog_list.dart +++ b/lib/widgets/home_widgets/catalog_list.dart @@ -1,4 +1,5 @@ import 'package:flutter/material.dart'; +import 'package:flutter_catalog/models/cart.dart'; import 'package:flutter_catalog/models/catalog.dart'; import 'package:flutter_catalog/pages/home_detail_page.dart'; import 'package:flutter_catalog/widgets/themes.dart'; @@ -59,16 +60,7 @@ class CatalogItem extends StatelessWidget { buttonPadding: EdgeInsets.zero, children: [ "\$${catalog.price}".text.bold.xl.make(), - ElevatedButton( - onPressed: () {}, - style: ButtonStyle( - backgroundColor: MaterialStateProperty.all( - context.theme.buttonColor), - shape: MaterialStateProperty.all( - StadiumBorder(), - )), - child: "Add to cart".text.make(), - ) + _AddToCart(catalog: catalog) ], ).pOnly(right: 8.0) ], @@ -78,3 +70,38 @@ class CatalogItem extends StatelessWidget { ).color(context.cardColor).rounded.square(150).make().py16(); } } + +class _AddToCart extends StatefulWidget { + final Item catalog; + const _AddToCart({ + Key key, + this.catalog, + }) : super(key: key); + + @override + __AddToCartState createState() => __AddToCartState(); +} + +class __AddToCartState extends State<_AddToCart> { + bool isAdded = false; + + @override + Widget build(BuildContext context) { + return ElevatedButton( + onPressed: () { + isAdded = isAdded.toggle(); + final _catalog = CatalogModel(); + final _cart = CartModel(); + _cart.catalog = _catalog; + _cart.add(widget.catalog); + setState(() {}); + }, + style: ButtonStyle( + backgroundColor: MaterialStateProperty.all(context.theme.buttonColor), + shape: MaterialStateProperty.all( + StadiumBorder(), + )), + child: isAdded ? Icon(Icons.done) : "Add to cart".text.make(), + ); + } +} From d18059ebb43e455bfee89946ae96af0c1e7e35ce Mon Sep 17 00:00:00 2001 From: iampawan Date: Sat, 6 Mar 2021 15:44:24 +0530 Subject: [PATCH 24/29] day25 completed --- lib/pages/cart_page.dart | 27 ++++++++------ lib/pages/home_detail_page.dart | 10 ++---- lib/widgets/home_widgets/add_to_cart.dart | 42 ++++++++++++++++++++++ lib/widgets/home_widgets/catalog_list.dart | 40 ++------------------- 4 files changed, 63 insertions(+), 56 deletions(-) create mode 100644 lib/widgets/home_widgets/add_to_cart.dart diff --git a/lib/pages/cart_page.dart b/lib/pages/cart_page.dart index 205a3e1..282d9bb 100644 --- a/lib/pages/cart_page.dart +++ b/lib/pages/cart_page.dart @@ -63,16 +63,21 @@ class __CartListState extends State<_CartList> { final _cart = CartModel(); @override Widget build(BuildContext context) { - return ListView.builder( - itemCount: _cart.items?.length, - itemBuilder: (context, index) => ListTile( - leading: Icon(Icons.done), - trailing: IconButton( - icon: Icon(Icons.remove_circle_outline), - onPressed: () {}, - ), - title: _cart.items[index].name.text.make(), - ), - ); + return _cart.items.isEmpty + ? "Nothing to show".text.xl3.makeCentered() + : ListView.builder( + itemCount: _cart.items?.length, + itemBuilder: (context, index) => ListTile( + leading: Icon(Icons.done), + trailing: IconButton( + icon: Icon(Icons.remove_circle_outline), + onPressed: () { + _cart.remove(_cart.items[index]); + setState(() {}); + }, + ), + title: _cart.items[index].name.text.make(), + ), + ); } } diff --git a/lib/pages/home_detail_page.dart b/lib/pages/home_detail_page.dart index 0b42ea1..8f9d85e 100644 --- a/lib/pages/home_detail_page.dart +++ b/lib/pages/home_detail_page.dart @@ -1,5 +1,6 @@ import 'package:flutter/material.dart'; import 'package:flutter_catalog/models/catalog.dart'; +import 'package:flutter_catalog/widgets/home_widgets/add_to_cart.dart'; import 'package:flutter_catalog/widgets/themes.dart'; import 'package:velocity_x/velocity_x.dart'; @@ -21,13 +22,8 @@ class HomeDetailPage extends StatelessWidget { buttonPadding: EdgeInsets.zero, children: [ "\$${catalog.price}".text.bold.xl4.red800.make(), - ElevatedButton( - onPressed: () {}, - style: ButtonStyle( - backgroundColor: - MaterialStateProperty.all(context.theme.buttonColor), - shape: MaterialStateProperty.all(StadiumBorder())), - child: "Add to cart".text.make(), + AddToCart( + catalog: catalog, ).wh(120, 50) ], ).p32(), diff --git a/lib/widgets/home_widgets/add_to_cart.dart b/lib/widgets/home_widgets/add_to_cart.dart new file mode 100644 index 0000000..ee0caf6 --- /dev/null +++ b/lib/widgets/home_widgets/add_to_cart.dart @@ -0,0 +1,42 @@ +import 'package:flutter/cupertino.dart'; +import 'package:flutter/material.dart'; +import 'package:flutter_catalog/models/cart.dart'; +import 'package:flutter_catalog/models/catalog.dart'; +import 'package:velocity_x/velocity_x.dart'; + +class AddToCart extends StatefulWidget { + final Item catalog; + const AddToCart({ + Key key, + this.catalog, + }) : super(key: key); + + @override + _AddToCartState createState() => _AddToCartState(); +} + +class _AddToCartState extends State { + final _cart = CartModel(); + @override + Widget build(BuildContext context) { + bool isInCart = _cart.items.contains(widget.catalog) ?? false; + return ElevatedButton( + onPressed: () { + if (!isInCart) { + isInCart = isInCart.toggle(); + final _catalog = CatalogModel(); + + _cart.catalog = _catalog; + _cart.add(widget.catalog); + setState(() {}); + } + }, + style: ButtonStyle( + backgroundColor: MaterialStateProperty.all(context.theme.buttonColor), + shape: MaterialStateProperty.all( + StadiumBorder(), + )), + child: isInCart ? Icon(Icons.done) : Icon(CupertinoIcons.cart_badge_plus), + ); + } +} diff --git a/lib/widgets/home_widgets/catalog_list.dart b/lib/widgets/home_widgets/catalog_list.dart index febf070..3985a55 100644 --- a/lib/widgets/home_widgets/catalog_list.dart +++ b/lib/widgets/home_widgets/catalog_list.dart @@ -1,10 +1,9 @@ import 'package:flutter/material.dart'; -import 'package:flutter_catalog/models/cart.dart'; import 'package:flutter_catalog/models/catalog.dart'; import 'package:flutter_catalog/pages/home_detail_page.dart'; -import 'package:flutter_catalog/widgets/themes.dart'; import 'package:velocity_x/velocity_x.dart'; +import 'add_to_cart.dart'; import 'catalog_image.dart'; class CatalogList extends StatelessWidget { @@ -60,7 +59,7 @@ class CatalogItem extends StatelessWidget { buttonPadding: EdgeInsets.zero, children: [ "\$${catalog.price}".text.bold.xl.make(), - _AddToCart(catalog: catalog) + AddToCart(catalog: catalog) ], ).pOnly(right: 8.0) ], @@ -70,38 +69,3 @@ class CatalogItem extends StatelessWidget { ).color(context.cardColor).rounded.square(150).make().py16(); } } - -class _AddToCart extends StatefulWidget { - final Item catalog; - const _AddToCart({ - Key key, - this.catalog, - }) : super(key: key); - - @override - __AddToCartState createState() => __AddToCartState(); -} - -class __AddToCartState extends State<_AddToCart> { - bool isAdded = false; - - @override - Widget build(BuildContext context) { - return ElevatedButton( - onPressed: () { - isAdded = isAdded.toggle(); - final _catalog = CatalogModel(); - final _cart = CartModel(); - _cart.catalog = _catalog; - _cart.add(widget.catalog); - setState(() {}); - }, - style: ButtonStyle( - backgroundColor: MaterialStateProperty.all(context.theme.buttonColor), - shape: MaterialStateProperty.all( - StadiumBorder(), - )), - child: isAdded ? Icon(Icons.done) : "Add to cart".text.make(), - ); - } -} From bdb5038d115343fe183693a1ae0e835869acb763 Mon Sep 17 00:00:00 2001 From: iampawan Date: Sat, 6 Mar 2021 16:26:48 +0530 Subject: [PATCH 25/29] Day 26 completed --- lib/core/store.dart | 14 ++++++++++++++ lib/main.dart | 4 +++- lib/models/cart.dart | 6 ------ lib/models/catalog.dart | 6 ------ lib/pages/cart_page.dart | 9 ++------- lib/pages/home_detail_page.dart | 1 - lib/pages/home_page.dart | 1 - lib/widgets/home_widgets/add_to_cart.dart | 15 +++++---------- lib/widgets/home_widgets/catalog_header.dart | 1 - 9 files changed, 24 insertions(+), 33 deletions(-) create mode 100644 lib/core/store.dart diff --git a/lib/core/store.dart b/lib/core/store.dart new file mode 100644 index 0000000..50ce464 --- /dev/null +++ b/lib/core/store.dart @@ -0,0 +1,14 @@ +import 'package:flutter_catalog/models/cart.dart'; +import 'package:flutter_catalog/models/catalog.dart'; +import 'package:velocity_x/velocity_x.dart'; + +class MyStore extends VxStore { + CatalogModel catalog; + CartModel cart; + + MyStore() { + catalog = CatalogModel(); + cart = CartModel(); + cart.catalog = catalog; + } +} diff --git a/lib/main.dart b/lib/main.dart index 683c7a0..9a34248 100644 --- a/lib/main.dart +++ b/lib/main.dart @@ -1,12 +1,14 @@ import 'package:flutter/material.dart'; +import 'package:flutter_catalog/core/store.dart'; import 'package:flutter_catalog/pages/cart_page.dart'; import 'package:flutter_catalog/pages/login_page.dart'; import 'package:flutter_catalog/utils/routes.dart'; +import 'package:velocity_x/velocity_x.dart'; import 'pages/home_page.dart'; import 'widgets/themes.dart'; void main() { - runApp(MyApp()); + runApp(VxState(store: MyStore(), child: MyApp())); } class MyApp extends StatelessWidget { diff --git a/lib/models/cart.dart b/lib/models/cart.dart index 0ed28f8..3f93c17 100644 --- a/lib/models/cart.dart +++ b/lib/models/cart.dart @@ -1,12 +1,6 @@ import 'package:flutter_catalog/models/catalog.dart'; class CartModel { - static final cartModel = CartModel._internal(); - - CartModel._internal(); - - factory CartModel() => cartModel; - // catalog field CatalogModel _catalog; diff --git a/lib/models/catalog.dart b/lib/models/catalog.dart index d8395b7..1b88d1e 100644 --- a/lib/models/catalog.dart +++ b/lib/models/catalog.dart @@ -1,12 +1,6 @@ import 'dart:convert'; class CatalogModel { - static final catModel = CatalogModel._internal(); - - CatalogModel._internal(); - - factory CatalogModel() => catModel; - static List items; // Get Item by ID diff --git a/lib/pages/cart_page.dart b/lib/pages/cart_page.dart index 282d9bb..f146d7f 100644 --- a/lib/pages/cart_page.dart +++ b/lib/pages/cart_page.dart @@ -54,12 +54,7 @@ class _CartTotal extends StatelessWidget { } } -class _CartList extends StatefulWidget { - @override - __CartListState createState() => __CartListState(); -} - -class __CartListState extends State<_CartList> { +class _CartList extends StatelessWidget { final _cart = CartModel(); @override Widget build(BuildContext context) { @@ -73,7 +68,7 @@ class __CartListState extends State<_CartList> { icon: Icon(Icons.remove_circle_outline), onPressed: () { _cart.remove(_cart.items[index]); - setState(() {}); + // setState(() {}); }, ), title: _cart.items[index].name.text.make(), diff --git a/lib/pages/home_detail_page.dart b/lib/pages/home_detail_page.dart index 8f9d85e..d85f39c 100644 --- a/lib/pages/home_detail_page.dart +++ b/lib/pages/home_detail_page.dart @@ -1,7 +1,6 @@ import 'package:flutter/material.dart'; import 'package:flutter_catalog/models/catalog.dart'; import 'package:flutter_catalog/widgets/home_widgets/add_to_cart.dart'; -import 'package:flutter_catalog/widgets/themes.dart'; import 'package:velocity_x/velocity_x.dart'; class HomeDetailPage extends StatelessWidget { diff --git a/lib/pages/home_page.dart b/lib/pages/home_page.dart index d98df02..8c9b17c 100644 --- a/lib/pages/home_page.dart +++ b/lib/pages/home_page.dart @@ -6,7 +6,6 @@ import 'package:flutter_catalog/models/catalog.dart'; import 'package:flutter_catalog/utils/routes.dart'; import 'package:flutter_catalog/widgets/home_widgets/catalog_header.dart'; import 'package:flutter_catalog/widgets/home_widgets/catalog_list.dart'; -import 'package:flutter_catalog/widgets/themes.dart'; import 'package:velocity_x/velocity_x.dart'; class HomePage extends StatefulWidget { diff --git a/lib/widgets/home_widgets/add_to_cart.dart b/lib/widgets/home_widgets/add_to_cart.dart index ee0caf6..a805e05 100644 --- a/lib/widgets/home_widgets/add_to_cart.dart +++ b/lib/widgets/home_widgets/add_to_cart.dart @@ -4,22 +4,17 @@ import 'package:flutter_catalog/models/cart.dart'; import 'package:flutter_catalog/models/catalog.dart'; import 'package:velocity_x/velocity_x.dart'; -class AddToCart extends StatefulWidget { +class AddToCart extends StatelessWidget { final Item catalog; - const AddToCart({ + AddToCart({ Key key, this.catalog, }) : super(key: key); - @override - _AddToCartState createState() => _AddToCartState(); -} - -class _AddToCartState extends State { final _cart = CartModel(); @override Widget build(BuildContext context) { - bool isInCart = _cart.items.contains(widget.catalog) ?? false; + bool isInCart = _cart.items.contains(catalog) ?? false; return ElevatedButton( onPressed: () { if (!isInCart) { @@ -27,8 +22,8 @@ class _AddToCartState extends State { final _catalog = CatalogModel(); _cart.catalog = _catalog; - _cart.add(widget.catalog); - setState(() {}); + _cart.add(catalog); + // setState(() {}); } }, style: ButtonStyle( diff --git a/lib/widgets/home_widgets/catalog_header.dart b/lib/widgets/home_widgets/catalog_header.dart index ff5c993..49fdbb8 100644 --- a/lib/widgets/home_widgets/catalog_header.dart +++ b/lib/widgets/home_widgets/catalog_header.dart @@ -1,5 +1,4 @@ import 'package:flutter/material.dart'; -import 'package:flutter_catalog/widgets/themes.dart'; import 'package:velocity_x/velocity_x.dart'; class CatalogHeader extends StatelessWidget { From 3fdde4c6c3f5d65e9039b1a358ada6d719b917c2 Mon Sep 17 00:00:00 2001 From: iampawan Date: Sat, 6 Mar 2021 16:43:59 +0530 Subject: [PATCH 26/29] Day 27 completed --- lib/models/cart.dart | 18 ++++++++++++------ lib/pages/cart_page.dart | 5 +++-- lib/widgets/home_widgets/add_to_cart.dart | 11 ++++------- 3 files changed, 19 insertions(+), 15 deletions(-) diff --git a/lib/models/cart.dart b/lib/models/cart.dart index 3f93c17..8e1c8f5 100644 --- a/lib/models/cart.dart +++ b/lib/models/cart.dart @@ -1,4 +1,6 @@ +import 'package:flutter_catalog/core/store.dart'; import 'package:flutter_catalog/models/catalog.dart'; +import 'package:velocity_x/velocity_x.dart'; class CartModel { // catalog field @@ -22,15 +24,19 @@ class CartModel { num get totalPrice => items.fold(0, (total, current) => total + current.price); - // Add Item - - void add(Item item) { - _itemIds.add(item.id); - } - // Remove Item void remove(Item item) { _itemIds.remove(item.id); } } + +class AddMutation extends VxMutation { + final Item item; + + AddMutation(this.item); + @override + perform() { + store.cart._itemIds.add(item.id); + } +} diff --git a/lib/pages/cart_page.dart b/lib/pages/cart_page.dart index f146d7f..f6be724 100644 --- a/lib/pages/cart_page.dart +++ b/lib/pages/cart_page.dart @@ -1,4 +1,5 @@ import 'package:flutter/material.dart'; +import 'package:flutter_catalog/core/store.dart'; import 'package:flutter_catalog/models/cart.dart'; import 'package:velocity_x/velocity_x.dart'; @@ -25,7 +26,7 @@ class CartPage extends StatelessWidget { class _CartTotal extends StatelessWidget { @override Widget build(BuildContext context) { - final _cart = CartModel(); + final CartModel _cart = (VxState.store as MyStore).cart; return SizedBox( height: 200, child: Row( @@ -55,9 +56,9 @@ class _CartTotal extends StatelessWidget { } class _CartList extends StatelessWidget { - final _cart = CartModel(); @override Widget build(BuildContext context) { + final CartModel _cart = (VxState.store as MyStore).cart; return _cart.items.isEmpty ? "Nothing to show".text.xl3.makeCentered() : ListView.builder( diff --git a/lib/widgets/home_widgets/add_to_cart.dart b/lib/widgets/home_widgets/add_to_cart.dart index a805e05..5290358 100644 --- a/lib/widgets/home_widgets/add_to_cart.dart +++ b/lib/widgets/home_widgets/add_to_cart.dart @@ -1,5 +1,6 @@ import 'package:flutter/cupertino.dart'; import 'package:flutter/material.dart'; +import 'package:flutter_catalog/core/store.dart'; import 'package:flutter_catalog/models/cart.dart'; import 'package:flutter_catalog/models/catalog.dart'; import 'package:velocity_x/velocity_x.dart'; @@ -11,19 +12,15 @@ class AddToCart extends StatelessWidget { this.catalog, }) : super(key: key); - final _cart = CartModel(); @override Widget build(BuildContext context) { + VxState.listen(context, to: [AddMutation]); + final CartModel _cart = (VxState.store as MyStore).cart; bool isInCart = _cart.items.contains(catalog) ?? false; return ElevatedButton( onPressed: () { if (!isInCart) { - isInCart = isInCart.toggle(); - final _catalog = CatalogModel(); - - _cart.catalog = _catalog; - _cart.add(catalog); - // setState(() {}); + AddMutation(catalog); } }, style: ButtonStyle( From 9141bfe9482ce8f4429946a3b56fe5a76625f365 Mon Sep 17 00:00:00 2001 From: iampawan Date: Sat, 6 Mar 2021 16:57:35 +0530 Subject: [PATCH 27/29] Day 28 completed --- lib/models/cart.dart | 16 ++++++++++------ lib/pages/cart_page.dart | 21 ++++++++++++--------- lib/widgets/home_widgets/add_to_cart.dart | 2 +- 3 files changed, 23 insertions(+), 16 deletions(-) diff --git a/lib/models/cart.dart b/lib/models/cart.dart index 8e1c8f5..61878c7 100644 --- a/lib/models/cart.dart +++ b/lib/models/cart.dart @@ -23,12 +23,6 @@ class CartModel { // Get total price num get totalPrice => items.fold(0, (total, current) => total + current.price); - - // Remove Item - - void remove(Item item) { - _itemIds.remove(item.id); - } } class AddMutation extends VxMutation { @@ -40,3 +34,13 @@ class AddMutation extends VxMutation { store.cart._itemIds.add(item.id); } } + +class RemoveMutation extends VxMutation { + final Item item; + + RemoveMutation(this.item); + @override + perform() { + store.cart._itemIds.remove(item.id); + } +} diff --git a/lib/pages/cart_page.dart b/lib/pages/cart_page.dart index f6be724..b6f665f 100644 --- a/lib/pages/cart_page.dart +++ b/lib/pages/cart_page.dart @@ -32,11 +32,16 @@ class _CartTotal extends StatelessWidget { child: Row( mainAxisAlignment: MainAxisAlignment.spaceAround, children: [ - "\$${_cart.totalPrice}" - .text - .xl5 - .color(context.theme.accentColor) - .make(), + VxBuilder( + mutations: {RemoveMutation}, + builder: (context, _) { + return "\$${_cart.totalPrice}" + .text + .xl5 + .color(context.theme.accentColor) + .make(); + }, + ), 30.widthBox, ElevatedButton( onPressed: () { @@ -58,6 +63,7 @@ class _CartTotal extends StatelessWidget { class _CartList extends StatelessWidget { @override Widget build(BuildContext context) { + VxState.listen(context, to: [RemoveMutation]); final CartModel _cart = (VxState.store as MyStore).cart; return _cart.items.isEmpty ? "Nothing to show".text.xl3.makeCentered() @@ -67,10 +73,7 @@ class _CartList extends StatelessWidget { leading: Icon(Icons.done), trailing: IconButton( icon: Icon(Icons.remove_circle_outline), - onPressed: () { - _cart.remove(_cart.items[index]); - // setState(() {}); - }, + onPressed: () => RemoveMutation(_cart.items[index]), ), title: _cart.items[index].name.text.make(), ), diff --git a/lib/widgets/home_widgets/add_to_cart.dart b/lib/widgets/home_widgets/add_to_cart.dart index 5290358..34da4df 100644 --- a/lib/widgets/home_widgets/add_to_cart.dart +++ b/lib/widgets/home_widgets/add_to_cart.dart @@ -14,7 +14,7 @@ class AddToCart extends StatelessWidget { @override Widget build(BuildContext context) { - VxState.listen(context, to: [AddMutation]); + VxState.listen(context, to: [AddMutation, RemoveMutation]); final CartModel _cart = (VxState.store as MyStore).cart; bool isInCart = _cart.items.contains(catalog) ?? false; return ElevatedButton( From 17d10d16e39ca34cbe6572d805b15c8ea542987e Mon Sep 17 00:00:00 2001 From: iampawan Date: Sun, 14 Mar 2021 13:46:20 +0530 Subject: [PATCH 28/29] Day 29 completed --- integration_test/app_test.dart | 36 -------- integration_test/driver.dart | 8 -- lib/pages/cart_page.dart | 2 +- lib/pages/home_page.dart | 37 ++++++-- lib/widgets/home_widgets/add_to_cart.dart | 2 +- pubspec.lock | 107 +++++----------------- pubspec.yaml | 9 +- 7 files changed, 60 insertions(+), 141 deletions(-) delete mode 100644 integration_test/app_test.dart delete mode 100644 integration_test/driver.dart diff --git a/integration_test/app_test.dart b/integration_test/app_test.dart deleted file mode 100644 index 51fd2f5..0000000 --- a/integration_test/app_test.dart +++ /dev/null @@ -1,36 +0,0 @@ -// This is a basic Flutter integration test. -// -// To perform an interaction with a widget in your test, use the WidgetTester -// utility that Flutter provides. For example, you can send tap and scroll -// gestures. You can also use WidgetTester to find child widgets in the widget -// tree, read text, and verify that the values of widget properties are correct. - -import 'package:flutter/material.dart'; -import 'package:flutter_test/flutter_test.dart'; -import 'package:integration_test/integration_test.dart'; - -import 'package:flutter_catalog/main.dart' as app; - -// void main() => run(_testMain); - -void _testMain() { - testWidgets('Counter increments smoke test', (WidgetTester tester) async { - // Build our app and trigger a frame. - app.main(); - - // Trigger a frame. - await tester.pumpAndSettle(); - - // Verify that our counter starts at 0. - expect(find.text('0'), findsOneWidget); - expect(find.text('1'), findsNothing); - - // Tap the '+' icon and trigger a frame. - await tester.tap(find.byIcon(Icons.add)); - await tester.pump(); - - // Verify that our counter has incremented. - expect(find.text('0'), findsNothing); - expect(find.text('1'), findsOneWidget); - }); -} diff --git a/integration_test/driver.dart b/integration_test/driver.dart deleted file mode 100644 index a03bca0..0000000 --- a/integration_test/driver.dart +++ /dev/null @@ -1,8 +0,0 @@ -// This file is provided as a convenience for running integration tests via the -// flutter drive command. -// -// flutter drive --driver integration_test/driver.dart --target integration_test/app_test.dart - -import 'package:integration_test/integration_test_driver.dart'; - -Future main() => integrationDriver(); diff --git a/lib/pages/cart_page.dart b/lib/pages/cart_page.dart index b6f665f..f29f32a 100644 --- a/lib/pages/cart_page.dart +++ b/lib/pages/cart_page.dart @@ -63,7 +63,7 @@ class _CartTotal extends StatelessWidget { class _CartList extends StatelessWidget { @override Widget build(BuildContext context) { - VxState.listen(context, to: [RemoveMutation]); + VxState.watch(context, on: [RemoveMutation]); final CartModel _cart = (VxState.store as MyStore).cart; return _cart.items.isEmpty ? "Nothing to show".text.xl3.makeCentered() diff --git a/lib/pages/home_page.dart b/lib/pages/home_page.dart index 8c9b17c..dab04af 100644 --- a/lib/pages/home_page.dart +++ b/lib/pages/home_page.dart @@ -1,12 +1,15 @@ import 'package:flutter/cupertino.dart'; import 'package:flutter/material.dart'; import 'package:flutter/services.dart'; +import 'package:flutter_catalog/core/store.dart'; +import 'package:flutter_catalog/models/cart.dart'; import 'dart:convert'; import 'package:flutter_catalog/models/catalog.dart'; import 'package:flutter_catalog/utils/routes.dart'; import 'package:flutter_catalog/widgets/home_widgets/catalog_header.dart'; import 'package:flutter_catalog/widgets/home_widgets/catalog_list.dart'; import 'package:velocity_x/velocity_x.dart'; +import 'package:http/http.dart' as http; class HomePage extends StatefulWidget { @override @@ -18,6 +21,8 @@ class _HomePageState extends State { final String name = "Codepur"; + final url = "https://api.jsonbin.io/b/604dbddb683e7e079c4eefd3"; + @override void initState() { super.initState(); @@ -26,8 +31,11 @@ class _HomePageState extends State { loadData() async { await Future.delayed(Duration(seconds: 2)); - final catalogJson = - await rootBundle.loadString("assets/files/catalog.json"); + // final catalogJson = + // await rootBundle.loadString("assets/files/catalog.json"); + + final response = await http.get(Uri.parse(url)); + final catalogJson = response.body; final decodedData = jsonDecode(catalogJson); var productsData = decodedData["products"]; CatalogModel.items = List.from(productsData) @@ -38,15 +46,26 @@ class _HomePageState extends State { @override Widget build(BuildContext context) { + final _cart = (VxState.store as MyStore).cart; return Scaffold( backgroundColor: context.canvasColor, - floatingActionButton: FloatingActionButton( - onPressed: () => Navigator.pushNamed(context, MyRoutes.cartRoute), - backgroundColor: context.theme.buttonColor, - child: Icon( - CupertinoIcons.cart, - color: Colors.white, - ), + floatingActionButton: VxBuilder( + mutations: {AddMutation, RemoveMutation}, + builder: (ctx, _) => FloatingActionButton( + onPressed: () => Navigator.pushNamed(context, MyRoutes.cartRoute), + backgroundColor: context.theme.buttonColor, + child: Icon( + CupertinoIcons.cart, + color: Colors.white, + ), + ).badge( + color: Vx.gray200, + size: 22, + count: _cart.items.length, + textStyle: TextStyle( + color: Colors.black, + fontWeight: FontWeight.bold, + )), ), body: SafeArea( child: Container( diff --git a/lib/widgets/home_widgets/add_to_cart.dart b/lib/widgets/home_widgets/add_to_cart.dart index 34da4df..698a7fa 100644 --- a/lib/widgets/home_widgets/add_to_cart.dart +++ b/lib/widgets/home_widgets/add_to_cart.dart @@ -14,7 +14,7 @@ class AddToCart extends StatelessWidget { @override Widget build(BuildContext context) { - VxState.listen(context, to: [AddMutation, RemoveMutation]); + VxState.watch(context, on: [AddMutation, RemoveMutation]); final CartModel _cart = (VxState.store as MyStore).cart; bool isInCart = _cart.items.contains(catalog) ?? false; return ElevatedButton( diff --git a/pubspec.lock b/pubspec.lock index 7bae492..8b52e96 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -7,21 +7,7 @@ packages: name: animator url: "https://pub.dartlang.org" source: hosted - version: "2.0.2" - archive: - dependency: transitive - description: - name: archive - url: "https://pub.dartlang.org" - source: hosted - version: "2.0.13" - args: - dependency: transitive - description: - name: args - url: "https://pub.dartlang.org" - source: hosted - version: "1.6.0" + version: "3.0.0" async: dependency: transitive description: @@ -29,13 +15,13 @@ packages: url: "https://pub.dartlang.org" source: hosted version: "2.5.0" - auto_size_text: + auto_size_text_pk: dependency: transitive description: - name: auto_size_text + name: auto_size_text_pk url: "https://pub.dartlang.org" source: hosted - version: "2.1.0" + version: "3.0.0" boolean_selector: dependency: transitive description: @@ -71,20 +57,13 @@ packages: url: "https://pub.dartlang.org" source: hosted version: "1.15.0" - convert: - dependency: transitive - description: - name: convert - url: "https://pub.dartlang.org" - source: hosted - version: "2.1.1" crypto: dependency: transitive description: name: crypto url: "https://pub.dartlang.org" source: hosted - version: "2.1.5" + version: "3.0.0" cupertino_icons: dependency: "direct main" description: @@ -105,7 +84,7 @@ packages: name: ffi url: "https://pub.dartlang.org" source: hosted - version: "0.1.3" + version: "1.0.0" file: dependency: transitive description: @@ -118,54 +97,39 @@ packages: description: flutter source: sdk version: "0.0.0" - flutter_driver: - dependency: transitive - description: flutter - source: sdk - version: "0.0.0" flutter_test: dependency: "direct dev" description: flutter source: sdk version: "0.0.0" - fuchsia_remote_debug_protocol: - dependency: transitive - description: flutter - source: sdk - version: "0.0.0" google_fonts: dependency: "direct main" description: name: google_fonts url: "https://pub.dartlang.org" source: hosted - version: "1.1.2" + version: "2.0.0" http: - dependency: transitive + dependency: "direct main" description: name: http url: "https://pub.dartlang.org" source: hosted - version: "0.12.2" + version: "0.13.0" http_parser: dependency: transitive description: name: http_parser url: "https://pub.dartlang.org" source: hosted - version: "3.1.4" - integration_test: - dependency: "direct dev" - description: flutter - source: sdk - version: "0.9.2+2" + version: "4.0.0" intl: dependency: transitive description: name: intl url: "https://pub.dartlang.org" source: hosted - version: "0.16.1" + version: "0.17.0" matcher: dependency: transitive description: @@ -193,42 +157,42 @@ packages: name: path_provider url: "https://pub.dartlang.org" source: hosted - version: "1.6.27" + version: "2.0.1" path_provider_linux: dependency: transitive description: name: path_provider_linux url: "https://pub.dartlang.org" source: hosted - version: "0.0.1+2" + version: "2.0.0" path_provider_macos: dependency: transitive description: name: path_provider_macos url: "https://pub.dartlang.org" source: hosted - version: "0.0.4+8" + version: "2.0.0" path_provider_platform_interface: dependency: transitive description: name: path_provider_platform_interface url: "https://pub.dartlang.org" source: hosted - version: "1.0.4" + version: "2.0.1" path_provider_windows: dependency: transitive description: name: path_provider_windows url: "https://pub.dartlang.org" source: hosted - version: "0.0.4+3" + version: "2.0.0" pedantic: dependency: transitive description: name: pedantic url: "https://pub.dartlang.org" source: hosted - version: "1.10.0-nullsafety.3" + version: "1.11.0" platform: dependency: transitive description: @@ -242,7 +206,7 @@ packages: name: plugin_platform_interface url: "https://pub.dartlang.org" source: hosted - version: "1.0.3" + version: "2.0.0" process: dependency: transitive description: @@ -275,7 +239,7 @@ packages: name: states_rebuilder url: "https://pub.dartlang.org" source: hosted - version: "3.2.0" + version: "4.0.0+1" stream_channel: dependency: transitive description: @@ -290,13 +254,6 @@ packages: url: "https://pub.dartlang.org" source: hosted version: "1.1.0" - sync_http: - dependency: transitive - description: - name: sync_http - url: "https://pub.dartlang.org" - source: hosted - version: "0.2.0" term_glyph: dependency: transitive description: @@ -331,42 +288,28 @@ packages: name: velocity_x url: "https://pub.dartlang.org" source: hosted - version: "1.4.1" - vm_service: - dependency: transitive - description: - name: vm_service - url: "https://pub.dartlang.org" - source: hosted - version: "5.5.0" + version: "2.5.0" vxstate: dependency: transitive description: name: vxstate url: "https://pub.dartlang.org" source: hosted - version: "1.0.1" - webdriver: - dependency: transitive - description: - name: webdriver - url: "https://pub.dartlang.org" - source: hosted - version: "2.1.2" + version: "2.0.1" win32: dependency: transitive description: name: win32 url: "https://pub.dartlang.org" source: hosted - version: "1.7.4+1" + version: "2.0.4" xdg_directories: dependency: transitive description: name: xdg_directories url: "https://pub.dartlang.org" source: hosted - version: "0.1.2" + version: "0.2.0" sdks: - dart: ">=2.12.0-0.0 <3.0.0" - flutter: ">=1.17.0" + dart: ">=2.12.0 <3.0.0" + flutter: ">=2.0.0" diff --git a/pubspec.yaml b/pubspec.yaml index 793406d..727860d 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -24,14 +24,15 @@ dependencies: flutter: sdk: flutter cupertino_icons: ^1.0.1 - google_fonts: ^1.1.2 - velocity_x: ^1.4.1 + google_fonts: ^2.0.0 + http: ^0.13.0 + velocity_x: ^2.5.0 dev_dependencies: flutter_test: sdk: flutter - integration_test: - sdk: flutter + # integration_test: + # sdk: flutter # For information on the generic Dart part of this file, see the # following page: https://dart.dev/tools/pub/pubspec From a43548c7a4fd8f5c911f2e96cb9be88da9360e78 Mon Sep 17 00:00:00 2001 From: iampawan Date: Sun, 14 Mar 2021 14:06:10 +0530 Subject: [PATCH 29/29] Day 30 completed --- lib/pages/home_page.dart | 1 - lib/widgets/home_widgets/catalog_image.dart | 9 +- lib/widgets/home_widgets/catalog_list.dart | 111 +-- macos/.gitignore | 6 + macos/Flutter/Flutter-Debug.xcconfig | 2 + macos/Flutter/Flutter-Release.xcconfig | 2 + macos/Flutter/GeneratedPluginRegistrant.swift | 12 + macos/Podfile | 40 ++ macos/Podfile.lock | 22 + macos/Runner.xcodeproj/project.pbxproj | 632 ++++++++++++++++++ .../xcshareddata/IDEWorkspaceChecks.plist | 8 + .../xcshareddata/xcschemes/Runner.xcscheme | 89 +++ .../contents.xcworkspacedata | 10 + .../xcshareddata/IDEWorkspaceChecks.plist | 8 + macos/Runner/AppDelegate.swift | 9 + .../AppIcon.appiconset/Contents.json | 68 ++ .../AppIcon.appiconset/app_icon_1024.png | Bin 0 -> 46993 bytes .../AppIcon.appiconset/app_icon_128.png | Bin 0 -> 3276 bytes .../AppIcon.appiconset/app_icon_16.png | Bin 0 -> 1429 bytes .../AppIcon.appiconset/app_icon_256.png | Bin 0 -> 5933 bytes .../AppIcon.appiconset/app_icon_32.png | Bin 0 -> 1243 bytes .../AppIcon.appiconset/app_icon_512.png | Bin 0 -> 14800 bytes .../AppIcon.appiconset/app_icon_64.png | Bin 0 -> 1874 bytes macos/Runner/Base.lproj/MainMenu.xib | 339 ++++++++++ macos/Runner/Configs/AppInfo.xcconfig | 14 + macos/Runner/Configs/Debug.xcconfig | 2 + macos/Runner/Configs/Release.xcconfig | 2 + macos/Runner/Configs/Warnings.xcconfig | 13 + macos/Runner/DebugProfile.entitlements | 14 + macos/Runner/Info.plist | 32 + macos/Runner/MainFlutterWindow.swift | 15 + macos/Runner/Release.entitlements | 12 + web/favicon.png | Bin 0 -> 917 bytes web/icons/Icon-192.png | Bin 0 -> 5292 bytes web/icons/Icon-512.png | Bin 0 -> 8252 bytes web/index.html | 45 ++ web/manifest.json | 23 + 37 files changed, 1495 insertions(+), 45 deletions(-) create mode 100644 macos/.gitignore create mode 100644 macos/Flutter/Flutter-Debug.xcconfig create mode 100644 macos/Flutter/Flutter-Release.xcconfig create mode 100644 macos/Flutter/GeneratedPluginRegistrant.swift create mode 100644 macos/Podfile create mode 100644 macos/Podfile.lock create mode 100644 macos/Runner.xcodeproj/project.pbxproj create mode 100644 macos/Runner.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist create mode 100644 macos/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme create mode 100644 macos/Runner.xcworkspace/contents.xcworkspacedata create mode 100644 macos/Runner.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist create mode 100644 macos/Runner/AppDelegate.swift create mode 100644 macos/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json create mode 100644 macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_1024.png create mode 100644 macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_128.png create mode 100644 macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_16.png create mode 100644 macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_256.png create mode 100644 macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_32.png create mode 100644 macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_512.png create mode 100644 macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_64.png create mode 100644 macos/Runner/Base.lproj/MainMenu.xib create mode 100644 macos/Runner/Configs/AppInfo.xcconfig create mode 100644 macos/Runner/Configs/Debug.xcconfig create mode 100644 macos/Runner/Configs/Release.xcconfig create mode 100644 macos/Runner/Configs/Warnings.xcconfig create mode 100644 macos/Runner/DebugProfile.entitlements create mode 100644 macos/Runner/Info.plist create mode 100644 macos/Runner/MainFlutterWindow.swift create mode 100644 macos/Runner/Release.entitlements create mode 100644 web/favicon.png create mode 100644 web/icons/Icon-192.png create mode 100644 web/icons/Icon-512.png create mode 100644 web/index.html create mode 100644 web/manifest.json diff --git a/lib/pages/home_page.dart b/lib/pages/home_page.dart index dab04af..6336789 100644 --- a/lib/pages/home_page.dart +++ b/lib/pages/home_page.dart @@ -1,6 +1,5 @@ import 'package:flutter/cupertino.dart'; import 'package:flutter/material.dart'; -import 'package:flutter/services.dart'; import 'package:flutter_catalog/core/store.dart'; import 'package:flutter_catalog/models/cart.dart'; import 'dart:convert'; diff --git a/lib/widgets/home_widgets/catalog_image.dart b/lib/widgets/home_widgets/catalog_image.dart index 8724a53..04a4996 100644 --- a/lib/widgets/home_widgets/catalog_image.dart +++ b/lib/widgets/home_widgets/catalog_image.dart @@ -9,6 +9,13 @@ class CatalogImage extends StatelessWidget { Widget build(BuildContext context) { return Image.network( image, - ).box.rounded.p8.color(context.canvasColor).make().p16().w40(context); + ) + .box + .rounded + .p8 + .color(context.canvasColor) + .make() + .p16() + .wPCT(context: context, widthPCT: context.isMobile ? 40 : 20); } } diff --git a/lib/widgets/home_widgets/catalog_list.dart b/lib/widgets/home_widgets/catalog_list.dart index 3985a55..de66bbf 100644 --- a/lib/widgets/home_widgets/catalog_list.dart +++ b/lib/widgets/home_widgets/catalog_list.dart @@ -9,22 +9,41 @@ import 'catalog_image.dart'; class CatalogList extends StatelessWidget { @override Widget build(BuildContext context) { - return ListView.builder( - shrinkWrap: true, - itemCount: CatalogModel.items.length, - itemBuilder: (context, index) { - final catalog = CatalogModel.items[index]; - return InkWell( - onTap: () => Navigator.push( - context, - MaterialPageRoute( - builder: (context) => HomeDetailPage(catalog: catalog), - ), - ), - child: CatalogItem(catalog: catalog), - ); - }, - ); + return !context.isMobile + ? GridView.builder( + gridDelegate: SliverGridDelegateWithFixedCrossAxisCount( + crossAxisCount: 2, crossAxisSpacing: 20.0), + shrinkWrap: true, + itemCount: CatalogModel.items.length, + itemBuilder: (context, index) { + final catalog = CatalogModel.items[index]; + return InkWell( + onTap: () => Navigator.push( + context, + MaterialPageRoute( + builder: (context) => HomeDetailPage(catalog: catalog), + ), + ), + child: CatalogItem(catalog: catalog), + ); + }, + ) + : ListView.builder( + shrinkWrap: true, + itemCount: CatalogModel.items.length, + itemBuilder: (context, index) { + final catalog = CatalogModel.items[index]; + return InkWell( + onTap: () => Navigator.push( + context, + MaterialPageRoute( + builder: (context) => HomeDetailPage(catalog: catalog), + ), + ), + child: CatalogItem(catalog: catalog), + ); + }, + ); } } @@ -37,35 +56,41 @@ class CatalogItem extends StatelessWidget { @override Widget build(BuildContext context) { + var children2 = [ + Hero( + tag: Key(catalog.id.toString()), + child: CatalogImage( + image: catalog.image, + ), + ), + Expanded( + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + mainAxisAlignment: MainAxisAlignment.center, + children: [ + catalog.name.text.lg.color(context.accentColor).bold.make(), + catalog.desc.text.textStyle(context.captionStyle).make(), + 10.heightBox, + ButtonBar( + alignment: MainAxisAlignment.spaceBetween, + buttonPadding: EdgeInsets.zero, + children: [ + "\$${catalog.price}".text.bold.xl.make(), + AddToCart(catalog: catalog) + ], + ).pOnly(right: 8.0) + ], + ).p(context.isMobile ? 0 : 16), + ) + ]; return VxBox( - child: Row( - children: [ - Hero( - tag: Key(catalog.id.toString()), - child: CatalogImage( - image: catalog.image, + child: context.isMobile + ? Row( + children: children2, + ) + : Column( + children: children2, ), - ), - Expanded( - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - mainAxisAlignment: MainAxisAlignment.center, - children: [ - catalog.name.text.lg.color(context.accentColor).bold.make(), - catalog.desc.text.textStyle(context.captionStyle).make(), - 10.heightBox, - ButtonBar( - alignment: MainAxisAlignment.spaceBetween, - buttonPadding: EdgeInsets.zero, - children: [ - "\$${catalog.price}".text.bold.xl.make(), - AddToCart(catalog: catalog) - ], - ).pOnly(right: 8.0) - ], - )) - ], - ), ).color(context.cardColor).rounded.square(150).make().py16(); } } diff --git a/macos/.gitignore b/macos/.gitignore new file mode 100644 index 0000000..d2fd377 --- /dev/null +++ b/macos/.gitignore @@ -0,0 +1,6 @@ +# Flutter-related +**/Flutter/ephemeral/ +**/Pods/ + +# Xcode-related +**/xcuserdata/ diff --git a/macos/Flutter/Flutter-Debug.xcconfig b/macos/Flutter/Flutter-Debug.xcconfig new file mode 100644 index 0000000..4b81f9b --- /dev/null +++ b/macos/Flutter/Flutter-Debug.xcconfig @@ -0,0 +1,2 @@ +#include? "Pods/Target Support Files/Pods-Runner/Pods-Runner.debug.xcconfig" +#include "ephemeral/Flutter-Generated.xcconfig" diff --git a/macos/Flutter/Flutter-Release.xcconfig b/macos/Flutter/Flutter-Release.xcconfig new file mode 100644 index 0000000..5caa9d1 --- /dev/null +++ b/macos/Flutter/Flutter-Release.xcconfig @@ -0,0 +1,2 @@ +#include? "Pods/Target Support Files/Pods-Runner/Pods-Runner.release.xcconfig" +#include "ephemeral/Flutter-Generated.xcconfig" diff --git a/macos/Flutter/GeneratedPluginRegistrant.swift b/macos/Flutter/GeneratedPluginRegistrant.swift new file mode 100644 index 0000000..0d56f51 --- /dev/null +++ b/macos/Flutter/GeneratedPluginRegistrant.swift @@ -0,0 +1,12 @@ +// +// Generated file. Do not edit. +// + +import FlutterMacOS +import Foundation + +import path_provider_macos + +func RegisterGeneratedPlugins(registry: FlutterPluginRegistry) { + PathProviderPlugin.register(with: registry.registrar(forPlugin: "PathProviderPlugin")) +} diff --git a/macos/Podfile b/macos/Podfile new file mode 100644 index 0000000..dade8df --- /dev/null +++ b/macos/Podfile @@ -0,0 +1,40 @@ +platform :osx, '10.11' + +# CocoaPods analytics sends network stats synchronously affecting flutter build latency. +ENV['COCOAPODS_DISABLE_STATS'] = 'true' + +project 'Runner', { + 'Debug' => :debug, + 'Profile' => :release, + 'Release' => :release, +} + +def flutter_root + generated_xcode_build_settings_path = File.expand_path(File.join('..', 'Flutter', 'ephemeral', 'Flutter-Generated.xcconfig'), __FILE__) + unless File.exist?(generated_xcode_build_settings_path) + raise "#{generated_xcode_build_settings_path} must exist. If you're running pod install manually, make sure \"flutter pub get\" is executed first" + end + + File.foreach(generated_xcode_build_settings_path) do |line| + matches = line.match(/FLUTTER_ROOT\=(.*)/) + return matches[1].strip if matches + end + raise "FLUTTER_ROOT not found in #{generated_xcode_build_settings_path}. Try deleting Flutter-Generated.xcconfig, then run \"flutter pub get\"" +end + +require File.expand_path(File.join('packages', 'flutter_tools', 'bin', 'podhelper'), flutter_root) + +flutter_macos_podfile_setup + +target 'Runner' do + use_frameworks! + use_modular_headers! + + flutter_install_all_macos_pods File.dirname(File.realpath(__FILE__)) +end + +post_install do |installer| + installer.pods_project.targets.each do |target| + flutter_additional_macos_build_settings(target) + end +end diff --git a/macos/Podfile.lock b/macos/Podfile.lock new file mode 100644 index 0000000..328ddd1 --- /dev/null +++ b/macos/Podfile.lock @@ -0,0 +1,22 @@ +PODS: + - FlutterMacOS (1.0.0) + - path_provider_macos (0.0.1): + - FlutterMacOS + +DEPENDENCIES: + - FlutterMacOS (from `Flutter/ephemeral`) + - path_provider_macos (from `Flutter/ephemeral/.symlinks/plugins/path_provider_macos/macos`) + +EXTERNAL SOURCES: + FlutterMacOS: + :path: Flutter/ephemeral + path_provider_macos: + :path: Flutter/ephemeral/.symlinks/plugins/path_provider_macos/macos + +SPEC CHECKSUMS: + FlutterMacOS: 57701585bf7de1b3fc2bb61f6378d73bbdea8424 + path_provider_macos: a0a3fd666cb7cd0448e936fb4abad4052961002b + +PODFILE CHECKSUM: 6eac6b3292e5142cfc23bdeb71848a40ec51c14c + +COCOAPODS: 1.10.1 diff --git a/macos/Runner.xcodeproj/project.pbxproj b/macos/Runner.xcodeproj/project.pbxproj new file mode 100644 index 0000000..9ecd739 --- /dev/null +++ b/macos/Runner.xcodeproj/project.pbxproj @@ -0,0 +1,632 @@ +// !$*UTF8*$! +{ + archiveVersion = 1; + classes = { + }; + objectVersion = 51; + objects = { + +/* Begin PBXAggregateTarget section */ + 33CC111A2044C6BA0003C045 /* Flutter Assemble */ = { + isa = PBXAggregateTarget; + buildConfigurationList = 33CC111B2044C6BA0003C045 /* Build configuration list for PBXAggregateTarget "Flutter Assemble" */; + buildPhases = ( + 33CC111E2044C6BF0003C045 /* ShellScript */, + ); + dependencies = ( + ); + name = "Flutter Assemble"; + productName = FLX; + }; +/* End PBXAggregateTarget section */ + +/* Begin PBXBuildFile section */ + 335BBD1B22A9A15E00E9071D /* GeneratedPluginRegistrant.swift in Sources */ = {isa = PBXBuildFile; fileRef = 335BBD1A22A9A15E00E9071D /* GeneratedPluginRegistrant.swift */; }; + 33CC10F12044A3C60003C045 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 33CC10F02044A3C60003C045 /* AppDelegate.swift */; }; + 33CC10F32044A3C60003C045 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 33CC10F22044A3C60003C045 /* Assets.xcassets */; }; + 33CC10F62044A3C60003C045 /* MainMenu.xib in Resources */ = {isa = PBXBuildFile; fileRef = 33CC10F42044A3C60003C045 /* MainMenu.xib */; }; + 33CC11132044BFA00003C045 /* MainFlutterWindow.swift in Sources */ = {isa = PBXBuildFile; fileRef = 33CC11122044BFA00003C045 /* MainFlutterWindow.swift */; }; + 70F95C47A5B52CADF48DBC32 /* Pods_Runner.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 21BA7B375494B00E3FEC35AC /* Pods_Runner.framework */; }; +/* End PBXBuildFile section */ + +/* Begin PBXContainerItemProxy section */ + 33CC111F2044C79F0003C045 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 33CC10E52044A3C60003C045 /* Project object */; + proxyType = 1; + remoteGlobalIDString = 33CC111A2044C6BA0003C045; + remoteInfo = FLX; + }; +/* End PBXContainerItemProxy section */ + +/* Begin PBXCopyFilesBuildPhase section */ + 33CC110E2044A8840003C045 /* Bundle Framework */ = { + isa = PBXCopyFilesBuildPhase; + buildActionMask = 2147483647; + dstPath = ""; + dstSubfolderSpec = 10; + files = ( + ); + name = "Bundle Framework"; + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXCopyFilesBuildPhase section */ + +/* Begin PBXFileReference section */ + 1BCA94FA4759E69C5A5B95C7 /* Pods-Runner.profile.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.profile.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.profile.xcconfig"; sourceTree = ""; }; + 21BA7B375494B00E3FEC35AC /* Pods_Runner.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_Runner.framework; sourceTree = BUILT_PRODUCTS_DIR; }; + 333000ED22D3DE5D00554162 /* Warnings.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = Warnings.xcconfig; sourceTree = ""; }; + 335BBD1A22A9A15E00E9071D /* GeneratedPluginRegistrant.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = GeneratedPluginRegistrant.swift; sourceTree = ""; }; + 33CC10ED2044A3C60003C045 /* flutter_catalog.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = flutter_catalog.app; sourceTree = BUILT_PRODUCTS_DIR; }; + 33CC10F02044A3C60003C045 /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = ""; }; + 33CC10F22044A3C60003C045 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; name = Assets.xcassets; path = Runner/Assets.xcassets; sourceTree = ""; }; + 33CC10F52044A3C60003C045 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = Base; path = Base.lproj/MainMenu.xib; sourceTree = ""; }; + 33CC10F72044A3C60003C045 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; name = Info.plist; path = Runner/Info.plist; sourceTree = ""; }; + 33CC11122044BFA00003C045 /* MainFlutterWindow.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MainFlutterWindow.swift; sourceTree = ""; }; + 33CEB47222A05771004F2AC0 /* Flutter-Debug.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = "Flutter-Debug.xcconfig"; sourceTree = ""; }; + 33CEB47422A05771004F2AC0 /* Flutter-Release.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = "Flutter-Release.xcconfig"; sourceTree = ""; }; + 33CEB47722A0578A004F2AC0 /* Flutter-Generated.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; name = "Flutter-Generated.xcconfig"; path = "ephemeral/Flutter-Generated.xcconfig"; sourceTree = ""; }; + 33E51913231747F40026EE4D /* DebugProfile.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = DebugProfile.entitlements; sourceTree = ""; }; + 33E51914231749380026EE4D /* Release.entitlements */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.entitlements; path = Release.entitlements; sourceTree = ""; }; + 33E5194F232828860026EE4D /* AppInfo.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = AppInfo.xcconfig; sourceTree = ""; }; + 70371A43512C77BB83949689 /* Pods-Runner.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.debug.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.debug.xcconfig"; sourceTree = ""; }; + 7AFA3C8E1D35360C0083082E /* Release.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = Release.xcconfig; sourceTree = ""; }; + 9740EEB21CF90195004384FC /* Debug.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; path = Debug.xcconfig; sourceTree = ""; }; + C6758DDD150FDA44DA3A2D65 /* Pods-Runner.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.release.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.release.xcconfig"; sourceTree = ""; }; +/* End PBXFileReference section */ + +/* Begin PBXFrameworksBuildPhase section */ + 33CC10EA2044A3C60003C045 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + 70F95C47A5B52CADF48DBC32 /* Pods_Runner.framework in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXFrameworksBuildPhase section */ + +/* Begin PBXGroup section */ + 33BA886A226E78AF003329D5 /* Configs */ = { + isa = PBXGroup; + children = ( + 33E5194F232828860026EE4D /* AppInfo.xcconfig */, + 9740EEB21CF90195004384FC /* Debug.xcconfig */, + 7AFA3C8E1D35360C0083082E /* Release.xcconfig */, + 333000ED22D3DE5D00554162 /* Warnings.xcconfig */, + ); + path = Configs; + sourceTree = ""; + }; + 33CC10E42044A3C60003C045 = { + isa = PBXGroup; + children = ( + 33FAB671232836740065AC1E /* Runner */, + 33CEB47122A05771004F2AC0 /* Flutter */, + 33CC10EE2044A3C60003C045 /* Products */, + D73912EC22F37F3D000D13A0 /* Frameworks */, + 9FDEFE169DF45EC2AD3F8E58 /* Pods */, + ); + sourceTree = ""; + }; + 33CC10EE2044A3C60003C045 /* Products */ = { + isa = PBXGroup; + children = ( + 33CC10ED2044A3C60003C045 /* flutter_catalog.app */, + ); + name = Products; + sourceTree = ""; + }; + 33CC11242044D66E0003C045 /* Resources */ = { + isa = PBXGroup; + children = ( + 33CC10F22044A3C60003C045 /* Assets.xcassets */, + 33CC10F42044A3C60003C045 /* MainMenu.xib */, + 33CC10F72044A3C60003C045 /* Info.plist */, + ); + name = Resources; + path = ..; + sourceTree = ""; + }; + 33CEB47122A05771004F2AC0 /* Flutter */ = { + isa = PBXGroup; + children = ( + 335BBD1A22A9A15E00E9071D /* GeneratedPluginRegistrant.swift */, + 33CEB47222A05771004F2AC0 /* Flutter-Debug.xcconfig */, + 33CEB47422A05771004F2AC0 /* Flutter-Release.xcconfig */, + 33CEB47722A0578A004F2AC0 /* Flutter-Generated.xcconfig */, + ); + path = Flutter; + sourceTree = ""; + }; + 33FAB671232836740065AC1E /* Runner */ = { + isa = PBXGroup; + children = ( + 33CC10F02044A3C60003C045 /* AppDelegate.swift */, + 33CC11122044BFA00003C045 /* MainFlutterWindow.swift */, + 33E51913231747F40026EE4D /* DebugProfile.entitlements */, + 33E51914231749380026EE4D /* Release.entitlements */, + 33CC11242044D66E0003C045 /* Resources */, + 33BA886A226E78AF003329D5 /* Configs */, + ); + path = Runner; + sourceTree = ""; + }; + 9FDEFE169DF45EC2AD3F8E58 /* Pods */ = { + isa = PBXGroup; + children = ( + 70371A43512C77BB83949689 /* Pods-Runner.debug.xcconfig */, + C6758DDD150FDA44DA3A2D65 /* Pods-Runner.release.xcconfig */, + 1BCA94FA4759E69C5A5B95C7 /* Pods-Runner.profile.xcconfig */, + ); + name = Pods; + path = Pods; + sourceTree = ""; + }; + D73912EC22F37F3D000D13A0 /* Frameworks */ = { + isa = PBXGroup; + children = ( + 21BA7B375494B00E3FEC35AC /* Pods_Runner.framework */, + ); + name = Frameworks; + sourceTree = ""; + }; +/* End PBXGroup section */ + +/* Begin PBXNativeTarget section */ + 33CC10EC2044A3C60003C045 /* Runner */ = { + isa = PBXNativeTarget; + buildConfigurationList = 33CC10FB2044A3C60003C045 /* Build configuration list for PBXNativeTarget "Runner" */; + buildPhases = ( + A16109005A77ADFFCB06A9D3 /* [CP] Check Pods Manifest.lock */, + 33CC10E92044A3C60003C045 /* Sources */, + 33CC10EA2044A3C60003C045 /* Frameworks */, + 33CC10EB2044A3C60003C045 /* Resources */, + 33CC110E2044A8840003C045 /* Bundle Framework */, + 3399D490228B24CF009A79C7 /* ShellScript */, + 5911F07D09231A98C7BE9175 /* [CP] Embed Pods Frameworks */, + ); + buildRules = ( + ); + dependencies = ( + 33CC11202044C79F0003C045 /* PBXTargetDependency */, + ); + name = Runner; + productName = Runner; + productReference = 33CC10ED2044A3C60003C045 /* flutter_catalog.app */; + productType = "com.apple.product-type.application"; + }; +/* End PBXNativeTarget section */ + +/* Begin PBXProject section */ + 33CC10E52044A3C60003C045 /* Project object */ = { + isa = PBXProject; + attributes = { + LastSwiftUpdateCheck = 0920; + LastUpgradeCheck = 0930; + ORGANIZATIONNAME = ""; + TargetAttributes = { + 33CC10EC2044A3C60003C045 = { + CreatedOnToolsVersion = 9.2; + LastSwiftMigration = 1100; + ProvisioningStyle = Automatic; + SystemCapabilities = { + com.apple.Sandbox = { + enabled = 1; + }; + }; + }; + 33CC111A2044C6BA0003C045 = { + CreatedOnToolsVersion = 9.2; + ProvisioningStyle = Manual; + }; + }; + }; + buildConfigurationList = 33CC10E82044A3C60003C045 /* Build configuration list for PBXProject "Runner" */; + compatibilityVersion = "Xcode 9.3"; + developmentRegion = en; + hasScannedForEncodings = 0; + knownRegions = ( + en, + Base, + ); + mainGroup = 33CC10E42044A3C60003C045; + productRefGroup = 33CC10EE2044A3C60003C045 /* Products */; + projectDirPath = ""; + projectRoot = ""; + targets = ( + 33CC10EC2044A3C60003C045 /* Runner */, + 33CC111A2044C6BA0003C045 /* Flutter Assemble */, + ); + }; +/* End PBXProject section */ + +/* Begin PBXResourcesBuildPhase section */ + 33CC10EB2044A3C60003C045 /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 33CC10F32044A3C60003C045 /* Assets.xcassets in Resources */, + 33CC10F62044A3C60003C045 /* MainMenu.xib in Resources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXResourcesBuildPhase section */ + +/* Begin PBXShellScriptBuildPhase section */ + 3399D490228B24CF009A79C7 /* ShellScript */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputFileListPaths = ( + ); + inputPaths = ( + ); + outputFileListPaths = ( + ); + outputPaths = ( + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "echo \"$PRODUCT_NAME.app\" > \"$PROJECT_DIR\"/Flutter/ephemeral/.app_filename && \"$FLUTTER_ROOT\"/packages/flutter_tools/bin/macos_assemble.sh embed\n"; + }; + 33CC111E2044C6BF0003C045 /* ShellScript */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputFileListPaths = ( + Flutter/ephemeral/FlutterInputs.xcfilelist, + ); + inputPaths = ( + Flutter/ephemeral/tripwire, + ); + outputFileListPaths = ( + Flutter/ephemeral/FlutterOutputs.xcfilelist, + ); + outputPaths = ( + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "\"$FLUTTER_ROOT\"/packages/flutter_tools/bin/macos_assemble.sh && touch Flutter/ephemeral/tripwire"; + }; + 5911F07D09231A98C7BE9175 /* [CP] Embed Pods Frameworks */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputFileListPaths = ( + "${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-frameworks-${CONFIGURATION}-input-files.xcfilelist", + ); + name = "[CP] Embed Pods Frameworks"; + outputFileListPaths = ( + "${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-frameworks-${CONFIGURATION}-output-files.xcfilelist", + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-frameworks.sh\"\n"; + showEnvVarsInLog = 0; + }; + A16109005A77ADFFCB06A9D3 /* [CP] Check Pods Manifest.lock */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputFileListPaths = ( + ); + inputPaths = ( + "${PODS_PODFILE_DIR_PATH}/Podfile.lock", + "${PODS_ROOT}/Manifest.lock", + ); + name = "[CP] Check Pods Manifest.lock"; + outputFileListPaths = ( + ); + outputPaths = ( + "$(DERIVED_FILE_DIR)/Pods-Runner-checkManifestLockResult.txt", + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n"; + showEnvVarsInLog = 0; + }; +/* End PBXShellScriptBuildPhase section */ + +/* Begin PBXSourcesBuildPhase section */ + 33CC10E92044A3C60003C045 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 33CC11132044BFA00003C045 /* MainFlutterWindow.swift in Sources */, + 33CC10F12044A3C60003C045 /* AppDelegate.swift in Sources */, + 335BBD1B22A9A15E00E9071D /* GeneratedPluginRegistrant.swift in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXSourcesBuildPhase section */ + +/* Begin PBXTargetDependency section */ + 33CC11202044C79F0003C045 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = 33CC111A2044C6BA0003C045 /* Flutter Assemble */; + targetProxy = 33CC111F2044C79F0003C045 /* PBXContainerItemProxy */; + }; +/* End PBXTargetDependency section */ + +/* Begin PBXVariantGroup section */ + 33CC10F42044A3C60003C045 /* MainMenu.xib */ = { + isa = PBXVariantGroup; + children = ( + 33CC10F52044A3C60003C045 /* Base */, + ); + name = MainMenu.xib; + path = Runner; + sourceTree = ""; + }; +/* End PBXVariantGroup section */ + +/* Begin XCBuildConfiguration section */ + 338D0CE9231458BD00FA5F75 /* Profile */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 7AFA3C8E1D35360C0083082E /* Release.xcconfig */; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_ANALYZER_NONNULL = YES; + CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_DOCUMENTATION_COMMENTS = YES; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CODE_SIGN_IDENTITY = "-"; + COPY_PHASE_STRIP = NO; + DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; + ENABLE_NS_ASSERTIONS = NO; + ENABLE_STRICT_OBJC_MSGSEND = YES; + GCC_C_LANGUAGE_STANDARD = gnu11; + GCC_NO_COMMON_BLOCKS = YES; + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + MACOSX_DEPLOYMENT_TARGET = 10.11; + MTL_ENABLE_DEBUG_INFO = NO; + SDKROOT = macosx; + SWIFT_COMPILATION_MODE = wholemodule; + SWIFT_OPTIMIZATION_LEVEL = "-O"; + }; + name = Profile; + }; + 338D0CEA231458BD00FA5F75 /* Profile */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 33E5194F232828860026EE4D /* AppInfo.xcconfig */; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + CLANG_ENABLE_MODULES = YES; + CODE_SIGN_ENTITLEMENTS = Runner/DebugProfile.entitlements; + CODE_SIGN_STYLE = Automatic; + COMBINE_HIDPI_IMAGES = YES; + INFOPLIST_FILE = Runner/Info.plist; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/../Frameworks", + ); + PROVISIONING_PROFILE_SPECIFIER = ""; + SWIFT_VERSION = 5.0; + }; + name = Profile; + }; + 338D0CEB231458BD00FA5F75 /* Profile */ = { + isa = XCBuildConfiguration; + buildSettings = { + CODE_SIGN_STYLE = Manual; + PRODUCT_NAME = "$(TARGET_NAME)"; + }; + name = Profile; + }; + 33CC10F92044A3C60003C045 /* Debug */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 9740EEB21CF90195004384FC /* Debug.xcconfig */; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_ANALYZER_NONNULL = YES; + CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_DOCUMENTATION_COMMENTS = YES; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CODE_SIGN_IDENTITY = "-"; + COPY_PHASE_STRIP = NO; + DEBUG_INFORMATION_FORMAT = dwarf; + ENABLE_STRICT_OBJC_MSGSEND = YES; + ENABLE_TESTABILITY = YES; + GCC_C_LANGUAGE_STANDARD = gnu11; + GCC_DYNAMIC_NO_PIC = NO; + GCC_NO_COMMON_BLOCKS = YES; + GCC_OPTIMIZATION_LEVEL = 0; + GCC_PREPROCESSOR_DEFINITIONS = ( + "DEBUG=1", + "$(inherited)", + ); + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + MACOSX_DEPLOYMENT_TARGET = 10.11; + MTL_ENABLE_DEBUG_INFO = YES; + ONLY_ACTIVE_ARCH = YES; + SDKROOT = macosx; + SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG; + SWIFT_OPTIMIZATION_LEVEL = "-Onone"; + }; + name = Debug; + }; + 33CC10FA2044A3C60003C045 /* Release */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 7AFA3C8E1D35360C0083082E /* Release.xcconfig */; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_ANALYZER_NONNULL = YES; + CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_DOCUMENTATION_COMMENTS = YES; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CODE_SIGN_IDENTITY = "-"; + COPY_PHASE_STRIP = NO; + DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; + ENABLE_NS_ASSERTIONS = NO; + ENABLE_STRICT_OBJC_MSGSEND = YES; + GCC_C_LANGUAGE_STANDARD = gnu11; + GCC_NO_COMMON_BLOCKS = YES; + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + MACOSX_DEPLOYMENT_TARGET = 10.11; + MTL_ENABLE_DEBUG_INFO = NO; + SDKROOT = macosx; + SWIFT_COMPILATION_MODE = wholemodule; + SWIFT_OPTIMIZATION_LEVEL = "-O"; + }; + name = Release; + }; + 33CC10FC2044A3C60003C045 /* Debug */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 33E5194F232828860026EE4D /* AppInfo.xcconfig */; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + CLANG_ENABLE_MODULES = YES; + CODE_SIGN_ENTITLEMENTS = Runner/DebugProfile.entitlements; + CODE_SIGN_STYLE = Automatic; + COMBINE_HIDPI_IMAGES = YES; + INFOPLIST_FILE = Runner/Info.plist; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/../Frameworks", + ); + PROVISIONING_PROFILE_SPECIFIER = ""; + SWIFT_OPTIMIZATION_LEVEL = "-Onone"; + SWIFT_VERSION = 5.0; + }; + name = Debug; + }; + 33CC10FD2044A3C60003C045 /* Release */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 33E5194F232828860026EE4D /* AppInfo.xcconfig */; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + CLANG_ENABLE_MODULES = YES; + CODE_SIGN_ENTITLEMENTS = Runner/Release.entitlements; + CODE_SIGN_STYLE = Automatic; + COMBINE_HIDPI_IMAGES = YES; + INFOPLIST_FILE = Runner/Info.plist; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/../Frameworks", + ); + PROVISIONING_PROFILE_SPECIFIER = ""; + SWIFT_VERSION = 5.0; + }; + name = Release; + }; + 33CC111C2044C6BA0003C045 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + CODE_SIGN_STYLE = Manual; + PRODUCT_NAME = "$(TARGET_NAME)"; + }; + name = Debug; + }; + 33CC111D2044C6BA0003C045 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + CODE_SIGN_STYLE = Automatic; + PRODUCT_NAME = "$(TARGET_NAME)"; + }; + name = Release; + }; +/* End XCBuildConfiguration section */ + +/* Begin XCConfigurationList section */ + 33CC10E82044A3C60003C045 /* Build configuration list for PBXProject "Runner" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 33CC10F92044A3C60003C045 /* Debug */, + 33CC10FA2044A3C60003C045 /* Release */, + 338D0CE9231458BD00FA5F75 /* Profile */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + 33CC10FB2044A3C60003C045 /* Build configuration list for PBXNativeTarget "Runner" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 33CC10FC2044A3C60003C045 /* Debug */, + 33CC10FD2044A3C60003C045 /* Release */, + 338D0CEA231458BD00FA5F75 /* Profile */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + 33CC111B2044C6BA0003C045 /* Build configuration list for PBXAggregateTarget "Flutter Assemble" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 33CC111C2044C6BA0003C045 /* Debug */, + 33CC111D2044C6BA0003C045 /* Release */, + 338D0CEB231458BD00FA5F75 /* Profile */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; +/* End XCConfigurationList section */ + }; + rootObject = 33CC10E52044A3C60003C045 /* Project object */; +} diff --git a/macos/Runner.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist b/macos/Runner.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist new file mode 100644 index 0000000..18d9810 --- /dev/null +++ b/macos/Runner.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist @@ -0,0 +1,8 @@ + + + + + IDEDidComputeMac32BitWarning + + + diff --git a/macos/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme b/macos/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme new file mode 100644 index 0000000..d246e6b --- /dev/null +++ b/macos/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme @@ -0,0 +1,89 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/macos/Runner.xcworkspace/contents.xcworkspacedata b/macos/Runner.xcworkspace/contents.xcworkspacedata new file mode 100644 index 0000000..21a3cc1 --- /dev/null +++ b/macos/Runner.xcworkspace/contents.xcworkspacedata @@ -0,0 +1,10 @@ + + + + + + + diff --git a/macos/Runner.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist b/macos/Runner.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist new file mode 100644 index 0000000..18d9810 --- /dev/null +++ b/macos/Runner.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist @@ -0,0 +1,8 @@ + + + + + IDEDidComputeMac32BitWarning + + + diff --git a/macos/Runner/AppDelegate.swift b/macos/Runner/AppDelegate.swift new file mode 100644 index 0000000..d53ef64 --- /dev/null +++ b/macos/Runner/AppDelegate.swift @@ -0,0 +1,9 @@ +import Cocoa +import FlutterMacOS + +@NSApplicationMain +class AppDelegate: FlutterAppDelegate { + override func applicationShouldTerminateAfterLastWindowClosed(_ sender: NSApplication) -> Bool { + return true + } +} diff --git a/macos/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json b/macos/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json new file mode 100644 index 0000000..a2ec33f --- /dev/null +++ b/macos/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json @@ -0,0 +1,68 @@ +{ + "images" : [ + { + "size" : "16x16", + "idiom" : "mac", + "filename" : "app_icon_16.png", + "scale" : "1x" + }, + { + "size" : "16x16", + "idiom" : "mac", + "filename" : "app_icon_32.png", + "scale" : "2x" + }, + { + "size" : "32x32", + "idiom" : "mac", + "filename" : "app_icon_32.png", + "scale" : "1x" + }, + { + "size" : "32x32", + "idiom" : "mac", + "filename" : "app_icon_64.png", + "scale" : "2x" + }, + { + "size" : "128x128", + "idiom" : "mac", + "filename" : "app_icon_128.png", + "scale" : "1x" + }, + { + "size" : "128x128", + "idiom" : "mac", + "filename" : "app_icon_256.png", + "scale" : "2x" + }, + { + "size" : "256x256", + "idiom" : "mac", + "filename" : "app_icon_256.png", + "scale" : "1x" + }, + { + "size" : "256x256", + "idiom" : "mac", + "filename" : "app_icon_512.png", + "scale" : "2x" + }, + { + "size" : "512x512", + "idiom" : "mac", + "filename" : "app_icon_512.png", + "scale" : "1x" + }, + { + "size" : "512x512", + "idiom" : "mac", + "filename" : "app_icon_1024.png", + "scale" : "2x" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} diff --git a/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_1024.png b/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_1024.png new file mode 100644 index 0000000000000000000000000000000000000000..3c4935a7ca84f0976aca34b7f2895d65fb94d1ea GIT binary patch literal 46993 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 literal 0 HcmV?d00001 diff --git a/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_128.png b/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_128.png new file mode 100644 index 0000000000000000000000000000000000000000..ed4cc16421680a50164ba74381b4b35ceaa0ccfc GIT binary patch literal 3276 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 N;OXk;vd$@?2>?>Ex^Vyi literal 0 HcmV?d00001 diff --git a/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_256.png b/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_256.png new file mode 100644 index 0000000000000000000000000000000000000000..bcbf36df2f2aaaa0a63c7dabc94e600184229d0d GIT binary patch literal 5933 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 f$KZHO*s&vt|9^w-6P?|#0pRK8NSwWJ?9znhg z3{`3j3=J&|48MRv4KElNN(~qoUL`OvSj}Ky5HFasE6@fg!ItFh?!xdN1Q+aGJ{c&& zS>O>_%)r1c48n{Iv*t(u1=&kHeO=ifbFy+6aSK)V_AxLppYn8Z42d|rc6w}vOsL55 z`t&mC&y2@JTEyg!eDiFX^k#CC!jq%>erB=yHqUP0XcDOTw6ko}L zX;EmMrq(fKk*eygEuA616;0)>@A{TK|55PV@70 z$OfzS*(VJxQev3J?yY?O=ul(v`fp}?u9z`JK3ugibK>)DyCwImZOF4d{xK%%Ks1*} zv$oa)9anR%lXIBUqYnhLmT>VOzHfNP?ZwJNZ!5$s9M08RynIvaXw>@G^T9@r9^KH1 zVy??F&uuk)bH9Y4pQY!hP58i_H6 znl-NcuCpLV6ZWU;4C zu@9exF&OZi`Bovq_m%T+WhU2kvkz@^_LpycBvqm3bMpLw8X-Or5sL>0AKE1$(k_L=_Zc=CUq#=x1-QZf)G7nHu@fmsQ1eN_N3+nTEz`4HI4Z6uVlE zJH+X&det8JU?tO?upcM4Z=cV!JV;yF>FfL5Q$M|W_2Z!P`S=}Wzp|_1^#d%e?_H`> zV@%vA$+bFVqhw9`U;TfP|5|PD{||OiYdor8P*i??|NJcb%kzT_73*7WE?Ua5hAnR2 z=7WE=PhTlJ#ZeRznjTUb;`E(wkMZrj4e|Hilz-mK>9cZHQY**5TUPw~u}k;u73KI}xAx!0m-)GVia|x^d3p~s_9gh83jA&Ra<8rM%`>U3x69t&NzbwWY}7Ar?)FK#IZ0z|d0H0EkRO w3{9;}4Xg|ebq&m|3=9_N6z8I7$jwj5OsmAL;bP(Gi$Dzwp00i_>zopr02+f8CIA2c literal 0 HcmV?d00001 diff --git a/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_512.png b/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_512.png new file mode 100644 index 0000000000000000000000000000000000000000..e71a726136a47ed24125c7efc79d68a4a01961b4 GIT binary patch literal 14800 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 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/macos/Runner/Configs/AppInfo.xcconfig b/macos/Runner/Configs/AppInfo.xcconfig new file mode 100644 index 0000000..255aa3a --- /dev/null +++ b/macos/Runner/Configs/AppInfo.xcconfig @@ -0,0 +1,14 @@ +// Application-level settings for the Runner target. +// +// This may be replaced with something auto-generated from metadata (e.g., pubspec.yaml) in the +// future. If not, the values below would default to using the project name when this becomes a +// 'flutter create' template. + +// The application's name. By default this is also the title of the Flutter window. +PRODUCT_NAME = flutter_catalog + +// The application's bundle identifier +PRODUCT_BUNDLE_IDENTIFIER = com.example.flutterCatalog + +// The copyright displayed in application information +PRODUCT_COPYRIGHT = Copyright © 2021 com.example. All rights reserved. diff --git a/macos/Runner/Configs/Debug.xcconfig b/macos/Runner/Configs/Debug.xcconfig new file mode 100644 index 0000000..36b0fd9 --- /dev/null +++ b/macos/Runner/Configs/Debug.xcconfig @@ -0,0 +1,2 @@ +#include "../../Flutter/Flutter-Debug.xcconfig" +#include "Warnings.xcconfig" diff --git a/macos/Runner/Configs/Release.xcconfig b/macos/Runner/Configs/Release.xcconfig new file mode 100644 index 0000000..dff4f49 --- /dev/null +++ b/macos/Runner/Configs/Release.xcconfig @@ -0,0 +1,2 @@ +#include "../../Flutter/Flutter-Release.xcconfig" +#include "Warnings.xcconfig" diff --git a/macos/Runner/Configs/Warnings.xcconfig b/macos/Runner/Configs/Warnings.xcconfig new file mode 100644 index 0000000..42bcbf4 --- /dev/null +++ b/macos/Runner/Configs/Warnings.xcconfig @@ -0,0 +1,13 @@ +WARNING_CFLAGS = -Wall -Wconditional-uninitialized -Wnullable-to-nonnull-conversion -Wmissing-method-return-type -Woverlength-strings +GCC_WARN_UNDECLARED_SELECTOR = YES +CLANG_UNDEFINED_BEHAVIOR_SANITIZER_NULLABILITY = YES +CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE +CLANG_WARN__DUPLICATE_METHOD_MATCH = YES +CLANG_WARN_PRAGMA_PACK = YES +CLANG_WARN_STRICT_PROTOTYPES = YES +CLANG_WARN_COMMA = YES +GCC_WARN_STRICT_SELECTOR_MATCH = YES +CLANG_WARN_OBJC_REPEATED_USE_OF_WEAK = YES +CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES +GCC_WARN_SHADOW = YES +CLANG_WARN_UNREACHABLE_CODE = YES diff --git a/macos/Runner/DebugProfile.entitlements b/macos/Runner/DebugProfile.entitlements new file mode 100644 index 0000000..3ba6c12 --- /dev/null +++ b/macos/Runner/DebugProfile.entitlements @@ -0,0 +1,14 @@ + + + + + com.apple.security.app-sandbox + + com.apple.security.cs.allow-jit + + com.apple.security.network.client + + com.apple.security.network.server + + + diff --git a/macos/Runner/Info.plist b/macos/Runner/Info.plist new file mode 100644 index 0000000..4789daa --- /dev/null +++ b/macos/Runner/Info.plist @@ -0,0 +1,32 @@ + + + + + CFBundleDevelopmentRegion + $(DEVELOPMENT_LANGUAGE) + CFBundleExecutable + $(EXECUTABLE_NAME) + CFBundleIconFile + + CFBundleIdentifier + $(PRODUCT_BUNDLE_IDENTIFIER) + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + $(PRODUCT_NAME) + CFBundlePackageType + APPL + CFBundleShortVersionString + $(FLUTTER_BUILD_NAME) + CFBundleVersion + $(FLUTTER_BUILD_NUMBER) + LSMinimumSystemVersion + $(MACOSX_DEPLOYMENT_TARGET) + NSHumanReadableCopyright + $(PRODUCT_COPYRIGHT) + NSMainNibFile + MainMenu + NSPrincipalClass + NSApplication + + diff --git a/macos/Runner/MainFlutterWindow.swift b/macos/Runner/MainFlutterWindow.swift new file mode 100644 index 0000000..2722837 --- /dev/null +++ b/macos/Runner/MainFlutterWindow.swift @@ -0,0 +1,15 @@ +import Cocoa +import FlutterMacOS + +class MainFlutterWindow: NSWindow { + override func awakeFromNib() { + let flutterViewController = FlutterViewController.init() + let windowFrame = self.frame + self.contentViewController = flutterViewController + self.setFrame(windowFrame, display: true) + + RegisterGeneratedPlugins(registry: flutterViewController) + + super.awakeFromNib() + } +} diff --git a/macos/Runner/Release.entitlements b/macos/Runner/Release.entitlements new file mode 100644 index 0000000..7a2230d --- /dev/null +++ b/macos/Runner/Release.entitlements @@ -0,0 +1,12 @@ + + + + + com.apple.security.app-sandbox + + com.apple.security.network.client + + com.apple.security.network.server + + + diff --git a/web/favicon.png b/web/favicon.png new file mode 100644 index 0000000000000000000000000000000000000000..8aaa46ac1ae21512746f852a42ba87e4165dfdd1 GIT binary patch literal 917 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61|;P_|4#%`jKx9jP7LeL$-D$|I14-?iy0X7 zltGxWVyS%@P(fs7NJL45ua8x7ey(0(N`6wRUPW#JP&EUCO@$SZnVVXYs8ErclUHn2 zVXFjIVFhG^g!Ppaz)DK8ZIvQ?0~DO|i&7O#^-S~(l1AfjnEK zjFOT9D}DX)@^Za$W4-*MbbUihOG|wNBYh(yU7!lx;>x^|#0uTKVr7USFmqf|i<65o z3raHc^AtelCMM;Vme?vOfh>Xph&xL%(-1c06+^uR^q@XSM&D4+Kp$>4P^%3{)XKjo zGZknv$b36P8?Z_gF{nK@`XI}Z90TzwSQO}0J1!f2c(B=V`5aP@1P1a|PZ!4!3&Gl8 zTYqUsf!gYFyJnXpu0!n&N*SYAX-%d(5gVjrHJWqXQshj@!Zm{!01WsQrH~9=kTxW#6SvuapgMqt>$=j#%eyGrQzr zP{L-3gsMA^$I1&gsBAEL+vxi1*Igl=8#8`5?A-T5=z-sk46WA1IUT)AIZHx1rdUrf zVJrJn<74DDw`j)Ki#gt}mIT-Q`XRa2-jQXQoI%w`nb|XblvzK${ZzlV)m-XcwC(od z71_OEC5Bt9GEXosOXaPTYOia#R4ID2TiU~`zVMl08TV_C%DnU4^+HE>9(CE4D6?Fz oujB08i7adh9xk7*FX66dWH6F5TM;?E2b5PlUHx3vIVCg!0Dx9vYXATM literal 0 HcmV?d00001 diff --git a/web/icons/Icon-192.png b/web/icons/Icon-192.png new file mode 100644 index 0000000000000000000000000000000000000000..b749bfef07473333cf1dd31e9eed89862a5d52aa GIT binary patch literal 5292 zcmZ`-2T+sGz6~)*FVZ`aW+(v>MIm&M-g^@e2u-B-DoB?qO+b1Tq<5uCCv>ESfRum& zp%X;f!~1{tzL__3=gjVJ=j=J>+nMj%ncXj1Q(b|Ckbw{Y0FWpt%4y%$uD=Z*c-x~o zE;IoE;xa#7Ll5nj-e4CuXB&G*IM~D21rCP$*xLXAK8rIMCSHuSu%bL&S3)8YI~vyp@KBu9Ph7R_pvKQ@xv>NQ`dZp(u{Z8K3yOB zn7-AR+d2JkW)KiGx0hosml;+eCXp6+w%@STjFY*CJ?udJ64&{BCbuebcuH;}(($@@ znNlgBA@ZXB)mcl9nbX#F!f_5Z=W>0kh|UVWnf!At4V*LQP%*gPdCXd6P@J4Td;!Ur z<2ZLmwr(NG`u#gDEMP19UcSzRTL@HsK+PnIXbVBT@oHm53DZr?~V(0{rsalAfwgo zEh=GviaqkF;}F_5-yA!1u3!gxaR&Mj)hLuj5Q-N-@Lra{%<4ONja8pycD90&>yMB` zchhd>0CsH`^|&TstH-8+R`CfoWqmTTF_0?zDOY`E`b)cVi!$4xA@oO;SyOjJyP^_j zx^@Gdf+w|FW@DMdOi8=4+LJl$#@R&&=UM`)G!y%6ZzQLoSL%*KE8IO0~&5XYR9 z&N)?goEiWA(YoRfT{06&D6Yuu@Qt&XVbuW@COb;>SP9~aRc+z`m`80pB2o%`#{xD@ zI3RAlukL5L>px6b?QW1Ac_0>ew%NM!XB2(H+1Y3AJC?C?O`GGs`331Nd4ZvG~bMo{lh~GeL zSL|tT*fF-HXxXYtfu5z+T5Mx9OdP7J4g%@oeC2FaWO1D{=NvL|DNZ}GO?O3`+H*SI z=grGv=7dL{+oY0eJFGO!Qe(e2F?CHW(i!!XkGo2tUvsQ)I9ev`H&=;`N%Z{L zO?vV%rDv$y(@1Yj@xfr7Kzr<~0{^T8wM80xf7IGQF_S-2c0)0D6b0~yD7BsCy+(zL z#N~%&e4iAwi4F$&dI7x6cE|B{f@lY5epaDh=2-(4N05VO~A zQT3hanGy_&p+7Fb^I#ewGsjyCEUmSCaP6JDB*=_()FgQ(-pZ28-{qx~2foO4%pM9e z*_63RT8XjgiaWY|*xydf;8MKLd{HnfZ2kM%iq}fstImB-K6A79B~YoPVa@tYN@T_$ zea+9)<%?=Fl!kd(Y!G(-o}ko28hg2!MR-o5BEa_72uj7Mrc&{lRh3u2%Y=Xk9^-qa zBPWaD=2qcuJ&@Tf6ue&)4_V*45=zWk@Z}Q?f5)*z)-+E|-yC4fs5CE6L_PH3=zI8p z*Z3!it{1e5_^(sF*v=0{`U9C741&lub89gdhKp|Y8CeC{_{wYK-LSbp{h)b~9^j!s z7e?Y{Z3pZv0J)(VL=g>l;<}xk=T*O5YR|hg0eg4u98f2IrA-MY+StQIuK-(*J6TRR z|IM(%uI~?`wsfyO6Tgmsy1b3a)j6M&-jgUjVg+mP*oTKdHg?5E`!r`7AE_#?Fc)&a z08KCq>Gc=ne{PCbRvs6gVW|tKdcE1#7C4e`M|j$C5EYZ~Y=jUtc zj`+?p4ba3uy7><7wIokM79jPza``{Lx0)zGWg;FW1^NKY+GpEi=rHJ+fVRGfXO zPHV52k?jxei_!YYAw1HIz}y8ZMwdZqU%ESwMn7~t zdI5%B;U7RF=jzRz^NuY9nM)&<%M>x>0(e$GpU9th%rHiZsIT>_qp%V~ILlyt^V`=d z!1+DX@ah?RnB$X!0xpTA0}lN@9V-ePx>wQ?-xrJr^qDlw?#O(RsXeAvM%}rg0NT#t z!CsT;-vB=B87ShG`GwO;OEbeL;a}LIu=&@9cb~Rsx(ZPNQ!NT7H{@j0e(DiLea>QD zPmpe90gEKHEZ8oQ@6%E7k-Ptn#z)b9NbD@_GTxEhbS+}Bb74WUaRy{w;E|MgDAvHw zL)ycgM7mB?XVh^OzbC?LKFMotw3r@i&VdUV%^Efdib)3@soX%vWCbnOyt@Y4swW925@bt45y0HY3YI~BnnzZYrinFy;L?2D3BAL`UQ zEj))+f>H7~g8*VuWQ83EtGcx`hun$QvuurSMg3l4IP8Fe`#C|N6mbYJ=n;+}EQm;< z!!N=5j1aAr_uEnnzrEV%_E|JpTb#1p1*}5!Ce!R@d$EtMR~%9# zd;h8=QGT)KMW2IKu_fA_>p_und#-;Q)p%%l0XZOXQicfX8M~7?8}@U^ihu;mizj)t zgV7wk%n-UOb z#!P5q?Ex+*Kx@*p`o$q8FWL*E^$&1*!gpv?Za$YO~{BHeGY*5%4HXUKa_A~~^d z=E*gf6&+LFF^`j4$T~dR)%{I)T?>@Ma?D!gi9I^HqvjPc3-v~=qpX1Mne@*rzT&Xw zQ9DXsSV@PqpEJO-g4A&L{F&;K6W60D!_vs?Vx!?w27XbEuJJP&);)^+VF1nHqHBWu z^>kI$M9yfOY8~|hZ9WB!q-9u&mKhEcRjlf2nm_@s;0D#c|@ED7NZE% zzR;>P5B{o4fzlfsn3CkBK&`OSb-YNrqx@N#4CK!>bQ(V(D#9|l!e9(%sz~PYk@8zt zPN9oK78&-IL_F zhsk1$6p;GqFbtB^ZHHP+cjMvA0(LqlskbdYE_rda>gvQLTiqOQ1~*7lg%z*&p`Ry& zRcG^DbbPj_jOKHTr8uk^15Boj6>hA2S-QY(W-6!FIq8h$<>MI>PYYRenQDBamO#Fv zAH5&ImqKBDn0v5kb|8i0wFhUBJTpT!rB-`zK)^SNnRmLraZcPYK7b{I@+}wXVdW-{Ps17qdRA3JatEd?rPV z4@}(DAMf5EqXCr4-B+~H1P#;t@O}B)tIJ(W6$LrK&0plTmnPpb1TKn3?f?Kk``?D+ zQ!MFqOX7JbsXfQrz`-M@hq7xlfNz;_B{^wbpG8des56x(Q)H)5eLeDwCrVR}hzr~= zM{yXR6IM?kXxauLza#@#u?Y|o;904HCqF<8yT~~c-xyRc0-vxofnxG^(x%>bj5r}N zyFT+xnn-?B`ohA>{+ZZQem=*Xpqz{=j8i2TAC#x-m;;mo{{sLB_z(UoAqD=A#*juZ zCv=J~i*O8;F}A^Wf#+zx;~3B{57xtoxC&j^ie^?**T`WT2OPRtC`xj~+3Kprn=rVM zVJ|h5ux%S{dO}!mq93}P+h36mZ5aZg1-?vhL$ke1d52qIiXSE(llCr5i=QUS?LIjc zV$4q=-)aaR4wsrQv}^shL5u%6;`uiSEs<1nG^?$kl$^6DL z43CjY`M*p}ew}}3rXc7Xck@k41jx}c;NgEIhKZ*jsBRZUP-x2cm;F1<5$jefl|ppO zmZd%%?gMJ^g9=RZ^#8Mf5aWNVhjAS^|DQO+q$)oeob_&ZLFL(zur$)); zU19yRm)z<4&4-M}7!9+^Wl}Uk?`S$#V2%pQ*SIH5KI-mn%i;Z7-)m$mN9CnI$G7?# zo`zVrUwoSL&_dJ92YhX5TKqaRkfPgC4=Q&=K+;_aDs&OU0&{WFH}kKX6uNQC6%oUH z2DZa1s3%Vtk|bglbxep-w)PbFG!J17`<$g8lVhqD2w;Z0zGsh-r zxZ13G$G<48leNqR!DCVt9)@}(zMI5w6Wo=N zpP1*3DI;~h2WDWgcKn*f!+ORD)f$DZFwgKBafEZmeXQMAsq9sxP9A)7zOYnkHT9JU zRA`umgmP9d6=PHmFIgx=0$(sjb>+0CHG)K@cPG{IxaJ&Ueo8)0RWgV9+gO7+Bl1(F z7!BslJ2MP*PWJ;x)QXbR$6jEr5q3 z(3}F@YO_P1NyTdEXRLU6fp?9V2-S=E+YaeLL{Y)W%6`k7$(EW8EZSA*(+;e5@jgD^I zaJQ2|oCM1n!A&-8`;#RDcZyk*+RPkn_r8?Ak@agHiSp*qFNX)&i21HE?yuZ;-C<3C zwJGd1lx5UzViP7sZJ&|LqH*mryb}y|%AOw+v)yc`qM)03qyyrqhX?ub`Cjwx2PrR! z)_z>5*!*$x1=Qa-0uE7jy0z`>|Ni#X+uV|%_81F7)b+nf%iz=`fF4g5UfHS_?PHbr zB;0$bK@=di?f`dS(j{l3-tSCfp~zUuva+=EWxJcRfp(<$@vd(GigM&~vaYZ0c#BTs z3ijkxMl=vw5AS&DcXQ%eeKt!uKvh2l3W?&3=dBHU=Gz?O!40S&&~ei2vg**c$o;i89~6DVns zG>9a*`k5)NI9|?W!@9>rzJ;9EJ=YlJTx1r1BA?H`LWijk(rTax9(OAu;q4_wTj-yj z1%W4GW&K4T=uEGb+E!>W0SD_C0RR91 literal 0 HcmV?d00001 diff --git a/web/icons/Icon-512.png b/web/icons/Icon-512.png new file mode 100644 index 0000000000000000000000000000000000000000..88cfd48dff1169879ba46840804b412fe02fefd6 GIT binary patch literal 8252 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 literal 0 HcmV?d00001 diff --git a/web/index.html b/web/index.html new file mode 100644 index 0000000..17093da --- /dev/null +++ b/web/index.html @@ -0,0 +1,45 @@ + + + + + + + + + + + + + + + + + + + + flutter_catalog + + + + + + + + diff --git a/web/manifest.json b/web/manifest.json new file mode 100644 index 0000000..2b6b867 --- /dev/null +++ b/web/manifest.json @@ -0,0 +1,23 @@ +{ + "name": "flutter_catalog", + "short_name": "flutter_catalog", + "start_url": ".", + "display": "standalone", + "background_color": "#0175C2", + "theme_color": "#0175C2", + "description": "A new Flutter project.", + "orientation": "portrait-primary", + "prefer_related_applications": false, + "icons": [ + { + "src": "icons/Icon-192.png", + "sizes": "192x192", + "type": "image/png" + }, + { + "src": "icons/Icon-512.png", + "sizes": "512x512", + "type": "image/png" + } + ] +}