diff --git a/assets/files/catalog.json b/assets/files/catalog.json new file mode 100644 index 0000000..c52284b --- /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://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, + "name": "Pixel 5", + "desc": "Google Pixel phone 5th generation", + "price": 699, + "color": "#00ac51", + "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, + "name": "M1 Macbook Air", + "desc": "Apple Macbook air with apple silicon", + "price": 1099, + "color": "#e0bfae", + "image": "https://support.apple.com/library/APPLE/APPLECARE_ALLGEOS/SP825/macbookair.png" + }, + { + "id": 4, + "name": "Playstation 5", + "desc": "Sony Playstation 5th generation", + "price": 500, + "color": "#544ee4", + "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, + "name": "Airpods Pro", + "desc": "Apple Aipods Pro 1st generation", + "price": 200, + "color": "#e3e4e9", + "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, + "name": "iPad Pro", + "desc": "Apple iPad Pro 2020 edition", + "price": 799, + "color": "#f73984", + "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, + "name": "Galaxy S21 Ultra", + "desc": "Samsung Galaxy S21 Ultra 2021 edition", + "price": 1299, + "color": "#1c1c1c", + "image": "https://lh3.googleusercontent.com/qRQPjHrhRVIs-xnfNSyiPXOH2vH97ylMacgbTKebqJtRfNH3LlYo8pN-5igsLDWUH62tGl5zNpTsl5xd8SprzGmXoCEmWFOi2-2cQVGS-r3PaRXHt62DmJHq-jrYX0UQvWZ9BA=s800-c" + }, + { + "id": 8, + "name": "Galaxy S21", + "desc": "Samsung Galaxy S21 2021 edition", + "price": 899, + "color": "#7c95eb", + "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/assets/images/hey.png b/assets/images/hey.png new file mode 100644 index 0000000..caeca23 Binary files /dev/null and b/assets/images/hey.png differ diff --git a/assets/images/login_image.png b/assets/images/login_image.png new file mode 100644 index 0000000..b175b35 Binary files /dev/null and b/assets/images/login_image.png differ diff --git a/integration_test/app_test.dart b/integration_test/app_test.dart deleted file mode 100644 index bbf8055..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/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/ios/Podfile.lock b/ios/Podfile.lock index 97ee771..8fd4783 100644 --- a/ios/Podfile.lock +++ b/ios/Podfile.lock @@ -2,20 +2,26 @@ PODS: - Flutter (1.0.0) - integration_test (0.0.1): - Flutter + - path_provider (0.0.1): + - Flutter DEPENDENCIES: - Flutter (from `Flutter`) - integration_test (from `.symlinks/plugins/integration_test/ios`) + - path_provider (from `.symlinks/plugins/path_provider/ios`) EXTERNAL SOURCES: Flutter: :path: Flutter integration_test: :path: ".symlinks/plugins/integration_test/ios" + path_provider: + :path: ".symlinks/plugins/path_provider/ios" 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/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 dda5a28..9a34248 100644 --- a/lib/main.dart +++ b/lib/main.dart @@ -1,22 +1,31 @@ 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 { - 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"), - ), - ), - ), + themeMode: ThemeMode.system, + theme: MyTheme.lightTheme(context), + darkTheme: MyTheme.darkTheme(context), + debugShowCheckedModeBanner: false, + initialRoute: MyRoutes.homeRoute, + routes: { + "/": (context) => LoginPage(), + MyRoutes.homeRoute: (context) => HomePage(), + MyRoutes.loginRoute: (context) => LoginPage(), + MyRoutes.cartRoute: (context) => CartPage(), + }, ); } } diff --git a/lib/models/cart.dart b/lib/models/cart.dart new file mode 100644 index 0000000..61878c7 --- /dev/null +++ b/lib/models/cart.dart @@ -0,0 +1,46 @@ +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 + 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); +} + +class AddMutation extends VxMutation { + final Item item; + + AddMutation(this.item); + @override + perform() { + 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/models/catalog.dart b/lib/models/catalog.dart new file mode 100644 index 0000000..1b88d1e --- /dev/null +++ b/lib/models/catalog.dart @@ -0,0 +1,104 @@ +import 'dart:convert'; + +class CatalogModel { + static List items; + + // Get Item by ID + Item getById(int id) => + items.firstWhere((element) => element.id == id, orElse: null); + + // Get Item by position + Item getByPosition(int pos) => items[pos]; +} + +class Item { + final int 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, + }); + + 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/cart_page.dart b/lib/pages/cart_page.dart new file mode 100644 index 0000000..f29f32a --- /dev/null +++ b/lib/pages/cart_page.dart @@ -0,0 +1,82 @@ +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'; + +class CartPage extends StatelessWidget { + @override + Widget build(BuildContext context) { + return Scaffold( + backgroundColor: context.canvasColor, + appBar: AppBar( + backgroundColor: Colors.transparent, + title: "Cart".text.make(), + ), + body: Column( + children: [ + _CartList().p32().expand(), + Divider(), + _CartTotal(), + ], + ), + ); + } +} + +class _CartTotal extends StatelessWidget { + @override + Widget build(BuildContext context) { + final CartModel _cart = (VxState.store as MyStore).cart; + return SizedBox( + height: 200, + child: Row( + mainAxisAlignment: MainAxisAlignment.spaceAround, + children: [ + VxBuilder( + mutations: {RemoveMutation}, + builder: (context, _) { + return "\$${_cart.totalPrice}" + .text + .xl5 + .color(context.theme.accentColor) + .make(); + }, + ), + 30.widthBox, + ElevatedButton( + onPressed: () { + ScaffoldMessenger.of(context).showSnackBar(SnackBar( + content: "Buying not supported yet.".text.make(), + )); + }, + style: ButtonStyle( + backgroundColor: + MaterialStateProperty.all(context.theme.buttonColor)), + child: "Buy".text.white.make(), + ).w32(context) + ], + ), + ); + } +} + +class _CartList extends StatelessWidget { + @override + Widget build(BuildContext context) { + VxState.watch(context, on: [RemoveMutation]); + final CartModel _cart = (VxState.store as MyStore).cart; + 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: () => RemoveMutation(_cart.items[index]), + ), + title: _cart.items[index].name.text.make(), + ), + ); + } +} diff --git a/lib/pages/home_detail_page.dart b/lib/pages/home_detail_page.dart new file mode 100644 index 0000000..d85f39c --- /dev/null +++ b/lib/pages/home_detail_page.dart @@ -0,0 +1,68 @@ +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: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: Colors.transparent), + backgroundColor: context.canvasColor, + bottomNavigationBar: Container( + color: context.cardColor, + child: ButtonBar( + alignment: MainAxisAlignment.spaceBetween, + buttonPadding: EdgeInsets.zero, + children: [ + "\$${catalog.price}".text.bold.xl4.red800.make(), + AddToCart( + catalog: catalog, + ).wh(120, 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: context.cardColor, + width: context.screenWidth, + child: Column( + children: [ + catalog.name.text.xl4 + .color(context.accentColor) + .bold + .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 new file mode 100644 index 0000000..6336789 --- /dev/null +++ b/lib/pages/home_page.dart @@ -0,0 +1,85 @@ +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 '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 + _HomePageState createState() => _HomePageState(); +} + +class _HomePageState extends State { + final int days = 30; + + final String name = "Codepur"; + + final url = "https://api.jsonbin.io/b/604dbddb683e7e079c4eefd3"; + + @override + void initState() { + super.initState(); + loadData(); + } + + loadData() async { + await Future.delayed(Duration(seconds: 2)); + // 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) + .map((item) => Item.fromMap(item)) + .toList(); + setState(() {}); + } + + @override + Widget build(BuildContext context) { + final _cart = (VxState.store as MyStore).cart; + return Scaffold( + backgroundColor: context.canvasColor, + 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( + padding: Vx.m32, + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + CatalogHeader(), + if (CatalogModel.items != null && CatalogModel.items.isNotEmpty) + CatalogList().py16().expand() + else + CircularProgressIndicator().centered().expand(), + ], + ), + ), + )); + } +} diff --git a/lib/pages/login_page.dart b/lib/pages/login_page.dart new file mode 100644 index 0000000..5ce6d6f --- /dev/null +++ b/lib/pages/login_page.dart @@ -0,0 +1,130 @@ +import 'package:flutter/material.dart'; +import 'package:flutter_catalog/utils/routes.dart'; +import 'package:velocity_x/velocity_x.dart'; + +class LoginPage extends StatefulWidget { + @override + _LoginPageState createState() => _LoginPageState(); +} + +class _LoginPageState extends State { + 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: context.canvasColor, + child: SingleChildScrollView( + child: Form( + key: _formKey, + child: Column( + children: [ + Image.asset( + "assets/images/hey.png", + fit: BoxFit.cover, + ), + 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(() {}); + }, + ), + 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"; + } + + return null; + }, + ), + SizedBox( + height: 40.0, + ), + Material( + color: context.theme.buttonColor, + 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, + ) + : Text( + "Login", + style: TextStyle( + color: Colors.white, + fontWeight: FontWeight.bold, + fontSize: 18), + ), + ), + ), + ), + ], + ), + ) + ], + ), + ), + )); + } +} diff --git a/lib/utils/routes.dart b/lib/utils/routes.dart new file mode 100644 index 0000000..9832f8b --- /dev/null +++ b/lib/utils/routes.dart @@ -0,0 +1,6 @@ +class MyRoutes { + static String loginRoute = "/login"; + static String homeRoute = "/home"; + static String homeDetailsRoute = "/detail"; + static String cartRoute = "/cart"; +} 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, + ), + ), + ) + ], + ), + ), + ); + } +} 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..698a7fa --- /dev/null +++ b/lib/widgets/home_widgets/add_to_cart.dart @@ -0,0 +1,34 @@ +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'; + +class AddToCart extends StatelessWidget { + final Item catalog; + AddToCart({ + Key key, + this.catalog, + }) : super(key: key); + + @override + Widget build(BuildContext context) { + VxState.watch(context, on: [AddMutation, RemoveMutation]); + final CartModel _cart = (VxState.store as MyStore).cart; + bool isInCart = _cart.items.contains(catalog) ?? false; + return ElevatedButton( + onPressed: () { + if (!isInCart) { + AddMutation(catalog); + } + }, + 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_header.dart b/lib/widgets/home_widgets/catalog_header.dart new file mode 100644 index 0000000..49fdbb8 --- /dev/null +++ b/lib/widgets/home_widgets/catalog_header.dart @@ -0,0 +1,15 @@ +import 'package:flutter/material.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(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 new file mode 100644 index 0000000..04a4996 --- /dev/null +++ b/lib/widgets/home_widgets/catalog_image.dart @@ -0,0 +1,21 @@ +import 'package:flutter/material.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(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 new file mode 100644 index 0000000..de66bbf --- /dev/null +++ b/lib/widgets/home_widgets/catalog_list.dart @@ -0,0 +1,96 @@ +import 'package:flutter/material.dart'; +import 'package:flutter_catalog/models/catalog.dart'; +import 'package:flutter_catalog/pages/home_detail_page.dart'; +import 'package:velocity_x/velocity_x.dart'; + +import 'add_to_cart.dart'; +import 'catalog_image.dart'; + +class CatalogList extends StatelessWidget { + @override + Widget build(BuildContext context) { + 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), + ); + }, + ); + } +} + +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) { + 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: context.isMobile + ? Row( + children: children2, + ) + : Column( + children: children2, + ), + ).color(context.cardColor).rounded.square(150).make().py16(); + } +} 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, + ), + ), + ), + ); + } +} diff --git a/lib/widgets/themes.dart b/lib/widgets/themes.dart new file mode 100644 index 0000000..e6d3ed2 --- /dev/null +++ b/lib/widgets/themes.dart @@ -0,0 +1,42 @@ +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, + iconTheme: IconThemeData(color: Colors.black), + textTheme: Theme.of(context).textTheme, + )); + + static ThemeData darkTheme(BuildContext context) => ThemeData( + 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.copyWith( + headline6: + context.textTheme.headline6.copyWith(color: Colors.white), + ), + )); + + //Colors + static Color creamColor = Color(0xfff5f5f5); + static Color darkCreamColor = Vx.gray900; + static Color darkBluishColor = Color(0xff403b58); + static Color lightBluishColor = Vx.indigo500; +} 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 0000000..3c4935a Binary files /dev/null and b/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_1024.png differ 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 0000000..ed4cc16 Binary files /dev/null and b/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_128.png differ diff --git a/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_16.png b/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_16.png new file mode 100644 index 0000000..483be61 Binary files /dev/null and b/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_16.png differ 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 0000000..bcbf36d Binary files /dev/null and b/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_256.png differ diff --git a/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_32.png b/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_32.png new file mode 100644 index 0000000..9c0a652 Binary files /dev/null and b/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_32.png differ 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 0000000..e71a726 Binary files /dev/null and b/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_512.png differ diff --git a/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_64.png b/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_64.png new file mode 100644 index 0000000..8a31fe2 Binary files /dev/null and b/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_64.png differ diff --git a/macos/Runner/Base.lproj/MainMenu.xib b/macos/Runner/Base.lproj/MainMenu.xib new file mode 100644 index 0000000..537341a --- /dev/null +++ b/macos/Runner/Base.lproj/MainMenu.xib @@ -0,0 +1,339 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 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/pubspec.lock b/pubspec.lock index 62bef60..8b52e96 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -1,104 +1,69 @@ # Generated by pub # See https://dart.dev/tools/pub/glossary#lockfile packages: - _fe_analyzer_shared: + animator: dependency: transitive description: - name: _fe_analyzer_shared + name: animator 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: - name: archive - url: "https://pub.dartlang.org" - source: hosted - version: "2.0.13" - args: + version: "3.0.0" + async: dependency: transitive description: - name: args + name: async url: "https://pub.dartlang.org" source: hosted - version: "1.6.0" - async: + version: "2.5.0" + auto_size_text_pk: dependency: transitive description: - name: async + name: auto_size_text_pk url: "https://pub.dartlang.org" source: hosted - version: "2.5.0-nullsafety.3" + version: "3.0.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" - convert: - dependency: transitive - description: - name: convert - 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" + version: "1.15.0" 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: @@ -112,274 +77,239 @@ 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: + name: ffi + url: "https://pub.dartlang.org" + source: hosted + version: "1.0.0" file: dependency: transitive description: 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 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" - glob: - dependency: transitive + google_fonts: + dependency: "direct main" description: - name: glob + name: google_fonts url: "https://pub.dartlang.org" source: hosted - version: "1.2.0" - integration_test: - dependency: "direct dev" - description: flutter - source: sdk - version: "0.9.2+2" - io: + version: "2.0.0" + http: + dependency: "direct main" + description: + name: http + url: "https://pub.dartlang.org" + source: hosted + version: "0.13.0" + http_parser: dependency: transitive description: - name: io + name: http_parser url: "https://pub.dartlang.org" source: hosted - version: "0.3.4" - js: + version: "4.0.0" + intl: dependency: transitive description: - name: js + name: intl url: "https://pub.dartlang.org" source: hosted - version: "0.6.3-nullsafety.3" - json_rpc_2: + version: "0.17.0" + matcher: dependency: transitive description: - name: json_rpc_2 + name: matcher url: "https://pub.dartlang.org" source: hosted - version: "2.2.2" - logging: + version: "0.12.10" + meta: dependency: transitive description: - name: logging + name: meta url: "https://pub.dartlang.org" source: hosted - version: "0.11.4" - matcher: + version: "1.3.0" + path: dependency: transitive description: - name: matcher + name: path url: "https://pub.dartlang.org" source: hosted - version: "0.12.10-nullsafety.3" - meta: + version: "1.8.0" + path_provider: dependency: transitive description: - name: meta + name: path_provider url: "https://pub.dartlang.org" source: hosted - version: "1.3.0-nullsafety.6" - node_interop: + version: "2.0.1" + path_provider_linux: dependency: transitive description: - name: node_interop + name: path_provider_linux url: "https://pub.dartlang.org" source: hosted - version: "1.2.1" - node_io: + version: "2.0.0" + path_provider_macos: dependency: transitive description: - name: node_io + name: path_provider_macos url: "https://pub.dartlang.org" source: hosted - version: "1.1.1" - package_config: + version: "2.0.0" + path_provider_platform_interface: dependency: transitive description: - name: package_config + name: path_provider_platform_interface url: "https://pub.dartlang.org" source: hosted - version: "1.9.3" - path: + version: "2.0.1" + path_provider_windows: dependency: transitive description: - name: path + name: path_provider_windows url: "https://pub.dartlang.org" source: hosted - version: "1.8.0-nullsafety.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: name: platform url: "https://pub.dartlang.org" source: hosted - version: "3.0.0-nullsafety.4" - pool: + version: "3.0.0" + plugin_platform_interface: dependency: transitive description: - name: pool + name: plugin_platform_interface url: "https://pub.dartlang.org" source: hosted - version: "1.5.0-nullsafety.3" + version: "2.0.0" 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" - stream_channel: + version: "1.10.0" + states_rebuilder: dependency: transitive description: - name: stream_channel + name: states_rebuilder url: "https://pub.dartlang.org" source: hosted - version: "2.1.0-nullsafety.3" - string_scanner: + version: "4.0.0+1" + stream_channel: dependency: transitive description: - name: string_scanner + name: stream_channel url: "https://pub.dartlang.org" source: hosted - version: "1.1.0-nullsafety.3" - sync_http: + version: "2.1.0" + string_scanner: dependency: transitive description: - name: sync_http + name: string_scanner url: "https://pub.dartlang.org" source: hosted - version: "0.2.0" + version: "1.1.0" term_glyph: dependency: transitive description: 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" - vm_service: - dependency: transitive - description: - name: vm_service - url: "https://pub.dartlang.org" - source: hosted - version: "5.5.0" - watcher: - dependency: transitive + version: "2.1.0" + velocity_x: + dependency: "direct main" description: - name: watcher + name: velocity_x url: "https://pub.dartlang.org" source: hosted - version: "0.9.7+15" - web_socket_channel: + version: "2.5.0" + vxstate: dependency: transitive description: - name: web_socket_channel + name: vxstate url: "https://pub.dartlang.org" source: hosted - version: "1.1.0" - webdriver: + version: "2.0.1" + win32: dependency: transitive description: - name: webdriver + name: win32 url: "https://pub.dartlang.org" source: hosted - version: "2.1.2" - yaml: + version: "2.0.4" + xdg_directories: dependency: transitive description: - name: yaml + name: xdg_directories url: "https://pub.dartlang.org" source: hosted - version: "2.2.1" + version: "0.2.0" sdks: - dart: ">=2.12.0-0.0 <3.0.0" + dart: ">=2.12.0 <3.0.0" + flutter: ">=2.0.0" diff --git a/pubspec.yaml b/pubspec.yaml index 8efae22..727860d 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -23,20 +23,19 @@ 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: ^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 - # The following section is specific to Flutter. flutter: # The following line ensures that the Material Icons font is @@ -45,16 +44,14 @@ 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/ + - 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 diff --git a/web/favicon.png b/web/favicon.png new file mode 100644 index 0000000..8aaa46a Binary files /dev/null and b/web/favicon.png differ diff --git a/web/icons/Icon-192.png b/web/icons/Icon-192.png new file mode 100644 index 0000000..b749bfe Binary files /dev/null and b/web/icons/Icon-192.png differ diff --git a/web/icons/Icon-512.png b/web/icons/Icon-512.png new file mode 100644 index 0000000..88cfd48 Binary files /dev/null and b/web/icons/Icon-512.png differ 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" + } + ] +}