diff --git a/MAINTENANCE.md b/MAINTENANCE.md index 722ed96c8..21a2ec334 100644 --- a/MAINTENANCE.md +++ b/MAINTENANCE.md @@ -17,6 +17,6 @@ match any new language/SDK features, etc.). | platform_design | johnpryan | 10/7/19 | | platform_view_swift | redbrogdon | 10/7/19 | | provider_counter | filiph | 8/13/20 | -| provider_shopper | redbrogdon | 11/21/19 | +| provider_shopper | filiph | 8/13/20 | | testing_app | | | | veggieseasons | filiph | 8/13/20 | diff --git a/provider_shopper/ios/Runner.xcodeproj/project.pbxproj b/provider_shopper/ios/Runner.xcodeproj/project.pbxproj index 21329ea3e..e5cfe4715 100644 --- a/provider_shopper/ios/Runner.xcodeproj/project.pbxproj +++ b/provider_shopper/ios/Runner.xcodeproj/project.pbxproj @@ -9,11 +9,7 @@ /* Begin PBXBuildFile section */ 1498D2341E8E89220040F4C2 /* GeneratedPluginRegistrant.m in Sources */ = {isa = PBXBuildFile; fileRef = 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */; }; 3B3967161E833CAA004F5970 /* AppFrameworkInfo.plist in Resources */ = {isa = PBXBuildFile; fileRef = 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */; }; - 3B80C3941E831B6300D905FE /* App.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 3B80C3931E831B6300D905FE /* App.framework */; }; - 3B80C3951E831B6300D905FE /* App.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 3B80C3931E831B6300D905FE /* App.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; 74858FAF1ED2DC5600515810 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 74858FAE1ED2DC5600515810 /* AppDelegate.swift */; }; - 9705A1C61CF904A100538489 /* Flutter.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 9740EEBA1CF902C7004384FC /* Flutter.framework */; }; - 9705A1C71CF904A300538489 /* Flutter.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 9740EEBA1CF902C7004384FC /* Flutter.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; 97C146FC1CF9000F007C117D /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FA1CF9000F007C117D /* Main.storyboard */; }; 97C146FE1CF9000F007C117D /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FD1CF9000F007C117D /* Assets.xcassets */; }; 97C147011CF9000F007C117D /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */; }; @@ -26,8 +22,6 @@ dstPath = ""; dstSubfolderSpec = 10; files = ( - 3B80C3951E831B6300D905FE /* App.framework in Embed Frameworks */, - 9705A1C71CF904A300538489 /* Flutter.framework in Embed Frameworks */, ); name = "Embed Frameworks"; runOnlyForDeploymentPostprocessing = 0; @@ -38,13 +32,11 @@ 1498D2321E8E86230040F4C2 /* GeneratedPluginRegistrant.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = GeneratedPluginRegistrant.h; sourceTree = ""; }; 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GeneratedPluginRegistrant.m; sourceTree = ""; }; 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = AppFrameworkInfo.plist; path = Flutter/AppFrameworkInfo.plist; sourceTree = ""; }; - 3B80C3931E831B6300D905FE /* App.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = App.framework; path = Flutter/App.framework; sourceTree = ""; }; 74858FAD1ED2DC5600515810 /* Runner-Bridging-Header.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "Runner-Bridging-Header.h"; sourceTree = ""; }; 74858FAE1ED2DC5600515810 /* AppDelegate.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = ""; }; 7AFA3C8E1D35360C0083082E /* Release.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; name = Release.xcconfig; path = Flutter/Release.xcconfig; sourceTree = ""; }; 9740EEB21CF90195004384FC /* Debug.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; name = Debug.xcconfig; path = Flutter/Debug.xcconfig; sourceTree = ""; }; 9740EEB31CF90195004384FC /* Generated.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; name = Generated.xcconfig; path = Flutter/Generated.xcconfig; sourceTree = ""; }; - 9740EEBA1CF902C7004384FC /* Flutter.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Flutter.framework; path = Flutter/Flutter.framework; sourceTree = ""; }; 97C146EE1CF9000F007C117D /* Runner.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = Runner.app; sourceTree = BUILT_PRODUCTS_DIR; }; 97C146FB1CF9000F007C117D /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = ""; }; 97C146FD1CF9000F007C117D /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; @@ -57,8 +49,6 @@ isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( - 9705A1C61CF904A100538489 /* Flutter.framework in Frameworks */, - 3B80C3941E831B6300D905FE /* App.framework in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -68,9 +58,7 @@ 9740EEB11CF90186004384FC /* Flutter */ = { isa = PBXGroup; children = ( - 3B80C3931E831B6300D905FE /* App.framework */, 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */, - 9740EEBA1CF902C7004384FC /* Flutter.framework */, 9740EEB21CF90195004384FC /* Debug.xcconfig */, 7AFA3C8E1D35360C0083082E /* Release.xcconfig */, 9740EEB31CF90195004384FC /* Generated.xcconfig */, @@ -201,7 +189,7 @@ ); runOnlyForDeploymentPostprocessing = 0; shellPath = /bin/sh; - shellScript = "/bin/sh \"$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh\" thin"; + shellScript = "/bin/sh \"$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh\" embed_and_thin"; }; 9740EEB61CF901F6004384FC /* Run Script */ = { isa = PBXShellScriptBuildPhase; diff --git a/provider_shopper/lib/screens/cart.dart b/provider_shopper/lib/screens/cart.dart index 9dd95da2c..55bdaa241 100644 --- a/provider_shopper/lib/screens/cart.dart +++ b/provider_shopper/lib/screens/cart.dart @@ -37,7 +37,10 @@ class _CartList extends StatelessWidget { @override Widget build(BuildContext context) { var itemNameStyle = Theme.of(context).textTheme.headline6; - var cart = Provider.of(context); + // This gets the current state of CartModel and also tells Flutter + // to rebuild this widget when CartModel notifies listeners (in other words, + // when it changes). + var cart = context.watch(); return ListView.builder( itemCount: cart.items.length, @@ -64,6 +67,12 @@ class _CartTotal extends StatelessWidget { child: Row( mainAxisAlignment: MainAxisAlignment.center, children: [ + // Another way to listen to a model's change is to include + // the Consumer widget. This widget will automatically listen + // to CartModel and rerun its builder on every change. + // + // The important thing is that it will not rebuild + // the rest of the widgets in this build method. Consumer( builder: (context, cart, child) => Text('\$${cart.totalPrice}', style: hugeStyle)), diff --git a/provider_shopper/lib/screens/catalog.dart b/provider_shopper/lib/screens/catalog.dart index 31c1cb98a..3f4376a7e 100644 --- a/provider_shopper/lib/screens/catalog.dart +++ b/provider_shopper/lib/screens/catalog.dart @@ -32,14 +32,30 @@ class _AddButton extends StatelessWidget { @override Widget build(BuildContext context) { - var cart = Provider.of(context); + // The context.select() method will let you listen to changes to + // a *part* of a model. You define a function that "selects" (i.e. returns) + // the part you're interested in, and the provider package will not rebuild + // this widget unless that particular part of the model changes. + // + // This can lead to significant performance improvements. + var isInCart = context.select( + // Here, we are only interested whether [item] is inside the cart. + (cart) => cart.items.contains(item), + ); return FlatButton( - onPressed: cart.items.contains(item) ? null : () => cart.add(item), + onPressed: isInCart + ? null + : () { + // If the item is not in cart, we let the user add it. + // We are using context.read() here because the callback + // is executed whenever the user taps the the button. In other + // words, it is executed outside the build method. + var cart = context.read(); + cart.add(item); + }, splashColor: Theme.of(context).primaryColor, - child: cart.items.contains(item) - ? Icon(Icons.check, semanticLabel: 'ADDED') - : Text('ADD'), + child: isInCart ? Icon(Icons.check, semanticLabel: 'ADDED') : Text('ADD'), ); } } @@ -67,8 +83,11 @@ class _MyListItem extends StatelessWidget { @override Widget build(BuildContext context) { - var catalog = Provider.of(context); - var item = catalog.getByPosition(index); + var item = context.select( + // Here, we are only interested in the item at [index]. We don't care + // about any other change. + (catalog) => catalog.getByPosition(index), + ); var textTheme = Theme.of(context).textTheme.headline6; return Padding( diff --git a/provider_shopper/pubspec.lock b/provider_shopper/pubspec.lock index 0cf80ea1f..72d93cb5d 100644 --- a/provider_shopper/pubspec.lock +++ b/provider_shopper/pubspec.lock @@ -1,13 +1,27 @@ # Generated by pub # See https://dart.dev/tools/pub/glossary#lockfile packages: + 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" async: dependency: transitive description: name: async url: "https://pub.dartlang.org" source: hosted - version: "2.4.2" + version: "2.4.1" boolean_selector: dependency: transitive description: @@ -15,13 +29,6 @@ packages: url: "https://pub.dartlang.org" source: hosted version: "2.0.0" - characters: - dependency: transitive - description: - name: characters - url: "https://pub.dartlang.org" - source: hosted - version: "1.0.0" charcode: dependency: transitive description: @@ -29,27 +36,27 @@ packages: url: "https://pub.dartlang.org" source: hosted version: "1.1.3" - clock: + collection: dependency: transitive description: - name: clock + name: collection url: "https://pub.dartlang.org" source: hosted - version: "1.0.1" - collection: + version: "1.14.12" + convert: dependency: transitive description: - name: collection + name: convert url: "https://pub.dartlang.org" source: hosted - version: "1.14.13" - fake_async: + version: "2.1.1" + crypto: dependency: transitive description: - name: fake_async + name: crypto url: "https://pub.dartlang.org" source: hosted - version: "1.1.0" + version: "2.1.4" flutter: dependency: "direct main" description: flutter @@ -60,13 +67,20 @@ packages: description: flutter source: sdk version: "0.0.0" + image: + dependency: transitive + description: + name: image + url: "https://pub.dartlang.org" + source: hosted + version: "2.1.12" matcher: dependency: transitive description: name: matcher url: "https://pub.dartlang.org" source: hosted - version: "0.12.8" + version: "0.12.6" meta: dependency: transitive description: @@ -87,7 +101,7 @@ packages: name: path url: "https://pub.dartlang.org" source: hosted - version: "1.7.0" + version: "1.6.4" pedantic: dependency: "direct dev" description: @@ -95,13 +109,27 @@ packages: url: "https://pub.dartlang.org" source: hosted version: "1.9.0" + petitparser: + dependency: transitive + description: + name: petitparser + url: "https://pub.dartlang.org" + source: hosted + version: "2.4.0" provider: dependency: "direct main" description: name: provider url: "https://pub.dartlang.org" source: hosted - version: "4.1.0" + version: "4.3.2" + quiver: + dependency: transitive + description: + name: quiver + url: "https://pub.dartlang.org" + source: hosted + version: "2.1.3" sky_engine: dependency: transitive description: flutter @@ -120,7 +148,7 @@ packages: name: stack_trace url: "https://pub.dartlang.org" source: hosted - version: "1.9.5" + version: "1.9.3" stream_channel: dependency: transitive description: @@ -148,14 +176,14 @@ packages: name: test_api url: "https://pub.dartlang.org" source: hosted - version: "0.2.17" + version: "0.2.15" typed_data: dependency: transitive description: name: typed_data url: "https://pub.dartlang.org" source: hosted - version: "1.2.0" + version: "1.1.6" vector_math: dependency: transitive description: @@ -163,6 +191,13 @@ packages: url: "https://pub.dartlang.org" source: hosted version: "2.0.8" + xml: + dependency: transitive + description: + name: xml + url: "https://pub.dartlang.org" + source: hosted + version: "3.6.1" sdks: - dart: ">=2.9.0-14.0.dev <3.0.0" - flutter: ">=1.17.0" + dart: ">=2.7.0 <3.0.0" + flutter: ">=1.16.0" diff --git a/provider_shopper/pubspec.yaml b/provider_shopper/pubspec.yaml index 47716d07a..913345ea1 100644 --- a/provider_shopper/pubspec.yaml +++ b/provider_shopper/pubspec.yaml @@ -11,7 +11,7 @@ dependencies: sdk: flutter # Import the provider package. - provider: ^4.0.2 + provider: ^4.3.2 dev_dependencies: flutter_test: