Retire VeggieSeasons (really this time) (#2724)

Removes VeggieSeaons 

## Pre-launch Checklist

- [x] I read the [Flutter Style Guide] _recently_, and have followed its
advice.
- [x] I signed the [CLA].
- [x] I read the [Contributors Guide].
- [x] I have added sample code updates to the [changelog].
- [x] I updated/added relevant documentation (doc comments with `///`).

---------

Co-authored-by: Loïc Sharma <737941+loic-sharma@users.noreply.github.com>
main
Eric Windmill 2 weeks ago committed by GitHub
parent 0b9ad5b568
commit d5184b5647
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194

@ -25,7 +25,7 @@ jobs:
fail-fast: false
matrix:
flutter_version: [stable, beta]
os: [ubuntu-latest, macos-latest, windows-latest]
os: [ubuntu-latest, macos-latest]
steps:
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683
- uses: actions/setup-java@dded0888837ed1f317902acf8a20df0ad188d165

@ -3,34 +3,3 @@
The `experimental` directory has been deprecated. All samples within have been deleted or moved to [github.com/flutter/demos][]
---
# Master channel samples
In this directory, you'll find samples that target Flutter's master channel.
They may take advantage of new SDK features that haven't landed in the
stable channel, and they may crash, lock up your machine, or otherwise fail to
run correctly. In other words, consider everything in this directory to be an
experiment.
We're maintaining these samples here so that folks can see some of Flutter's
upcoming features as they evolve and get a sense for how they'll eventually
be used. If you'd like to run the apps, make sure to switch to the master
channel first:
```bash
flutter channel master
flutter upgrade
```
When you're done, use this command to return to the safety of the stable
channel:
```bash
flutter channel stable
```
## Want more info about the repo in general?
See the [README](../README.md) in the repo's root folder.

@ -0,0 +1,3 @@
# Sample deprecated
The `flutter_maps_firestore` sample has been deprecated.

@ -12,7 +12,7 @@ dependencies:
flutter:
sdk: flutter
cupertino_icons: ^1.0.2
meta: 1.16.0
meta: ^1.16.0
provider: ^6.0.2
window_size:
git:

@ -46,6 +46,5 @@ workspace:
- simplistic_editor
- testing_app
- tool
- veggieseasons
- web_embedding/element_embedding_demo
- web_embedding/ng-flutter/flutter

@ -1,45 +0,0 @@
# This app is designed to show how to use Flutter's cupertino package to build UI for iOS. It's not intended to run on Android, desktop, or web.
android
# Miscellaneous
*.class
*.log
*.pyc
*.swp
.DS_Store
.atom/
.buildlog/
.history
.svn/
# IntelliJ related
*.iml
*.ipr
*.iws
.idea/
# Visual Studio Code related
.vscode/
# Flutter/Dart/Pub related
**/doc/api/
**/ios/Flutter/.last_build_id
.dart_tool/
.flutter-plugins
.flutter-plugins-dependencies
.packages
.pub-cache/
.pub/
/build/
# Web related
lib/generated_plugin_registrant.dart
# Symbolication related
app.*.symbols
# Obfuscation related
app.*.map.json
# Exceptions to above rules.
!/packages/flutter_tools/test/data/dart_dependencies_test/**/.packages

@ -1,33 +0,0 @@
# This file tracks properties of this Flutter project.
# Used by Flutter tool to assess capabilities and perform upgrades etc.
#
# This file should be version controlled and should not be manually edited.
version:
revision: "5874a72aa4c779a02553007c47dacbefba2374dc"
channel: "stable"
project_type: app
# Tracks metadata for the flutter migrate command
migration:
platforms:
- platform: root
create_revision: 5874a72aa4c779a02553007c47dacbefba2374dc
base_revision: 5874a72aa4c779a02553007c47dacbefba2374dc
- platform: ios
create_revision: 5874a72aa4c779a02553007c47dacbefba2374dc
base_revision: 5874a72aa4c779a02553007c47dacbefba2374dc
- platform: macos
create_revision: 5874a72aa4c779a02553007c47dacbefba2374dc
base_revision: 5874a72aa4c779a02553007c47dacbefba2374dc
# User provided section
# List of Local paths (relative to this file) that should be
# ignored by the migrate tool.
#
# Files that are not part of the templates will be ignored by default.
unmanaged_files:
- 'lib/main.dart'
- 'ios/Runner.xcodeproj/project.pbxproj'

@ -1,33 +1,3 @@
# Veggie Seasons
# Sample deprecated
An iOS sample app that shows which fruits and vegetables are currently in season. It
showcases Flutter's Cupertino package.
**NOTE:** While Flutter supports many platforms, this application is designed
specifically for iOS. It's not intended to be run on Android, web, or desktop.
## Goals
* Show how to build an interface that iOS users will feel right at home
with.
* Show how Flutter's Cupertino widgets work together.
## The important bits
### `/screens/*`
These are the screens presented in the app, roughly analogous to
UIViewControllers. `HomeScreen` is the root, and the others are shown
as the user navigates.
## Questions/issues
If you have a general question about any of the techniques you see in
the sample, the best places to go are:
* [The FlutterDev Google Group](https://groups.google.com/forum/#!forum/flutter-dev)
* [The Flutter Gitter channel](https://gitter.im/flutter/flutter)
* [StackOverflow](https://stackoverflow.com/questions/tagged/flutter)
If you run into an issue with the sample itself, please file an issue
in the [main Flutter repo](https://github.com/flutter/flutter/issues).
The `veggieseasons` sample has been deprecated. It now lives in the [flutter/demos](https://github.com/flutter/demos) repository, where it will no longer be maintained.

@ -1,5 +0,0 @@
include: package:analysis_defaults/flutter.yaml
linter:
rules:
- prefer_relative_imports

Binary file not shown.

Before

Width:  |  Height:  |  Size: 22 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 154 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 197 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 210 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 155 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 305 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 130 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 281 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 89 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 174 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 111 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 146 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 154 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 271 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 187 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 134 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 169 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 122 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 198 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 154 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 115 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 168 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 114 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 172 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 214 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 225 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 106 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 274 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 196 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 178 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 190 KiB

@ -1,34 +0,0 @@
**/dgph
*.mode1v3
*.mode2v3
*.moved-aside
*.pbxuser
*.perspectivev3
**/*sync/
.sconsign.dblite
.tags*
**/.vagrant/
**/DerivedData/
Icon?
**/Pods/
**/.symlinks/
profile
xcuserdata
**/.generated/
Flutter/App.framework
Flutter/Flutter.framework
Flutter/Flutter.podspec
Flutter/Generated.xcconfig
Flutter/ephemeral/
Flutter/app.flx
Flutter/app.zip
Flutter/flutter_assets/
Flutter/flutter_export_environment.sh
ServiceDefinitions.json
Runner/GeneratedPluginRegistrant.*
# Exceptions to above rules.
!default.mode1v3
!default.mode2v3
!default.pbxuser
!default.perspectivev3

@ -1,26 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>CFBundleDevelopmentRegion</key>
<string>en</string>
<key>CFBundleExecutable</key>
<string>App</string>
<key>CFBundleIdentifier</key>
<string>io.flutter.flutter.app</string>
<key>CFBundleInfoDictionaryVersion</key>
<string>6.0</string>
<key>CFBundleName</key>
<string>App</string>
<key>CFBundlePackageType</key>
<string>FMWK</string>
<key>CFBundleShortVersionString</key>
<string>1.0</string>
<key>CFBundleSignature</key>
<string>????</string>
<key>CFBundleVersion</key>
<string>1.0</string>
<key>MinimumOSVersion</key>
<string>12.0</string>
</dict>
</plist>

@ -1,2 +0,0 @@
#include? "Pods/Target Support Files/Pods-Runner/Pods-Runner.debug.xcconfig"
#include "Generated.xcconfig"

@ -1,2 +0,0 @@
#include? "Pods/Target Support Files/Pods-Runner/Pods-Runner.release.xcconfig"
#include "Generated.xcconfig"

@ -1,44 +0,0 @@
# Uncomment this line to define a global platform for your project
# platform :ios, '12.0'
# 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', '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 Generated.xcconfig, then run flutter pub get"
end
require File.expand_path(File.join('packages', 'flutter_tools', 'bin', 'podhelper'), flutter_root)
flutter_ios_podfile_setup
target 'Runner' do
use_frameworks!
use_modular_headers!
flutter_install_all_ios_pods File.dirname(File.realpath(__FILE__))
target 'RunnerTests' do
inherit! :search_paths
end
end
post_install do |installer|
installer.pods_project.targets.each do |target|
flutter_additional_ios_build_settings(target)
end
end

@ -1,731 +0,0 @@
// !$*UTF8*$!
{
archiveVersion = 1;
classes = {
};
objectVersion = 54;
objects = {
/* Begin PBXBuildFile section */
1498D2341E8E89220040F4C2 /* GeneratedPluginRegistrant.m in Sources */ = {isa = PBXBuildFile; fileRef = 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */; };
331C808B294A63AB00263BE5 /* RunnerTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 331C807B294A618700263BE5 /* RunnerTests.swift */; };
3B3967161E833CAA004F5970 /* AppFrameworkInfo.plist in Resources */ = {isa = PBXBuildFile; fileRef = 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */; };
63DF5AF6EA7E5752FD193C17 /* Pods_Runner.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 38D833D84C3CBFFBC2A61387 /* Pods_Runner.framework */; };
74858FAF1ED2DC5600515810 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 74858FAE1ED2DC5600515810 /* AppDelegate.swift */; };
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 */; };
BDDC9E5BD53006E983AC444C /* Pods_RunnerTests.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 5C7D1011F5450B20EBA2923B /* Pods_RunnerTests.framework */; };
/* End PBXBuildFile section */
/* Begin PBXContainerItemProxy section */
331C8085294A63A400263BE5 /* PBXContainerItemProxy */ = {
isa = PBXContainerItemProxy;
containerPortal = 97C146E61CF9000F007C117D /* Project object */;
proxyType = 1;
remoteGlobalIDString = 97C146ED1CF9000F007C117D;
remoteInfo = Runner;
};
/* End PBXContainerItemProxy section */
/* Begin PBXCopyFilesBuildPhase section */
9705A1C41CF9048500538489 /* Embed Frameworks */ = {
isa = PBXCopyFilesBuildPhase;
buildActionMask = 2147483647;
dstPath = "";
dstSubfolderSpec = 10;
files = (
);
name = "Embed Frameworks";
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXCopyFilesBuildPhase section */
/* Begin PBXFileReference section */
1498D2321E8E86230040F4C2 /* GeneratedPluginRegistrant.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = GeneratedPluginRegistrant.h; sourceTree = "<group>"; };
1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GeneratedPluginRegistrant.m; sourceTree = "<group>"; };
1D00FE80EC6A4B68C8E227F8 /* 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 = "<group>"; };
2E0D48114CA3C6D9CCFFEF16 /* Pods-RunnerTests.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-RunnerTests.debug.xcconfig"; path = "Target Support Files/Pods-RunnerTests/Pods-RunnerTests.debug.xcconfig"; sourceTree = "<group>"; };
331C807B294A618700263BE5 /* RunnerTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RunnerTests.swift; sourceTree = "<group>"; };
331C8081294A63A400263BE5 /* RunnerTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = RunnerTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; };
38D833D84C3CBFFBC2A61387 /* Pods_Runner.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_Runner.framework; sourceTree = BUILT_PRODUCTS_DIR; };
3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = AppFrameworkInfo.plist; path = Flutter/AppFrameworkInfo.plist; sourceTree = "<group>"; };
5C5AC2EFB5606C655AB6C34A /* Pods-RunnerTests.profile.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-RunnerTests.profile.xcconfig"; path = "Target Support Files/Pods-RunnerTests/Pods-RunnerTests.profile.xcconfig"; sourceTree = "<group>"; };
5C7D1011F5450B20EBA2923B /* Pods_RunnerTests.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_RunnerTests.framework; sourceTree = BUILT_PRODUCTS_DIR; };
67C3CA414545302E36760BB5 /* 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 = "<group>"; };
74858FAD1ED2DC5600515810 /* Runner-Bridging-Header.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "Runner-Bridging-Header.h"; sourceTree = "<group>"; };
74858FAE1ED2DC5600515810 /* AppDelegate.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = "<group>"; };
7AFA3C8E1D35360C0083082E /* Release.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; name = Release.xcconfig; path = Flutter/Release.xcconfig; sourceTree = "<group>"; };
971FE7CB47EC26D3DD304A6B /* 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 = "<group>"; };
9740EEB21CF90195004384FC /* Debug.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; name = Debug.xcconfig; path = Flutter/Debug.xcconfig; sourceTree = "<group>"; };
9740EEB31CF90195004384FC /* Generated.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; name = Generated.xcconfig; path = Flutter/Generated.xcconfig; sourceTree = "<group>"; };
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 = "<group>"; };
97C146FD1CF9000F007C117D /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = "<group>"; };
97C147001CF9000F007C117D /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = "<group>"; };
97C147021CF9000F007C117D /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
FA6AACB3CDFE5B8D169FDAD3 /* Pods-RunnerTests.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-RunnerTests.release.xcconfig"; path = "Target Support Files/Pods-RunnerTests/Pods-RunnerTests.release.xcconfig"; sourceTree = "<group>"; };
/* End PBXFileReference section */
/* Begin PBXFrameworksBuildPhase section */
97C146EB1CF9000F007C117D /* Frameworks */ = {
isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647;
files = (
63DF5AF6EA7E5752FD193C17 /* Pods_Runner.framework in Frameworks */,
);
runOnlyForDeploymentPostprocessing = 0;
};
C3870E06F7C4E0C4CA0F4C1C /* Frameworks */ = {
isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647;
files = (
BDDC9E5BD53006E983AC444C /* Pods_RunnerTests.framework in Frameworks */,
);
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXFrameworksBuildPhase section */
/* Begin PBXGroup section */
1AC2876AB73DE877F0C0B83B /* Pods */ = {
isa = PBXGroup;
children = (
971FE7CB47EC26D3DD304A6B /* Pods-Runner.debug.xcconfig */,
67C3CA414545302E36760BB5 /* Pods-Runner.release.xcconfig */,
1D00FE80EC6A4B68C8E227F8 /* Pods-Runner.profile.xcconfig */,
2E0D48114CA3C6D9CCFFEF16 /* Pods-RunnerTests.debug.xcconfig */,
FA6AACB3CDFE5B8D169FDAD3 /* Pods-RunnerTests.release.xcconfig */,
5C5AC2EFB5606C655AB6C34A /* Pods-RunnerTests.profile.xcconfig */,
);
name = Pods;
path = Pods;
sourceTree = "<group>";
};
331C8082294A63A400263BE5 /* RunnerTests */ = {
isa = PBXGroup;
children = (
331C807B294A618700263BE5 /* RunnerTests.swift */,
);
path = RunnerTests;
sourceTree = "<group>";
};
4968362A1680EFDF9222A5B5 /* Frameworks */ = {
isa = PBXGroup;
children = (
38D833D84C3CBFFBC2A61387 /* Pods_Runner.framework */,
5C7D1011F5450B20EBA2923B /* Pods_RunnerTests.framework */,
);
name = Frameworks;
sourceTree = "<group>";
};
9740EEB11CF90186004384FC /* Flutter */ = {
isa = PBXGroup;
children = (
3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */,
9740EEB21CF90195004384FC /* Debug.xcconfig */,
7AFA3C8E1D35360C0083082E /* Release.xcconfig */,
9740EEB31CF90195004384FC /* Generated.xcconfig */,
);
name = Flutter;
sourceTree = "<group>";
};
97C146E51CF9000F007C117D = {
isa = PBXGroup;
children = (
9740EEB11CF90186004384FC /* Flutter */,
97C146F01CF9000F007C117D /* Runner */,
97C146EF1CF9000F007C117D /* Products */,
331C8082294A63A400263BE5 /* RunnerTests */,
1AC2876AB73DE877F0C0B83B /* Pods */,
4968362A1680EFDF9222A5B5 /* Frameworks */,
);
sourceTree = "<group>";
};
97C146EF1CF9000F007C117D /* Products */ = {
isa = PBXGroup;
children = (
97C146EE1CF9000F007C117D /* Runner.app */,
331C8081294A63A400263BE5 /* RunnerTests.xctest */,
);
name = Products;
sourceTree = "<group>";
};
97C146F01CF9000F007C117D /* Runner */ = {
isa = PBXGroup;
children = (
97C146FA1CF9000F007C117D /* Main.storyboard */,
97C146FD1CF9000F007C117D /* Assets.xcassets */,
97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */,
97C147021CF9000F007C117D /* Info.plist */,
1498D2321E8E86230040F4C2 /* GeneratedPluginRegistrant.h */,
1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */,
74858FAE1ED2DC5600515810 /* AppDelegate.swift */,
74858FAD1ED2DC5600515810 /* Runner-Bridging-Header.h */,
);
path = Runner;
sourceTree = "<group>";
};
/* End PBXGroup section */
/* Begin PBXNativeTarget section */
331C8080294A63A400263BE5 /* RunnerTests */ = {
isa = PBXNativeTarget;
buildConfigurationList = 331C8087294A63A400263BE5 /* Build configuration list for PBXNativeTarget "RunnerTests" */;
buildPhases = (
EEF989F59E37C6946EC40F1B /* [CP] Check Pods Manifest.lock */,
331C807D294A63A400263BE5 /* Sources */,
331C807F294A63A400263BE5 /* Resources */,
C3870E06F7C4E0C4CA0F4C1C /* Frameworks */,
);
buildRules = (
);
dependencies = (
331C8086294A63A400263BE5 /* PBXTargetDependency */,
);
name = RunnerTests;
productName = RunnerTests;
productReference = 331C8081294A63A400263BE5 /* RunnerTests.xctest */;
productType = "com.apple.product-type.bundle.unit-test";
};
97C146ED1CF9000F007C117D /* Runner */ = {
isa = PBXNativeTarget;
buildConfigurationList = 97C147051CF9000F007C117D /* Build configuration list for PBXNativeTarget "Runner" */;
buildPhases = (
25194613EC4035A63337D2AA /* [CP] Check Pods Manifest.lock */,
9740EEB61CF901F6004384FC /* Run Script */,
97C146EA1CF9000F007C117D /* Sources */,
97C146EB1CF9000F007C117D /* Frameworks */,
97C146EC1CF9000F007C117D /* Resources */,
9705A1C41CF9048500538489 /* Embed Frameworks */,
3B06AD1E1E4923F5004D2608 /* Thin Binary */,
1F3480CB2DDBB3AE2233D2E2 /* [CP] Embed Pods Frameworks */,
);
buildRules = (
);
dependencies = (
);
name = Runner;
productName = Runner;
productReference = 97C146EE1CF9000F007C117D /* Runner.app */;
productType = "com.apple.product-type.application";
};
/* End PBXNativeTarget section */
/* Begin PBXProject section */
97C146E61CF9000F007C117D /* Project object */ = {
isa = PBXProject;
attributes = {
BuildIndependentTargetsInParallel = YES;
LastUpgradeCheck = 1510;
ORGANIZATIONNAME = "";
TargetAttributes = {
331C8080294A63A400263BE5 = {
CreatedOnToolsVersion = 14.0;
TestTargetID = 97C146ED1CF9000F007C117D;
};
97C146ED1CF9000F007C117D = {
CreatedOnToolsVersion = 7.3.1;
LastSwiftMigration = 1100;
};
};
};
buildConfigurationList = 97C146E91CF9000F007C117D /* Build configuration list for PBXProject "Runner" */;
compatibilityVersion = "Xcode 9.3";
developmentRegion = en;
hasScannedForEncodings = 0;
knownRegions = (
en,
Base,
);
mainGroup = 97C146E51CF9000F007C117D;
productRefGroup = 97C146EF1CF9000F007C117D /* Products */;
projectDirPath = "";
projectRoot = "";
targets = (
97C146ED1CF9000F007C117D /* Runner */,
331C8080294A63A400263BE5 /* RunnerTests */,
);
};
/* End PBXProject section */
/* Begin PBXResourcesBuildPhase section */
331C807F294A63A400263BE5 /* Resources */ = {
isa = PBXResourcesBuildPhase;
buildActionMask = 2147483647;
files = (
);
runOnlyForDeploymentPostprocessing = 0;
};
97C146EC1CF9000F007C117D /* Resources */ = {
isa = PBXResourcesBuildPhase;
buildActionMask = 2147483647;
files = (
97C147011CF9000F007C117D /* LaunchScreen.storyboard in Resources */,
3B3967161E833CAA004F5970 /* AppFrameworkInfo.plist in Resources */,
97C146FE1CF9000F007C117D /* Assets.xcassets in Resources */,
97C146FC1CF9000F007C117D /* Main.storyboard in Resources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXResourcesBuildPhase section */
/* Begin PBXShellScriptBuildPhase section */
1F3480CB2DDBB3AE2233D2E2 /* [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;
};
25194613EC4035A63337D2AA /* [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;
};
3B06AD1E1E4923F5004D2608 /* Thin Binary */ = {
isa = PBXShellScriptBuildPhase;
alwaysOutOfDate = 1;
buildActionMask = 2147483647;
files = (
);
inputPaths = (
"${TARGET_BUILD_DIR}/${INFOPLIST_PATH}",
);
name = "Thin Binary";
outputPaths = (
);
runOnlyForDeploymentPostprocessing = 0;
shellPath = /bin/sh;
shellScript = "/bin/sh \"$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh\" embed_and_thin";
};
9740EEB61CF901F6004384FC /* Run Script */ = {
isa = PBXShellScriptBuildPhase;
alwaysOutOfDate = 1;
buildActionMask = 2147483647;
files = (
);
inputPaths = (
);
name = "Run Script";
outputPaths = (
);
runOnlyForDeploymentPostprocessing = 0;
shellPath = /bin/sh;
shellScript = "/bin/sh \"$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh\" build";
};
EEF989F59E37C6946EC40F1B /* [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-RunnerTests-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 */
331C807D294A63A400263BE5 /* Sources */ = {
isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647;
files = (
331C808B294A63AB00263BE5 /* RunnerTests.swift in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
97C146EA1CF9000F007C117D /* Sources */ = {
isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647;
files = (
74858FAF1ED2DC5600515810 /* AppDelegate.swift in Sources */,
1498D2341E8E89220040F4C2 /* GeneratedPluginRegistrant.m in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXSourcesBuildPhase section */
/* Begin PBXTargetDependency section */
331C8086294A63A400263BE5 /* PBXTargetDependency */ = {
isa = PBXTargetDependency;
target = 97C146ED1CF9000F007C117D /* Runner */;
targetProxy = 331C8085294A63A400263BE5 /* PBXContainerItemProxy */;
};
/* End PBXTargetDependency section */
/* Begin PBXVariantGroup section */
97C146FA1CF9000F007C117D /* Main.storyboard */ = {
isa = PBXVariantGroup;
children = (
97C146FB1CF9000F007C117D /* Base */,
);
name = Main.storyboard;
sourceTree = "<group>";
};
97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */ = {
isa = PBXVariantGroup;
children = (
97C147001CF9000F007C117D /* Base */,
);
name = LaunchScreen.storyboard;
sourceTree = "<group>";
};
/* End PBXVariantGroup section */
/* Begin XCBuildConfiguration section */
249021D3217E4FDB00AE95B9 /* Profile */ = {
isa = XCBuildConfiguration;
buildSettings = {
ALWAYS_SEARCH_USER_PATHS = NO;
ASSETCATALOG_COMPILER_GENERATE_SWIFT_ASSET_SYMBOL_EXTENSIONS = YES;
CLANG_ANALYZER_NONNULL = YES;
CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
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_COMMA = YES;
CLANG_WARN_CONSTANT_CONVERSION = YES;
CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
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_IMPLICIT_RETAIN_SELF = YES;
CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
CLANG_WARN_STRICT_PROTOTYPES = YES;
CLANG_WARN_SUSPICIOUS_MOVE = YES;
CLANG_WARN_UNREACHABLE_CODE = YES;
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
COPY_PHASE_STRIP = NO;
DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
ENABLE_NS_ASSERTIONS = NO;
ENABLE_STRICT_OBJC_MSGSEND = YES;
ENABLE_USER_SCRIPT_SANDBOXING = NO;
GCC_C_LANGUAGE_STANDARD = gnu99;
GCC_NO_COMMON_BLOCKS = YES;
GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
GCC_WARN_UNDECLARED_SELECTOR = YES;
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
GCC_WARN_UNUSED_FUNCTION = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
IPHONEOS_DEPLOYMENT_TARGET = 12.0;
MTL_ENABLE_DEBUG_INFO = NO;
SDKROOT = iphoneos;
SUPPORTED_PLATFORMS = iphoneos;
TARGETED_DEVICE_FAMILY = "1,2";
VALIDATE_PRODUCT = YES;
};
name = Profile;
};
249021D4217E4FDB00AE95B9 /* Profile */ = {
isa = XCBuildConfiguration;
baseConfigurationReference = 7AFA3C8E1D35360C0083082E /* Release.xcconfig */;
buildSettings = {
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
CLANG_ENABLE_MODULES = YES;
CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)";
DEVELOPMENT_TEAM = TC87DMJLQP;
ENABLE_BITCODE = NO;
INFOPLIST_FILE = Runner/Info.plist;
LD_RUNPATH_SEARCH_PATHS = (
"$(inherited)",
"@executable_path/Frameworks",
);
PRODUCT_BUNDLE_IDENTIFIER = dev.flutter.veggieseasons;
PRODUCT_NAME = "$(TARGET_NAME)";
SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h";
SWIFT_VERSION = 5.0;
VERSIONING_SYSTEM = "apple-generic";
};
name = Profile;
};
331C8088294A63A400263BE5 /* Debug */ = {
isa = XCBuildConfiguration;
baseConfigurationReference = 2E0D48114CA3C6D9CCFFEF16 /* Pods-RunnerTests.debug.xcconfig */;
buildSettings = {
BUNDLE_LOADER = "$(TEST_HOST)";
CODE_SIGN_STYLE = Automatic;
CURRENT_PROJECT_VERSION = 1;
GENERATE_INFOPLIST_FILE = YES;
MARKETING_VERSION = 1.0;
PRODUCT_BUNDLE_IDENTIFIER = dev.flutter.veggieseasons.RunnerTests;
PRODUCT_NAME = "$(TARGET_NAME)";
SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG;
SWIFT_OPTIMIZATION_LEVEL = "-Onone";
SWIFT_VERSION = 5.0;
TEST_HOST = "$(BUILT_PRODUCTS_DIR)/Runner.app/$(BUNDLE_EXECUTABLE_FOLDER_PATH)/Runner";
};
name = Debug;
};
331C8089294A63A400263BE5 /* Release */ = {
isa = XCBuildConfiguration;
baseConfigurationReference = FA6AACB3CDFE5B8D169FDAD3 /* Pods-RunnerTests.release.xcconfig */;
buildSettings = {
BUNDLE_LOADER = "$(TEST_HOST)";
CODE_SIGN_STYLE = Automatic;
CURRENT_PROJECT_VERSION = 1;
GENERATE_INFOPLIST_FILE = YES;
MARKETING_VERSION = 1.0;
PRODUCT_BUNDLE_IDENTIFIER = dev.flutter.veggieseasons.RunnerTests;
PRODUCT_NAME = "$(TARGET_NAME)";
SWIFT_VERSION = 5.0;
TEST_HOST = "$(BUILT_PRODUCTS_DIR)/Runner.app/$(BUNDLE_EXECUTABLE_FOLDER_PATH)/Runner";
};
name = Release;
};
331C808A294A63A400263BE5 /* Profile */ = {
isa = XCBuildConfiguration;
baseConfigurationReference = 5C5AC2EFB5606C655AB6C34A /* Pods-RunnerTests.profile.xcconfig */;
buildSettings = {
BUNDLE_LOADER = "$(TEST_HOST)";
CODE_SIGN_STYLE = Automatic;
CURRENT_PROJECT_VERSION = 1;
GENERATE_INFOPLIST_FILE = YES;
MARKETING_VERSION = 1.0;
PRODUCT_BUNDLE_IDENTIFIER = dev.flutter.veggieseasons.RunnerTests;
PRODUCT_NAME = "$(TARGET_NAME)";
SWIFT_VERSION = 5.0;
TEST_HOST = "$(BUILT_PRODUCTS_DIR)/Runner.app/$(BUNDLE_EXECUTABLE_FOLDER_PATH)/Runner";
};
name = Profile;
};
97C147031CF9000F007C117D /* Debug */ = {
isa = XCBuildConfiguration;
buildSettings = {
ALWAYS_SEARCH_USER_PATHS = NO;
ASSETCATALOG_COMPILER_GENERATE_SWIFT_ASSET_SYMBOL_EXTENSIONS = YES;
CLANG_ANALYZER_NONNULL = YES;
CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
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_COMMA = YES;
CLANG_WARN_CONSTANT_CONVERSION = YES;
CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
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_IMPLICIT_RETAIN_SELF = YES;
CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
CLANG_WARN_STRICT_PROTOTYPES = YES;
CLANG_WARN_SUSPICIOUS_MOVE = YES;
CLANG_WARN_UNREACHABLE_CODE = YES;
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
COPY_PHASE_STRIP = NO;
DEBUG_INFORMATION_FORMAT = dwarf;
ENABLE_STRICT_OBJC_MSGSEND = YES;
ENABLE_TESTABILITY = YES;
ENABLE_USER_SCRIPT_SANDBOXING = NO;
GCC_C_LANGUAGE_STANDARD = gnu99;
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_UNDECLARED_SELECTOR = YES;
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
GCC_WARN_UNUSED_FUNCTION = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
IPHONEOS_DEPLOYMENT_TARGET = 12.0;
MTL_ENABLE_DEBUG_INFO = YES;
ONLY_ACTIVE_ARCH = YES;
SDKROOT = iphoneos;
TARGETED_DEVICE_FAMILY = "1,2";
};
name = Debug;
};
97C147041CF9000F007C117D /* Release */ = {
isa = XCBuildConfiguration;
buildSettings = {
ALWAYS_SEARCH_USER_PATHS = NO;
ASSETCATALOG_COMPILER_GENERATE_SWIFT_ASSET_SYMBOL_EXTENSIONS = YES;
CLANG_ANALYZER_NONNULL = YES;
CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
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_COMMA = YES;
CLANG_WARN_CONSTANT_CONVERSION = YES;
CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
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_IMPLICIT_RETAIN_SELF = YES;
CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
CLANG_WARN_STRICT_PROTOTYPES = YES;
CLANG_WARN_SUSPICIOUS_MOVE = YES;
CLANG_WARN_UNREACHABLE_CODE = YES;
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
COPY_PHASE_STRIP = NO;
DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
ENABLE_NS_ASSERTIONS = NO;
ENABLE_STRICT_OBJC_MSGSEND = YES;
ENABLE_USER_SCRIPT_SANDBOXING = NO;
GCC_C_LANGUAGE_STANDARD = gnu99;
GCC_NO_COMMON_BLOCKS = YES;
GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
GCC_WARN_UNDECLARED_SELECTOR = YES;
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
GCC_WARN_UNUSED_FUNCTION = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
IPHONEOS_DEPLOYMENT_TARGET = 12.0;
MTL_ENABLE_DEBUG_INFO = NO;
SDKROOT = iphoneos;
SUPPORTED_PLATFORMS = iphoneos;
SWIFT_COMPILATION_MODE = wholemodule;
SWIFT_OPTIMIZATION_LEVEL = "-O";
TARGETED_DEVICE_FAMILY = "1,2";
VALIDATE_PRODUCT = YES;
};
name = Release;
};
97C147061CF9000F007C117D /* Debug */ = {
isa = XCBuildConfiguration;
baseConfigurationReference = 9740EEB21CF90195004384FC /* Debug.xcconfig */;
buildSettings = {
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
CLANG_ENABLE_MODULES = YES;
CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)";
DEVELOPMENT_TEAM = TC87DMJLQP;
ENABLE_BITCODE = NO;
INFOPLIST_FILE = Runner/Info.plist;
LD_RUNPATH_SEARCH_PATHS = (
"$(inherited)",
"@executable_path/Frameworks",
);
PRODUCT_BUNDLE_IDENTIFIER = dev.flutter.veggieseasons;
PRODUCT_NAME = "$(TARGET_NAME)";
SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h";
SWIFT_OPTIMIZATION_LEVEL = "-Onone";
SWIFT_VERSION = 5.0;
VERSIONING_SYSTEM = "apple-generic";
};
name = Debug;
};
97C147071CF9000F007C117D /* Release */ = {
isa = XCBuildConfiguration;
baseConfigurationReference = 7AFA3C8E1D35360C0083082E /* Release.xcconfig */;
buildSettings = {
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
CLANG_ENABLE_MODULES = YES;
CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)";
DEVELOPMENT_TEAM = TC87DMJLQP;
ENABLE_BITCODE = NO;
INFOPLIST_FILE = Runner/Info.plist;
LD_RUNPATH_SEARCH_PATHS = (
"$(inherited)",
"@executable_path/Frameworks",
);
PRODUCT_BUNDLE_IDENTIFIER = dev.flutter.veggieseasons;
PRODUCT_NAME = "$(TARGET_NAME)";
SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h";
SWIFT_VERSION = 5.0;
VERSIONING_SYSTEM = "apple-generic";
};
name = Release;
};
/* End XCBuildConfiguration section */
/* Begin XCConfigurationList section */
331C8087294A63A400263BE5 /* Build configuration list for PBXNativeTarget "RunnerTests" */ = {
isa = XCConfigurationList;
buildConfigurations = (
331C8088294A63A400263BE5 /* Debug */,
331C8089294A63A400263BE5 /* Release */,
331C808A294A63A400263BE5 /* Profile */,
);
defaultConfigurationIsVisible = 0;
defaultConfigurationName = Release;
};
97C146E91CF9000F007C117D /* Build configuration list for PBXProject "Runner" */ = {
isa = XCConfigurationList;
buildConfigurations = (
97C147031CF9000F007C117D /* Debug */,
97C147041CF9000F007C117D /* Release */,
249021D3217E4FDB00AE95B9 /* Profile */,
);
defaultConfigurationIsVisible = 0;
defaultConfigurationName = Release;
};
97C147051CF9000F007C117D /* Build configuration list for PBXNativeTarget "Runner" */ = {
isa = XCConfigurationList;
buildConfigurations = (
97C147061CF9000F007C117D /* Debug */,
97C147071CF9000F007C117D /* Release */,
249021D4217E4FDB00AE95B9 /* Profile */,
);
defaultConfigurationIsVisible = 0;
defaultConfigurationName = Release;
};
/* End XCConfigurationList section */
};
rootObject = 97C146E61CF9000F007C117D /* Project object */;
}

@ -1,7 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<Workspace
version = "1.0">
<FileRef
location = "self:">
</FileRef>
</Workspace>

@ -1,8 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>IDEDidComputeMac32BitWarning</key>
<true/>
</dict>
</plist>

@ -1,8 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>PreviewsEnabled</key>
<false/>
</dict>
</plist>

@ -1,98 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<Scheme
LastUpgradeVersion = "1510"
version = "1.3">
<BuildAction
parallelizeBuildables = "YES"
buildImplicitDependencies = "YES">
<BuildActionEntries>
<BuildActionEntry
buildForTesting = "YES"
buildForRunning = "YES"
buildForProfiling = "YES"
buildForArchiving = "YES"
buildForAnalyzing = "YES">
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "97C146ED1CF9000F007C117D"
BuildableName = "Runner.app"
BlueprintName = "Runner"
ReferencedContainer = "container:Runner.xcodeproj">
</BuildableReference>
</BuildActionEntry>
</BuildActionEntries>
</BuildAction>
<TestAction
buildConfiguration = "Debug"
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
shouldUseLaunchSchemeArgsEnv = "YES">
<MacroExpansion>
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "97C146ED1CF9000F007C117D"
BuildableName = "Runner.app"
BlueprintName = "Runner"
ReferencedContainer = "container:Runner.xcodeproj">
</BuildableReference>
</MacroExpansion>
<Testables>
<TestableReference
skipped = "NO"
parallelizable = "YES">
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "331C8080294A63A400263BE5"
BuildableName = "RunnerTests.xctest"
BlueprintName = "RunnerTests"
ReferencedContainer = "container:Runner.xcodeproj">
</BuildableReference>
</TestableReference>
</Testables>
</TestAction>
<LaunchAction
buildConfiguration = "Debug"
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
launchStyle = "0"
useCustomWorkingDirectory = "NO"
ignoresPersistentStateOnLaunch = "NO"
debugDocumentVersioning = "YES"
debugServiceExtension = "internal"
allowLocationSimulation = "YES">
<BuildableProductRunnable
runnableDebuggingMode = "0">
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "97C146ED1CF9000F007C117D"
BuildableName = "Runner.app"
BlueprintName = "Runner"
ReferencedContainer = "container:Runner.xcodeproj">
</BuildableReference>
</BuildableProductRunnable>
</LaunchAction>
<ProfileAction
buildConfiguration = "Profile"
shouldUseLaunchSchemeArgsEnv = "YES"
savedToolIdentifier = ""
useCustomWorkingDirectory = "NO"
debugDocumentVersioning = "YES">
<BuildableProductRunnable
runnableDebuggingMode = "0">
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "97C146ED1CF9000F007C117D"
BuildableName = "Runner.app"
BlueprintName = "Runner"
ReferencedContainer = "container:Runner.xcodeproj">
</BuildableReference>
</BuildableProductRunnable>
</ProfileAction>
<AnalyzeAction
buildConfiguration = "Debug">
</AnalyzeAction>
<ArchiveAction
buildConfiguration = "Release"
revealArchiveInOrganizer = "YES">
</ArchiveAction>
</Scheme>

@ -1,10 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<Workspace
version = "1.0">
<FileRef
location = "group:Runner.xcodeproj">
</FileRef>
<FileRef
location = "group:Pods/Pods.xcodeproj">
</FileRef>
</Workspace>

@ -1,8 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>IDEDidComputeMac32BitWarning</key>
<true/>
</dict>
</plist>

@ -1,8 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>PreviewsEnabled</key>
<false/>
</dict>
</plist>

@ -1,13 +0,0 @@
import Flutter
import UIKit
@main
@objc class AppDelegate: FlutterAppDelegate {
override func application(
_ application: UIApplication,
didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?
) -> Bool {
GeneratedPluginRegistrant.register(with: self)
return super.application(application, didFinishLaunchingWithOptions: launchOptions)
}
}

@ -1,122 +0,0 @@
{
"images" : [
{
"size" : "20x20",
"idiom" : "iphone",
"filename" : "Icon-App-20x20@2x.png",
"scale" : "2x"
},
{
"size" : "20x20",
"idiom" : "iphone",
"filename" : "Icon-App-20x20@3x.png",
"scale" : "3x"
},
{
"size" : "29x29",
"idiom" : "iphone",
"filename" : "Icon-App-29x29@1x.png",
"scale" : "1x"
},
{
"size" : "29x29",
"idiom" : "iphone",
"filename" : "Icon-App-29x29@2x.png",
"scale" : "2x"
},
{
"size" : "29x29",
"idiom" : "iphone",
"filename" : "Icon-App-29x29@3x.png",
"scale" : "3x"
},
{
"size" : "40x40",
"idiom" : "iphone",
"filename" : "Icon-App-40x40@2x.png",
"scale" : "2x"
},
{
"size" : "40x40",
"idiom" : "iphone",
"filename" : "Icon-App-40x40@3x.png",
"scale" : "3x"
},
{
"size" : "60x60",
"idiom" : "iphone",
"filename" : "Icon-App-60x60@2x.png",
"scale" : "2x"
},
{
"size" : "60x60",
"idiom" : "iphone",
"filename" : "Icon-App-60x60@3x.png",
"scale" : "3x"
},
{
"size" : "20x20",
"idiom" : "ipad",
"filename" : "Icon-App-20x20@1x.png",
"scale" : "1x"
},
{
"size" : "20x20",
"idiom" : "ipad",
"filename" : "Icon-App-20x20@2x.png",
"scale" : "2x"
},
{
"size" : "29x29",
"idiom" : "ipad",
"filename" : "Icon-App-29x29@1x.png",
"scale" : "1x"
},
{
"size" : "29x29",
"idiom" : "ipad",
"filename" : "Icon-App-29x29@2x.png",
"scale" : "2x"
},
{
"size" : "40x40",
"idiom" : "ipad",
"filename" : "Icon-App-40x40@1x.png",
"scale" : "1x"
},
{
"size" : "40x40",
"idiom" : "ipad",
"filename" : "Icon-App-40x40@2x.png",
"scale" : "2x"
},
{
"size" : "76x76",
"idiom" : "ipad",
"filename" : "Icon-App-76x76@1x.png",
"scale" : "1x"
},
{
"size" : "76x76",
"idiom" : "ipad",
"filename" : "Icon-App-76x76@2x.png",
"scale" : "2x"
},
{
"size" : "83.5x83.5",
"idiom" : "ipad",
"filename" : "Icon-App-83.5x83.5@2x.png",
"scale" : "2x"
},
{
"size" : "1024x1024",
"idiom" : "ios-marketing",
"filename" : "Icon-App-1024x1024@1x.png",
"scale" : "1x"
}
],
"info" : {
"version" : 1,
"author" : "xcode"
}
}

Binary file not shown.

Before

Width:  |  Height:  |  Size: 73 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 685 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1012 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.9 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.9 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 7.5 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.0 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 6.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 7.0 KiB

@ -1,23 +0,0 @@
{
"images" : [
{
"idiom" : "universal",
"filename" : "LaunchImage.png",
"scale" : "1x"
},
{
"idiom" : "universal",
"filename" : "LaunchImage@2x.png",
"scale" : "2x"
},
{
"idiom" : "universal",
"filename" : "LaunchImage@3x.png",
"scale" : "3x"
}
],
"info" : {
"version" : 1,
"author" : "xcode"
}
}

Binary file not shown.

Before

Width:  |  Height:  |  Size: 68 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 68 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 68 B

@ -1,5 +0,0 @@
# Launch Screen Assets
You can customize the launch screen with your own desired assets by replacing the image files in this directory.
You can also do it by opening your Flutter project's Xcode project with `open ios/Runner.xcworkspace`, selecting `Runner/Assets.xcassets` in the Project Navigator and dropping in the desired images.

@ -1,37 +0,0 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="12121" systemVersion="16G29" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" launchScreen="YES" colorMatched="YES" initialViewController="01J-lp-oVM">
<dependencies>
<deployment identifier="iOS"/>
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="12089"/>
</dependencies>
<scenes>
<!--View Controller-->
<scene sceneID="EHf-IW-A2E">
<objects>
<viewController id="01J-lp-oVM" sceneMemberID="viewController">
<layoutGuides>
<viewControllerLayoutGuide type="top" id="Ydg-fD-yQy"/>
<viewControllerLayoutGuide type="bottom" id="xbc-2k-c8Z"/>
</layoutGuides>
<view key="view" contentMode="scaleToFill" id="Ze5-6b-2t3">
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<subviews>
<imageView opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" image="LaunchImage" translatesAutoresizingMaskIntoConstraints="NO" id="YRO-k0-Ey4">
</imageView>
</subviews>
<color key="backgroundColor" red="1" green="1" blue="1" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
<constraints>
<constraint firstItem="YRO-k0-Ey4" firstAttribute="centerX" secondItem="Ze5-6b-2t3" secondAttribute="centerX" id="1a2-6s-vTC"/>
<constraint firstItem="YRO-k0-Ey4" firstAttribute="centerY" secondItem="Ze5-6b-2t3" secondAttribute="centerY" id="4X2-HB-R7a"/>
</constraints>
</view>
</viewController>
<placeholder placeholderIdentifier="IBFirstResponder" id="iYj-Kq-Ea1" userLabel="First Responder" sceneMemberID="firstResponder"/>
</objects>
<point key="canvasLocation" x="53" y="375"/>
</scene>
</scenes>
<resources>
<image name="LaunchImage" width="168" height="185"/>
</resources>
</document>

@ -1,26 +0,0 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="10117" systemVersion="15F34" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" initialViewController="BYZ-38-t0r">
<dependencies>
<deployment identifier="iOS"/>
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="10085"/>
</dependencies>
<scenes>
<!--Flutter View Controller-->
<scene sceneID="tne-QT-ifu">
<objects>
<viewController id="BYZ-38-t0r" customClass="FlutterViewController" sceneMemberID="viewController">
<layoutGuides>
<viewControllerLayoutGuide type="top" id="y3c-jy-aDJ"/>
<viewControllerLayoutGuide type="bottom" id="wfy-db-euE"/>
</layoutGuides>
<view key="view" contentMode="scaleToFill" id="8bC-Xf-vdC">
<rect key="frame" x="0.0" y="0.0" width="600" height="600"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<color key="backgroundColor" white="1" alpha="1" colorSpace="custom" customColorSpace="calibratedWhite"/>
</view>
</viewController>
<placeholder placeholderIdentifier="IBFirstResponder" id="dkx-z0-nzr" sceneMemberID="firstResponder"/>
</objects>
</scene>
</scenes>
</document>

@ -1,48 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>CFBundleDevelopmentRegion</key>
<string>$(DEVELOPMENT_LANGUAGE)</string>
<key>CFBundleDisplayName</key>
<string>Veggie Seasons</string>
<key>CFBundleExecutable</key>
<string>$(EXECUTABLE_NAME)</string>
<key>CFBundleIdentifier</key>
<string>$(PRODUCT_BUNDLE_IDENTIFIER)</string>
<key>CFBundleInfoDictionaryVersion</key>
<string>6.0</string>
<key>CFBundleName</key>
<string>veggieseasons</string>
<key>CFBundlePackageType</key>
<string>APPL</string>
<key>CFBundleShortVersionString</key>
<string>$(FLUTTER_BUILD_NAME)</string>
<key>CFBundleSignature</key>
<string>????</string>
<key>CFBundleVersion</key>
<string>$(FLUTTER_BUILD_NUMBER)</string>
<key>LSRequiresIPhoneOS</key>
<true/>
<key>UILaunchStoryboardName</key>
<string>LaunchScreen</string>
<key>UIMainStoryboardFile</key>
<string>Main</string>
<key>UISupportedInterfaceOrientations</key>
<array>
<string>UIInterfaceOrientationPortrait</string>
<string>UIInterfaceOrientationPortraitUpsideDown</string>
</array>
<key>UISupportedInterfaceOrientations~ipad</key>
<array>
<string>UIInterfaceOrientationPortrait</string>
<string>UIInterfaceOrientationPortraitUpsideDown</string>
<string>UIInterfaceOrientationLandscapeLeft</string>
<string>UIInterfaceOrientationLandscapeRight</string>
</array>
<key>CADisableMinimumFrameDurationOnPhone</key>
<true/>
<key>UIApplicationSupportsIndirectInputEvents</key>
<true/>
</dict>
</plist>

@ -1 +0,0 @@
#import "GeneratedPluginRegistrant.h"

@ -1,12 +0,0 @@
import Flutter
import UIKit
import XCTest
class RunnerTests: XCTestCase {
func testExample() {
// If you add code to the Runner application, consider adding tests here.
// See https://developer.apple.com/documentation/xctest for more information about using XCTest.
}
}

@ -1,86 +0,0 @@
// Copyright 2018 The Flutter team. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
import 'package:flutter/foundation.dart';
import 'local_veggie_provider.dart';
import 'veggie.dart';
class AppState extends ChangeNotifier {
final List<Veggie> _veggies;
AppState() : _veggies = LocalVeggieProvider.veggies;
List<Veggie> get allVeggies => List<Veggie>.from(_veggies);
List<Veggie> get availableVeggies {
var currentSeason = _getSeasonForDate(DateTime.now());
return _veggies
.where((v) => v.seasons.contains(currentSeason))
.toList();
}
List<Veggie> get favoriteVeggies =>
_veggies.where((v) => v.isFavorite).toList();
List<Veggie> get unavailableVeggies {
var currentSeason = _getSeasonForDate(DateTime.now());
return _veggies
.where((v) => !v.seasons.contains(currentSeason))
.toList();
}
Veggie getVeggie(int? id) => _veggies.singleWhere((v) => v.id == id);
List<Veggie> searchVeggies(String? terms) => _veggies
.where((v) => v.name.toLowerCase().contains(terms!.toLowerCase()))
.toList();
void setFavorite(int? id, bool isFavorite) {
var veggie = getVeggie(id);
veggie.isFavorite = isFavorite;
notifyListeners();
}
/// Used in tests to set the season independent of the current date.
static Season? debugCurrentSeason;
static Season? _getSeasonForDate(DateTime date) {
if (debugCurrentSeason != null) {
return debugCurrentSeason;
}
// Technically the start and end dates of seasons can vary by a day or so,
// but this is close enough for produce.
switch (date.month) {
case 1:
return Season.winter;
case 2:
return Season.winter;
case 3:
return date.day < 21 ? Season.winter : Season.spring;
case 4:
return Season.spring;
case 5:
return Season.spring;
case 6:
return date.day < 21 ? Season.spring : Season.summer;
case 7:
return Season.summer;
case 8:
return Season.summer;
case 9:
return date.day < 22 ? Season.autumn : Season.winter;
case 10:
return Season.autumn;
case 11:
return Season.autumn;
case 12:
return date.day < 22 ? Season.autumn : Season.winter;
default:
throw ArgumentError(
'Can\'t return a season for month #${date.month}.',
);
}
}
}

File diff suppressed because it is too large Load Diff

@ -1,90 +0,0 @@
// Copyright 2018 The Flutter team. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
import 'dart:async';
import 'package:flutter/cupertino.dart';
import 'package:shared_preferences/shared_preferences.dart';
import 'veggie.dart';
/// A model class that mirrors the options in [SettingsScreen] and stores data
/// in shared preferences.
class Preferences extends ChangeNotifier {
// Keys to use with shared preferences.
static const _caloriesKey = 'calories';
static const _preferredCategoriesKey = 'preferredCategories';
// Indicates whether a call to [_loadFromSharedPrefs] is in progress;
Future<void>? _loading;
int _desiredCalories = 2000;
final Set<VeggieCategory> _preferredCategories = <VeggieCategory>{};
Future<int> get desiredCalories async {
await _loading;
return _desiredCalories;
}
Future<Set<VeggieCategory>> get preferredCategories async {
await _loading;
return Set.from(_preferredCategories);
}
Future<void> addPreferredCategory(VeggieCategory category) async {
_preferredCategories.add(category);
await _saveToSharedPrefs();
notifyListeners();
}
Future<void> removePreferredCategory(VeggieCategory category) async {
_preferredCategories.remove(category);
await _saveToSharedPrefs();
notifyListeners();
}
Future<void> setDesiredCalories(int calories) async {
_desiredCalories = calories;
await _saveToSharedPrefs();
notifyListeners();
}
Future<void> restoreDefaults() async {
final prefs = await SharedPreferences.getInstance();
await prefs.clear();
load();
}
void load() {
_loading = _loadFromSharedPrefs();
}
Future<void> _saveToSharedPrefs() async {
final prefs = await SharedPreferences.getInstance();
await prefs.setInt(_caloriesKey, _desiredCalories);
// Store preferred categories as a comma-separated string containing their
// indices.
await prefs.setString(
_preferredCategoriesKey,
_preferredCategories.map((c) => c.index.toString()).join(','),
);
}
Future<void> _loadFromSharedPrefs() async {
final prefs = await SharedPreferences.getInstance();
_desiredCalories = prefs.getInt(_caloriesKey) ?? 2000;
_preferredCategories.clear();
final names = prefs.getString(_preferredCategoriesKey);
if (names != null && names.isNotEmpty) {
for (final name in names.split(',')) {
final index = int.tryParse(name) ?? -1;
_preferredCategories.add(VeggieCategory.values[index]);
}
}
notifyListeners();
}
}

@ -1,125 +0,0 @@
// Copyright 2018 The Flutter team. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
import 'package:flutter/cupertino.dart';
enum VeggieCategory {
allium,
berry,
citrus,
cruciferous,
fern,
flower,
fruit,
fungus,
gourd,
leafy,
legume,
melon,
root,
stealthFruit,
stoneFruit,
tropical,
tuber,
vegetable,
}
enum Season { winter, spring, summer, autumn }
class Trivia {
final String question;
final List<String> answers;
final int correctAnswerIndex;
const Trivia(this.question, this.answers, this.correctAnswerIndex);
}
const Map<VeggieCategory, String> veggieCategoryNames = {
VeggieCategory.allium: 'Allium',
VeggieCategory.berry: 'Berry',
VeggieCategory.citrus: 'Citrus',
VeggieCategory.cruciferous: 'Cruciferous',
VeggieCategory.fern: 'Technically a fern',
VeggieCategory.flower: 'Flower',
VeggieCategory.fruit: 'Fruit',
VeggieCategory.fungus: 'Fungus',
VeggieCategory.gourd: 'Gourd',
VeggieCategory.leafy: 'Leafy',
VeggieCategory.legume: 'Legume',
VeggieCategory.melon: 'Melon',
VeggieCategory.root: 'Root vegetable',
VeggieCategory.stealthFruit: 'Stealth fruit',
VeggieCategory.stoneFruit: 'Stone fruit',
VeggieCategory.tropical: 'Tropical',
VeggieCategory.tuber: 'Tuber',
VeggieCategory.vegetable: 'Vegetable',
};
const Map<Season, String> seasonNames = {
Season.winter: 'Winter',
Season.spring: 'Spring',
Season.summer: 'Summer',
Season.autumn: 'Autumn',
};
class Veggie {
Veggie({
required this.id,
required this.name,
required this.imageAssetPath,
required this.category,
required this.shortDescription,
required this.accentColor,
required this.seasons,
required this.vitaminAPercentage,
required this.vitaminCPercentage,
required this.servingSize,
required this.caloriesPerServing,
required this.trivia,
this.isFavorite = false,
});
final int id;
final String name;
/// Each veggie has an associated image asset that's used as a background
/// image and icon.
final String imageAssetPath;
final VeggieCategory category;
/// A short, snappy line.
final String shortDescription;
/// A color value to use when constructing UI elements to match the image
/// found at [imageAssetPath].
final Color accentColor;
/// Seasons during which a veggie is harvested.
final List<Season> seasons;
/// Percentage of the FDA's recommended daily value of vitamin A for someone
/// with a 2,000 calorie diet.
final int vitaminAPercentage;
/// Percentage of the FDA's recommended daily value of vitamin C for someone
/// with a 2,000 calorie diet.
final int vitaminCPercentage;
/// A text description of a single serving (e.g. '1 apple' or '1/2 cup').
final String servingSize;
/// Calories per serving (as described in [servingSize]).
final int caloriesPerServing;
/// Whether or not the veggie has been saved to the user's garden (i.e. marked
/// as a favorite).
bool isFavorite;
/// A set of trivia questions and answers related to the veggie.
final List<Trivia> trivia;
String? get categoryName => veggieCategoryNames[category];
}

@ -1,243 +0,0 @@
// Copyright 2018 The Flutter team. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
import 'dart:io' show Platform;
import 'package:flutter/cupertino.dart';
import 'package:flutter/foundation.dart' show kIsWeb;
import 'package:flutter/services.dart'
show DeviceOrientation, SystemChrome;
import 'package:go_router/go_router.dart';
import 'package:provider/provider.dart';
import 'package:window_size/window_size.dart';
import 'data/app_state.dart';
import 'data/preferences.dart';
import 'screens/details.dart';
import 'screens/favorites.dart';
import 'screens/home.dart';
import 'screens/list.dart';
import 'screens/search.dart';
import 'screens/settings.dart';
import 'styles.dart';
import 'widgets/veggie_seasons_page.dart';
void main() {
WidgetsFlutterBinding.ensureInitialized();
SystemChrome.setPreferredOrientations([
DeviceOrientation.portraitUp,
DeviceOrientation.portraitDown,
]);
setupWindow();
runApp(
const RootRestorationScope(restorationId: 'root', child: VeggieApp()),
);
}
const double windowWidth = 480;
const double windowHeight = 854;
void setupWindow() {
if (!kIsWeb &&
(Platform.isWindows || Platform.isLinux || Platform.isMacOS)) {
setWindowTitle('Veggie Seasons');
setWindowMinSize(const Size(windowWidth, windowHeight));
setWindowMaxSize(const Size(windowWidth, windowHeight));
getCurrentScreen().then((screen) {
setWindowFrame(
Rect.fromCenter(
center: screen!.frame.center,
width: windowWidth,
height: windowHeight,
),
);
});
}
}
final _rootNavigatorKey = GlobalKey<NavigatorState>();
final _shellNavigatorKey = GlobalKey<NavigatorState>();
class VeggieApp extends StatefulWidget {
const VeggieApp({super.key});
@override
State<StatefulWidget> createState() => _VeggieAppState();
}
class _VeggieAppState extends State<VeggieApp> with RestorationMixin {
final _RestorableAppState _appState = _RestorableAppState();
@override
String get restorationId => 'wrapper';
@override
void restoreState(RestorationBucket? oldBucket, bool initialRestore) {
registerForRestoration(_appState, 'state');
}
@override
void dispose() {
_appState.dispose();
super.dispose();
}
@override
Widget build(BuildContext context) {
return MultiProvider(
providers: [
ChangeNotifierProvider.value(value: _appState.value),
ChangeNotifierProvider(create: (_) => Preferences()..load()),
],
child: CupertinoApp.router(
theme: Styles.veggieThemeData,
debugShowCheckedModeBanner: false,
restorationScopeId: 'app',
routerConfig: GoRouter(
navigatorKey: _rootNavigatorKey,
restorationScopeId: 'router',
initialLocation: '/list',
redirect: (context, state) {
if (state.path == '/') {
return '/list';
}
return null;
},
debugLogDiagnostics: true,
routes: [
ShellRoute(
navigatorKey: _shellNavigatorKey,
pageBuilder: (context, state, child) {
return CupertinoPage(
restorationId: 'router.shell',
child: HomeScreen(
restorationId: 'home',
child: child,
onTap: (index) {
if (index == 0) {
context.go('/list');
} else if (index == 1) {
context.go('/favorites');
} else if (index == 2) {
context.go('/search');
} else {
context.go('/settings');
}
},
),
);
},
routes: [
GoRoute(
path: '/list',
pageBuilder: (context, state) {
return VeggieSeasonsPage(
key: state.pageKey,
restorationId: 'route.list',
child: const ListScreen(restorationId: 'list'),
);
},
routes: [_buildDetailsRoute()],
),
GoRoute(
path: '/favorites',
pageBuilder: (context, state) {
return VeggieSeasonsPage(
key: state.pageKey,
restorationId: 'route.favorites',
child: const FavoritesScreen(
restorationId: 'favorites',
),
);
},
routes: [_buildDetailsRoute()],
),
GoRoute(
path: '/search',
pageBuilder: (context, state) {
return VeggieSeasonsPage(
key: state.pageKey,
restorationId: 'route.search',
child: const SearchScreen(restorationId: 'search'),
);
},
routes: [_buildDetailsRoute()],
),
GoRoute(
path: '/settings',
pageBuilder: (context, state) {
return VeggieSeasonsPage(
key: state.pageKey,
restorationId: 'route.settings',
child: const SettingsScreen(
restorationId: 'settings',
),
);
},
routes: [
GoRoute(
parentNavigatorKey: _rootNavigatorKey,
path: 'categories',
pageBuilder: (context, state) {
return VeggieCategorySettingsScreen.pageBuilder(
context,
);
},
),
GoRoute(
parentNavigatorKey: _rootNavigatorKey,
path: 'calories',
pageBuilder: (context, state) {
return CalorieSettingsScreen.pageBuilder(context);
},
),
],
),
],
),
],
),
),
);
}
// GoRouter does not support relative routes,
// see https://github.com/flutter/flutter/issues/108177
GoRoute _buildDetailsRoute() {
return GoRoute(
parentNavigatorKey: _rootNavigatorKey,
path: 'details/:id',
pageBuilder: (context, state) {
final veggieId = int.parse(state.pathParameters['id']!);
return CupertinoPage(
restorationId: 'route.details',
child: DetailsScreen(id: veggieId, restorationId: 'details'),
);
},
);
}
}
class _RestorableAppState extends RestorableListenable<AppState> {
@override
AppState createDefaultValue() {
return AppState();
}
@override
AppState fromPrimitives(Object? data) {
final appState = AppState();
final favorites = (data as List<dynamic>).cast<int>();
for (var id in favorites) {
appState.setFavorite(id, true);
}
return appState;
}
@override
Object toPrimitives() {
return value.favoriteVeggies.map((veggie) => veggie.id).toList();
}
}

@ -1,294 +0,0 @@
// Copyright 2018 The Flutter team. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
import 'package:flutter/cupertino.dart';
import 'package:go_router/go_router.dart';
import 'package:provider/provider.dart';
import '../data/app_state.dart';
import '../data/preferences.dart';
import '../data/veggie.dart';
import '../styles.dart';
import '../widgets/detail_buttons.dart';
class ServingInfoChart extends StatelessWidget {
const ServingInfoChart(this.veggie, this.prefs, {super.key});
final Veggie veggie;
final Preferences prefs;
// Creates a [Text] widget to display a veggie's "percentage of your daily
// value of this vitamin" data adjusted for the user's preferred calorie
// target.
Widget _buildVitaminText(
int standardPercentage,
Future<int> targetCalories,
) {
return FutureBuilder<int>(
future: targetCalories,
builder: (context, snapshot) {
final target = snapshot.data ?? 2000;
final percent = standardPercentage * 2000 ~/ target;
return Text(
'$percent% DV',
style: CupertinoTheme.of(context).textTheme.textStyle,
textAlign: TextAlign.end,
);
},
);
}
@override
Widget build(BuildContext context) {
final themeData = CupertinoTheme.of(context);
return Column(
children: [
const SizedBox(height: 32),
Row(
mainAxisSize: MainAxisSize.max,
children: [
Text(
'Serving size',
style: Styles.detailsServingLabelText(themeData),
),
const Spacer(),
Text(
veggie.servingSize,
textAlign: TextAlign.end,
style: CupertinoTheme.of(context).textTheme.textStyle,
),
],
),
const SizedBox(height: 24),
Row(
mainAxisSize: MainAxisSize.max,
children: [
Text(
'Calories',
style: Styles.detailsServingLabelText(themeData),
),
const Spacer(),
Text(
'${veggie.caloriesPerServing} kCal',
style: CupertinoTheme.of(context).textTheme.textStyle,
textAlign: TextAlign.end,
),
],
),
const SizedBox(height: 24),
Row(
mainAxisSize: MainAxisSize.max,
children: [
Text(
'Vitamin A',
style: Styles.detailsServingLabelText(themeData),
),
const Spacer(),
_buildVitaminText(
veggie.vitaminAPercentage,
prefs.desiredCalories,
),
],
),
const SizedBox(height: 24),
Row(
mainAxisSize: MainAxisSize.max,
children: [
Text(
'Vitamin C',
style: Styles.detailsServingLabelText(themeData),
),
const Spacer(),
_buildVitaminText(
veggie.vitaminCPercentage,
prefs.desiredCalories,
),
],
),
Padding(
padding: const EdgeInsets.only(top: 32),
child: FutureBuilder(
future: prefs.desiredCalories,
builder: (context, snapshot) {
return Text(
'Percent daily values based on a diet of '
'${snapshot.data ?? '2,000'} calories.',
style: Styles.detailsServingNoteText(themeData),
);
},
),
),
],
);
}
}
class InfoView extends StatelessWidget {
final int? id;
const InfoView(this.id, {super.key});
@override
Widget build(BuildContext context) {
final appState = Provider.of<AppState>(context);
final prefs = Provider.of<Preferences>(context);
final veggie = appState.getVeggie(id);
final themeData = CupertinoTheme.of(context);
return Padding(
padding: const EdgeInsets.all(24),
child: Column(
crossAxisAlignment: CrossAxisAlignment.stretch,
children: [
Text(veggie.name, style: Styles.detailsTitleText(themeData)),
const SizedBox(height: 8),
Text(
veggie.shortDescription,
style: CupertinoTheme.of(context).textTheme.textStyle,
),
const SizedBox(height: 16),
Text(
'Seasons',
style: Styles.detailsServingLabelText(themeData),
),
const SizedBox(height: 12),
Row(
mainAxisSize: MainAxisSize.max,
children: <Widget>[
for (var season in Season.values) ...[
const Spacer(),
Column(
mainAxisSize: MainAxisSize.min,
children: [
Icon(
Styles.seasonIconData[season],
color: veggie.seasons.contains(season)
? Styles.seasonColors[season]
: const Color.fromRGBO(128, 128, 128, 1),
size: 24,
),
const SizedBox(height: 4),
Text(
season.name.characters.first.toUpperCase() +
season.name.characters.skip(1).string,
style: Styles.minorText(
CupertinoTheme.of(context),
).copyWith(fontSize: 11),
),
],
),
const Spacer(),
],
],
),
ServingInfoChart(veggie, prefs),
],
),
);
}
}
class DetailsScreen extends StatelessWidget {
final int? id;
final String? restorationId;
const DetailsScreen({this.id, this.restorationId, super.key});
Widget _buildHeader(BuildContext context, AppState model) {
final veggie = model.getVeggie(id);
return SizedBox(
height: 240,
child: Stack(
children: [
Positioned(
right: 0,
left: 0,
child: Image.asset(
veggie.imageAssetPath,
fit: BoxFit.cover,
semanticLabel: 'A background image of ${veggie.name}',
),
),
Positioned(
top: 16,
left: 16,
child: SafeArea(
child: CloseButton(() {
context.pop();
}),
),
),
Positioned(
top: 16,
right: 16,
child: SafeArea(
child: Row(
mainAxisSize: MainAxisSize.min,
children: [
ShareButton(() {
showCupertinoModalPopup<void>(
context: context,
builder: (context) {
return CupertinoActionSheet(
title: Text('Share ${veggie.name}'),
message: Text(veggie.shortDescription),
actions: [
CupertinoActionSheetAction(
onPressed: () {
Navigator.pop(context);
},
child: const Text('OK'),
),
],
);
},
);
}),
const SizedBox(width: 8),
Builder(
builder: (context) {
final appState = Provider.of<AppState>(context);
final veggie = appState.getVeggie(id);
return FavoriteButton(
() => appState.setFavorite(id, !veggie.isFavorite),
veggie.isFavorite,
);
},
),
],
),
),
),
],
),
);
}
@override
Widget build(BuildContext context) {
final appState = Provider.of<AppState>(context);
return CupertinoPageScaffold(
child: Column(
crossAxisAlignment: CrossAxisAlignment.stretch,
mainAxisSize: MainAxisSize.min,
children: [
Expanded(
child: ListView(
restorationId: 'list',
children: [
_buildHeader(context, appState),
const SizedBox(height: 20),
InfoView(id),
],
),
),
],
),
);
}
}

@ -1,59 +0,0 @@
// Copyright 2018 The Flutter team. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
import 'package:flutter/cupertino.dart';
import 'package:provider/provider.dart';
import '../data/app_state.dart';
import '../data/veggie.dart';
import '../widgets/veggie_headline.dart';
class FavoritesScreen extends StatelessWidget {
const FavoritesScreen({this.restorationId, super.key});
final String? restorationId;
@override
Widget build(BuildContext context) {
return CupertinoTabView(
restorationScopeId: restorationId,
builder: (context) {
final model = Provider.of<AppState>(context);
return CupertinoPageScaffold(
navigationBar: const CupertinoNavigationBar(
middle: Text('My Garden'),
),
child: Center(
child: model.favoriteVeggies.isEmpty
? Padding(
padding: const EdgeInsets.symmetric(horizontal: 24),
child: Text(
'You haven\'t added any favorite veggies to your garden yet.',
style: CupertinoTheme.of(
context,
).textTheme.textStyle,
),
)
: ListView(
restorationId: 'list',
children: [
const SizedBox(height: 24),
for (Veggie veggie in model.favoriteVeggies)
Padding(
padding: const EdgeInsets.fromLTRB(
16,
0,
16,
24,
),
child: VeggieHeadline(veggie),
),
],
),
),
);
},
);
}
}

@ -1,81 +0,0 @@
// Copyright 2018 The Flutter team. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
import 'package:flutter/cupertino.dart';
import 'package:go_router/go_router.dart';
const _bottomNavigationBarItemIconPadding = EdgeInsets.only(top: 4.0);
class HomeScreen extends StatelessWidget {
const HomeScreen({
super.key,
this.restorationId,
required this.child,
required this.onTap,
});
final String? restorationId;
final Widget child;
final void Function(int) onTap;
@override
Widget build(BuildContext context) {
final String location = GoRouter.of(
context,
).routerDelegate.currentConfiguration.uri.toString();
final index = _getSelectedIndex(location);
return RestorationScope(
restorationId: restorationId,
child: CupertinoPageScaffold(
child: Column(
children: [
Expanded(child: child),
CupertinoTabBar(
currentIndex: index,
items: const [
BottomNavigationBarItem(
icon: Padding(
padding: _bottomNavigationBarItemIconPadding,
child: Icon(CupertinoIcons.home),
),
label: 'Home',
),
BottomNavigationBarItem(
icon: Padding(
padding: _bottomNavigationBarItemIconPadding,
child: Icon(CupertinoIcons.book),
),
label: 'My Garden',
),
BottomNavigationBarItem(
icon: Padding(
padding: _bottomNavigationBarItemIconPadding,
child: Icon(CupertinoIcons.search),
),
label: 'Search',
),
BottomNavigationBarItem(
icon: Padding(
padding: _bottomNavigationBarItemIconPadding,
child: Icon(CupertinoIcons.settings),
),
label: 'Settings',
),
],
onTap: onTap,
),
],
),
),
);
}
int _getSelectedIndex(String location) {
if (location.startsWith('/list')) return 0;
if (location.startsWith('/favorites')) return 1;
if (location.startsWith('/search')) return 2;
if (location.startsWith('/settings')) return 3;
return 0;
}
}

@ -1,95 +0,0 @@
// Copyright 2018 The Flutter team. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
import 'package:flutter/cupertino.dart';
import 'package:flutter/services.dart';
import 'package:provider/provider.dart';
import '../data/app_state.dart';
import '../data/preferences.dart';
import '../data/veggie.dart';
import '../styles.dart';
import '../widgets/veggie_card.dart';
class ListScreen extends StatelessWidget {
const ListScreen({this.restorationId, super.key});
final String? restorationId;
Widget _generateVeggieCard(
Veggie veggie,
Preferences prefs, {
bool inSeason = true,
}) {
return Padding(
padding: const EdgeInsets.only(left: 16, right: 16, bottom: 24),
child: FutureBuilder<Set<VeggieCategory>>(
future: prefs.preferredCategories,
builder: (context, snapshot) {
final data = snapshot.data ?? <VeggieCategory>{};
return VeggieCard(
veggie,
inSeason,
data.contains(veggie.category),
);
},
),
);
}
@override
Widget build(BuildContext context) {
return CupertinoTabView(
restorationScopeId: restorationId,
builder: (context) {
final appState = Provider.of<AppState>(context);
final prefs = Provider.of<Preferences>(context);
final themeData = CupertinoTheme.of(context);
return AnnotatedRegion<SystemUiOverlayStyle>(
value: SystemUiOverlayStyle(
statusBarBrightness: MediaQuery.platformBrightnessOf(context),
),
child: SafeArea(
bottom: false,
child: ListView.builder(
restorationId: 'list',
itemCount: appState.allVeggies.length + 2,
itemBuilder: (context, index) {
if (index == 0) {
return Padding(
padding: const EdgeInsets.fromLTRB(16, 24, 16, 16),
child: Text(
'In season today',
style: Styles.headlineText(themeData),
),
);
} else if (index <= appState.availableVeggies.length) {
return _generateVeggieCard(
appState.availableVeggies[index - 1],
prefs,
);
} else if (index <= appState.availableVeggies.length + 1) {
return Padding(
padding: const EdgeInsets.fromLTRB(16, 24, 16, 16),
child: Text(
'Not in season',
style: Styles.headlineText(themeData),
),
);
} else {
var relativeIndex =
index - (appState.availableVeggies.length + 2);
return _generateVeggieCard(
appState.unavailableVeggies[relativeIndex],
prefs,
inSeason: false,
);
}
},
),
),
);
},
);
}
}

@ -1,132 +0,0 @@
// Copyright 2018 The Flutter team. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
import 'package:flutter/cupertino.dart';
import 'package:flutter/services.dart';
import 'package:provider/provider.dart';
import '../data/app_state.dart';
import '../data/veggie.dart';
import '../widgets/veggie_headline.dart';
class SearchScreen extends StatefulWidget {
const SearchScreen({this.restorationId, super.key});
final String? restorationId;
@override
State<SearchScreen> createState() => _SearchScreenState();
}
class _SearchScreenState extends State<SearchScreen>
with RestorationMixin {
final controller = RestorableTextEditingController();
final focusNode = FocusNode();
String? terms;
@override
String? get restorationId => widget.restorationId;
@override
void restoreState(RestorationBucket? oldBucket, bool initialRestore) {
registerForRestoration(controller, 'text');
controller.addListener(_onTextChanged);
terms = controller.value.text;
}
@override
void dispose() {
focusNode.dispose();
controller.dispose();
super.dispose();
}
void _onTextChanged() {
setState(() => terms = controller.value.text);
}
Widget _createSearchBox({bool focus = true}) {
return Padding(
padding: const EdgeInsets.all(8),
child: CupertinoSearchTextField(
controller: controller.value,
focusNode: focus ? focusNode : null,
),
);
}
Widget _buildSearchResults(List<Veggie> veggies) {
if (veggies.isEmpty) {
return Center(
child: Padding(
padding: const EdgeInsets.symmetric(horizontal: 24),
child: Text(
'No veggies matching your search terms were found.',
style: CupertinoTheme.of(context).textTheme.textStyle,
),
),
);
}
return ListView.builder(
restorationId: 'list',
itemCount: veggies.length + 1,
itemBuilder: (context, i) {
if (i == 0) {
return Visibility(
// This invisible and otherwise unnecessary search box is used to
// pad the list entries downward, so none will be underneath the
// real search box when the list is at its top scroll position.
visible: false,
maintainSize: true,
maintainAnimation: true,
maintainState: true,
// This invisible and otherwise unnecessary search box is used to
// pad the list entries downward, so none will be underneath the
// real search box when the list is at its top scroll position.
child: _createSearchBox(focus: false),
);
} else {
return Padding(
padding: const EdgeInsets.only(
left: 16,
right: 16,
bottom: 24,
),
child: VeggieHeadline(veggies[i - 1]),
);
}
},
);
}
@override
Widget build(BuildContext context) {
final model = Provider.of<AppState>(context);
return UnmanagedRestorationScope(
bucket: bucket,
child: CupertinoTabView(
restorationScopeId: 'tabview',
builder: (context) {
return AnnotatedRegion<SystemUiOverlayStyle>(
value: SystemUiOverlayStyle(
statusBarBrightness: MediaQuery.platformBrightnessOf(
context,
),
),
child: SafeArea(
bottom: false,
child: Stack(
children: [
_buildSearchResults(model.searchVeggies(terms)),
_createSearchBox(),
],
),
),
);
},
),
);
}
}

@ -1,311 +0,0 @@
// Copyright 2018 The Flutter team. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
import 'package:flutter/cupertino.dart';
import 'package:go_router/go_router.dart';
import 'package:provider/provider.dart';
import '../data/preferences.dart';
import '../data/veggie.dart';
import '../styles.dart';
class VeggieCategorySettingsScreen extends StatelessWidget {
const VeggieCategorySettingsScreen({super.key, this.restorationId});
final String? restorationId;
static Page<void> pageBuilder(BuildContext context) {
return const CupertinoPage(
restorationId: 'router.categories',
child: VeggieCategorySettingsScreen(restorationId: 'category'),
title: 'Preferred Categories',
);
}
@override
Widget build(BuildContext context) {
final model = Provider.of<Preferences>(context);
final currentPrefs = model.preferredCategories;
var brightness = CupertinoTheme.brightnessOf(context);
return RestorationScope(
restorationId: restorationId,
child: CupertinoPageScaffold(
navigationBar: const CupertinoNavigationBar(
middle: Text('Preferred Categories'),
previousPageTitle: 'Settings',
),
backgroundColor: Styles.scaffoldBackground(brightness),
child: FutureBuilder<Set<VeggieCategory>>(
future: currentPrefs,
builder: (context, snapshot) {
final tiles = <CupertinoListTile>[];
for (final category in VeggieCategory.values) {
CupertinoSwitch toggle;
// It's possible that category data hasn't loaded from shared prefs
// yet, so display it if possible and fall back to disabled switches
// otherwise.
if (snapshot.hasData) {
toggle = CupertinoSwitch(
value: snapshot.data!.contains(category),
onChanged: (value) {
if (value) {
model.addPreferredCategory(category);
} else {
model.removePreferredCategory(category);
}
},
);
} else {
toggle = const CupertinoSwitch(
value: false,
onChanged: null,
);
}
tiles.add(
CupertinoListTile.notched(
title: Text(veggieCategoryNames[category]!),
trailing: toggle,
),
);
}
return ListView(
restorationId: 'list',
children: [
CupertinoListSection.insetGrouped(
hasLeading: false,
children: tiles,
),
],
);
},
),
),
);
}
}
class CalorieSettingsScreen extends StatelessWidget {
const CalorieSettingsScreen({super.key, this.restorationId});
final String? restorationId;
static const max = 1000;
static const min = 2600;
static const step = 200;
static Page<void> pageBuilder(BuildContext context) {
return const CupertinoPage<void>(
restorationId: 'router.calorie',
child: CalorieSettingsScreen(restorationId: 'calorie'),
title: 'Calorie Target',
);
}
@override
Widget build(BuildContext context) {
final model = Provider.of<Preferences>(context);
var brightness = CupertinoTheme.brightnessOf(context);
return RestorationScope(
restorationId: restorationId,
child: CupertinoPageScaffold(
navigationBar: const CupertinoNavigationBar(
previousPageTitle: 'Settings',
),
backgroundColor: Styles.scaffoldBackground(brightness),
child: ListView(
restorationId: 'list',
children: [
FutureBuilder<int>(
future: model.desiredCalories,
builder: (context, snapshot) {
final tiles = <CupertinoListTile>[];
for (var cals = max; cals < min; cals += step) {
tiles.add(
CupertinoListTile.notched(
title: Text('$cals calories'),
trailing: SettingsIcon(
icon: CupertinoIcons.check_mark,
foregroundColor:
snapshot.hasData && snapshot.data == cals
? CupertinoColors.activeBlue
: Styles.transparentColor,
backgroundColor: Styles.transparentColor,
),
onTap: snapshot.hasData
? () => model.setDesiredCalories(cals)
: null,
),
);
}
return CupertinoListSection.insetGrouped(
header: Text(
'Available calorie levels'.toUpperCase(),
style: Styles.settingsGroupHeaderText(
CupertinoTheme.of(context),
),
),
footer: Text(
'These are used for serving calculations',
style: Styles.settingsGroupFooterText(
CupertinoTheme.of(context),
),
),
children: tiles,
);
},
),
],
),
),
);
}
}
class SettingsScreen extends StatefulWidget {
const SettingsScreen({this.restorationId, super.key});
final String? restorationId;
@override
State<SettingsScreen> createState() => _SettingsScreenState();
}
class _SettingsScreenState extends State<SettingsScreen> {
CupertinoListTile _buildCaloriesTile(
BuildContext context,
Preferences prefs,
) {
return CupertinoListTile.notched(
leading: const SettingsIcon(
backgroundColor: CupertinoColors.systemBlue,
icon: Styles.calorieIcon,
),
title: const Text('Calorie Target'),
additionalInfo: FutureBuilder<int>(
future: prefs.desiredCalories,
builder: (context, snapshot) {
return Text(
snapshot.data?.toString() ?? '',
style: CupertinoTheme.of(context).textTheme.textStyle,
);
},
),
trailing: const CupertinoListTileChevron(),
onTap: () => context.go('/settings/calories'),
);
}
CupertinoListTile _buildCategoriesTile(
BuildContext context,
Preferences prefs,
) {
return CupertinoListTile.notched(
leading: const SettingsIcon(
backgroundColor: CupertinoColors.systemOrange,
icon: Styles.preferenceIcon,
),
title: const Text('Preferred Categories'),
trailing: const CupertinoListTileChevron(),
onTap: () => context.go('/settings/categories'),
);
}
CupertinoListTile _buildRestoreDefaultsTile(
BuildContext context,
Preferences prefs,
) {
return CupertinoListTile.notched(
leading: const SettingsIcon(
backgroundColor: CupertinoColors.systemRed,
icon: Styles.resetIcon,
),
title: const Text('Restore Defaults'),
onTap: () {
showCupertinoDialog<void>(
context: context,
builder: (context) => CupertinoAlertDialog(
title: const Text('Are you sure?'),
content: const Text(
'Are you sure you want to reset the current settings?',
),
actions: [
CupertinoDialogAction(
isDestructiveAction: true,
child: const Text('Yes'),
onPressed: () async {
await prefs.restoreDefaults();
if (!context.mounted) return;
context.pop();
},
),
CupertinoDialogAction(
isDefaultAction: true,
child: const Text('No'),
onPressed: () => context.pop(),
),
],
),
);
},
);
}
@override
Widget build(BuildContext context) {
final prefs = Provider.of<Preferences>(context);
return CupertinoPageScaffold(
backgroundColor: Styles.scaffoldBackground(
CupertinoTheme.brightnessOf(context),
),
child: CustomScrollView(
slivers: <Widget>[
const CupertinoSliverNavigationBar(largeTitle: Text('Settings')),
SliverList(
delegate: SliverChildListDelegate([
CupertinoListSection.insetGrouped(
children: [
_buildCaloriesTile(context, prefs),
_buildCategoriesTile(context, prefs),
],
),
CupertinoListSection.insetGrouped(
children: [_buildRestoreDefaultsTile(context, prefs)],
),
]),
),
],
),
);
}
}
class SettingsIcon extends StatelessWidget {
const SettingsIcon({
required this.icon,
this.foregroundColor = CupertinoColors.white,
this.backgroundColor = CupertinoColors.black,
super.key,
});
final Color backgroundColor;
final Color foregroundColor;
final IconData icon;
@override
Widget build(BuildContext context) {
return Container(
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(5),
color: backgroundColor,
),
child: Center(child: Icon(icon, color: foregroundColor, size: 20)),
);
}
}

@ -1,221 +0,0 @@
// Copyright 2018 The Flutter team. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
import 'package:flutter/cupertino.dart';
import 'package:font_awesome_flutter/font_awesome_flutter.dart';
import 'data/veggie.dart';
abstract class Styles {
static CupertinoThemeData veggieThemeData = const CupertinoThemeData(
textTheme: CupertinoTextThemeData(
textStyle: TextStyle(
color: CupertinoColors.label,
fontSize: 16,
fontWeight: FontWeight.normal,
fontStyle: FontStyle.normal,
fontFamily: 'CupertinoSystemText',
letterSpacing: -0.41,
decoration: TextDecoration.none,
),
),
);
static TextStyle headlineText(CupertinoThemeData themeData) => themeData
.textTheme
.textStyle
.copyWith(fontSize: 32, fontWeight: FontWeight.bold);
static TextStyle minorText(CupertinoThemeData themeData) => themeData
.textTheme
.textStyle
.copyWith(color: const Color.fromRGBO(128, 128, 128, 1));
static TextStyle headlineName(CupertinoThemeData themeData) => themeData
.textTheme
.textStyle
.copyWith(fontSize: 24, fontWeight: FontWeight.bold);
static TextStyle cardTitleText(CupertinoThemeData themeData) =>
themeData.textTheme.textStyle.copyWith(
color: const Color.fromRGBO(0, 0, 0, 0.9),
fontSize: 32,
fontWeight: FontWeight.bold,
);
static TextStyle cardCategoryText(CupertinoThemeData themeData) =>
themeData.textTheme.textStyle.copyWith(
color: const Color.fromRGBO(255, 255, 255, 0.9),
);
static TextStyle cardDescriptionText(CupertinoThemeData themeData) =>
themeData.textTheme.textStyle.copyWith(
color: const Color.fromRGBO(0, 0, 0, 0.9),
);
static TextStyle detailsTitleText(CupertinoThemeData themeData) =>
themeData.textTheme.textStyle.copyWith(
fontSize: 30,
fontWeight: FontWeight.bold,
);
static TextStyle detailsPreferredCategoryText(
CupertinoThemeData themeData,
) => themeData.textTheme.textStyle.copyWith(fontWeight: FontWeight.bold);
static TextStyle detailsBoldDescriptionText(
CupertinoThemeData themeData,
) => themeData.textTheme.textStyle.copyWith(
color: const Color.fromRGBO(0, 0, 0, 0.9),
fontWeight: FontWeight.bold,
);
static TextStyle detailsServingHeaderText(
CupertinoThemeData themeData,
) => themeData.textTheme.textStyle.copyWith(
color: const Color.fromRGBO(176, 176, 176, 1),
fontWeight: FontWeight.bold,
);
static TextStyle detailsServingLabelText(CupertinoThemeData themeData) =>
themeData.textTheme.textStyle.copyWith(fontWeight: FontWeight.bold);
static TextStyle detailsServingNoteText(CupertinoThemeData themeData) =>
themeData.textTheme.textStyle.copyWith(fontStyle: FontStyle.italic);
static TextStyle triviaFinishedTitleText(CupertinoThemeData themeData) =>
themeData.textTheme.textStyle.copyWith(fontSize: 32);
static TextStyle triviaFinishedBigText(CupertinoThemeData themeData) =>
themeData.textTheme.textStyle.copyWith(fontSize: 48);
static TextStyle settingsGroupHeaderText(CupertinoThemeData themeData) =>
themeData.textTheme.textStyle.copyWith(
color: CupertinoColors.inactiveGray,
fontSize: 13.5,
letterSpacing: -0.5,
);
static TextStyle settingsGroupFooterText(CupertinoThemeData themeData) =>
themeData.textTheme.textStyle.copyWith(
color: const Color(0xff777777),
fontSize: 13,
letterSpacing: -0.08,
);
static const appBackground = Color(0xffd0d0d0);
static Color? scaffoldBackground(Brightness brightness) =>
brightness == Brightness.light
? CupertinoColors.extraLightBackgroundGray
: null;
static const frostedBackground = Color(0xccf8f8f8);
static const closeButtonUnpressed = Color(0xff101010);
static const closeButtonPressed = Color(0xff808080);
static TextStyle settingsItemSubtitleText(
CupertinoThemeData themeData,
) => themeData.textTheme.textStyle.copyWith(
fontSize: 12,
letterSpacing: -0.2,
);
static const Color searchCursorColor = Color.fromRGBO(0, 122, 255, 1);
static const Color searchIconColor = Color.fromRGBO(128, 128, 128, 1);
static const seasonColors = <Season, Color>{
Season.winter: Color(0xff336dcc),
Season.spring: Color(0xff2fa02b),
Season.summer: Color(0xff287213),
Season.autumn: Color(0xff724913),
};
// While handy, some of the Font Awesome icons sometimes bleed over their
// allotted bounds. This padding is used to adjust for that.
static const seasonIconPadding = {
Season.winter: EdgeInsets.only(right: 0),
Season.spring: EdgeInsets.only(right: 4),
Season.summer: EdgeInsets.only(right: 6),
Season.autumn: EdgeInsets.only(right: 0),
};
static const seasonIconData = {
Season.winter: FontAwesomeIcons.snowflake,
Season.spring: FontAwesomeIcons.leaf,
Season.summer: FontAwesomeIcons.umbrellaBeach,
Season.autumn: FontAwesomeIcons.canadianMapleLeaf,
};
static const seasonBorder = Border(
top: BorderSide(color: Color(0xff606060)),
left: BorderSide(color: Color(0xff606060)),
bottom: BorderSide(color: Color(0xff606060)),
right: BorderSide(color: Color(0xff606060)),
);
static const uncheckedIcon = IconData(
0xf372,
fontFamily: CupertinoIcons.iconFont,
fontPackage: CupertinoIcons.iconFontPackage,
);
static const checkedIcon = IconData(
0xf373,
fontFamily: CupertinoIcons.iconFont,
fontPackage: CupertinoIcons.iconFontPackage,
);
static const transparentColor = Color(0x00000000);
static const shadowColor = Color(0xa0000000);
static const shadowGradient = LinearGradient(
begin: Alignment.topCenter,
end: Alignment.bottomCenter,
colors: [transparentColor, shadowColor],
);
static const Color settingsMediumGray = Color(0xffc7c7c7);
static const Color settingsItemPressed = Color(0xffd9d9d9);
static Color settingsItemColor(Brightness brightness) =>
brightness == Brightness.light
? CupertinoColors.tertiarySystemBackground
: CupertinoColors.darkBackgroundGray;
static Color settingsLineation(Brightness brightness) =>
brightness == Brightness.light
? const Color(0xffbcbbc1)
: const Color(0xff4c4b4b);
static const Color settingsBackground = Color(0xffefeff4);
static const preferenceIcon = IconData(
0xf443,
fontFamily: CupertinoIcons.iconFont,
fontPackage: CupertinoIcons.iconFontPackage,
);
static const resetIcon = IconData(
0xf4c4,
fontFamily: CupertinoIcons.iconFont,
fontPackage: CupertinoIcons.iconFontPackage,
);
static const calorieIcon = IconData(
0xf3bb,
fontFamily: CupertinoIcons.iconFont,
fontPackage: CupertinoIcons.iconFontPackage,
);
static const servingInfoBorderColor = Color(0xffb0b0b0);
static const ColorFilter desaturatedColorFilter =
// 222222 is a random color that has low color saturation.
ColorFilter.mode(Color(0xff222222), BlendMode.saturation);
}

@ -1,148 +0,0 @@
// Copyright 2018 The Flutter team. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
import 'dart:ui' as ui;
import 'package:flutter/cupertino.dart';
import '../styles.dart';
/// Partially overlays and then blurs its child's background.
class FrostedBox extends StatelessWidget {
const FrostedBox({this.child, super.key});
final Widget? child;
@override
Widget build(BuildContext context) {
return BackdropFilter(
filter: ui.ImageFilter.blur(sigmaX: 10, sigmaY: 10),
child: DecoratedBox(
decoration: const BoxDecoration(color: Styles.frostedBackground),
child: child,
),
);
}
}
/// An Icon that implicitly animates changes to its color.
class ColorChangingIcon extends ImplicitlyAnimatedWidget {
const ColorChangingIcon(
this.icon, {
this.color = CupertinoColors.black,
this.size,
required super.duration,
super.key,
});
final Color color;
final IconData icon;
final double? size;
@override
AnimatedWidgetBaseState<ColorChangingIcon> createState() =>
_ColorChangingIconState();
}
class _ColorChangingIconState
extends AnimatedWidgetBaseState<ColorChangingIcon> {
ColorTween? _colorTween;
@override
Widget build(BuildContext context) {
return Icon(
widget.icon,
semanticLabel: 'Close button',
size: widget.size,
color: _colorTween?.evaluate(animation),
);
}
@override
void forEachTween(TweenVisitor<dynamic> visitor) {
_colorTween =
visitor(
_colorTween,
widget.color,
(dynamic value) => ColorTween(begin: value as Color?),
)
as ColorTween?;
}
}
/// A close button that invokes a callback when pressed.
class CloseButton extends _DetailPageButton {
const CloseButton(VoidCallback onPressed, {super.key})
: super(onPressed, CupertinoIcons.chevron_back);
}
/// A share button that invokes a callback when pressed.
class ShareButton extends _DetailPageButton {
const ShareButton(VoidCallback onPressed, {super.key})
: super(onPressed, CupertinoIcons.share);
}
/// A favorite button that invokes a callback when pressed.
class FavoriteButton extends _DetailPageButton {
const FavoriteButton(
VoidCallback onPressed,
bool isFavorite, {
super.key,
}) : super(
onPressed,
isFavorite ? CupertinoIcons.heart_fill : CupertinoIcons.heart,
);
}
class _DetailPageButton extends StatefulWidget {
const _DetailPageButton(this.onPressed, this.icon, {super.key});
final VoidCallback onPressed;
final IconData icon;
@override
State<_DetailPageButton> createState() => _DetailPageButtonState();
}
class _DetailPageButtonState extends State<_DetailPageButton> {
bool tapInProgress = false;
@override
Widget build(BuildContext context) {
return GestureDetector(
onTapDown: (details) {
setState(() => tapInProgress = true);
},
onTapUp: (details) {
setState(() => tapInProgress = false);
widget.onPressed();
},
onTapCancel: () {
setState(() => tapInProgress = false);
},
child: ClipOval(
child: FrostedBox(
child: Container(
width: 30,
height: 30,
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(15),
),
child: Center(
child: ColorChangingIcon(
widget.icon,
duration: const Duration(milliseconds: 300),
color: tapInProgress
? Styles.closeButtonPressed
: Styles.closeButtonUnpressed,
size: 20,
),
),
),
),
),
);
}
}

@ -1,114 +0,0 @@
// Copyright 2018 The Flutter team. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:go_router/go_router.dart';
import '../data/veggie.dart';
import '../styles.dart';
/// A Card-like Widget that responds to tap events by animating changes to its
/// elevation and invoking an optional [onPressed] callback.
class PressableCard extends StatelessWidget {
const PressableCard({
required this.child,
this.borderRadius = const BorderRadius.all(Radius.circular(16)),
this.onPressed,
super.key,
});
final VoidCallback? onPressed;
final Widget child;
final BorderRadius borderRadius;
@override
Widget build(BuildContext context) {
return GestureDetector(
onTap: onPressed,
child: Container(
decoration: BoxDecoration(borderRadius: borderRadius),
child: ClipRRect(borderRadius: borderRadius, child: child),
),
);
}
}
class VeggieCard extends StatelessWidget {
const VeggieCard(
this.veggie,
this.isInSeason,
this.isPreferredCategory, {
super.key,
});
/// Veggie to be displayed by the card.
final Veggie veggie;
/// If the veggie is in season, it's displayed more prominently and the
/// image is fully saturated. Otherwise, it's reduced and de-saturated.
final bool isInSeason;
/// Whether [veggie] falls into one of user's preferred [VeggieCategory]s
final bool isPreferredCategory;
Widget _buildDetails(BuildContext context) {
final themeData = CupertinoTheme.of(context);
return Container(
color: Colors.white,
child: Padding(
padding: const EdgeInsets.fromLTRB(20, 16, 16, 20),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(veggie.name, style: Styles.cardTitleText(themeData)),
const SizedBox(height: 8),
Text(
veggie.shortDescription,
style: Styles.cardDescriptionText(themeData),
),
],
),
),
);
}
@override
Widget build(BuildContext context) {
return PressableCard(
onPressed: () {
// GoRouter does not support relative routes,
// so navigate to the absolute route.
// see https://github.com/flutter/flutter/issues/108177
context.go('/list/details/${veggie.id}');
},
child: Stack(
children: [
Semantics(
label: 'A card background featuring ${veggie.name}',
child: Container(
height: isInSeason ? 300 : 150,
decoration: BoxDecoration(
image: DecorationImage(
fit: BoxFit.cover,
colorFilter: isInSeason
? null
: Styles.desaturatedColorFilter,
image: AssetImage(veggie.imageAssetPath),
),
),
),
),
Positioned(
bottom: 0,
left: 0,
right: 0,
child: _buildDetails(context),
),
],
),
);
}
}

@ -1,117 +0,0 @@
// Copyright 2018 The Flutter team. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
import 'package:flutter/cupertino.dart';
import 'package:go_router/go_router.dart';
import '../data/veggie.dart';
import '../styles.dart';
class ZoomClipAssetImage extends StatelessWidget {
const ZoomClipAssetImage({
required this.zoom,
this.height,
this.width,
required this.imageAsset,
super.key,
});
final double zoom;
final double? height;
final double? width;
final String imageAsset;
@override
Widget build(BuildContext context) {
return Container(
height: height,
width: width,
alignment: Alignment.center,
child: ClipRRect(
borderRadius: BorderRadius.circular(10),
child: OverflowBox(
maxHeight: height! * zoom,
maxWidth: width! * zoom,
child: Image.asset(imageAsset, fit: BoxFit.fill),
),
),
);
}
}
class VeggieHeadline extends StatelessWidget {
final Veggie veggie;
const VeggieHeadline(this.veggie, {super.key});
List<Widget> _buildSeasonDots(List<Season> seasons) {
var widgets = <Widget>[];
for (var season in seasons) {
widgets.add(const SizedBox(width: 4));
widgets.add(
Container(
height: 10,
width: 10,
decoration: BoxDecoration(
color: Styles.seasonColors[season],
borderRadius: BorderRadius.circular(5),
),
),
);
}
return widgets;
}
@override
Widget build(BuildContext context) {
final themeData = CupertinoTheme.of(context);
final String location = GoRouter.of(
context,
).routerDelegate.currentConfiguration.uri.toString();
return GestureDetector(
onTap: () {
// GoRouter does not support relative routes,
// so navigate to the absolute route, which can be either
// `/favorites/details/${veggie.id}` or `/search/details/${veggie.id}`
// see https://github.com/flutter/flutter/issues/108177
context.go('$location/details/${veggie.id}');
},
child: Row(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
ZoomClipAssetImage(
imageAsset: veggie.imageAssetPath,
zoom: 2.4,
height: 72,
width: 72,
),
const SizedBox(width: 8),
Flexible(
child: Column(
mainAxisAlignment: MainAxisAlignment.start,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Row(
children: [
Text(
veggie.name,
style: Styles.headlineName(themeData),
),
..._buildSeasonDots(veggie.seasons),
],
),
Text(
veggie.shortDescription,
style: themeData.textTheme.textStyle,
),
],
),
),
],
),
);
}
}

@ -1,45 +0,0 @@
// Copyright 2024, the Flutter project authors. Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
import 'package:flutter/cupertino.dart';
class VeggieSeasonsPage<T> extends Page<T> {
final Widget child;
const VeggieSeasonsPage({
super.key,
required this.child,
super.restorationId,
});
@override
VeggieSeasonsPageRoute<T> createRoute(BuildContext context) =>
VeggieSeasonsPageRoute<T>(this);
}
class VeggieSeasonsPageRoute<T> extends PageRoute<T> {
VeggieSeasonsPageRoute(VeggieSeasonsPage<T> page)
: super(settings: page);
VeggieSeasonsPage<T> get _page => settings as VeggieSeasonsPage<T>;
@override
Color? get barrierColor => null;
@override
String? get barrierLabel => null;
@override
bool get maintainState => true;
@override
Duration get transitionDuration => Duration.zero;
@override
Widget buildPage(
BuildContext context,
Animation<double> animation,
Animation<double> secondaryAnimation,
) => _page.child;
}

Some files were not shown because too many files have changed in this diff Show More

Loading…
Cancel
Save